一次典型的 MySQL 故障排查與修復全過程,涵蓋登錄失敗、表崩潰、innodb_force_recovery 救援、壞表剔除與數據恢復等關鍵操作。
一、問題背景
某業務系統運行多年,數據庫使用的是 MySQL 8.0.18,近期在一次服務器重啟后,發現無法正常連接數據庫,提示:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
嘗試重啟 MySQL,過程似乎正常:
sudo service mysql restart # 顯示 SUCCESS
但用 mysql -u root -p
登錄時依舊提示賬號密碼錯誤。開始懷疑是否數據損壞或權限配置有誤。
二、排查思路
1. 登錄失敗:確認密碼正確性
使用其他賬戶嘗試連接(如 test 用戶)。
發現部分用戶仍可登錄,說明 數據庫服務本身是正常的,但
root
權限或數據可能損壞。
2. 可登錄用戶訪問數據時報錯
登錄后,執行 SQL 刪除某張表時報錯:
DROP TABLE imp_index_warn_data; ERROR 1036 (HY000): Table 'tablespace_files' is read only
甚至強制設置參數后依舊失敗:
SET GLOBAL innodb_fast_shutdown = 0; DROP TABLE imp_index_warn_data; # 報錯 3604,存儲引擎無法刪除該表
結論:該表已嚴重崩潰,影響了 InnoDB 正常功能。
三、制定解決策略
目標
保住正常表的數據。
剔除壞表 imp_index_warn_data。
盡量避免數據損失與停機時間。
解決方案路線圖
使用
innodb_force_recovery
啟動數據庫。導出除壞表以外的所有數據。
停止數據庫服務,物理刪除壞表相關文件。
啟動數據庫,刪除壞表元數據。
恢復數據庫服務到正常模式。
四、操作步驟詳解
步驟 1:修改 my.cnf,啟用恢復模式
編輯 /etc/my.cnf
:
[mysqld] innodb_force_recovery = 6
含義:略過大部分恢復步驟并只讀啟動。僅用于應急,不可長期開啟。
保存后重啟數據庫:
sudo service mysql restart
步驟 2:導出正常表數據
使用 mysqldump
排除壞表:
mysqldump -u root -p --skip-lock-tables i18n_demo > i18n_demo.sql
確保 imp_index_warn_data
未導出。
步驟 3:停止數據庫服務,刪除壞表文件
sudo service mysql stop
進入數據目錄(示例路徑如下,具體看你的配置):
cd /usr/local/mysql/mysql-8.0.18/data/i18n_demo
備份壞表相關文件:
mkdir ~/bad_table_backup mv imp_index_warn_data.* ~/bad_table_backup/
步驟 4:重啟數據庫,清除元數據
重啟服務:
sudo service mysql start
登錄數據庫,清理元數據:
DROP TABLE imp_index_warn_data;
此時應該不會再報錯。
步驟 5:導入數據并恢復服務正常
取消 innodb_force_recovery
:
# /etc/my.cnf 中移除或注釋: # innodb_force_recovery = 6
重啟服務:
sudo service mysql restart
導入之前備份的數據:
mysql -u root -p i18n_demo < i18n_demo.sql
至此,數據庫恢復完成!
五、總結與經驗教訓
? 收獲
理解
innodb_force_recovery
各個級別的作用。掌握 MySQL 啟動失敗或崩潰時的應急處理手段。
明確了“邏輯刪除表”與“物理刪除文件”的邊界和使用時機。
? 教訓
未開啟 binlog、沒有定期全量備份,是很大風險。
某些老舊系統的數據表結構混亂、未做分區或冷熱分離,極易出現單表崩潰。
六、附錄:常用命令速查
操作 | 命令 |
---|---|
查看服務狀態 | sudo systemctl status mysql |
停止 MySQL | sudo service mysql stop |
啟動 MySQL | sudo service mysql start |
數據導出 | mysqldump -u root -p db_name > backup.sql |
數據導入 | mysql -u root -p db_name < backup.sql |
如果你也遇到類似問題,記得第一時間備份,并小心操作 innodb_force_recovery
的等級!任何強制操作都要以“可恢復”為前提。