溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MySQL主從數(shù)據(jù)庫的同步延遲原理及解決方案

發(fā)布時(shí)間:2020-04-22 14:51:20 來源:億速云 閱讀:307 作者:三月 欄目:數(shù)據(jù)庫

下文內(nèi)容主要給大家?guī)?a title="MySQL" target="_blank" href="http://www.kemok4.com/mysql/">MySQL主從數(shù)據(jù)庫的同步延遲原理及解決方案,所講到的知識(shí),與書籍略有不同,都是億速云專業(yè)技術(shù)人員在與用戶接觸過程中,總結(jié)出來的,具有一定的經(jīng)驗(yàn)分享價(jià)值,希望給廣大讀者帶來幫助。

MySQL主從數(shù)據(jù)庫同步延遲問題

                        摘要: MySQL的主從同步是一個(gè)很成熟的架構(gòu),優(yōu)點(diǎn)為:①在從云服務(wù)器可以執(zhí)行查詢工作(即我們常說的讀功能),降低主服務(wù)器壓力;②在從主服務(wù)器進(jìn)行備份,避免備份期間影響主服務(wù)器服務(wù);③當(dāng)主服務(wù)器出現(xiàn)問題時(shí),可以切換到從服務(wù)器。 相信大家對(duì)于這些好處已經(jīng)非常了解了,在項(xiàng)目的部署中也采用這種方案。但是MySQL...

MySQL主從數(shù)據(jù)庫的同步延遲原理及解決方案

MySQL的主從同步是一個(gè)很成熟的架構(gòu),優(yōu)點(diǎn)為:①在從服務(wù)器可以執(zhí)行查詢工作(即我們常說的讀功能),降低主服務(wù)器壓力;②在從主服務(wù)器進(jìn)行備份,避免備份期間影響主服務(wù)器服務(wù);③當(dāng)主服務(wù)器出現(xiàn)問題時(shí),可以切換到從服務(wù)器。

相信大家對(duì)于這些好處已經(jīng)非常了解了,在項(xiàng)目的部署中也采用這種方案。但是MySQL的主從同步一直有從庫延遲的問題,那么為什么會(huì)有這種問題。這種問題如何解決呢?

1. MySQL數(shù)據(jù)庫主從同步延遲原理。

2. MySQL數(shù)據(jù)庫主從同步延遲是怎么產(chǎn)生的。

3. MySQL數(shù)據(jù)庫主從同步延遲解決方案。

 

1. MySQL數(shù)據(jù)庫主從同步延遲原理。

答:談到MySQL數(shù)據(jù)庫主從同步延遲原理,得從mysql的數(shù)據(jù)庫主從復(fù)制原理說起,mysql的主從復(fù)制都是單線程的操作,主庫對(duì)所有DDL和 DML產(chǎn)生binlog,binlog是順序?qū)?,所以效率很高,slave的Slave_IO_Running線程到主庫取日志,效率很比較高,下一步, 問題來了,slave的Slave_SQL_Running線程將主庫的DDL和DML操作在slave實(shí)施。DML和DDL的IO操作是隨即的,不是順 序的,成本高很多,還可能可slave上的其他查詢產(chǎn)生lock爭(zhēng)用,由于Slave_SQL_Running也是單線程的,所以一個(gè)DDL卡主了,需要 執(zhí)行10分鐘,那么所有之后的DDL會(huì)等待這個(gè)DDL執(zhí)行完才會(huì)繼續(xù)執(zhí)行,這就導(dǎo)致了延時(shí)。有朋友會(huì)問:“主庫上那個(gè)相同的DDL也需要執(zhí)行10分,為什 么slave會(huì)延時(shí)?”,答案是master可以并發(fā),Slave_SQL_Running線程卻不可以。

2. MySQL數(shù)據(jù)庫主從同步延遲是怎么產(chǎn)生的。

答:當(dāng)主庫的TPS并發(fā)較高時(shí),產(chǎn)生的DDL數(shù)量超過slave一個(gè)sql線程所能承受的范圍,那么延時(shí)就產(chǎn)生了,當(dāng)然還有就是可能與slave的大型query語句產(chǎn)生了鎖等待。

3. MySQL數(shù)據(jù)庫主從同步延遲解決方案

答:最簡(jiǎn)單的減少slave同步延時(shí)的方案就是在架構(gòu)上做優(yōu)化,盡量讓主庫的DDL快速執(zhí)行。還有就是主庫是寫,對(duì)數(shù)據(jù)安全性較高,比如 sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設(shè)置,而slave則不需要這么高的數(shù)據(jù)安全,完全可以講sync_binlog設(shè)置為0或者關(guān)閉binlog,innodb_flushlog也 可以設(shè)置為0來提高sql的執(zhí)行效率。另外就是使用比主庫更好的硬件設(shè)備作為slave。

mysql-5.6.3已經(jīng)支持了多線程的主從復(fù)制。原理和丁奇的類似,丁奇的是以表做多線程,Oracle使用的是以數(shù)據(jù)庫(schema)為單位做多線程,不同的庫可以使用不同的復(fù)制線程。

 

基于局域網(wǎng)的master/slave機(jī)制在通常情況下已經(jīng)可以滿足'實(shí)時(shí)'備份的要求了。如果延遲比較大,就先確認(rèn)以下幾個(gè)因素: 
1. 網(wǎng)絡(luò)延遲
2. master負(fù)載
3. slave負(fù)載
一般的做法是,使用多臺(tái)slave來分?jǐn)傋x請(qǐng)求,再從這些slave中取一臺(tái)專用的服務(wù)器,只作為備份用,不進(jìn)行其他任何操作,就能相對(duì)最大限度地達(dá)到'實(shí)時(shí)'的要求了

slave_net_timeout單位為秒 默認(rèn)設(shè)置為 3600秒

參數(shù)含義:當(dāng)slave從主數(shù)據(jù)庫讀取log數(shù)據(jù)失敗后,等待多久重新建立連接并獲取數(shù)據(jù)

master-connect-retry單位為秒 默認(rèn)設(shè)置為 60秒

參數(shù)含義:當(dāng)重新建立主從連接時(shí),如果連接建立失敗,間隔多久后重試。

通常配置以上2個(gè)參數(shù)可以減少網(wǎng)絡(luò)問題導(dǎo)致的主從數(shù)據(jù)同步延遲

 

判斷主從延時(shí),通常有兩個(gè)方法:

1. Seconds_Behind_Master  vs  2. mk-heartbeat,下面具體說下兩者在實(shí)現(xiàn)功能的差別。

可以通過監(jiān)控show slave status\G命令輸出的Seconds_Behind_Master參數(shù)的值來判斷,是否有發(fā)生主從延時(shí)。
其值有這么幾種:
NULL - 表示io_thread或是sql_thread有任何一個(gè)發(fā)生故障,也就是該線程的Running狀態(tài)是No,而非Yes.
0 - 該值為零,是我們極為渴望看到的情況,表示主從復(fù)制良好,可以認(rèn)為lag不存在。
正值 - 表示主從已經(jīng)出現(xiàn)延時(shí),數(shù)字越大表示從庫落后主庫越多。
負(fù)值 - 幾乎很少見,只是聽一些資深的DBA說見過,其實(shí),這是一個(gè)BUG值,該參數(shù)是不支持負(fù)值的,也就是不應(yīng)該出現(xiàn)。

Seconds_Behind_Master是通過比較sql_thread執(zhí)行的event的timestamp和io_thread復(fù)制好的 event的timestamp(簡(jiǎn)寫為ts)進(jìn)行比較,而得到的這么一個(gè)差值。我們都知道的relay-log和主庫的bin-log里面的內(nèi)容完全一 樣,在記錄sql語句的同時(shí)會(huì)被記錄上當(dāng)時(shí)的ts,所以比較參考的值來自于binlog,其實(shí)主從沒有必要與NTP進(jìn)行同步,也就是說無需保證主從時(shí)鐘的 一致。你也會(huì)發(fā)現(xiàn),其實(shí)比較真正是發(fā)生在io_thread與sql_thread之間,而io_thread才真正與主庫有關(guān)聯(lián),于是,問題就出來了, 當(dāng)主庫I/O負(fù)載很大或是網(wǎng)絡(luò)阻塞,io_thread不能及時(shí)復(fù)制binlog(沒有中斷,也在復(fù)制),而sql_thread一直都能跟上 io_thread的腳本,這時(shí)Seconds_Behind_Master的值是0,也就是我們認(rèn)為的無延時(shí),但是,實(shí)際上不是,你懂得。這也就是為什 么大家要批判用這個(gè)參數(shù)來監(jiān)控?cái)?shù)據(jù)庫是否發(fā)生延時(shí)不準(zhǔn)的原因,但是這個(gè)值并不是總是不準(zhǔn),如果當(dāng)io_thread與master網(wǎng)絡(luò)很好的情況下,那么 該值也是很有價(jià)值的。(就好比:媽–兒子–媳婦的關(guān)系,媽與兒子親人,媳婦和兒子也親人,不見得媳婦與媽就很親。開個(gè)玩笑:-)之前,提到 Seconds_Behind_Master這個(gè)參數(shù)會(huì)有負(fù)值出現(xiàn),我們已經(jīng)知道該值是io_thread的最近跟新的ts與sql_thread執(zhí)行到 的ts差值,前者始終是大于后者的,唯一的肯能就是某個(gè)event的ts發(fā)生了錯(cuò)誤,比之前的小了,那么當(dāng)這種情況發(fā)生時(shí),負(fù)值出現(xiàn)就成為可能。

方法2. mk-heartbeat,Maatkit萬能工具包中的一個(gè)工具,被認(rèn)為可以準(zhǔn)確判斷復(fù)制延時(shí)的方法。

mk-heartbeat的實(shí)現(xiàn)也是借助timestmp的比較實(shí)現(xiàn)的,它首先需要保證主從服務(wù)器必須要保持一致,通過與相同的一個(gè)NTP server同步時(shí)鐘。它需要在主庫上創(chuàng)建一個(gè)heartbeat的表,里面至少有id與ts兩個(gè)字段,id為server_id,ts就是當(dāng)前的時(shí)間戳 now(),該結(jié)構(gòu)也會(huì)被復(fù)制到從庫上,表建好以后,會(huì)在主庫上以后臺(tái)進(jìn)程的模式去執(zhí)行一行更新操作的命令,定期去向表中的插入數(shù)據(jù),這個(gè)周期默認(rèn)為1 秒,同時(shí)從庫也會(huì)在后臺(tái)執(zhí)行一個(gè)監(jiān)控命令,與主庫保持一致的周期去比較,復(fù)制過來記錄的ts值與主庫上的同一條ts值,差值為0表示無延時(shí),差值越大表示 延時(shí)的秒數(shù)越多。我們都知道復(fù)制是異步的ts不肯完全一致,所以該工具允許半秒的差距,在這之內(nèi)的差異都可忽略認(rèn)為無延時(shí)。這個(gè)工具就是通過實(shí)打?qū)嵉膹?fù) 制,巧妙的借用timestamp來檢查延時(shí),贊一個(gè)!

對(duì)于以上關(guān)于MySQL主從數(shù)據(jù)庫的同步延遲原理及解決方案,如果大家還有更多需要了解的可以持續(xù)關(guān)注我們億速云的行業(yè)推新,如需獲取專業(yè)解答,可在官網(wǎng)聯(lián)系售前售后的,希望該文章可給大家?guī)硪欢ǖ闹R(shí)更新。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI