2009. 6. 25. 00:51

[MySQL] Replication 환경 싱크 깨지는것 회피하기





MySQL의 리플리케이션 환경을 운영하다 보면 유난히도 싱크가 어긋나는 일이 많이 일어나는 것을 알 수 있습니다.

확실히 MySQL은 아직 엔터프라이즈 환경에서의 도입에 무리가 있는 제품이 아닐까 생각이 드는군요.

하지만 리플리케이션 기능이 추가된지 얼마 되지 않았고 저장프로시저도 생겼고 나날이 발전하는 모습을 보면 더더욱 좋아질것이라고 기대해 봅니다.

그러면 이미 MySQL을 이용한 리플리케이션 상황을 운영중이고 또 관련 오류가 많이 나는 상황이라면 어떻게 해야 할까요?

다음의 방법을 시도해볼만합니다.

MySQL의 경우 리플리케이션 환경 중 에러가 나면 그 Slave 서버는 리플리케이션이 중단됩니다.

갑자기 좀비 서버가 되어 버리는 것이죠. 에러를 확인해 봅시다.

[root@SLAVE ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2060
Server version: 5.0.51

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> show slave status\G
*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: MASTER
                Master_User: replicator
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: mysql-bin.000005
        Read_Master_Log_Pos: 96305365
             Relay_Log_File: slave-relay-bin.000006
              Relay_Log_Pos: 73184178
      Relay_Master_Log_File: mysql-bin.000005
           Slave_IO_Running: Yes
          Slave_SQL_Running: No
            Replicate_Do_DB: THEEYE
        Replicate_Ignore_DB: 
         Replicate_Do_Table: 
     Replicate_Ignore_Table: 
    Replicate_Wild_Do_Table: 
Replicate_Wild_Ignore_Table: 
                 Last_Errno: 1062
                 Last_Error: Error 'Duplicate entry '116069-10002826' for key 1' on query. Default database: 'THEEYE'. Query: 'INSERT INTO    THEEYE_INFO_LOG    ( IDX, NAME, REG_DATE    )    VALUES ( 3, "GOOD", NOW() )'
               Skip_Counter: 0
        Exec_Master_Log_Pos: 73184876
            Relay_Log_Space: 96304951
            Until_Condition: None
             Until_Log_File: 
              Until_Log_Pos: 0
         Master_SSL_Allowed: No
         Master_SSL_CA_File: 
         Master_SSL_CA_Path: 
            Master_SSL_Cert: 
          Master_SSL_Cipher: 
             Master_SSL_Key: 
      Seconds_Behind_Master: NULL
1 row in set (0.00 sec)

mysql> exit



show slave status\G 명령으로 현재 슬레이브의 상태를 확인할 수 있습니다.

상태를 보니 Last_Errno 가 1062이고 Last_Error에는 어떤 에러인지 표시가 됩니다.

근데 에러를 확인해 보니 같은 똑같은 Entry가 존재한다는군요. 위의 디비 설계상 같은 키값을 가진 값이 두개가 들어갈 필요가 없다는것을 알았습니다.

그런데 저런 사소한 문제로 리플리케이션이 중단된다는것도 억울한 일이죠. 위와 같은 사소한 에러는 무시하도록 해보겠습니다.

--slave-skip-errors 라는 옵션이 있는데요. 에러코드값을 지정해 주거나 all로 모든 에러를 무시할 수 있습니다.
--slave-skip-errors=[err_code1,err_code2,...|all]


서버측 에러 코드는 [ 이곳 ] 에서 확인 하실 수 있습니다.

1062번 에러의 경우 사소한 문제이기 때문에 서버 설정에 추가해 보도록 하겠습니다.

저같은 경우에는 /etc/my.cnf 파일에 다음의 내용을 추가하였습니다.
[mysqld]
...
slave-skip-errors = 1062


앞으로는 위의 코드에 해당하는 에러가 발생할 경우 에러를 건너뛰고 Master의 Log Position에 강제적으로 맞춰질 것입니다.