[MySQL] GTID Binary 로그 유실에 따른 복제 에러-errno 1236

GTID 복제 모드에서 1236 에러에 관련된 내용에 대해 알아보겠습니다.

원문 : https://www.percona.com/blog/2016/12/01/database-daily-ops-series-gtid-replication-binary-logs-purge/

 

mysql> show slave status
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 
'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the 
master has purged binary logs containing GTIDs that the slave requires.'

 

위와같이 에러 메세지 번호 그리고 에러 내용에 대해 출력됩니다.

 

시점에서 마스터(gzipped)에서 압축된 형태로 바이너리 로그 파일을 있습니다. 물론 MySQL 확장자가 .gz 압축 파일을 바이너리 로그로 식별할 없습니다. 파일의 압축을 풀었지만 파일의 압축을 풀고 현재 마스터의 UUID TRX_ID 있는지 확인한 후에도 복제에서 동일한 문제가 발생했습니다.

 

참고 :

서버가 시작되면 이전에 gtid_lost 불렸던 gtid_purged 전역 값이 가장 오래된 바이너리 로그의 Previous_gtid_log_event 포함된 GTID 집합으로 초기화됩니다. 바이너리 로그가 제거되면 gtid_purged 이제 가장 오래된 바이너리 로그에서 다시 읽힙니다.

=> https://dev.mysql.com/doc/refman/5.6/en/replication-options-gtids.html#sysvar_gtid_purged

 

GTID 메커니즘에서 예상 한대로 제거하지 않고 마스터에서 binlog 압축하는 경우 디스크의 기존 GTID 다시 읽을 없습니다.

슬레이브 복제 스레드가 다시 시작되거나 DBA 슬레이브 재설정 마스터 재설정과 같은 명령을 실행하면

( : SHOW SLAVE STATUS 명령에서 Executed_Gtid_Set 증가된 GTID 세트를 정리하기 위해) 오류가 발생할 있습니다.

하지만 파일을 압축하면 다음과 같은 문제를 예상해볼 있습니다.

- 슬레이브가 손실되고 슬레이브 / 리셋 마스터를 재설정한 마스터에서 필요한 모든 GTID 찾지 못합니까?

- PURGE BINARY LOGS 사용하여 로그를 올바르게 제거하면 복제 스레드를 다시 시작할 슬레이브가 정상입니까?

 

 

테스트 1 : 마스터에서 가장 오래된 바이너리 로그 파일 압축, 슬레이브 스레드 다시 시작

바이너리 로그 하나의 GTID 생성 다음 슬레이브에서 사용할 없도록 가장 오래된 바이너리 로그 파일을 압축합니다.

1 개의 마스터와 2 개의 슬레이브로 테스트를 진행해 봅니다. 

2 번째 슬레이브에서 슬레이브 중지, 슬레이브 재설정, 마스터 재설정, 슬레이브 시작, 결과 확인 순서를 실행합니다.

 

On master (tool01):

tool01 [(none)]:> show master logs;
+-------------------+-----------+
| Log_name          | File_size |
+-------------------+-----------+
| mysqld-bin.000001 |       341 |
| mysqld-bin.000002 |       381 |
| mysqld-bin.000003 |       333 |
+-------------------+-----------+
3 rows in set (0.00 sec)

tool01 [(none)]:> show binlog events in 'mysqld-bin.000001';
+-------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name          | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |
+-------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysqld-bin.000001 |   4 | Format_desc    |         1 |         120 | Server ver: 5.6.32-log, Binlog ver: 4                             |
| mysqld-bin.000001 | 120 | Previous_gtids |         1 |         151 |                                                                   |
| mysqld-bin.000001 | 151 | Gtid           |         1 |         199 | SET @@SESSION.GTID_NEXT= '4fbe2d57-5843-11e6-9268-0800274fb806:1' |
| mysqld-bin.000001 | 199 | Query          |         1 |         293 | create database wb01                                              |
| mysqld-bin.000001 | 293 | Rotate         |         1 |         341 | mysqld-bin.000002;pos=4                                           |
+-------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
5 rows in set (0.00 sec)

tool01 [(none)]:> show binlog events in 'mysqld-bin.000002';
+-------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name          | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |
+-------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysqld-bin.000002 |   4 | Format_desc    |         1 |         120 | Server ver: 5.6.32-log, Binlog ver: 4                             |
| mysqld-bin.000002 | 120 | Previous_gtids |         1 |         191 | 4fbe2d57-5843-11e6-9268-0800274fb806:1                            |
| mysqld-bin.000002 | 191 | Gtid           |         1 |         239 | SET @@SESSION.GTID_NEXT= '4fbe2d57-5843-11e6-9268-0800274fb806:2' |
| mysqld-bin.000002 | 239 | Query          |         1 |         333 | create database wb02                                              |
| mysqld-bin.000002 | 333 | Rotate         |         1 |         381 | mysqld-bin.000003;pos=4                                           |
+-------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
5 rows in set (0.00 sec)

tool01 [(none)]:> show binlog events in 'mysqld-bin.000003';
+-------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name          | Pos | Event_type     | Server_id | End_log_pos | Info                                                              |
+-------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysqld-bin.000003 |   4 | Format_desc    |         1 |         120 | Server ver: 5.6.32-log, Binlog ver: 4                             |
| mysqld-bin.000003 | 120 | Previous_gtids |         1 |         191 | 4fbe2d57-5843-11e6-9268-0800274fb806:1-2                          |
| mysqld-bin.000003 | 191 | Gtid           |         1 |         239 | SET @@SESSION.GTID_NEXT= '4fbe2d57-5843-11e6-9268-0800274fb806:3' |
| mysqld-bin.000003 | 239 | Query          |         1 |         333 | create database wb03                                              |
+-------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+
4 rows in set (0.00 sec)

 

여기에서 기존의 바이너리 로그 파일에 트랜잭션이 하나만 있음을 있습니다. 이렇게하면 가장 오래된 바이너리 로그를 쉽게 압축한 다음 기존 GTID 일부와 함께 사라집니다. 슬레이브가 마스터에 연결되면 먼저 모든 Executed_Gtid_Set 보낸 다음 마스터는 누락된 모든 ID 슬레이브에 보냅니다. 그리고 그것에 대해 강제가 필요합니다. 슬레이브 데이터베이스 서버는 현재 둘다 같은 위치에 있습니다.

 

tool02 [(none)]:> show slave statusG
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.10
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysqld-bin.000003
          Read_Master_Log_Pos: 333
               Relay_Log_File: mysqld-relay-bin.000006
                Relay_Log_Pos: 545
        Relay_Master_Log_File: mysqld-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            ...
           Retrieved_Gtid_Set: 4fbe2d57-5843-11e6-9268-0800274fb806:1-3
            Executed_Gtid_Set: 4fbe2d57-5843-11e6-9268-0800274fb806:1-3
            
tool03 [(none)]:> show slave statusG
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.10
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysqld-bin.000003
          Read_Master_Log_Pos: 333
               Relay_Log_File: mysqld-relay-bin.000008
                Relay_Log_Pos: 451
        Relay_Master_Log_File: mysqld-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...
           Retrieved_Gtid_Set: 4fbe2d57-5843-11e6-9268-0800274fb806:1-3
            Executed_Gtid_Set: 4fbe2d57-5843-11e6-9268-0800274fb806:1-3
======

이제 마스터에서 가장 오래된 바이너리 로그를 압축합니다.
=====
[root@tool01 mysql]# ls -lh | grep mysqld-bin.
-rw-rw---- 1 mysql mysql  262 Nov 11 13:55 mysqld-bin.000001.gz #: this is the file containing 4fbe2d57-5843-11e6-9268-0800274fb806:1
-rw-rw---- 1 mysql mysql  381 Nov 11 13:55 mysqld-bin.000002
-rw-rw---- 1 mysql mysql  333 Nov 11 13:55 mysqld-bin.000003
-rw-rw---- 1 mysql mysql   60 Nov 11 13:55 mysqld-bin.index
=====

사용될 데이터베이스 서버인 tool03에서 복제 재로드를 실행합니다.
=====
tool03 [(none)]:> stop slave; reset slave; reset master; start slave;
Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.03 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.02 sec)

tool03 [(none)]:> show slave statusG
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 192.168.0.10
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File:
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 4
        Relay_Master_Log_File:
             Slave_IO_Running: No
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 0
              Relay_Log_Space: 151
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: 4fbe2d57-5843-11e6-9268-0800274fb806
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp: 161111 14:47:13
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 1
1 row in set (0.00 sec)

슬레이브에서 복제 스트리밍을 끊었습니다. 이제 마스터에서 누락된 GTID 압축 파일로 인한 것이며 negotiation(재연결시도) 중에 연결하는 슬레이브로 전달할 없다는 것을 알고 있습니다. 또한 @@GTID_PURGED 온라인 설명서에 나와있듯이 다시 로드되지 않았습니다. 테스트가 완료되었고 이론이 확인되었습니다 (추가 의견이있는 경우 블로그 끝에 입력).

 

 

 

 

 

테스트 2 : 마스터에서 가장 오래된 파일을 제거하고 슬레이브에서 복제를 다시로드합니다.

binary 로그 인덱스 파일도 제거 작업의 일부로 간주되어야 하므로 PURGE BINARY LOGS 명령을 사용하여 수동으로 제거를 수행할 있습니다

(디스크의 로그 파일과 함께 파일 이름 색인 항목을 제거하도록 편집해야합니다.). 이전과 동일하게 실행하되 언급된 명령을 사용하여 파일을 수동으로 제거하는 것을 포함합니다.

 

tool01 [(none)]:> show master logs;
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| mysqld-bin.000001 | 341 |
| mysqld-bin.000002 | 381 |
| mysqld-bin.000003 | 333 |
+-------------------+-----------+
3 rows in set (0.00 sec)

tool01 [(none)]:> purge binary logs to 'mysqld-bin.000002';
Query OK, 0 rows affected (0.01 sec)

tool01 [(none)]:> show master logs;
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| mysqld-bin.000002 | 381 |
| mysqld-bin.000003 | 333 |
+-------------------+-----------+
2 rows in set (0.00 sec)

이제 명령을 실행하여 진행 상황을 확인합니다.

 

 

tool03 [(none)]:> stop slave; reset slave; reset master; start slave;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.02 sec)

tool03 [(none)]:> show slave statusG
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 192.168.0.10
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File:
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 4
        Relay_Master_Log_File:
             Slave_IO_Running: No
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 0
              Relay_Log_Space: 151
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: 4fbe2d57-5843-11e6-9268-0800274fb806
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp: 161111 16:35:02
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 1
1 row in set (0.00 sec)

 

제거 파일의 GTID 슬레이브에 필요합니다. 경우 모두 제거된 트랜잭션으로 아래와 같이 @@GTID_PURGED 설정하고 복제를 진행할 있습니다.

 

tool03 [(none)]:> stop slave; set global gtid_purged='4fbe2d57-5843-11e6-9268-0800274fb806:1';
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

tool03 [(none)]:> start slave;
Query OK, 0 rows affected (0.01 sec)

위는 @@ GTID_PURGED GTID 조정하여 가장 오래된 기존 GTID에서 1 값을 사용하여 슬레이브가 가장 오래된 기존 GTID에서 복제를 시작하도록합니다.

위의 시나리오에서 복제본은 바이너리 로그 파일 mysqld-bin.000002에있는 4fbe2d57-5843-11e6-9268-0800274fb806 : 2에서 복제를 다시 시작합니다.

스레드가 마스터에서 오는 데이터 스트리밍 처리를 다시 시작할 있으므로 복제가 수정되었습니다.

 

@@GTID_PURGED 대한 값을 설정할 점프된 트랜잭션 집합에 대해 체크섬 동기화에서 추가 단계를 실행해야합니다.

다시 시작한 후에도 복제가 계속 중단되면 슬레이브를 다시 빌드하는 것이 좋습니다.

이에 대한 버그는 다음과 같습니다.

MySQL 버그 : # 72635 : 마스터가 충돌 GTID가있는 바이너리 로그를자를 데이터 불일치;

MySQL 버그 : # 73032 : gtid_purged 설정하면 auto_position 중단되어 슬레이브가 있습니다.

 

 

결론

이진 로그를 제거 @@ GTID_PURGED 자동으로 업데이트해야 하므로 이진 로그를 사용하여 수동으로 제거하거나 작업을 수행할 때는 주의해야 합니다.

expire_logs_days 바이너리 로그를 제거하도록 설정된 경우에도 발생합니다. 변수는 데이터베이스 서버의 쓰기 횟수에 따라 안에 디스크가 가득 차게 있으므로 일의 비율을 고려하지 않기 때문에 주의해야 합니다.

 

 

GTID 이론

https://myinfrabox.tistory.com/29

 

[MySQL][Master-Slave] GTID를 이용한 복제 - 이론

이 섹션에서는 GTID (Global Transaction Identifier)를 사용한 트랜잭션 기반 복제에 대해 설명합니다. GTID를 사용할 때 각 트랜잭션은 원래 서버에서 커밋되고 슬레이브에 의해 적용될때 식별되고 추적

myinfrabox.tistory.com

 

GTID 설정방법

https://myinfrabox.tistory.com/30

 

[MySQL][Master-Slave] GTID를 이용한 복제 - 구성방법

■ GTID를 이용한 복제 설정. 여기에서는 처음으로 GTID를 이용하여 처음 설정하는 "콜드 스타트"방법입니다. 이 포스트를 통해서 복제를 어떻게 설정하고, 주의할점은 무엇인지 알아봅니다. ■ 서

myinfrabox.tistory.com

 

※도움이 되셨다면 광고클릭 한번 부탁드립니다.※

 

Designed by JB FACTORY