天天看點

【案例】複制靜止問題一則

一背景

  早上7點多接到一個資料庫伺服器空間報警,磁盤空間不足。登陸資料庫檢視,mysql slave 大量延遲,有68g 的relay log。檢視slave status 發現relay_log_pos ,exec_master_log_pos  位點始終不變,當時的狀态展示如下:

二 分析

根據slave 複制的原理可知  relay_log_pos 是指sql_thread 程序讀取relay log檔案的位點,exec_master_log_pos是sql_thread 執行relay log中相對于 主庫master binlog file的位點。那為什麼sql_thread 一直顯示靜止狀态呢?

我們如下幾個方面思考 

1 主機的io層面,是否是伺服器的io能力不足導緻的呢?

【案例】複制靜止問題一則

從結果上看io使用率極低,不可能導緻sql_thread執行緩慢的或者靜止的。 

2 sql_thread 等待mysql的mdl鎖,或者備份的flus table with read lock 等常見的所等待 

登陸資料庫檢視 ,備庫無任何業務連接配接,也沒有備份在進行。是以可以排除mysql 鎖層面的問題。 

【案例】複制靜止問題一則

使用 pt-pmp工具檢視資料庫程序此時的狀态,能否獲得一些線索

【案例】複制靜止問題一則

從pt-pmp執行結果上來看,注意 execute_command, reader_loop 函數,說明資料庫一直在執行sql語句,隻是執行的比較緩慢,循環讀取relay log中的event 。我們進一步将問題範圍縮小。

3 分析有沒有大事務,全表delete 等,sql_thread将主庫的log event重新再備庫上執行一遍,遇到全表delete /update且表結構設計不合理導緻sql_thread 執行極其緩慢

使用工具分析目前relaylog 具體執行什麼事務?

mysqlbinlog  ../mysql/relay-bin.000421  --start-position=233450854 > relay.log

【案例】複制靜止問題一則

果然是有大事務--大批量的delete操作,查詢資料庫該表有1200w左右的記錄,無主鍵(在這裡給無專職dba的公司開發提個醒,所有的表務必要建立主鍵)且沒有任何索引。至此問題的原因找到了,那麼如何解決呢?

可以參考的解決方法有

1 提高資料庫的寫速度。

  set global sync_binlog=0

  set global innodb_log_flush_at_trx_commit=0;

2 在從庫給表添加索引

set session sql_log_bin=0;

alter table xxx add key idx_curday(current_day)

實際過程中該問題于晚上22點左右将延遲的relaylog應用完畢,該伺服器的磁盤為sas 機械盤,io能力較差。如果更換為ssd 存儲媒體應該會更快一些。各位讀者朋友如果還有其他想法,可以留言互相交流提供更好的解決方法。

三 小結