Mysql
修復 mysql 複製由於底層儲存損壞而崩潰
我們有在兩個虛擬機上執行的關鍵數據庫伺服器。一台虛擬機由於底層儲存問題而崩潰,我們不得不將其移動到不同的儲存介質並恢復 xfs 文件系統。
啟動崩潰的 vm 後,我們注意到 mysql 複製已損壞,我們的應用程序無法正常執行。
從 server_01(從)
mysql> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Master_Host: x.x.x.10 Master_User: slave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.006822 Read_Master_Log_Pos: 484378856 Relay_Log_File: mysqld-server-relay-bin.015091 Relay_Log_Pos: 404689852 Relay_Master_Log_File: mysql-bin.006822 Slave_IO_Running: No Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: mysql 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: 484378856 Relay_Log_Space: 404690059 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: 1236 Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position; the first event 'mysql-bin.006822' at 484378856, the last event read from '/var/log/mysql/mysql-bin.006822' at 4, the last byte read from '/var/log/mysql/mysql-bin.006822' at 4.' Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 2 1 row in set (0.00 sec)
從 server_02 (Master-crashed and recovery)
mysql> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Master_Host: x.x.x.11 Master_User: slave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.011022 Read_Master_Log_Pos: 480910234 Relay_Log_File: mysqld-server-relay-bin.003852 Relay_Log_Pos: 162009 Relay_Master_Log_File: mysql-bin.011022 Slave_IO_Running: No Slave_SQL_Running: No Replicate_Do_DB: Replicate_Ignore_DB: mysql 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: 480909976 Relay_Log_Space: 0 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: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 0 1 row in set (0.00 sec)
在檢查兩個輸出時,我可以看到從站的 Relay_Log_Pos 比主站領先。這是否意味著奴隸比主人擁有新數據?
我正在閱讀有關使用以下選項恢復此內容的資訊。但我不確定這是正確的做法。
STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
如果從站領先於主站,我可以讓從站作為主數據庫並以其他方式複制嗎?用這種方法我會失去任何數據嗎?
或者以最小的數據失去恢復它的最佳方法是什麼?我們目前沒有任何備份
你沒有提到你有什麼版本的 MySQL,或者你正在使用什麼類型的複制,所以我從輸出中猜測它是 5.7 或更早版本並且你沒有使用 GTID。
根據我的經驗,此錯誤通常發生在主伺服器“意外關閉”之後。
會發生什麼:
$$ normal operation $$
- Slave I/O Thread 向 master 請求新數據並開始接收該數據
- master 將其二進制 log 輪換到下一個,通知 slave 開始從下一個二進制 log 讀取
- 從機開始從下一個二進制日誌讀取
$$ CRASH $$
- 大師崩潰
- 從機斷開
- 主人回來了
- 如果舊日誌損壞,Master 會啟動一個新的 binlog(正常啟動)
- 從站重新連接並從舊的二進制日誌中請求下一個位置
- 這個位置不存在,因為日誌現在已經關閉並且主人繼續前進。從機正試圖從“不可能的位置”讀取
- 複製停止
解決方案:在從數據庫上進行
SHOW SLAVE STATUS
查詢並記下Relay_Master_Log_File
. 這應該是崩潰發生時正在讀取的主伺服器上的二進制日誌。在Master上查看,應該有一個名字對應的二進制日誌,
Date Modified
時間就是crash發生的時間。在從屬問題
CHANGE MASTER COMMAND
上,將其指向下一個二進制日誌的開頭。例如,如果它
binlog.000001
在崩潰發生時正在讀取,則開始讀取binlog.000002
position 1
STOP SLAVE; CHANGE MASTER TO MASTER_LOG_FILE = 'binlog.000002', MASTER_LOG_POS = 1; START SLAVE;
複製現在應該繼續沒有錯誤。