前兩天遇到一個1205(ER_LOCK_WAIT_TIMEOUT)的錯誤,弄了半天終於找到緣由,掌握原理+細心才能找到罪歸禍首。下面我給你們分享下這個問題的分析處理過程,但願對你們有所幫助。接到slave error告警後,看到現場是這樣的:slave重作binlog由於鎖超時中斷,報HA_ERR_LOCK_WAIT_TIMEOUT錯誤。mysql
超時,easy啊,心想估計是有大事務長期持有鎖,致使其餘事務超時等待。可是這個庫是隻讀的備庫,不可能有寫事務,經過show processlist命令也確實沒有發現寫事務,卻是有一個大查詢任務。當時以爲MVCC查詢不上鎖啊,直接無視。我嘗試從新start slave,發現沒過幾秒鐘,錯誤依然出現,而且Exec_Master_Log_Pos沒有變化,這說明一樣的事務嘗試寫錯誤,依然被堵住,致使鎖超時等待了。這必定是事務持有鎖致使鎖超時,但機器上除了查詢,啥也木有。隔離級別,確認下隔離級別,雖然生產環境中機器都是RC(讀提交)模式,但也不排除這種可能。但結果再次讓我失望,事務隔離級別是讀提交。sql
會不會是存儲引擎的問題,我又驗證了一把,表是innodb存儲引擎,讀不存在說是上表鎖的狀況。無語了,難道innodb的MVCC,讀在某些狀況下也上鎖?這豈不是與讀不上鎖上違背嗎?繼續排查問題,查看鎖等待狀況:spa
select * from information_schema.innodb_lock_waits;orm
這說明確實有事務堵住了更新。繼續,blog
SELECT r.trx_id waiting_trx_id,事務
r.trx_query waiting_query,ssl
b.trx_id blocking_trx_id,it
b.trx_query blocking_query,io
b.trx_mysql_thread_id blocking_thread,innodb
b.trx_started,
b.trx_wait_started
FROM information_schema.innodb_lock_waits w
INNER JOIN information_schema.innodb_trx b
ON b.trx_id = w.blocking_trx_id
INNER JOIN information_schema.innodb_trx r
ON r.trx_id = w.requesting_trx_id
從圖中能夠看到,blocking_query確實是select語句,靠,難道真是它上鎖了,上的什麼鎖呢?
select * from information_schema.innodb_locks;
能夠看到一個讀鎖和一個寫鎖,這說明了,查詢的確是上了記錄的讀鎖,鎖應該都是在innodb層面加的。到底爲啥會上讀鎖呢?
select trx_id,trx_state,trx_isolation_level from information_schema.innodb_trx;
答案揭曉了,能夠看到RUNNING的事務隔離級別是SERIALIZABLE,串行化隔離級別致使讀上鎖,進而阻塞複製沒法進行下去。
這個例子其實很簡單,經過這個例子能夠看到,information_schema下面的幾張表過重要了,暴露了不少信息,方便咱們排查問題。同時排查問題時,必定要堅信原理,而且細心,問題總會水落石出。