InnoDB 修復紀錄

前兩天意外發現 blog 的資料庫(MariaDB)死掉起不來了,加上我剛好沒有新的備份,所以這兩天就花了些時間慢慢修復,總之首先,我根據一開始的錯誤訊息大概搜尋了一下,發現說可以把/var/lib/mysql目錄下的ibdata1ib_logfile0ib_logfile1aria_log_control等檔案砍掉試試看(當時完全不知道是什麼),於是我簡單備份後就砍掉重啟試試看,結果 MariaDB 真的就復活了,只是我接著要跑mysqldump時就出現其他的錯誤:

mariadb-dump: Got error: 1932: "Table 'blog.mt_asset' doesn't exist in engine" when using LOCK TABLES

而且因為我的 shell script 太簡單,沒檢查結果,這錯誤還把我的本地備份覆蓋掉了😂,總之搜尋研究一陣子之後,發現這問題是因為mt_asset資料表是用 InnoDB,然後 InnoDB 有些資訊是集中在ibdata1的,不能只靠資料庫目錄下的mt_asset.*檔案來還原,結果我的作法就是把備份的ibdata1還原回來,試著在my.cnf裡加上:

[mysql]
innodb_force_recovery = 1

如果用 service 的話就要放到[mysqld]區段內,數值從1試到6,然後 su 到mysql這個帳號下手動執行mariadbd指令來啟動資料庫,其實第一次嘗試是失敗的,到第二次試到6時才成功,然後趕快跑mysqldump,結果有成功跑完,不過因為之前mt_asset有出過錯誤,我就認真檢查了一下 dump 出來的資料,結果果然,mt_asset只有結構沒有資料,於是又檢查其它的 InnoDB 資料表的 dump 的輸出,結果是有的有資料有的沒有,不過由於資料本身應該還在,所以我接著嘗試用mariadb命令列模式進去 DB 手動 SELECTmt_asset的資料,發現真的都還在,不知道為何 dump 會失敗,不過總之我就試試看死馬當活馬醫,用 mysqldump 匯出單一個資料表的資料:

mariadb-dump -u user_name -p db_name mt_asset > blog.mt_asset.sql

結果,竟然成功匯出了,於是就手工把每個有問題的 InnoDB 匯出,然後手工整合回去全資料庫的 dump 出來的 sql 檔案,有些資料表還是沒資料,不確定是不是本來就沒有的,不過看起來也不是重要資料,不影響 MovableType 運作,所以就不管。

然後因為我好像用不太到 InnoDB 的優點,加上發生過一次這種事情,冷備份比較簡單的 MyISAM 還是比較適合我,就順手都改成 MyISAM 資料表;同時,又想到因為我的 CHARSET 還是用 utf8,所以一直都還不能用 emoji,之前也有想過要換到 utf8mb4,只是一直沒動手,就趁機一起手工改了mt_entry表下的幾個相關的欄位:

`entry_title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`entry_excerpt` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`entry_text` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`entry_text_more` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,

這樣大致上就把 sql 檔案準備好了,回到這次發生問題的原因,我推測是用 pacman 更新套件時,更新到 MariaDB 後,不知道為何造成ibdata1檔案損毀,一開始的錯誤訊息試有看到說某個檔案是 MariaDB 10.4.8 建立的,所以我是先退回 10.4.8 然後才進行上述的修正,還好上次已經操作過一次了,之後為了避免再次有太久沒更新出事,就決定也要把 MariaDB 更新一下,所以其實是先更新最後才把 sql 檔案匯入的。

更新完把/var/lib/mysql目錄下的ibdata1ib_logfile0ib_logfile1都砍掉,重新建立資料庫後才匯入,還好一切順利,詳細的說明其實在 MariaDB 的 Knowledge Base 也都有,最後就補上兩個我覺得很有幫助的文件:

  • Cold Backup: 一樣是 MariaDB 的 Knowledge Base 的官方文件,有提到 InnoDB 要冷備份時要備份哪些檔案;
  • Tag: InnoDB: Error: tablespace id in file: 一篇說明如果這時候要直接還原 InnoDB 資料表的話要怎樣弄,非常麻煩(網站已死,所以是 Internet Archive 的)。

另外補充,如果要在 MovableType 4.x 使用 emoji,除了資料庫欄位的設定外,還需要修改一點程式碼,詳見我的修改紀錄 🥳。