溫馨提示×

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

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

mysql常見(jiàn)slave延遲原因有哪些

發(fā)布時(shí)間:2021-11-06 14:08:55 來(lái)源:億速云 閱讀:265 作者:小新 欄目:MySQL數(shù)據(jù)庫(kù)

這篇文章主要介紹了mysql常見(jiàn)slave延遲原因有哪些,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

一  序言

在運(yùn)維線上M-M 架構(gòu)的MySQL數(shù)據(jù)庫(kù)時(shí),接收的比較多關(guān)于主備延時(shí)的報(bào)警:

  1. check_ins_slave_lag (err_cnt:1)critical-slavelag on ins:3306=39438

相信slave 延遲是MySQL dba 遇到的一個(gè)老生長(zhǎng)談的問(wèn)題了。先來(lái)分析一下slave延遲帶來(lái)的風(fēng)險(xiǎn)

  1. 異常情況下,主從HA無(wú)法切換。HA 軟件需要檢查數(shù)據(jù)的一致性,延遲時(shí),主備不一致。 

  2. 備庫(kù)復(fù)制hang會(huì)導(dǎo)致備份失敗(flush tables with read lock會(huì)900s超時(shí))

  3. 以 slave 為基準(zhǔn)進(jìn)行的備份,數(shù)據(jù)不是最新的,而是延遲。

二  如何解決

面對(duì)此類問(wèn)題我們?nèi)绾谓鉀Q ,如何規(guī)避?分析一下導(dǎo)致備庫(kù)延遲的幾種原因

1. ROW模式無(wú)主鍵、無(wú)索引或索引區(qū)分度不高.有如下特征

   a. show slave status 顯示position一直沒(méi)有變

   b. show open tables 顯示某個(gè)表一直是 in_use 為 1

   c. show create table 查看表結(jié)構(gòu)可以看到無(wú)主鍵,或者無(wú)任何索引,或者索引區(qū)分度很差。

解決方法:

   a. 找到表區(qū)分度比較高的幾個(gè)字段, 可以使用這個(gè)方法判斷:

    select count(*) from xx; 

    select count(*) from (select distinct xx from xxx) t;

    如果2個(gè)查詢count(*)的結(jié)果差不多,說(shuō)明可以對(duì)這些字段加索引

   b. 備庫(kù)stop slave;

    可能會(huì)執(zhí)行比較久,因?yàn)樾枰貪L事務(wù)。

  c. 備庫(kù)

    set sql_log_bin=0;

    alter table xx add key xx(xx);

   老的版本slave應(yīng)用binlog時(shí)只會(huì)選擇第一個(gè)索引,需要把新加的索引放在最前面,可以先把老的索引刪掉,建新的索引,再把老的索引建上。可以放到一個(gè)sql中執(zhí)行。

  d. 備庫(kù)start slave

    如果是innodb,可以通過(guò)show innodb status來(lái)查看 rows_inserted,updated,deleted,selected這幾個(gè)指標(biāo)來(lái)判斷。

    如果每秒修改的記錄數(shù)比較多,說(shuō)明復(fù)制正在以比較快的速度執(zhí)行。

2 MIXED模式無(wú)索引或SQL慢

   在從庫(kù)上show full processlist 查看到正在執(zhí)行的SQL。

解決方法:

  a.  SQL比較簡(jiǎn)單, 則檢查是否缺少索引,并添加索引。

  b. 另一類是 insert into select from的語(yǔ)句,如果select 里包含group by,多表關(guān)聯(lián),可能效率會(huì)比較低。

      這類可以到主庫(kù)把binlog_format改成row。

3 主庫(kù)上有大事務(wù),導(dǎo)致從庫(kù)延時(shí)

現(xiàn)象解析binlog 發(fā)現(xiàn)類似于下圖的情況看

解決方法:

與開(kāi)發(fā)溝通,增加緩存,異步寫(xiě)入數(shù)據(jù)庫(kù),減少直接對(duì)db的大量寫(xiě)入。

4. 主庫(kù)寫(xiě)入頻繁,從庫(kù)壓力跟不上導(dǎo)致延時(shí)

  此類原因的主要現(xiàn)象是數(shù)據(jù)庫(kù)的 IUD 操作非常多,slave由于sql_thread單線程的原因追不上主庫(kù)。

 解決方法:

 a 升級(jí)從庫(kù)的硬件配置,比如ssd,fio.

 b 使用@丁奇的預(yù)熱工具-relay fetch

   在備庫(kù)sql線程執(zhí)行更新之前,預(yù)先將相應(yīng)的數(shù)據(jù)加載到內(nèi)存中,并不能提高sql_thread線程執(zhí)行sql的能力,也不能加快io_thread線程讀取日志的速度。

 c 使用多線程復(fù)制 阿里MySQL團(tuán)隊(duì)實(shí)現(xiàn)的方案--基于行的并行復(fù)制。

   該方案允許對(duì)同一張表進(jìn)行修改的兩個(gè)事務(wù)并行執(zhí)行,只要這兩個(gè)事務(wù)修改了表中的不同的行。這個(gè)方案可以達(dá)到事務(wù)間更高的并發(fā)度,但是局限是必須使用Row格式的binlog。因?yàn)橹挥惺褂?     Row格式的binlog才可以知道一個(gè)事務(wù)所修改的行的范圍,而使用Statement格式的binlog只能知道修改的表對(duì)象。

5. 數(shù)據(jù)庫(kù)中存在大量myisam表,在備份的時(shí)候?qū)е聅lave 延遲

 由于xtrabackup 工具備份到最后會(huì)執(zhí)行flash tables with read lock ,對(duì)數(shù)據(jù)庫(kù)進(jìn)行鎖表以便進(jìn)行一致性備份,然后對(duì)于myisam表 鎖,會(huì)阻礙salve_sql_thread 停滯運(yùn)行進(jìn)而導(dǎo)致hang

該問(wèn)題目前的比較好的解決方式是修改表結(jié)構(gòu)為innodb存儲(chǔ)引擎的表。

 三 拓展閱讀

 [1] 怎樣解決MySQL數(shù)據(jù)庫(kù)主從復(fù)制延遲的問(wèn)題 

 [2] 三種MySQL并行復(fù)制方案的分析                

 [3] 一種MySQL主從同步加速方案-改進(jìn)

 [4] MySQL多線程同步MySQL-Transfer介紹


6、如何確認(rèn)真正延遲多少?
seconds_bebind_master這個(gè)參數(shù)不準(zhǔn),有時(shí)顯示為0,但是有數(shù)據(jù)延遲的情況,在stop slave和start slave后,數(shù)據(jù)就同步過(guò)來(lái)了,因?yàn)閟lave有時(shí)候檢測(cè)網(wǎng)絡(luò)正常失敗,可以使用腳本來(lái)實(shí)現(xiàn)監(jiān)控,在salve和master節(jié)點(diǎn)分別部署。
先在兩個(gè)節(jié)點(diǎn)都創(chuàng)建監(jiān)控表

  1. <span style="font-size:16px;">#filename: run_mysql_replication_heartbeat.py  

  2. #encoding=gbk  

  3. import datetime,time  

  4. import os,sys  

  5. from public import db  

  6.   

  7. import db_conf  

  8.   

  9. source_folder = db_conf.SOURCE_FOLDER  

  10.   

  11.   

  12. def init_eviroment_path():  

  13.     print sys.path  

  14.     python_path = (source_folder)  

  15.       

  16.     for i in python_path:  

  17.         if i not in sys.path:  

  18.             sys.path.append(i)  

  19.       

  20.     print sys.path  

  21.   

  22. def main():  

  23.     conn, cursor = db.GetMysqlCursor('update')  

  24.       

  25.     cursor.execute("insert into heartbeat (master_datetime,slave_datetime) values(now(),sysdate())")  

  26.       

  27.     cursor.close()  

  28.     conn.close()  

  29.   

  30. if __name__ == '__main__':  

  31.     init_eviroment_path()  

  32.     os.system("title MySQL Replication心跳")  

  33.     count = 1  

  34.     while True:  

  35.         main()  

  36.         print "(%d)%s"%(count,datetime.datetime.now())  

  37.         count+=1  

  38.         time.sleep(60)<span style="font-size: 24px;">  

  39.  

修改master端的binlog模式為statement(默認(rèn)為mix)

所以這么修改是因?yàn)楸仨毷莝tatement的SQL語(yǔ)句同步模式才行,否則mix下有可能是ROW的結(jié)果數(shù)據(jù)同步模式就不行,這個(gè)我也是通過(guò)master>show binlog events才找到這個(gè)原因。

如果要立刻看到結(jié)果,只要把master端的時(shí)間修改一下,例如提前一個(gè)小時(shí),執(zhí)行:

insert into heartbeat (master_datetime,slave_datetime) values(now(),sysdate())在slave上就可以看到類似如下結(jié)果:

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“mysql常見(jiàn)slave延遲原因有哪些”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!

向AI問(wèn)一下細(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