1.3.1. 리플리케이션 기능 및 이슈 사항
1.3.1.1. 리플리케이션과 AUTO_INCREMENT
1.3.1.2. 리플리케이션과 문자 셋
1.3.1.3. 리플리케이션과 DIRECTORY 명령문
1.3.1.4. 이미 실행된 기능에 대한 리플리케이션
1.3.1.5. 부동 소수점 값을 사용한 리플리케이션
1.3.1.6. 리플리케이션과 FLUSH
1.3.1.7. 리플리케이션과 시스템 함수
1.3.1.8. 마스터 서버에서 크래시가 발생하는 동안의 리플리케이션
1.3.1.9. 마스터 서버가 셧 다운되는 동안의 리플리케이션
1.3.1.10. MEMORY 테이블 타입을 사용하는 리플리케이션
1.3.1.11. 시스템 mysql 데이터베이스 리플리케이션
1.3.1.12. 리플리케이션이 실행되는 동안에 발생하는 슬레이브 에러
1.3.1.13. 슬레이브가 셧 다운 되는 동안의 리플리케이션
1.3.1.14. 리플리케이션과 임시 테이블
1.3.1.15. 리플리케이션 재 시도와 타임 아웃
1.3.1.16. 리플리케이션과 타임존
1.3.1.17. 리플리케이션과 트랜젝션
1.3.1.18. 슬레이브가 마스터보다 더 많은 컬럼을 사용하는 경우의 리플리케이션
1.3.1.19. 리플리케이션과 변수
1.3.1.20. 리플리케이션과 뷰
일반적으로, SQL 레벨의 리플리케이션 호환성은 마스터와 슬레이브 서버 양쪽 모두가 지원하는 기능을 사용해야 한다. 주어진 MySQL 버전 이상에서만 사용할 수 있는 기능을 마스터에서 사용한다면, 그 버전 보다 낮은 것을 사용하는 슬레이브와는 리플리케이션을 실행할 수 없다. 이러한 호환성 문제는 버전 시리즈 사이에서 발생할 수 있다. 하지만, 같은 버전 시리즈 간에서도 이러한 호환성 문제가 발생할 수 있다. 예를 들면, SLEEP() 함수는 MySQL 5.0.12 이상 버전에서만 사용이 가능하다. 이 함수를 마스터 서버에서 사용한다면, MySQL 5.0.12보다 이전 버전을 사용하는 슬레이브와는 리플리케이션을 구현할 수 없게 된다.
MySQL 5.1 서버와 5.1 이전 버전 서버를 리플리케이션 하고자 계획한다면, 5.1 이전 버전의 리플리케이션 특성을 설명하는 레퍼런스 매뉴얼을 참조하도록 한다.
1.3.1.1. 리플리케이션과 AUTO_INCREMENT
AUTO_INCREMENT, LAST_INSERT_ID(), 그리고 TIMESTAMP 값에 대한 리플리케이션은 올바르게 실행되지만, 다음과 같은 상황에서는 리플리케이션이 올바르게 진행되지 않는다.
LAST_INSERT_ID()를 사용하는 스토어드 프로시저는 명령문 기반 바이너리 로깅으로 올바르게 복제할 수 없다. 이 제약 사항은 MySQL 5.1.12 이후에 해결 되었다.
ALTER TABLE를 사용해서 AUTO_INCREMENT 컬럼을 테이블에 추가하면 슬레이브와 마스터에 동일한 순서의 열이 생성되지 않을 수 있다. 그 이유는, 열의 순서는 테이블이 사용하는 특정 스토리지 엔진과 열이 삽입되는 순서에 따라 달라지기 때문이다. 마스터와 슬레이브의 테이블 열 순서가 같아야만 하는 경우라면, AUTO_INCREMENT를 실행하기 전에 열을 우선 정렬하도록 한다. AUTO_INCREMENT 컬럼을 테이블 t1에 추가하는 경우, 아래의 명령문은 AUTO_INCREMENT 컬럼을 사용해서 t1과 동일한 t2 테이블을 새롭게 생성한다:
CREATE TABLE t2 LIKE t1;
ALTER TABLE t2 ADD id INT AUTO_INCREMENT PRIMARY KEY;
INSERT INTO t2 SELECT * FROM t1 ORDER BY col1, col2;
Important: 마스터와 슬레이브 양쪽 테이블이 동일한 순서를 가지도록 하기 위해서는, t1 테이블의 모든 컬럼을 ORDER BY 구문이 참조해야 한다.
위에서 설명한 내용은 CREATE TABLE ... LIKE의 제약 사항과 관련이 있다: 퍼린 키 (Foreign key) 정의문은 DATA DIRECTORY 및 INDEX DIRECTORY 테이블 옵션과 마찬가지로 무시된다. 테이블 정의문에 이러한 특성 중의 하나가 포함되어 있다면, t1을 생성할 때 사용한 것과 같은 CREATE TABLE 명령문을 사용해서 t2 테이블을 생성하되, AUTO_INCREMENT 컬럼을 추가적으로 사용하도록 한다.
AUTO_INCREMENT 컬럼을 가지고 있는 복사본을 생성 및 파퓰레이트 (populate)할 때 사용한 방법과는 상관없이, 마지막 단계에서는 원본 테이블을 제거한 후에 복사본 이름을 다른 것으로 변경한다:
DROP t1;
ALTER TABLE t2 RENAME t1;
1.3.1.2. 리플리케이션과 문자 셋
서로 다른 문자 셋을 사용하는 MySQL 서버 간의 리플리케이션은 다음과 같이 구성한다:
1. 마스터가 MySQL 4.1 버전을 사용하고 있다면, 슬레이브의 MySQL 버전과는 상관 없이 마스터와 슬레이브에서 항상 동일한 글로벌 문자 셋과 콜레션을 사용하도록 한다. (--character-set-server 및 --collation-server 옵션을 사용할 것.) 그렇지 않으면, 마스터 문자 셋에서는 고유 값을 갖는 키라도 슬레이브 문자 셋에서는 그렇지 않을 수 있기 때문에 슬레이브에서 중복-키 에러가 발생할 수 있다. 마스터와 슬레이브가 모두 MySQL 5.0 이상의 버전을 사용한다면 이 문제는 발생하지 않는다는 점을 알아 두자.
2. 마스터가 MySQL 4.1.3 이전 버전을 사용한다면, 모든 클라이언트 문자 셋을 글로벌 값과는 다르게 만들 수 없는데, 그 이유는 이러한 문자 셋 변경을 슬레이브가 알지 못하기 때문이다. 다른 말로 설명하면, 클라이언트는 SET NAMES, SET CHARACTER SET 등을 사용할 수 없게 된다. 마스터와 슬레이브 모두가 4.1.3 이후 버전을 사용한다면, 클라이언트는 문자 셋 변수 세션 값을 자유롭게 설정할 수 있는데, 그 이유는 이러한 설정이 바이너리 로그에 기록되고 슬레이브가 그 내용을 알게 되기 때문이다. 즉, 클라이언트는 SET NAMES 또는 SET CHARACTER SET을 사용하거나 또는 변수 collation_client 또는 collation_server와 같은 변수를 설정할 수 있다. 하지만, 클라이언트는 이러한 변수의 글로벌 값을 변경하지는 못한다; 위에서 언급하였듯이, 마스터와 슬레이브는 반드시 동일한 글로벌 문자 셋 값을 가져야 한다.
3. 마스터 데이터베이스가 글로벌 character_set_server 값과 다른 문자 셋을 사용한다면, 데이터베이스 테이블이 데이터베이스 디폴트 문자 셋에 의존하지 않도록 CREATE TABLE 명령문을 작성해야 한다. CREATE TABLE 명령문에서 문자 셋과 콜레션을 명확하게 언급하면 된다.
1.3.1.3. 리플리케이션과 DIRECTORY 명령문
마스터 서버의 CREATE TABLE 명령문에서 DATA DIRECTORY 또는 INDEX DIRECTORY 테이블 옵션이 사용되었다면, 테이블 옵션 역시 슬레이브에서 사용된다. 이로 인해, 슬레이브 호스트 파일 시스템에 이에 상응하는 디렉토리가 존재하지 않거나 또는 그러한 디렉토리가 존재하기는 하지만 슬레이브가 접근할 수 없다면, 문제가 발생하게 된다. MySQL은 NO_DIR_IN_CREATE라고 하는 sql_mode 옵션을 지원한다. 슬레이브 서버가 SQL 모드 활성화 상태로 구동되면, 슬레이브 서버는 CREATE TABLE 명령문을 복제할 때 DATA DIRECTORY 및 INDEX DIRECTORY 테이블 옵션을 무시한다. 그 결과, MyISAM 데이터 및 인덱스 파일은 테이블의 데이터베이스 디렉토리에 생성된다.
1.3.1.4. 이미 실행된 기능 (Invoked feature)에 대한 리플리케이션
스케줄된 이벤트, 사용자-정의 함수 (UDF), 스토어드 루틴 (스토어드 프로시저 및 스토어드 함수를 포함), 그리고 트리거와 같이 이미 실행된 기능에 대한 리플리케이션은 MySQL 5.1.18 이후에 다음과 같은 특성을 제공한다:
-
이러한 기능들은 항상 복제된다.
-
다음의 명령문들은 명령문 기반 리플리케이션을 사용해서 복제된다:
-
CREATE EVENT
-
ALTER EVENT
-
DROP EVENT
-
CREATE PROCEDURE
-
DROP PROCEDURE
-
CREATE FUNCTION
-
DROP FUNCTION
-
CREATE TRIGGER
-
DROP TRIGGER
하지만, 이러한 명령문이 생성, 수정, 삭제한 것들은 열 기반 리플리케이션으로 복제할 수 있다.
-
CREATE EVENT 및 ALTER EVENT의 경우:
-
이벤트 상태는 지정된 상태와는 상관없이 슬레이브의 SLAVESIDE_DISABLED에 설정된다. (DROP EVENT에는 적용되지 않음).
-
이벤트가 생성된 마스터는 자신의 서버 ID에 의해 슬레이브에서 구분된다. INFORMATION_SCHEMA.EVENTS의 ORIGINATOR 컬럼 및 mysql.event의 originator 컬럼은 MySQL 5.1.18에서 이러한 정보를 저장하기 위해 테이블에 추가되었다.
-
마스터가 실패하는 경우에 다시 할 수 있도록 기능 구현을 슬레이브에 저장하였기 때문에, 슬레이브는 이벤트 프로세싱을 잃어 버리지 않은 채로 마스터 역할을 수행할 수 있다.
서로 다른 서버에서 생성된 스케줄 이벤트가 마스터에 존재하는지를 확인하기 위해서는, SHOW EVENTS 명령문을 다음과 같이 사용한다:
SHOW EVENTS
WHERE STATUS = 'SLAVESIDE_DISABLED';
또한, 다음과 같이 INFORMATION_SCHEMA.EVENTS 테이블 쿼리를 사용해도 된다:
SELECT EVENT_SCHEMA, EVENT_NAME, ORIGINATOR
FROM INFORMATION_SCHEMA.EVENTS
WHERE STATUS = 'SLAVESIDE_DISABLED';
그와 같은 이벤트를 가지고 있는 리플리케이션 슬레이브를 리플리케이션 마스터로 변환 시키는 경우에는, 이벤트를 활성화 하기 위한 쿼리를 다음과 같이 사용한다:
UPDATE mysql.event
SET STATUS = 'ENABLED'
WHERE STATUS = 'SLAVESIDE_DISABLED';
하나 이상의 마스터 서버가 슬레이브에 있는 이벤트를 생성하는 경우에 서버 ID가 master_id인 마스터가 생성한 이벤트만 활성화 하고자 한다면, 다음과 같은 쿼리를 대신 사용한다:
UPDATE mysql.event
SET STATUS = 'ENABLED'
WHERE ORIGINATOR = master_id
AND STATUS = 'SLAVESIDE_DISABLED';
Important
위의 두 UPDATE 명령문 중의 하나를 실행하기 전에는 반드시 슬레이브의 이벤트 스케줄러 (Event Scheduler)는 비활성화 시키고 (SET GLOBAL EVENT_SCHEDULER = OFF;를 사용), UPDATE를 구동하고, 서버를 재 시작한 후에, 마지막으로 이벤트 스케줄러를 다시 활성화 시켜야 한다 (SET GLOBAL EVENT_SCHEDULER = ON;를 사용).
새로운 마스터를 나중에 다시 리플리케이션 슬레이브로 변경하는 경우에는, UPDATE 명령문이 활성화시킨 모든 이벤트를 반드시 수동으로 비활성화 시켜야 한다. 이렇게 하기 위해서는, 위의 SELECT 명령문 결과로 나온 이벤트 이름을 별도의 테이블에 저장하거나, 또는 UPDATE 명령문을 사용해서 공통의 접두사를 가진 이벤트 이름을 변경하면 된다:
UPDATE mysql.event
SET name = CONCAT('replicated_', name)
WHERE status = 'SLAVESIDE_DISABLED';
마스터 서버를 리플리케이션 슬레이브로 변경하는 경우에는, 다음과 같이 이벤트 이름을 변경하고 비활성화 시키도록 한다:
UPDATE mysql.event
SET name = REPLACE(name, 'replicated_', ''),
status = 'SLAVESIDE_DISABLED'
WHERE INSTR(name, 'replicated_') = 1;
1.3.1.5. 부동 소수점 값을 사용한 리플리케이션
부동 소수점 값은 대략적인 값 (approximate)이기 때문에, 이러한 값이 있는 것을 비교하는 것은 부정확하게 된다. 컴퓨터 구조 또는 MySQL을 구축할 때 사용한 컴파일러 등의 차이로 인해, 부동 소수점 값 비교는 마스터와 슬레이브에서 서로 다른 값을 가지게 된다.
1.3.1.6. 리플리케이션과 FLUSH
FLUSH 명령문 중의 어떤 것들은 슬레이브에 복제될 때 문제를 발생시키기 때문에 기록되지 않기도 한다: FLUSH LOGS, FLUSH MASTER, FLUSH SLAVE, 그리고 FLUSH TABLES WITH READ LOCK가 여기에 해당한다. FLUSH TABLES, ANALYZE TABLE, OPTIMIZE TABLE, 그리고 REPAIR TABLE 명령문은 바이너리 로그에 기록되기 때문에 당연히 슬레이브에 복제된다. 일반적인 경우에는, 이러한 명령문들이 테이블 데이터를 수정하지 않기 때문에 문제가 되지는 않지만, 특정 환경 아래에서는 해결하기 힘든 문제를 발생 시킬 수 있다. mysql 데이터베이스에 있는 권한 테이블을 복제한 후에 GRANT를 사용하지 않고서 직접 그 테이블을 업데이트한다면, 새로운 권한이 적용되도록 슬레이브에서 FLUSH PRIVILEGES를 실행해야만 한다. 또한, MERGE 테이블의 일부분인 MyISAM 테이블 이름을 변경할 때 FLUSH TABLES를 사용한다면, 반드시 슬레이브에서 수동으로 FLUSH TABLES를 실행해야 한다. 명령문 NO_WRITE_TO_BINLOG 또는 이에 대한 별칭인 LOCAL을 지정하지 않는 한 이러한 명령문들은 바이너리 로그에 기록된다.
1.3.1.7. 리플리케이션과 시스템 함수
다음과 같은 조건 아래에서는 특정 함수들이 올바르게 복제되지 않는다:
-
USER(), CURRENT_USER(), UUID(), VERSION(), 그리고 LOAD_FILE() 함수는 변경 없이 복제되기 때문에 열 기반 리플리케이션이 활성화 되지 않았다면 슬레이브에서 올바르게 구동을 하지 않는다.
-
NOW()와는 달리, SYSDATE() 함수는 리플리케이션-세이프 (replication-safe) 하지 않는데, 그 이유는 이 함수가 바이너리 로그에서 SET TIMESTAMP 명령문에 영향을 받지 않으며, 명령문 기반 리플리케이션이 활성화 되는 경우에는 논-디터미스틱 (non-deterministic)하기 때문이다. 하지만, 열 기반 리플리케이션 로깅을 사용하면 문제가 되지 않는다. 또 다른 방법으로는, 서버를 --sysdate-is-now 옵션과 함께 시작해서 SYSDATE()로 하여금 NOW() 함수의 별칭으로 동작하게끔 만들면 된다.
-
다음 내용은 열 기반 리플리케이션이 아닌 명령문 기반 리플리케이션에 대해서만 적용되는 제약 사항이다. 사용자-레벨 잠금을 처리하는 GET_LOCK(), RELEASE_LOCK(), IS_FREE_LOCK(), 그리고 IS_USED_LOCK() 함수는 마스터의 컨커런시 컨텍스트 (concurrency context)를 슬레이브가 모르더라도 올바르게 복제된다. 따라서, 마스터 테이블에 삽입을 할 때에는 이러한 함수들을 사용하지 말도록 한다. (예를 들면, INSERT INTO mytable VALUES(GET_LOCK(...))와 같은 명령문은 실행할 수 없다.)
명령문 기반 리플리케이션을 사용할 때 위의 제약 사항을 해소하기 위한 방법으로는, 문제를 일으킬 수 있는 함수가 사용자 변수 대신에 바로 전 명령문에 나오는 변수를 참조하도록 만드는 것이다. 예를 들면, 아래의 INSERT 명령문은 UUID() 함수를 참조하기 때문에 문제가 발생할 수 있다:
INSERT INTO t VALUES(UUID());
대신에, 다음과 같이 수정해서 사용하면 된다:
SET @my_uuid = UUID();
INSERT INTO t VALUES(@my_uuid);
위의 명령문 시퀀스는 @my_uuid 값이 바이너리 로그에 INSERT 명령문 앞에 저장되어 있고, INSERT명령문이 사용할 수 있기 때문에 올바르게 복제가 된다.
동일한 개념을 사용해서 여러 개의 열을 삽입할 수는 있으나 다소 사용이 번거로울 수 있다. 두 개의 열을 삽입하는 경우에는 다음과 같이 한다:
SET @my_uuid1 = UUID(); @my_uuid2 = UUID();
INSERT INTO t VALUES(@my_uuid1),(@my_uuid2);
하지만, 많은 수의 열을 삽입할 수 있는 좋은 방법은 없다.
1.3.1.8. 마스터 서버에서 크래시가 발생하는 동안의 리플리케이션
마스터 서버에서 크래시가 발생하면, 마스터 서버의 바이너리 로그가 플러시 되지 않기 때문에 슬레이브는 가장 최근 위치가 아닌 마지막 위치를 가지고 있는 마스터 바이너리 로그를 읽게 된다. 마스터가 다시 구동을 하면, 이로 인해 슬레이브는 올바르게 복제를 할 수 없게 된다. 마스터 my.cnf 파일에서 sync_binlog=1을 설정하면 마스터가 자신의 바이너리 로그를 보다 자주 플러시하기 때문에 이러한 문제를 최소화 시킬 수 있다.
1.3.1.9. 마스터 서버가 셧 다운되는 동안의 리플리케이션
마스터 서버를 셧 다운 시킨 후에 나중에 다시 가동 시키는 것이 안전하다. 슬레이브가 마스터와의 연결을 잃게 되면, 슬레이브는 즉시 재 접속을 시도하고, 접속이 이루어질 때까지 주기적으로 계속 접속을 시도한다. 매 60초 마다 재 접속을 시도하도록 디폴트로 설정되어 있으며, 재 접속 주기는 --master-connect-retry 옵션으로 변경할 수 있다. 또한, 슬레이브는 네트워크 연결 중단 (outage)를 처리할 수 있다. 하지만, 마스터에서 slave_net_timeout 시간 (초) 동안 데이터를 받지 못하는 경우에만 슬레이브는 네트워크 중단을 인지한다.
1.3.1.10. MEMORY 테이블 타입을 사용하는 리플리케이션
서버가 셧 다운된 후에 다시 시작하게 되면, 서버의 MEMORY 테이블은 비게 된다. 마스터는 이러한 것을 다음과 같은 방식으로 슬레이브에 복제한다: 마스터를 시작한 후에 각각의 MEMORY 테이블을 처음 사용할 때, 마스터는 그 테이블이 비어 있어야 한다는 것을 슬레이브에 알려주는 이벤트를 DELETE 명령문을 통해 기록한다.
1.3.1.11. 시스템 mysql 데이터베이스 리플리케이션
MySQL 5.1.14 이상 버전부터는 mysql 데이터베이스가 복제되지 않는다. 대신에, mysql 데이터베이스는 노드 관련 데이터베이스 형태로 나타난다. 이 테이블에서는 열 기반 리플리케이션이 지원되지 않는다. 대신에, 이러한 정보 (GRANT, REVOKE, 트리거, 스토어드 루틴/프로시저, 뷰 등)를 업데이트하는 명령문은 명령문 기반 리플리케이션을 사용해서 모두 슬레이브에 복제된다.
MySQL 5.1.13 이전 버전에서는 mysql 데이터베이스가 복제되는 경우에만 사용자 권한이 복제되었다. 즉, 리플리케이션 설정이 mysql 데이터베이스를 포함하는 경우에만 GRANT, REVOKE, SET PASSWORD, CREATE USER, 그리고 DROP USER 명령문을 슬레이브에 복제할 수 있다.
모든 데이터베이스는 복제하지만 복제되는 사용자 권한에 영향을 주는 명령문은 제외하고 싶다면, --replicate-wild-ignore-table=mysql.% 옵션을 사용해서 mysql 데이터베이스를 복제하지 않도록 슬레이브를 설정한다. 이렇게 하면, 슬레이브는 실행되는 권한-관련 SQL 명령문이 효력이 없다는 것을 인지하기 때문에 해당 명령문을 실행하지 않게 된다.
1.3.1.12. 리플리케이션이 실행되는 동안 발생하는 슬레이브 에러
슬레이브 명령문이 에러를 발생시킨다면, 슬레이브 SQL 쓰레드는 종료를 하게 되고, 슬레이브는 에러 메시지를 자신의 에러 로그에 기록한다. 그렇게 되면, 수동으로 슬레이브에 접속을 해서 문제의 원인을 파악해야 한다. (이런 상황에서는 SHOW SLAVE STATUS 명령문이 유용하다.) 문제를 처리한 후에 START SLAVE를 다시 구동 한다.
1.3.1.13. 슬레이브가 셧 다운 되는 동안의 리플리케이션
슬레이브 서버도 함께 셧다운 시키는 것이 안전하다. 슬레이브를 정확하게 셧다운 시키지 않으면 문제가 발생할 수 있는데, 특히 디스크 캐시가 시스템 다운 이전에 디스크에 플러시되지 않았다면 문제가 발생한다. 마스터를 정확하게 셧다운 시키지 않으면 마스터 테이블과 바이너리 로그 사이에 일관성이 깨질 수 있다; 마스터에서 InnoDB 테이블과 --innodb-safe-binlog 옵션을 사용하면 이러한 문제를 피할 수 있다.
1.3.1.14. 리플리케이션과 임시 테이블
여기에서 설명하는 내용은 열 기반 리플리케이션에는 해당되지 않는다. (열 기반 리플리케이션은 임시 테이블을 복제하지 않기 때문에)
슬레이브 서버를 셧다운 시키는 경우와 슬레이브에서 아직 실행되지 않는 업데이트를 사용하는 복제된 임시 테이블을 가지고 있는 경우를 제외하면, 임시 테이블은 복제가 된다. 슬레이브 서버를 셧다운 시킨다면, 이러한 업데이트를 실행할 때 필요한 임시 테이블은 슬레이브를 다시 시작할 때 더 이상 사용할 수 없게 된다. 이러한 문제는 슬레이브가 임시 테이블을 열어 둔 상태에서는 슬레이브 서버를 셧다운 시키지 않으면 피할 수 있다. 대신에, 다음과 같은 절차를 진행하도록 한다:
1. STOP SLAVE 명령문을 실행한다.
2. SHOW STATUS를 사용해서 Slave_open_temp_tables 변수 값을 검사한다.
3. 값이 0 이면, mysqladmin shutdown 명령어를 실행해서 슬레이브를 종료 시킨다.
4. 값이 0 이 아니라면, START SLAVE를 사용해서 슬레이브 쓰레드를 다시 시작한다.
5. Slave_open_temp_tables 변수가 0 이 될 때까지 반복해서 4번을 실행한 후에 서버를 종료한다.
1.3.1.15. 리플리케이션 재 시도와 타임 아웃
글로벌 시스템 변수 slave_transaction_retries는 다음과 같이 리플리케이션에 영향을 준다: 리플리케이션 슬레이브 SQL 쓰레드가 InnoDB 데드락 (deadlock)으로 인해, 또는 InnoDB innodb_lock_wait_timeout 값 또는 NDBCluster TransactionDeadlockDetectionTimeout 또는 TransactionInactiveTimeout 값을 초과하기 때문에 트랜젝션을 실행할 수 없다면, 에러로 인해 쓰레드가 종료하기 전에 slave_transaction_retries 시간 동안 트랜젝션이 자동으로 재 실행된다. 디폴트 값은 10이다. 전체 재 시도 회수는 SHOW STATUS 결과 값에서 확인할 수 있다.
1.3.1.16. 리플리케이션과 타임존
마스터가 MySQL 4.1 버전을 사용하고 있다면, 마스터와 슬레이브 양쪽 모두에 동일한 시스템 타임 존을 설정해야 한다. 그렇지 않으면, NOW() 또는 FROM_UNIXTIME() 함수를 사용하는 명령문들이 올바르게 복제되지 않는다. mysqld_safe 스크립트의 --timezone=timezone_name 옵션을 사용하거나 또는 TZ 환경 변수를 사용하면 타임 존을 설정할 수 있다. 마스터와 슬레이브는 모두 동일한 디폴트 접속 타임 존을 가지고 있어야 한다; 즉, --default-time-zone 파라미터는 마스터와 슬레이브에 대해서 동일한 값을 가지고 있어야 한다. MySQL 5.0 이상 버전을 사용할 경우에는 이것이 필요 없다는 것을 알아두자.
CONVERT_TZ(...,...,@@session.time_zone)는 마스터와 슬레이브가 MySQL 5.0.4 이상 버전을 사용하는 경우에만 올바르게 복제된다.
1.3.1.17. 리플리케이션과 트랜젝션
슬레이브에 있는 논-트랜젝셔널 테이블을 사용해서 마스터에 있는 트랜젝셔널 테이블을 복제하는 것은 가능하다. 예를 들면, InnoDB 마스터 테이블을 MyISAM 슬레이브 테이블 형태로 복제할 수 있다. 하지만, 슬레이브가 BEGIN/COMMIT 블록을 처리하는 중간에 멈추게 되면 문제가 발생하는데, 그 이유는 슬레이브가 BEGIN 블록의 처음 시점에서 다시 시작하기 때문이다.
트랜젝션이 트랜젝셔널 테이블과 비-트랜젝션 테이블을 함께 업데이트하는 경우에는, 바이너리 로그에 있는 명령문 순서가 올바르게 처리되고, ROLLBACK이 되는 경우라도 필요한 모든 명령문이 바이너리 로그에 기록된다. 하지만, 첫 번째 접속이 종료하기 전에 두 번째 접속이 비-트랜젝션 테이블을 업데이트 한다면, 명령문의 순서가 잘못 기록될 수 있는데, 그 이유는 두 번째 접속의 업데이트는 첫 번째 접속이 실행한 트랜젝션 상태와는 상관없이 실행 후에 즉시 기록되기 때문이다..
Caution
트랜젝셔널 테이블과 비-트랜젝션 테이블을 모두 업데이트하는 상황에서는 리플리케이션을 사용하지 말도록 한다.
1.3.1.18. 슬레이브가 마스터보다 더 많은 컬럼을 사용하는 경우의 리플리케이션
슬레이브 테이블이 마스터 테이블보다 더 많은 컬럼을 가지고 있는 경우에도 리플리케이션을 구현할 수 있다.
이러한 경우에는 다음과 같이 진행하도록 한다:
-
반드시 열 기반 리플리케이션을 사용하도록 한다.
-
마스터와 슬레이브는 반드시 동일한 데이터베이스/테이블 이름을 사용해야 한다.
-
슬레이브 테이블이 마스터 테이블 보다 더 많은 컬럼을 가질 수는 있으나, 여분의 컬럼들은 마스터 테이블 컬럼에 상응하는 컬럼 다음에 순차적으로 나와야 한다.
-
마스터와 슬레이브에서 매칭되는 모든 컬럼은 반드시 동일한 타입을 가져야 한다.
-
슬레이브 테이블에 추가되는 모든 컬럼들은 반드시 디폴트 값을 가져야 한다.
이 기능은 MySQL 5.1.12에서 추가되었다.
1.3.1.19. 리플리케이션과 변수
FOREIGN_KEY_CHECKS, SQL_MODE, UNIQUE_CHECKS, 그리고 SQL_AUTO_IS_NULL변수는 모두 복제가 된다. storage_engine 시스템 변수 (table_type라고도 알려짐)는 아직까지 복제할 수 없다.
테이블을 업데이트하는 명령문에서 사용되는 세션 변수는 올바르게 복제할 수 없다. 예를 들면, SET MAX_JOIN_SIZE=1000 다음에 나오는 INSERT INTO mytable VALUES(@@MAX_JOIN_SIZE)는 마스터와 슬레이브에 동일한 데이터를 삽입할 수 없다.
열 기반 리플리케이션을 사용하는 경우에는 세션 변수를 리플리케이션 할 수 있다.
1.3.1.20. 리플리케이션과 뷰
뷰는 항상 슬레이브에 복제된다. 뷰는 자신이 참조하는 테이블이 아니라 자신의 이름을 사용해서 필터링된다. 즉, 뷰가 replication-ignore-table 규칙을 사용해서 정상적으로 필터링되는 테이블을 가지고 있다고 하더라도 슬레이브에 복제될 수 있다는 것을 의미한다.