記一次MySQL生產環境故障處理

1、故障描述

在2020年5月15日 凌晨三點,某臺生產環境的MySQL進程異常,無法連接到數據庫。早上上班開始排查問題並解決。
服務器是windows環境,設置每2天凌晨自動重啓主機,MySQL以及其他應用都設置了自動啓動。
注:以下所有步驟需要先關閉使用到數據庫的應用程序。

2、故障處理過程

2.1 故障定位1

查看系統的計劃任務,發現剛好15日凌晨3點執行了啓動任務。上次運行結果這一欄顯示0x40010004
在這裏插入圖片描述
在cn.bing.com上搜索“windows 0x400100004”找到一篇文章https://stackoverflow.com/questions/37078953/in-which-cases-does-program-exit-with-0x40010004-code。
文章是這樣回答的
在這裏插入圖片描述
【文章大意是說這個錯誤很可能是在windows系統重啓的時候發生。當windows系統要重啓時,它會嘗試以一種很友好的方式關閉正在運行中的程序,如果某個程序拒絕被關閉則會返回一個錯誤碼0x40010004。】

2.2 故障定位2

以管理員身份打開cmd窗口執行net start MySQL57返回mysql啓動失敗,並且沒有任何提示。
面向百度找到一篇文章https://blog.csdn.net/qq_37915248/article/details/82631398裏面提到【進入DOS界面,到MySQL文件夾下輸入mysqld --console】
於是進入到MySQL\bin目錄下執行:mysqld --console
此處日誌提示在mysql的Server目錄下找不到mysql的data文件夾[D:\company\software\MySQL\MySQL Server 5.7\data]但是我的數據文件是放在安裝目錄外面的。
我用的MySQL是安裝版,安裝目錄如下:

D:\company\software\MySQL
D:\company\software\MySQL\Connector.C++ 1.1
D:\company\software\MySQL\Connector.J 5.1
D:\company\software\MySQL\Connector.NET 6.9
D:\company\software\MySQL\Connector.ODBC 5.3
D:\company\software\MySQL\MySQL Connector.C 6.1
D:\company\software\MySQL\MySQL Documentation 5.7
D:\company\software\MySQL\MySQL Notifier 1.1
D:\company\software\MySQL\MySQL Router 2.1
D:\company\software\MySQL\MySQL Server 5.7
D:\company\software\MySQL\MySQL Utilities 1.6
D:\company\software\MySQL\MySQL Workbench 6.3 CE
D:\company\software\MySQL\Samples and Examples 5.7

外部數據目錄:
D:\nannar\database\MySQL_DATA\my.ini
D:\nannar\database\MySQL_DATA\data

這裏就很奇怪了:
1、系統重啓前MySQL的運行一直是正常的。
2、此前mysql一直是從D:\nannar\database\MySQL_DATA\my.ini讀取運行配置,從D:\nannar\database\MySQL_DATA\data讀取數據文件。
3、故障出錯時提示MySQL從D:\company\software\MySQL\MySQL Server 5.7\data下面讀取數據文件。

由於對MySQL底層不夠了解,此處果斷卸載MySQL改用解壓免安裝的版本。
卸載後,將D:\nannar\database\MySQL_DATA更名爲D:\nannar\database\MySQL_DATA-back

MySQL重裝後目錄結構如下:
免安裝解壓目錄
D:\company\software\mysql-5.7.18-winx64
my.ini位置
D:\company\software\mysql-5.7.18-winx64\my.ini
數據庫目錄(在my.ini中配置)
D:\company\database\MySQL_DATA

環境變量
MYSQL_HOME指向D:\company\software\mysql-5.7.18-winx64
%MYSQL_HOME%\bin;追加到path中。

2.3 故障處理1-數據遷移

  1. 重新創建數據庫 (不需要建表)
  2. 關閉數據庫net stop MySQL57
  3. 從舊的數據目錄中拷貝數據文件到新的數據目錄中。
    例如庫名是monitor
    D:\company\database\MySQL_DATA-back\data\monitor
    拷貝到D:\company\database\MySQL_DATA\monitor
  4. 啓動數據庫net start MySQL57
  5. 驗證數據庫
    命令行登錄數據庫後show databases; 數據庫列表包含monitor。OK
    use monitor
    show tables ; 可以查到表清單。OK
    select * from dict_enum; 拋出異常:“ERROR 1146 (42S02):Table monitor.dict_enum’ doesn’t exist”
    百度找到一篇文章https://blog.csdn.net/qq_25600055/article/details/48903629
    在這裏插入圖片描述
    對比之下,我的情況跟這位朋友的一樣。於是我關閉數據庫繼續拷貝了
    ib_logfile0、ib_logfile1和ibdata1這三個文件到以下路徑(若已存在則覆蓋)
    D:\company\database\MySQL_DATA\ib_logfile0
    D:\company\database\MySQL_DATA\ib_logfile1
    D:\company\database\MySQL_DATA\ibdata1

2.4 故障處理2-事務日誌處理

 重新啓動數據庫net start MySQL57,**發現又出現了“MySQL57 服務無法啓動,服務沒有報告任何錯誤。”**

再次執行mysqld console
在這裏插入圖片描述
百度“Ignoring the redo log”找到一篇文章https://blog.csdn.net/baidu_31030715/article/details/82350026裏面說把ib_logfile0和ib_logfile1這兩個文件刪除就可以了。
由於不瞭解這兩個文件的作用,謹慎起見繼續百度“ib_logfile”找到一篇
https://www.cnblogs.com/z-books/p/4285375.html瞭解到
在這裏插入圖片描述
由此可見,出現這個錯誤的原因就是MySQL啓動時嘗試讀ib_logfile0和ib_logfile1進行事務重做。至此原因已經搞明白了。
爲儘快恢復系統的使用,我將這兩個文件刪除,然後重新啓動數據庫。一切都恢復正常了。

2.5 故障處理3-數據驗證

數據庫是修復了,但是我刪除的是系統重做日誌呀,一個天大的問題是:我的數據到底有沒有丟失?
於是趕緊用客戶端連接服務器,然後查詢業務表的數據,查看最新的數據時間。數據時間戳停留在2020-05-14 23:57.00.000 。根據業務性質判斷,我的數據是物聯網傳感器數據,這個時間點已經接近設備下線時間。因此即使從這個時間段往後有業務數據,這些業務數據即使丟失也是不會有影響的。

3、故障處理總結

  1. 此次故障能及時發現得益於系統監控及釘釘機器人消息推送。
  2. 由於缺乏對數據庫的深度理解,最終只能採取放棄部分數據的方式使生產環境的應用能夠儘快恢復使用。
  3. 本次生產故障處理是否有丟失數據?丟失了多少筆數據?如何從redo文件中提取數據?這是一系列需要思考和研究的問題!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章