主從復(fù)制延遲原因剖析!

寫在前面:

成都創(chuàng)新互聯(lián)是專業(yè)的桂陽(yáng)網(wǎng)站建設(shè)公司,桂陽(yáng)接單;提供網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行桂陽(yáng)網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

之前在維護(hù)線上主從復(fù)制架構(gòu)的時(shí)候,遇到了一些主從延遲問(wèn)題,筆者呢,也是比較好學(xué)的,哈哈!所以,查閱了諸多資料,然后去其糟粕,根據(jù)自己的理解和查閱的資料整理成了本文,在此申明,本文內(nèi)容是筆者自己的理解,不代表權(quán)威性,僅供各位同行做個(gè)參考,自己呢,也做個(gè)學(xué)習(xí)記錄。本著實(shí)事求是的原則,對(duì)于網(wǎng)上的諸多資料,筆者自己也只是信5分,懷疑5分,就算是官方的資料,有的也有bug不是,只有自己動(dòng)手實(shí)踐過(guò)了,才能相信,才有發(fā)言權(quán),其他的,一切都是虛的!

MySQL主從復(fù)制過(guò)程:

1)主庫(kù) Binlog Dump線程在binlog有變化時(shí),主動(dòng)發(fā)送最新的binlog到從庫(kù)。

2)從庫(kù) I/O線程被動(dòng)接收主庫(kù)傳來(lái)的binlog之后,記錄到從庫(kù)的relay log中,當(dāng)沒(méi)有數(shù)據(jù)傳入的時(shí)候則會(huì)等待。與此同時(shí)SQL線程重放 relay log。

3)當(dāng)從庫(kù)長(zhǎng)時(shí)間未收到主庫(kù)傳來(lái)的數(shù)據(jù),并且等待時(shí)間超過(guò)了slave_net_timeout定義的時(shí)間(默認(rèn)3600秒)后,Slave_IO_State的狀態(tài)將會(huì)置為No。在此之后,每隔MASTER_CONNECT_RETRY [Connect_Retry: 30]定義的時(shí)間(默認(rèn)60秒)將會(huì)嘗試重新連接,直到連接成功或超過(guò)重試次數(shù)MASTER_RETRY_COUNT [Master_Retry_Count: 6666](默認(rèn)86400次)。

?

slave_net_timeout可以在配置文件中修改或set variable在線設(shè)置

而 MASTER_CONNECT_RETRY、MASTER_RETRY_COUNT 需要在CHANGE MASTER TO建立復(fù)制關(guān)系時(shí)提前指定

在線變更 slave_net_timeout:

SHOW VARIABLES LIKE 'slave_net_timeout'

Variable_name????????? `Value`

slave_net_timeout???? ?3600


SET GLOBAL slave_net_timeout=1800

修改MASTER_CONNECT_RETRY=30,MASTER_RETRY_COUNT值:

mysql> change master to MASTER_CONNECT_RETRY=30,MASTER_RETRY_COUNT=6666;

ERROR 1198 (HY000): This operation cannot be performed with a running slave; run STOP SLAVE first

?

mysql> stop slave;

Query OK, 0 rows affected (0.01 sec)

?

mysql> change master to MASTER_CONNECT_RETRY=30,MASTER_RETRY_COUNT=6666;

Query OK, 0 rows affected (0.01 sec)

?

mysql> start slave;

Query OK, 0 rows affected (0.02 sec)

MySQL主從復(fù)制延遲是怎樣形成的:

1、主庫(kù)的worker線程在寫binlog的時(shí)候是并發(fā)工作的(并行寫入),而主庫(kù)的dump線程和從庫(kù)的IO線程都是單線程推拉binlog,特別是SQL線程是拿著relay log中的event逐一單線程回放的(5.6版本開(kāi)啟slave_parallel_workers支持特定情況下的并行復(fù)制,5.7版本之后全面支持并行復(fù)制后在復(fù)制層面已極大改善了延遲問(wèn)題)。因此即使不考慮網(wǎng)絡(luò)延遲,主流MySQL版本在高并發(fā)的情況下,消費(fèi)很可能趕不上生產(chǎn),采用異步復(fù)制的從庫(kù)很有可能跟不上主庫(kù)的進(jìn)度。


2、在復(fù)制期間,無(wú)論是主庫(kù)或從庫(kù)負(fù)載高(特別是從庫(kù)落盤壓力大,關(guān)系到sync_binlog、innodb_flush_log_at_trx_commit的設(shè)置)或者是網(wǎng)絡(luò)傳輸慢(特別是跨機(jī)房的同步)等情況發(fā)生時(shí),都會(huì)產(chǎn)生主從延遲,并且是不可避免的。如果要實(shí)現(xiàn)強(qiáng)一致性,可采用Semi-sync,但采用該plugin也無(wú)法保證持續(xù)強(qiáng)一致性(rpl_semi_sync_master_timeout會(huì)引起復(fù)制模式的降級(jí))

根據(jù)MySQL主從復(fù)制延遲的形成原因,以下情況可能導(dǎo)致MySQL主從復(fù)制延遲:

1)MASTER高并發(fā),形成大量事務(wù)

2)網(wǎng)絡(luò)狀況差

3)從庫(kù)的硬件配置沒(méi)有主庫(kù)的好

4)本來(lái)就是異步復(fù)制

關(guān)于落盤時(shí)的部分參數(shù)解釋:

sync_binlog:

????????MySQL官方文檔參考:https://dev.mysql.com/doc/refman/5.6/en/replication-options-binary-log.html

解釋:

??????? Controlshow often the MySQL server synchronizes the binary log to disk

?控制MySQL將二進(jìn)制日志(binary log)同步到磁盤的頻率

sync_binlog=0:

????Disables synchronization of the binary log to disk by the MySQL server. Instead, the MySQL server relies on the operating system to flush the binary log to disk from time to time as it does for any other file. This setting provides the best performance, but in the event of a power failure or operating system crash, it is possible that the server has committed transactions that have not been synchronized to the binary log.

sync_binlog=1:

????Enables synchronization of the binary log to disk before transactions are committed. This is the safest setting but can have a negative impact on performance due to the increased number of disk writes. In the event of a power failure or operating system crash, transactions that are missing from the binary log are only in a prepared state. This permits the automatic recovery routine to roll back the transactions, which guarantees that no transaction is lost from the binary log.

sync_binlog=N:

???? where N is a value other than 0 or 1: The binary log is synchronized to disk after N binary log commit groups have been collected. In the event of a power failure or operating system crash, it is possible that the server has committed transactions that have not been flushed to the binary log. This setting can have a negative impact on performance due to the increased number of disk writes. A higher value improves performance, but with an increased risk of data loss.

innodb_flush_log_at_trx_commit:

????????MySQL官方文檔參考:https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit

????????其他參考文檔:

?? ????https://blog.csdn.net/codepen/article/details/52160715

????????https://www.cnblogs.com/mayipapa/p/4685313.html

解釋:

????????是 InnoDB 引擎特有的,ib_logfile的刷新方式

MySQL日志寫入順序:

log buffer => MySQL(write) => log file => OS刷新(flush) => disk

innodb_flush_log_at_trx_commit取值解釋:(從一些博客之中參考的)

0,延遲寫:

log buffer => 每隔1秒 => log file => OS 實(shí)時(shí)flush => disk

1,實(shí)時(shí)寫,實(shí)時(shí)刷:

?????? log buffer => 實(shí)時(shí) => log file => OS實(shí)時(shí)flush => disk

?????? 這樣的話,數(shù)據(jù)庫(kù)對(duì)IO的要求就非常高了,如果底層的硬件提供的IOPS比較差,那么MySQL數(shù)據(jù)庫(kù)的并發(fā)很快就會(huì)由于硬件IO的問(wèn)題而無(wú)法提升

2,實(shí)時(shí)寫,延遲刷:

?????? log buffer => 實(shí)時(shí) => log file => OS每隔1秒 => disk

?????? 如果只是MySQL數(shù)據(jù)庫(kù)掛掉了,由于文件系統(tǒng)沒(méi)有問(wèn)題,那么對(duì)應(yīng)的事務(wù)數(shù)據(jù)并沒(méi)有丟失。只有在數(shù)據(jù)庫(kù)所在的主機(jī)操作系統(tǒng)損壞或者突然掉電的情況下,數(shù)據(jù)庫(kù)的事務(wù)數(shù)據(jù)可能丟失1秒之類的事務(wù)數(shù)據(jù)。這樣的好處,減少了事務(wù)數(shù)據(jù)丟失的概率,而對(duì)底層硬件的IO要求也沒(méi)有那么高(log buffer寫到文件系統(tǒng)中,一般只是從log buffer的內(nèi)存轉(zhuǎn)移的文件系統(tǒng)的內(nèi)存緩存中,對(duì)底層IO沒(méi)有壓力)。

?

官方文檔中文解釋:(筆者自己的理解)

?????? 當(dāng)innodb_flush_log_at_trx_commit,被設(shè)置為0,日志緩沖(log buffer)每秒一次地被寫入到日志文件(log file),并且對(duì)日志文件做磁盤刷新(flush disk),該模式下在事務(wù)提交的時(shí)候,不會(huì)主動(dòng)觸發(fā)寫入磁盤的操作。

?????? 當(dāng)innodb_flush_log_at_trx_commit,被設(shè)置為1,在每個(gè)事務(wù)提交時(shí),日志緩沖(log buffer)被寫入到日志文件(log file),并且對(duì)日志文件做磁盤刷新(flush disk) [同時(shí)進(jìn)行]

?????? 當(dāng)innodb_flush_log_at_trx_commit,被設(shè)置為2,在每個(gè)事務(wù)提交時(shí),日志緩沖(log buffer)被寫入到日志文件(log file),但不對(duì)日志文件做磁盤刷新(flush disk) [不同時(shí)進(jìn)行],該模式下,MySQL會(huì)每秒執(zhí)行一次 flush(刷到磁盤)操作

? ? ?? 盡管如此,當(dāng)innodb_flush_log_at_trx_commit值為2時(shí),對(duì)日志文件(log file)的磁盤刷新(flush disk)也每秒發(fā)生一次。

?????? 因?yàn)檫M(jìn)程安排問(wèn)題,每秒一次的刷新不是100%保證都會(huì)發(fā)生??梢酝ㄟ^(guò)設(shè)置innodb_flush_log_at_trx_commit值不為1來(lái)獲得較好的性能,但如果你設(shè)置此值為0,那么MySQL崩潰會(huì)丟失崩潰前1秒的事務(wù)(該模式下性能最好,但不×××全);如果設(shè)置此值為2,當(dāng)操作系統(tǒng)崩潰或斷電時(shí)才會(huì)丟失最后1秒的事務(wù)(該模式下性能較好,也比0模式安全)。如果設(shè)置此值為0,該模式性能最低,但是最安全的模式。在MySQL服務(wù)崩潰或者操作系統(tǒng)crash的情況下,binlog只會(huì)丟失一個(gè)語(yǔ)句或一個(gè)事務(wù)。

注意,許多操作系統(tǒng)和一些磁盤硬件會(huì)欺騙刷新到磁盤操作(flush disk)。盡管刷新沒(méi)有進(jìn)行,也會(huì)告訴MySQL刷新已經(jīng)進(jìn)行。即使設(shè)置此值為1,事務(wù)的持久性也不被保證,且在最壞的情況下斷電甚至?xí)茐臄?shù)據(jù)庫(kù)。在SCSI磁盤控制器中,或在磁盤自身中,使用有后備電池的磁盤緩存會(huì)加速文件刷新并且使得操作更安全。可以試著使用hdparm命令在硬件緩存中禁止磁盤寫緩存,或者使用其他一些對(duì)硬件提供商專用的命令

最后MySQL官方建議:

A higher value improves performance, but with an increased risk of data loss

For the greatest possible durability and consistency in a replication setup that uses InnoDB with transactions, use these settings:

sync_binlog=1

innodb_flush_log_at_trx_commit=1

MySQL主從延遲如何計(jì)算

第一種計(jì)算方式:position(簡(jiǎn)單粗暴,僅僅能看出是否有延遲)

mysql> show slave status\G;

Read_Master_Log_Pos: 4

Exec_Master_Log_Pos: 0

?

第二種計(jì)算方式:Seconds_Behind_Master

參考MySQL官方文檔:

https://dev.mysql.com/doc/refman/5.6/en/replication-administration-status.html

https://dev.mysql.com/doc/refman/5.6/en/show-slave-status.html

參考其他文章:

https://blog.csdn.net/leonpenn/article/details/76489480

1) 當(dāng)SQL線程執(zhí)行event時(shí),從庫(kù)執(zhí)行時(shí)刻的timestamp值 減去 該event上附帶的時(shí)間戳(當(dāng)時(shí)主庫(kù)上的timestamp),這兩者的差值

2) 一旦SQL線程未在執(zhí)行event,則Seconds_Behind_Master為0

3) IO線程或SQL線程 is?not?running,則Seconds_Behind_Master為NULL

4) Seconds_Behind_Master為0時(shí),表示master slave 復(fù)制沒(méi)有延遲(絕大情況下如此)

在網(wǎng)絡(luò)很快的情況下,io thread 很快的從master獲取binlog到slave的realy log,然后sql thread replay,此時(shí)Seconds_Behind_Master值能真正表示slave落后于master的秒數(shù)。

在網(wǎng)絡(luò)很差的情況下,io thread同步master的binlog很慢,而sql thread replay很快,此時(shí)Seconds_Behind_Master也是0,但真正情況是,slave落后于master很多

假如有以下3種情況發(fā)生,雖然Seconds_Behind_Master仍然存在非NULL的值,但已經(jīng)變得不準(zhǔn)確

1、主從時(shí)間不一致(雖然引入了clock_diff_with_master,盡量調(diào)節(jié)時(shí)間差帶來(lái)的影響,但該值僅在從庫(kù)與主庫(kù)建立連接之時(shí)獲取,后續(xù)不再更新,若之后再去修改主從機(jī)的時(shí)間,該值就不可靠了)。

2、主從庫(kù)間網(wǎng)絡(luò)問(wèn)題或者從庫(kù)IO線程未發(fā)現(xiàn)主庫(kù)的binlog dump 線程掛了,仍然在等待數(shù)據(jù)傳輸過(guò)來(lái),SBM長(zhǎng)時(shí)間持續(xù)為零。

3、主庫(kù)有較大的binlog event執(zhí)行前后,從庫(kù)上看到的SBM將會(huì)有大的跳動(dòng)(監(jiān)控圖中將很可能產(chǎn)生毛刺)

4、對(duì)于并行復(fù)制,SMB是基于Exec_Master_Log_Pos,不精準(zhǔn)。


新聞標(biāo)題:主從復(fù)制延遲原因剖析!
本文URL:http://muchs.cn/article38/piscpp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、、網(wǎng)頁(yè)設(shè)計(jì)公司網(wǎng)站排名、響應(yīng)式網(wǎng)站網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)