Mysql - 關於relay_log_recovery參數的測試


一、概述

官方文檔中對relay_log_recovery參數的解釋
Enables automatic relay log recovery immediately following server startup. The recovery process creates a new relay log file, initializes the SQL thread position to this new relay log, and initializes the I/O thread to the SQL thread position. Reading of the relay log from the master then continues.

上面的英文看不懂,沒關系,后面有大白話的翻譯加實驗,不怕你不懂。
現在我們考慮一個問題,假設當從庫意外宕機后,同時從庫的relay log也一起損壞了,而主庫的日志已經傳到了從庫,只是從庫還沒有來得及應用這些日志,那么從庫該如何處理?


二、結論

1. 在從庫中將relay_log_recovery不設置或者設置為off,如果碰到上面的情形,從庫會丟失那些沒有應用的日志,主從會不一致。
2. 在從庫中將relay_log_recovery設置為on,假如果碰到上面的情形,從庫會自動放棄所有未執行的relay log,重新生成一個relay log,並將從庫的io線程的position重新指向新的relay log。並將sql線程的position退回到跟io線程的position保持一致,重新開始同步,這樣在從庫中事務不會丟失。這個參數建議開啟。是不是很繞,沒關系,看實驗。


三、實驗

1. 實驗環境介紹

mysql版本:5.7.25,操作系統版本:centos6.10
主庫ip:10.40.16.61,從庫ip:10.40.16.62
從庫的參數文件中加入了參數skip-slave-start,防止從庫自動啟動slave。

 

2. 將relay_log_recovery設置為off

默認情況這個參數就是off,所以無須設置

查看主庫狀態
image

查看從庫狀態
image

從上面的輸出可以看到,當前主從是同步的,而且從庫的relay_log_recovery參數是OFF

關閉從庫的sql線程
(root@localhost)[hello]> stop slave sql_thread;

主庫隨意做幾個更改
(root@localhost)[hello]> insert into t1 values(20);
(root@localhost)[hello]> insert into t1 values(30);

在主庫查看t1表
image

在從庫查看t1表
image

查看主庫狀態
image

查看從庫狀態
image

查看從庫的relay log
[root@mysqlb relaybin]# mysqlbinlog -vv slave-relay-bin.000010

image

可以看到主庫已經將日志傳送到relay log中了,只是從庫沒有執行而已。現在模擬從庫意外宕機。
[root@mysqlb relaybin]# reboot

等從庫節點啟動完畢后刪除從庫最后的relay log
[root@mysqlb relaybin]# rm -f slave-relay-bin.000010

然后啟動從庫
[root@mysqlb relaybin]# service mysql start

查看relay log目錄,發現又生成了一個slave-relay-bin.000010
image

去看看這個重新生成的slave-relay-bin.000010內容
[root@mysqlb relaybin]# mysqlbinlog -vv slave-relay-bin.000010
image
可以看到啥都沒有,這是因為數據庫在重啟的時候,會自動重新生成一個relay log,但是這個特性跟上面提到的參數relay_log_recovery沒有任何關系

再去從庫看看當前的從庫狀態
image
發現與重啟前的狀態信息是的一致的

啟動從庫的slave線程,再去從庫看看當前的從庫狀態
image
可以看到從庫又開始同步了,而且Exec_Master_Log_Pos=Read_Master_Log_Pos,還重新生成了一個slave-relay-bin.000011

再去從庫看當前的slave log
image

[root@mysqlb relaybin]# mysqlbinlog -vv slave-relay-bin.000010
image

[root@mysqlb relaybin]# mysqlbinlog -vv slave-relay-bin.000011
image

可以看到都是些空事務,也就是從庫對於那些還沒有執行的語句,全部拋棄了。強制將Exec_Master_Log_Pos移到了Read_Master_Log_Pos。

主庫
image

從庫
image

看到了吧,t1表中的20和30這兩條記錄就丟失了。

 

2. 將relay_log_recovery設置為on

在從庫參數文件中設置參數(relay_log_recovery = 1)並重啟從庫
image

查看主庫狀態
image

查看從庫狀態
image

停掉重庫的sql線程
(root@localhost)[hello]> stop slave sql_thread;

主庫做點改動,這次選用t2表
image

從庫查看t2表
image

從庫查看狀態
image

從庫查看slave log
[root@mysqlb relaybin]# mysqlbinlog -vv slave-relay-bin.000013

image

可以看到日志已經進入到slave log中了

現在模擬從庫意外宕機,等啟動后刪除從庫最新的relay log,跟第一個實驗步驟一致
[root@mysqlb relaybin]# reboot
[root@mysqlb relaybin]# rm -f slave-relay-bin.000013
[root@mysqlb relaybin]# service mysql start

查看從庫的狀態
image
可以看到Read_Master_Log_Pos已經由重啟前的5429退回到了5124,跟Exec_Master_Log_Pos保持一致。

查看從庫的relay log
image

[root@mysqlb relaybin]# mysqlbinlog -vv slave-relay-bin.000013
image
從庫照例又生成了一個slave-relay-bin.000013,不過這個依然是個空日志

啟動從庫的slave線程
(root@localhost)[hello]> start slave;

查看從庫的狀態
image
可以看到Exec_Master_Log_Pos沒變,Read_Master_Log_Pos增長了,我就在這里不明白,為什么sql線程不去執行日志呢,而且還多了一個線程System lock?

查看relay log

image

[root@mysqlb relaybin]# mysqlbinlog -vv slave-relay-bin.000014
image

可以看到啟動slave線程后,又生成了一個新的relay log,而且之前沒有執行的relay log條目的確又進到這個新的relay log中了。但是此刻sql線程並沒有執行relay log,應該就是system lock在作怪。

放大招,重啟從庫來達到釋放鎖的目的,再啟動slave線程
image

可以看到現在Slave_SQL_Running_State已經不是System lock了。

在從庫查看t2表的數據
image
可以看到數據並沒有任何丟失,由此證明在從庫中將relay_log_recovery設置為ON,能避免由於從庫relay log損壞導致的主從不一致的情形。


四、總結

在從庫中最好將relay_log_recovery設置為ON。如果有哪位高手知道system lock是個什么情況,期待您的留言。寫作不易,如果幫到了你,希望你點個贊,鼓勵下博主。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM