| | 1 | [[PageOutline]] |
| | 2 | = MariaDB 바이너리 로그 = |
| | 3 | 증분 백업을 하거나 복제를 하려면 바이너리 로그를 저장해야 한다. 그런데 바이너리 로그 파일은 세 가지 포맷이 있다. 이를 이해하기 위해서는 안전한 SQL문과 안전하지 않은 SQL문을 알아야 한다. |
| | 4 | |
| | 5 | FOUND_ROWS(), RAND(), USER(), UUID() 등과 같은 함수는 실행할 때마다 다른 결과가 나오므로(non deterministic) 마스터 서버에서 실행했던 함수를 슬레이브 서버에서 실행한다고 하더라도 같은 결과가 나오지 않는다. 이를 안전하지 않은 SQL문(unsafe statements)이라고 한다. |
| | 6 | |
| | 7 | == DETERMINISTIC == |
| | 8 | 프로시저나 함수를 만들 때 DETERMINISTIC인지 NOT DETERMINISTIC인지 지정해야 한다. |
| | 9 | - DETERMINISTIC 은 함수나 프로시저를 같은 파라미터로 호출했을 때 항상 같은 결과가 나오는 경우를 말한다. |
| | 10 | - DETERMINISTIC으로 지정한 프로시저나 함수는 바이너리 로그 포맷이 MIXED일 때 바이너리 로그를 STATEMENT 포맷으로 저장한다. |
| | 11 | - NOT DETERMINISTIC은 디폴트 값이므로 지정하지 않아도 무방하다. |
| | 12 | |
| | 13 | == 바이너리 로그 포맷 == |
| | 14 | |
| | 15 | === 1. STATEMENT === |
| | 16 | SQL문 자체를 로그로 저장한다. |
| | 17 | - 로그 파일의 크기가 작은 장점이 있다. |
| | 18 | - 안전하지 않은 SQL문도 로그로 저장되긴 하지만 제대로 복제되지 않는다. 안전하지 않은 SQL문은 다음과 같은 경고를 생성한다. [Warning] Statement is not safe to log in statement format. |
| | 19 | - 제대로 복제를 하기 위해서는 안전하지 않은 SQL문을 쓰지 않고 코딩해야 하는데 실수는 언제든지 할 수 있기 때문에 이 바이너리 포맷은 피하는 게 좋다. |
| | 20 | - MySQL부터 내려온 전통적인 포맷이다. 바이너리 로그 포맷을 명시적으로 지정하지 않으면 이 포맷이 디폴트가 된다. |
| | 21 | - 5.1.4 이전 버전에는 이 포맷만 사용할 수 있다. |
| | 22 | |
| | 23 | === 2. ROW === |
| | 24 | SQL문과 상관없이 개별 테이블이 어떻게 변했는지를 저장한다. |
| | 25 | - 다른 DBMS에서 사용하는 일반적인 포맷이다. |
| | 26 | - 복제에 가장 안전한 선택이다. 안전하지 않은 SQL문을 사용하더라도 복제에 문제가 없다. |
| | 27 | - STATEMENT 포맷에 비해 로그 파일 크기가 큰 경향이 있다. |
| | 28 | - 또다른 단점으로는 슬레이브 서버의 MyISAM 테이블에 INSERT를 할 때 STATEMENT 포맷보다 더 강력한 잠금이 필요해서 동시(concurrent) INSERT가 안된다. 슬레이브 서버의 MyISAM 테이블에 동기화가 좀 늦을 수 있다는 정도이므로 큰 문제는 아니다. |
| | 29 | - 임시 테이블은 복제할 수 없다. (복제할 필요도 없다.) |
| | 30 | - 바이너리 로그 포맷을 ROW로 지정해도 mysql 데이터베이스의 변경 사항(GRANT, REVOKE 같은 명령과 트리거, 프로시저, 함수, 뷰 생성 등)은 STATEMENT 포맷으로 저장한다. CREATE 문 같은 DDL 문 역시 STATEMENT 포맷으로 저장한다. |
| | 31 | |
| | 32 | === 3. MIXED === |
| | 33 | 안전한 SQL문은 STATEMENT 포맷으로, 안전하지 않은 SQL문은 ROW 포맷으로 저장한다. |
| | 34 | - STATEMENT 포맷과 ROW 포맷의 장점만 모아놓은 것 같지만, 안전하지 않은(NON DETERMINISTIC) 함수를 DETERMINISTIC이라고 잘못 지정하면 복제가 제대로 안된다. MySQL은 DETERMINISTIC 으로 선언된 함수가 실제로 DETERMINISTIC인지 확인하지 않으므로 내용에 상관없이 지정된 대로 STATEMENT 포맷으로 저장하기 때문이다. 예를 들어 다음 함수는 데이터를 수정해서 안전하지 않을 수 있는데 이를 DETERMINISTIC으로 생성하면 복제에 문제가 생긴다. |
| | 35 | {{{ |
| | 36 | CREATE FUNCTION f3(p_id INT) |
| | 37 | RETURNS INT |
| | 38 | DETERMINISTIC |
| | 39 | BEGIN |
| | 40 | UPDATE t SET modtime = NOW() WHERE id = p_id; |
| | 41 | RETURN ROW_COUNT(); |
| | 42 | END; |
| | 43 | }}} |
| | 44 | - 이런 위험 때문에 MySQL은 SUPER 권한을 가진 계정만 프로시저나 함수를 만들 수 있도록 하고 만든다 해도 DETERMINISTIC 함수만 만들 수 있게 제한한다 .(log_bin_trust_function_creators=1을 지정하면 CREATE ROUTINE 권한이 있는 계정은 프로시저나 함수를 만들 수 있고 NON DETERMINISTIC 함수도 만들 수 있다.) |
| | 45 | - DETERMINISTIC 여부는 복제 뿐만 아니라 성능 문제 때문에라도 정확하게 지정해야 하는 것은 맞지만, SUPER 권한을 가진 계정도 실수를 할 수 있기 때문에 이 포맷은 신중하게 판단해서 사용해야 한다. |
| | 46 | |
| | 47 | ---- |
| | 48 | [WikiStart 처음으로] |