MySQL?半同步復(fù)制的實(shí)現(xiàn)
一、半同步復(fù)制介紹
MySQL基礎(chǔ)復(fù)制有三種模式:異步復(fù)制/同步復(fù)制/半同步復(fù)制,3種模式各有利弊,下面對(duì)各種復(fù)制模式的優(yōu)缺點(diǎn)做個(gè)簡(jiǎn)要的介紹:
異步復(fù)制(Asynchronous replicaton)
這是MySQL默認(rèn)的復(fù)制模式,異步復(fù)制指主庫(kù)寫binlog、從庫(kù)I/O線程讀binlog并寫入relaylog、從庫(kù)SQL線程重放事務(wù)這三步之間是異步的。異步復(fù)制的優(yōu)點(diǎn)是主庫(kù)不需要關(guān)心備庫(kù)的狀態(tài),主庫(kù)不保證事務(wù)被傳輸?shù)綇膸?kù),如果主庫(kù)崩潰,某些事務(wù)可能還未發(fā)送到從庫(kù),切換后可能導(dǎo)致事務(wù)的丟失。其優(yōu)點(diǎn)是可以有更高的吞吐量,缺點(diǎn)是不能保持?jǐn)?shù)據(jù)實(shí)時(shí)一致,不適合要求主從數(shù)據(jù)一致性要求較高的應(yīng)用場(chǎng)景。
同步復(fù)制(Synchronous replicaton)
同步復(fù)制的模式下,主庫(kù)在提交事務(wù)前,必須確認(rèn)事務(wù)在所有的備庫(kù)上都已經(jīng)完成提交。即主庫(kù)是最后一個(gè)提交的,在提交前需要將事務(wù)傳遞給從庫(kù)并完成重放、提交等一系列動(dòng)作。其優(yōu)點(diǎn)是任何時(shí)候主備庫(kù)都是一致的,主庫(kù)的崩潰不會(huì)丟失事務(wù),缺點(diǎn)是由于主庫(kù)需要等待備庫(kù)先提交事務(wù),吞吐量很低。
半同步復(fù)制(Semisynchronous replicaiton)
MySQL從5.5開(kāi)始引入了半同步復(fù)制,半同步復(fù)制介于異步復(fù)制和同步復(fù)制之間。主庫(kù)在提交事務(wù)時(shí)先等待,必須確認(rèn)至少一個(gè)從庫(kù)收到了事件(從庫(kù)將事件寫入relaylog,不需要重放和提交,并向主庫(kù)發(fā)送一個(gè)確認(rèn)信息ACK),主庫(kù)收到確認(rèn)信息后才會(huì)正式commit。
與同步復(fù)制相比,半同步復(fù)制速度快很多,因?yàn)樗恍枰辽?個(gè)從庫(kù)確認(rèn)寫入relaylog,并不需要完成在從庫(kù)上的事務(wù)提交,同時(shí)又比異步復(fù)制更安全,因?yàn)橹鲙?kù)在提交時(shí),事務(wù)至少已經(jīng)存在2個(gè)地方(主庫(kù)的binlog和從庫(kù)的relaylog)。由于半同步復(fù)制在提交事務(wù)前,需要從庫(kù)返還確認(rèn)信息,所以這里涉及到網(wǎng)絡(luò)的往返通信開(kāi)銷,因此半同步復(fù)制只適合在網(wǎng)絡(luò)條件較好的且地理上距離不遠(yuǎn)的環(huán)境部署,否則可能會(huì)因?yàn)榫W(wǎng)絡(luò)延遲大幅降低主庫(kù)性能。
半同步復(fù)制的特點(diǎn):
- 從庫(kù)在連接主庫(kù)時(shí)需要表明它是否支持半同步復(fù)制。
- 如果主庫(kù)啟用了半同步復(fù)制,且有一個(gè)支持半同步復(fù)制的從庫(kù),則主庫(kù)上事務(wù)提交將等待至少一個(gè)從庫(kù)確認(rèn)已收到事務(wù),或者直到發(fā)生超時(shí)。
- 默認(rèn)只有在將事務(wù)寫入其中繼日志并刷新到磁盤后,主庫(kù)才會(huì)提交事務(wù)(也可以配置成提交后等待確認(rèn))。
- 如果沒(méi)有任何從庫(kù)確認(rèn)事務(wù)的情況下發(fā)生超時(shí),則主庫(kù)將退化為異步復(fù)制。當(dāng)至少有一個(gè)半同步從庫(kù)趕上時(shí),主庫(kù)恢復(fù)半同步復(fù)制。退化與恢復(fù)過(guò)程都是自動(dòng)的。
- 必須在主庫(kù)和從庫(kù)上都啟用半同步復(fù)制,否則使用異步復(fù)制。
二、搭建半同步復(fù)制
半同步復(fù)制是以插件的形式實(shí)現(xiàn)的,要使用半同步復(fù)制,要在主從分別安裝相應(yīng)的插件,并且通過(guò)參數(shù)來(lái)控制半同步復(fù)制。
在使用半同步復(fù)制前需要先滿足下列條件:
- 服務(wù)器要支持動(dòng)態(tài)加載,參數(shù)have_dynamic_loading要設(shè)置為True(MySQL8.0默認(rèn)就是True)。
- 已經(jīng)完成基礎(chǔ)異步復(fù)制的配置。
- 不支持一從多主的復(fù)制(多通道)。
現(xiàn)以上一篇配置好的異步復(fù)制為基礎(chǔ)來(lái)配置半同步復(fù)制
異步復(fù)制(Asynchronous replication)
2臺(tái)數(shù)據(jù)庫(kù)環(huán)境如下:
- 192.168.3.71(主庫(kù) 主機(jī)名master)
- 192.168.3.72(從庫(kù) 主機(jī)名slave01)
2.1 安裝半同步插件
安裝半同步插件時(shí),需要在主庫(kù)安裝semisync_master.so(8.0.26 以后版本為semisync_source.so),在從庫(kù)安裝semisync_slave.so(8.0.26以后版本為semisync_replica.so)。執(zhí)行安裝命令時(shí),插件必須在插件目錄(參數(shù)plugin_dir)存在。
在主庫(kù)安裝插件:
install plugin rpl_semi_sync_master soname 'semisync_master.so'; 或MySQL 8.0.26以上版本執(zhí)行下面命令: install plugin rpl_semi_sync_source soname 'semisync_source.so';

在備庫(kù)安裝插件:
install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; 或MySQL 8.0.26以上版本執(zhí)行下面命令: install plugin rpl_semi_sync_replica soname 'semisync_replica.so';

安裝完成后可以用show plugins來(lái)查看是否安裝成功,安裝成功后插件列表中應(yīng)該有下列類似信息:
show plugins;

2.2 啟用半同步復(fù)制
確認(rèn)主備的插件都成功安裝后,使用下面命名調(diào)整參數(shù),啟用半同步復(fù)制。
主庫(kù)執(zhí)行:
set global rpl_semi_sync_master_enabled=1; 或MySQL 8.0.26以后版本執(zhí)行: set global rpl_semi_sync_source_enabled = 1;

備庫(kù)執(zhí)行:
set global rpl_semi_sync_slave_enabled=1; 或MySQL 8.0.26以后版本執(zhí)行: set global rpl_semi_sync_replica_enabled = 1;

為了防止配置不丟失,建議也將配置添加到my.cnf中:
主庫(kù)配置文件添加:
[mysqld] rpl_semi_sync_master_enabled=1 # 或8.026版本添加: # rpl_semi_sync_source_enabled=1
主庫(kù)配置文件添加:
[mysqld] rpl_semi_sync_slave_enabled=1 # 或8.026版本添加: # rpl_semi_sync_replica_enabled=1
如果在完成上面配置時(shí)異步復(fù)制正在運(yùn)行,則需要重啟從庫(kù)的I/O線程來(lái)切換到半同步復(fù)制:
stop slave io_thread; start slave io_thread; show status like 'rpl_semi_sync_slave_status'; -- 查看備庫(kù)半同步復(fù)制狀態(tài)

查看主庫(kù)半同步復(fù)制狀態(tài):
show status like 'rpl_semi_sync_master_status';

通過(guò)狀態(tài)變量,我們看到主備的半同步都是處于工作狀態(tài),半同步復(fù)制的搭建完成。
三、配置半同步復(fù)制
當(dāng)完成了半同步配置后,系統(tǒng)上和半同步相關(guān)的配置參數(shù)就可以使用了,這些參數(shù)可用來(lái)調(diào)整半同步復(fù)制的配置:
主庫(kù)查看半同步相關(guān)配置參數(shù):
show variables like 'rpl_semi_sync%';

如果使用的是8.0.26以上的版本,參數(shù)中的'master'會(huì)被替換為'source','slave'會(huì)被替換為'replica',下面依次解釋各參數(shù)設(shè)置含義:
rpl_semi_sync_master_enabled
用來(lái)控制是否開(kāi)啟半同步復(fù)制,ON代表開(kāi)啟,OFF代表關(guān)閉。
rpl_semi_sync_master_timeout
主庫(kù)等待從庫(kù)ACK超時(shí)的時(shí)長(zhǎng),單位是毫秒,默認(rèn)是10000(10s)。
rpl_semi_sync_master_trace_level
半同步復(fù)制時(shí)主庫(kù)的調(diào)試級(jí)別
rpl_semi_sync_master_wait_for_slave_count
主庫(kù)需要收到多少個(gè)ACK才認(rèn)為此次提交成功,否則就降級(jí)為異步復(fù)制,默認(rèn)是1,即只要有1個(gè)從庫(kù)確認(rèn)即可提交。
rpl_semi_sync_master_wait_no_slave
為ON時(shí)(默認(rèn)值),當(dāng)狀態(tài)變量Rpl_semi_sync_master_clients中的值小于rpl_semi_sync_master_wait_for_slave_count時(shí)(即從庫(kù)數(shù)小于需要的最小確認(rèn)數(shù)),Rpl_semi_sync_master_status依舊為ON,只有當(dāng)事務(wù)提交后等待rpl_semi_sync_master_timeout超時(shí)后,Rpl_semi_sync_master_status才會(huì)變?yōu)镺FF,即降級(jí)為異步復(fù)制;
為OFF時(shí),當(dāng)狀態(tài)變量Rpl_semi_sync_master_clients中的值小于rpl_semi_sync_master_wait_for_slave_count時(shí),Rpl_semi_sync_master_status立即顯示為OFF,即立即降級(jí)為異步復(fù)制。
rpl_semi_sync_master_wait_point
控制主庫(kù)上commit、接收ACK、返回控制給客戶端的時(shí)間點(diǎn)。值為after_sync(默認(rèn))或after_commit。
- after_sync:主庫(kù)會(huì)等待從庫(kù)的ACK后再提交事務(wù),最后返還控制權(quán)給客戶端。主庫(kù)上所有會(huì)話同一時(shí)間看到提交的事務(wù),如果發(fā)生failover,主從數(shù)據(jù)是一致的。
- after_commit:主庫(kù)會(huì)先提交事務(wù),再等待ACK,最后返還控制權(quán)給客戶端。主庫(kù)會(huì)先提交,此時(shí)主庫(kù)上其他會(huì)話可以看到已提交的事務(wù),但執(zhí)行事務(wù)的會(huì)話還未返還,依然在等待從庫(kù)確認(rèn),如果從庫(kù)因?yàn)楸罎](méi)有處理這個(gè)事務(wù),那么其他會(huì)話會(huì)在主從看到不一致的數(shù)據(jù)(主庫(kù)事務(wù)提交了,從庫(kù)的事務(wù)丟了)。
四、監(jiān)控半同步復(fù)制
完成了半同步配置后,和半同步相關(guān)的相關(guān)狀態(tài)變量可以幫助我們監(jiān)控半同步復(fù)制的狀態(tài):
show status like 'rpl_semi_sync%';

主庫(kù)有半同步復(fù)制相關(guān)的狀態(tài)變量解釋:
Rpl_semi_sync_master_clients:當(dāng)前有多少個(gè)半同步從庫(kù)連接到主庫(kù)。
Rpl_semi_sync_master_net_avg_wait_time:主庫(kù)等待從庫(kù)回復(fù)的平均時(shí)間,以微秒為單位。此變量始終為0,不推薦使用,并且將在以后的版本中刪除。
Rpl_semi_sync_master_net_wait_time:主庫(kù)等待從庫(kù)回復(fù)的總時(shí)間,以微秒為單位。此變量始終為0,不推薦使用,并且將在以后的版本中刪除。
Rpl_semi_sync_master_net_waits:主庫(kù)等待從庫(kù)回復(fù)的總次數(shù)。
Rpl_semi_sync_master_no_times:主庫(kù)關(guān)閉半同步復(fù)制的次數(shù)。
Rpl_semi_sync_master_no_tx:從庫(kù)未成功確認(rèn)的事務(wù)數(shù)。
Rpl_semi_sync_master_status:為ON時(shí)表示使用半同步復(fù)制,為OFF時(shí)表示異步復(fù)制。
Rpl_semi_sync_master_timefunc_failures:調(diào)用gettimeofday等時(shí)間函數(shù)時(shí)主庫(kù)失敗的次數(shù)。
Rpl_semi_sync_master_tx_avg_wait_time:主庫(kù)等待一個(gè)事務(wù)的平均時(shí)間,以微秒為單位。
Rpl_semi_sync_master_tx_wait_time:主庫(kù)等待事務(wù)的總時(shí)間,以微秒為單位。
Rpl_semi_sync_master_tx_waits:主庫(kù)等待事務(wù)的總次數(shù)。
Rpl_semi_sync_master_wait_pos_backtraverse:主庫(kù)等待事件的二進(jìn)制日志次數(shù)低于之前等待事件的總次數(shù)。當(dāng)事務(wù)等待回復(fù)的順序與其二進(jìn)制日志事件的寫入順序不同時(shí),就會(huì)發(fā)生這種情況。
Rpl_semi_sync_master_wait_sessions:當(dāng)前正在等待從庫(kù)回復(fù)的會(huì)話數(shù)。
Rpl_semi_sync_master_yes_tx:從庫(kù)成功確認(rèn)的事務(wù)數(shù)。
到此這篇關(guān)于 MySQL 半同步復(fù)制的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān) MySQL 半同步復(fù)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mysql主從同步Last_IO_Errno:1236錯(cuò)誤解決方法
最近遇到Mysql主從同步的Last_IO_Errno:1236錯(cuò)誤問(wèn)題,然后在網(wǎng)上查找相關(guān)解決方案,這里分享給大家,供參考。2017-10-10
Mysql連接無(wú)效(invalid connection)問(wèn)題及解決
這篇文章主要介紹了Mysql連接無(wú)效(invalid connection)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
MySQL 處理重復(fù)數(shù)據(jù)的方法(防止、刪除)
這篇文章主要介紹了MySQL 處理重復(fù)數(shù)據(jù)的方法,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07
MySQL修改存儲(chǔ)過(guò)程的詳細(xì)步驟
這篇文章主要給大家介紹了關(guān)于MySQL修改存儲(chǔ)過(guò)程的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
mysql連接過(guò)多和死掉以及拒絕服務(wù)的解決方法
mysql連接過(guò)多和死掉以及拒絕服務(wù)的解決方法...2007-12-12
修改mysql允許主機(jī)訪問(wèn)的權(quán)限方法
默認(rèn)mysql的用戶是沒(méi)有遠(yuǎn)程訪問(wèn)的權(quán)限的,因此當(dāng)程序跟數(shù)據(jù)庫(kù)不在同一臺(tái)服務(wù)器上時(shí),我們需要開(kāi)啟mysql的遠(yuǎn)程訪問(wèn)權(quán)限,下面通過(guò)本文給大家分享修改mysql允許主機(jī)訪問(wèn)的權(quán)限的方法,感興趣的朋友一起看看吧2017-07-07
mysql如何刪除數(shù)據(jù)表和關(guān)聯(lián)的數(shù)據(jù)表刪除詳情
這篇文章主要介紹了mysql如何刪除數(shù)據(jù)表和關(guān)聯(lián)的數(shù)據(jù)表刪除詳情,刪除數(shù)據(jù)表的時(shí)候,表的定義和表中所有的數(shù)據(jù)均會(huì)被刪除。因此,在進(jìn)行刪除操作前,最好對(duì)表中的數(shù)據(jù)做一個(gè)備份,以免造成無(wú)法挽回的后果2022-07-07
數(shù)據(jù)庫(kù)中update與delete使用表別名的深入研究
本文介紹了UPDATE和DELETE?SQL語(yǔ)句在Oracle,?SQLite,?PostgreSQL,?MYSQL,?mariadb等數(shù)據(jù)庫(kù)系統(tǒng)中的執(zhí)行差異,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)數(shù)據(jù)庫(kù)開(kāi)發(fā)和維護(hù)人員有指導(dǎo)意義,需要的朋友可以參考下2024-10-10

