1. 程式人生 > >mysql slave 不能同步:Last_Errno: 1062

mysql slave 不能同步:Last_Errno: 1062

場景重現:

      mysql 雙主實現同步之後,同步機器IP設定為:192.168.101.118和192.168.101.119

在同步資料庫中建立一個表

 create table test (tno int(5),
tname char(10),
primary key(tno));

然後在118端插入資料如下:

+-------+---------+
| tno   | tname   |
+-------+---------+
| 10001 | liming  |
| 10002 | linxiao |

在119端實現了同步:

+-------+---------+
| tno   | tname   |
+-------+---------+
| 10001 | liming  |
| 10002 | linxiao |

然後把119的資料庫關閉(模擬119機器環境突然宕機)

在118機器上面插入資料(10003,hanmeimei);

mysql> select * from test;
+-------+-----------+
| tno   | tname     |
+-------+-----------+
| 10001 | liming    |
| 10002 | linxiao   |
| 10003 | hanmeimei |
+-------+-----------+

然後模擬118機器也宕機了,並恢復119的環境,然後在119庫裡面插入資料(10003,‘gaoyao’),,(10004, ‘chenhu'),插入成功

mysql> select * from test;
+-------+---------+
| tno   | tname   |
+-------+---------+
| 10001 | liming  |
| 10002 | linxiao |
| 10003 | gaoyao  |
| 10004 | chenhu  |
+-------+---------+

然後恢復118機器的環境,此時問題出現,兩邊不能同步了,

檢視記錄如下:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.101.118
                  Master_User: backup
                  Master_Port: 3306
                Connect_Retry: 50
              Master_Log_File: mysql-bin.000014
          Read_Master_Log_Pos: 202
               Relay_Log_File: localhost-relay-bin.000014
                Relay_Log_Pos: 251
        Relay_Master_Log_File: mysql-bin.000013
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB: cdn
          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 '10003' for key 'PRIMARY'' on query. Default database: 'cdn'. Query: 'insert into test values(10003, 'hanmeimei')'

                   Last_Error: Error 'Duplicate entry '10003' for key 'PRIMARY'' on query. Default database: 'cdn'. Query: 'insert into test values(10003, 'gaoyao')'
                  (紅色部分為118上面的日誌)

            Skip_Counter: 0
          Exec_Master_Log_Pos: 497
              Relay_Log_Space: 915
              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
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 1062
               Last_SQL_Error: Error 'Duplicate entry '10003' for key 'PRIMARY'' on query. Default database: 'cdn'. Query: 'insert into test values(10003, 'hanmeimei')'

              Last_SQL_Error: Error 'Duplicate entry '10003' for key 'PRIMARY'' on query. Default database: 'cdn'. Query: 'insert into test values(10003, 'gaoyao')'
1 row in set (0.00 sec)

原因分析:

兩邊資料不一致,資料庫開始進行同步,但是由於在複製同步的時候,發現對方庫中存在相同的主鍵,從而同步失敗

並導致  Slave_SQL_Running: No  出現

要求:

要求模擬上述場景,並解決工作中實際出現的這種問題

即雙主中有一臺機器A宕機後,緊接著另一臺B在插入了部分資料之後也宕機了,然後A機器先恢復啟動,並在不知情的情況下也插入了相同主鍵但是內容不一致的資料,

然後B再啟動,此時就會出現上述錯誤

解決(1)

此種情況下只要保證機器B先啟動就不會存在此種問題,所以要解決的問題是怎麼控制B先啟動的問題

解決(2)

網上有其他修改引數的相關建議,但是可能場景不是很合要求

如:

修改mysql的配置檔案,/etc/my.cnf,在[mysqld]下面新增一行

slave_skip_errors = 1062

儲存、重啟mysql服務,再次檢視主從複製,問題解決。

此種方法在此場景只能保證忽略報錯,在後序的資料中還能保持同步,但是對於已經不同步的資料不能恢復同步:

mysql> select * from test;    ------------A
+-------+-----------+
| tno   | tname     |
+-------+-----------+
| 10001 | liming    |
| 10002 | hanmeimei |
| 10003 | Jimmy     |
+-------+-----------+

mysql> select  * from test;            ------------------B
+-------+-----------+
| tno   | tname     |
+-------+-----------+
| 10001 | liming    |
| 10002 | hanmeimei |
| 10003 | gaoyao    |
+-------+-----------+

在A中插入一條資料(10004,’Green'), 這條資料馬上能同步到B, 但是 tno = 10003的資料還是混亂的,不知道選擇哪條了,所以此條記錄沒有同步

還有另外一種:  此種和上面方法類似,都是相當於路過了當前問題,令後面的同步

mysql> slave stop;
     mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
     mysql> slave start;

------------------------------------------------------------------------------------------------------------------------

先把情況記錄,根據後序情況慢慢完善,如有大牛有類似的解決經驗,敬請分享