簡介 匯總遇到過的異常宕機匯總
說明
1 本人也不懂代碼,無法找到原因,所以只記錄淺顯的解決辦法
2 異常宕機 分為能自行啟動和 必須通過調整隔離級別才能啟動兩種情況.本文應對的是第一種情況
場景1 mysql特性引起的(常見於相關特性,常見AHI 松散掃描等)
案例1
核心報錯區域
1 SEMAPHORES
2 has waited at buf0flu.cc line 1209 for 936.00 seconds the semaphore
3 SX-lock on RW-latch at thread_id created in file buf0buf.cc line a writer (thread id) has reserved it in mode
4 InnoDB: Semaphore wait has lasted > 600 seconds.
5 InnoDB: Assertion failure in thread 140282241115904 in file
分析
1 MySQL后台線程srv_error_monitor_thread發現存在阻塞超過600s的latch鎖時,如果連續10次檢測該鎖仍沒有釋放,就會觸發panic避免服務持續hang下去。等待的數據字典鎖
2 基本都是超過900S才會崩潰
3 根據 a writer后面的thread_id定位具體的線程語句
可能造成的原因
1 由於AHI導致的latch爭用,同樣是rw latch鎖爭用,日志關鍵字(btr0sea.c文件)
官網的描述
You can monitor the use of the adaptive hash index and the contention for its use in the SEMAPHORES section of the output of the SHOW ENGINE INNODB STATUS command. If you see many threads waiting on an RW-latch created in btr0sea.c, then it might be useful to disable adaptive hash indexing.
2 由於慢查詢導致的RW-Latch占有,導致其他事務阻塞
3 由於大事務導致的latch占有,比如replace into
解決方式
1 可以選擇暫時關閉AHI然后進行持續觀察 set global innodb_adaptive_hash_index=0;
2 根據show innodb status記錄的查詢語句進行分析優化
3 根據show innodb status記錄的事務語句進行分析優化
定義總結
latch鎖 Latch在MySQL中是用於保護高速緩沖區中共享數據的,舉個例子: 當我們執行select時,數據是緩存在buffer pool中的,多個線程並發訪問或者修改這個數據必然需要一個並發控制機制,這個就是 Latch.
1 只有多線程訪問相同的目標latch才有意義
2 mysql RW-LATCH
案例2
核心報錯區域
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (7fefc00bf590): select語句
Connection ID (thread ID): 508
Status: NOT_KILLED
分析
1 一旦執行指定的select記錄語句就會導致mysql重啟(包括程序與手動執行)
2 其他表的查詢沒有問題,可能是此表的問題
3 執行非特定select語句的其他select沒有任何問題
4 在從庫進行此表的此語句查詢也沒有任何問題
總結 就是特定表的特定查詢語句導致mysql宕機
解決方式
1 此問題聯系開發進行解決改造特定的查詢sql進行暫時解決,不會影響該數據庫的其他業務.至於造成的具體原因,只能根據pstack gdb進行跟蹤分析了
最新補充 關閉loosescan=off 就可以不用更改sql.是由於這個參數導致的.這個參數的作用是semi-join 的優化.explain的查詢語句一旦出現loosescan出現就代表應用了這個特性,導致當機,其他關於此表的查詢就不會出現問題
總結
1 對於此類BUG導致的宕機事件大部分的解決方式查到定位某個參數,然后關閉即可.根本不必升級
場景2 無法啟動匯總 (常見於基本頁的損壞導致LSN不一致)
案例1
報錯日志
2018-06-11T12:50:24.617098Z0[ERROR] InnoDB: Page [page id: space=42, page number=3]logsequence number14532708is in the future! Current systemlogsequence number12151645.
2018-06-11T12:50:24.617116Z0[ERROR] InnoDB: Your database may be corrupt or you may have copied the InnoDB tablespace but not the InnoDBlogfiles. Please refer to http://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html for information about forcing recovery.、
錯誤原因: redo page損壞,無法進行修復
解決方式: 調整恢復級別進行拯救
案例2
報錯日志
index for table is corrupt
錯誤原因: 表的index page頁出現損壞,導致一操作就會出問題
解決方式: 1 調整隔離級別為1 就不會啟動corrput檢測線程了 2 將數據進行備份 刪除原表 3 注釋參數 重新啟動
案例3
報錯日志
[ERROR] /usr/local/mysql/bin/mysqld: Binary logging not possible. Message: An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'ABORT_SERVER'. Hence aborting the server
分析
binlog_error_action=ABORT_SERVER
Binlog_error_action參數控制當不能寫binlog時,mysql-server將會采取什么行動。
設置binlog_error_action=ABORT_SERVER會使mysql-server在寫binlog遇到嚴重錯誤時退出,比如磁盤滿了,文件系統不可寫入了等。在ABORT_SERVER選項下,binlog和從庫都是安全的,這是官方修改此默認值的原因。
解決方式: 從linux層面尋找原因,可能是文件系統或者磁盤滿了(可能是由於斷電導致的異常)
1 導致各種page損壞的原因
- 硬件問題
- 驅動程序錯誤
- 內核錯誤
- 電源故障 (常見)
- 罕見的MySQL bug錯誤(常見)、
2 調整恢復級別需要從1-6進行逐步調整,在恢復之前進行備份一份數據文本. 因為 級別越高 對數據的影響會越大,所以逐步進行恢復測試
場景3 可以啟動但是可能是產品BUG導致的
案例1
報錯日志 [FATAL] InnoDB: Native Linux AIO interface. io_submit() call failed when resubmitting a partial I/O request on the file ./db_message_00001.ibd.
分析 : A Linux AIO handler function failed to check if completed I/O events AIO檢測IO事件失敗導致的
查看mysql官網 也能查到相應BUG BUG:90402
現在可能造成此問題的有兩個因素:1 執行 DDL語句 2 數據庫服務器的磁盤占滿
解決方式: 升級版本到5.7.26
案例3
報錯日志
InnoDB: Failing assertion: btr_page_get_next(get_page, mtr) == buf_frame_get_page_no(page)
分析 可能是innodb頁損壞的
解決方式 按照通用方式解決,此BUG常見於小於5.7版本,可以進行版本升級
案例 4
報錯日志 Database page corruption on disk or a failed"
說明: 為了保護數據,InnoDB使用校驗和(與頁儲存在一起)。當InnoDB從磁盤讀取時,它計算每個頁的校驗和,並與磁盤加載的校驗和進行比較。如果值是不同的,可能真的發生了一些錯誤。InnoDB將關閉MySQL服務器,以防止進一步的邏輯或物理損壞。
解決方案 先通過innodbchecksum先定位損壞的庫表文件,然后調整恢復級別為1,恢復級別1的時候會忽略相應的損壞的頁.導出其他安全的庫表,然后重建實例 也可以嘗試 Repair the ibd file with innochecksum with --write=innodb 進行覆蓋, 記住 作此操作之前需要備份
總結