InnoDB 修復紀錄
前兩天意外發現 blog 的資料庫(MariaDB)死掉起不來了,加上我剛好沒有新的備份,所以這兩天就花了些時間慢慢修復,總之首先,我根據一開始的錯誤訊息大概搜尋了一下,發現說可以把/var/lib/mysql
目錄下的ibdata1
、ib_logfile0
、ib_logfile1
、aria_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
目錄下的ibdata1
、ib_logfile0
、ib_logfile1
都砍掉,重新建立資料庫後才匯入,還好一切順利,詳細的說明其實在 MariaDB 的 Knowledge Base 也都有,最後就補上兩個我覺得很有幫助的文件:
- Cold Backup: 一樣是 MariaDB 的 Knowledge Base 的官方文件,有提到 InnoDB 要冷備份時要備份哪些檔案;
- Tag: InnoDB: Error: tablespace id in file: 一篇說明如果這時候要直接還原 InnoDB 資料表的話要怎樣弄,非常麻煩(網站已死,所以是 Internet Archive 的)。
另外補充,如果要在 MovableType 4.x 使用 emoji,除了資料庫欄位的設定外,還需要修改一點程式碼,詳見我的修改紀錄 🥳。