Mysql主從庫 數據不同步 解決記錄

背 景

週五快下班的時候,同事對我說線上的主從庫不能同步了。線上服務器也就我一個人維護,難道是我做的好事?最後一次維護主從庫,還是一年前在Linux系統上安裝主從庫。

上次主從庫不同步發生在兩年前的測試環境。而測試環境是windows系統,線上環境是Linux系統。這次線上環境主從庫突然出現問題,很想迅速解決。

但是在打開連接服務器的 putty 時,連接主從庫的命令愣是想不起來。好記性不如爛筆頭,出現問題還是要多記錄一下,不然下次敲個命令都要找半天,耽誤時間。

一、先看 Master 主庫的狀態

# 登錄mysql Master主庫,輸入登錄密碼
mysql -S /tmp/mysql_3306.sock -p
# 查看主庫狀態
show master status;

主庫的日誌文件是66,Position是 537609。

二、再來看 Slave 從庫的狀態

# 登錄mysql Slave從庫,輸入登錄密碼
mysql -S /tmp/mysql_3307.sock -p
# 查看從庫狀態,格式化一下輸出信息
show slave status\G

日誌文件如下:

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 127.0.0.1
                  Master_User: mysql_sync
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql3306_bin.000066
          Read_Master_Log_Pos: 537609
               Relay_Log_File: ecs-7f7b-relay-bin.000176
                Relay_Log_Pos: 23138574
        Relay_Master_Log_File: mysql3306_bin.000063
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 1594
                   Last_Error: Relay log read failure: Could not parse relay log event entry. The possible reason           s are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the            slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem,            or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay lo           g, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 23138353
              Relay_Log_Space: 23824100
              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: 1594
               Last_SQL_Error: Relay log read failure: Could not parse relay log event entry. The possible reason           s are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the            slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem,            or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay lo           g, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 3306
                  Master_UUID: 79529d27-823f-11eb-9fd0-fa163e773a43
             Master_Info_File: /mnt/databases/mysql/mysql_3307/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State:
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp: 221014 17:05:44
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

錯誤提示:Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem,or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.

日誌分析:

  • 從庫兩個重要的同步狀態指標,Slave_IO_running 的狀態是正常的,而Slave_SQL_running已經關閉。

  • 從庫同步的文件編號是63,Position是 23118574,也就是說主從庫同步相差4個文件。

  • Master 主服務器的 binary log 文件損壞,Slave從服務器的Relay log文件損壞。

  • 最後一次錯誤是1594,最後一次 Sql 錯誤也是1594。

在網上查了一下,錯誤 1594 一般是由掉電引起。而我使用的是雲服務器,怎麼會有機房掉電呢?想想我最近幾天對服務器做了啥?嗯,做了個壓測,把服務器的CPU撐爆了,沒想到數據庫最先受到了影響。

三、解決問題
1、解決 #1594 錯誤

# 停止從庫狀態
stop slave;
# 重置從庫
reset slave all;
# 重置同步狀態,從主庫最新的文件、最新的位置開始同步
CHANGE MASTER TO MASTER_HOST='127.0.0.1',MASTER_USER='mysql_sync',MASTER_PASSWORD='xxxx',MASTER_PORT=3306,MASTER_LOG_FILE='mysql3306_bin.000066',MASTER_LOG_POS=23138353;
# 開啓從庫狀態;
start slave;

重啓Slave從庫的同步開關後,再次查看slave狀態,Slave_IO_Running變成了No,出現了新的報錯信息1236。



錯誤提示:
Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from position > file size'

2、解決 #1236 錯誤

# 刷新主庫日誌
flush logs
# 查看主庫狀態
show master status;

回到 Slave 從庫再次操作:

# 停止從庫同步狀態
stop slave;
# 修改從庫日誌同步的開始文件
change master to master_log_file='mysql3306_bin.000068',master_log_pos=154;

master_log_file爲主庫的最新日誌文件,master_log_pos爲主庫最新的位置。
設置後重啓 Slave 從庫狀態:



從庫同步的兩個狀態都爲Yes,主從庫同步開關設置成功。3、另一種解決辦法 前面兩種辦法存在一個問題。在數據同步失效期間,新增的數據再次修改時,是無法被同步到 Slave從庫的。

其實還可以試一試這個參數:

# 從庫 slave 跳過一個事務,一次跳過一個錯誤信息
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1

https://dev.mysql.com/doc/refman/5.6/en/set-global-sql-slave-skip-counter.html先關閉從庫的同步,再跳過錯誤事件,N便是錯誤事件的次數,最後再重啓從庫的同步。這樣丟失的數據就可以減到最少。

既然出現了錯誤,總歸要看看錯誤,才能決定是不是可以跳過,怎麼查看出現的錯誤呢?

# 在Master主機上查看 Position 做了什麼操作
show binlog events in 'mysql-bin.000002' from 6840;

mysql-bin.000002 和 6840 是 Last_Error 中的提示信息,可以用此命令查看錯誤詳情,以此來確定出現的錯誤信息到底能不能跳過,如果可以那就跳過吧。這個方法可以嘗試。

4、遺留問題主從庫數據同步開關已經Ok。但是在數據同步失效期間,新增的數據在Slave從數據庫上還是不存在的,這些數據再次修改時,還是無法被同步到 Slave從庫的。這個只能在想其他辦法解決。

以上便是我調整本次主從庫同步異常的筆記,希望對你有幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章