[特殊字符] 从数据库无法访问到成功修复崩溃表:一次 MySQL 故障排查实录

一次典型的 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

  • 尽量避免数据损失与停机时间

解决方案路线图

  1. 使用 innodb_force_recovery 启动数据库。

  2. 导出除坏表以外的所有数据。

  3. 停止数据库服务,物理删除坏表相关文件。

  4. 启动数据库,删除坏表元数据。

  5. 恢复数据库服务到正常模式。


四、操作步骤详解

步骤 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 的等级!任何强制操作都要以"可恢复"为前提。

相关推荐
运维行者_7 小时前
企业无线网络监控的挑战与智能化演进趋势
大数据·运维·服务器·网络·数据库
国强_dev8 小时前
技术探讨:使用 stunnel 加密转发数据库连接时,如何获取客户端真实 IP?
数据库·网络协议·tcp/ip
@insist1238 小时前
系统规划与管理师-信息系统规划核心工作要点解析
数据库·软考·系统规划与管理师·软件水平考试·系统规划与管理工程师
超级数据查看器8 小时前
超级数据查看器 v10.0 发布
java·大数据·数据库·sqlite·安卓
数安3000天8 小时前
增量数据如何自动分类分级,避免目录“过期“?
大数据·数据库
南墙上的石头9 小时前
麒麟 V10 重装人大金仓 V8R6 踩坑实录(含 MySQL 兼容模式)
数据库·mysql
画中有画10 小时前
论向量数据库在项目中的应用
数据库
spider_xcxc11 小时前
Redis 数据库高质量实践指南(一)
运维·数据库·redis·oracle·云计算
l1t11 小时前
在linux和windows中解决duckdb 1.6dev版本输出执行计划报错问题
linux·运维·数据库·windows·duckdb
执子手 吹散苍茫茫烟波12 小时前
RC 隔离级别下 MySQL InnoDB 死锁典型案例
数据库·mysql