Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL Innodb表损坏

MySQL Innodb表空间损坏导致MySQL无法启动问题修复解决

作者:奈-chann

本文主要介绍了MySQL Innodb表空间损坏导致MySQL无法启动问题修复解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在日常服务器宕机后启动MySQL的时候,出现问题

Job for mysqld.service failed because the control process exited with error code. See "systemctl status mysqld.service" and "journalctl -xe" for details.

一定一定要去查看MySQL的启动日志 tail -n 50 /var/log/mysqld.log日志,这里查看日之后里面包含一条很重要的信息

[ERROR] [MY-011971] [InnoDB] Tablespace 'innodb_undo_002' Page [page id: space=4294967278, 
page number=87] log sequence number 155750010430 is in the future!
 Current system log sequence number 155735821216.

说明是innodb_undo_002表空间损坏导致MySQL无法启动,错误代码涉及MY-011971(日志序列号未来)和MY-012153(页号越界),最终触发MY-013183断言失败而退出。最安全、丢失数据最少的恢复方式是"删除损坏的undo表空间,让MySQL自动重建"。

第一步:尝试最简单修复

这是风险最小、成功率最高的方法,它不涉及数据导出导入,直接让MySQL忽略损坏的undo日志。

# 1. 进入MySQL数据目录,找到undo_002文件
cd /var/lib/mysql/           # 替换为你的实际数据目录
ls -la | grep undo           # 确认存在undo_002文件
# 2. 停止MySQL服务
sudo systemctl stop mysql
# 3. 重命名损坏的文件(相当于安全地删除)
mv undo_002 undo_002.bak
# 4. 启动MySQL服务
sudo systemctl start mysql
# 5. 检查服务状态
sudo systemctl status mysql
# 6.如果启动失败,继续查看日志,查看具体原因
tail -n 50 /var/log/mysqld.log

如果启动成功,MySQL 会在数据目录中自动生成一个新的undo_002文件,数据库恢复正常
我这里启动的时候还出现过一次undo_001的问题,按照上述方法再执行了一次。
注:如果自动创建失败,可以在配置文件中尝试手动指定

innodb_undo_tablespaces = 2
innodb_undo_directory = /var/lib/mysql

第二步:强制恢复模式

如果第一步无法启动,可以尝试此方法。其原理是通过参数innodb_force_recovery强制跳过一些检查,但数据写入会被禁用,主要用于导出数据。随后需要重建数据库,再将数据重新导入

1.修改MySQL配置文件 (/etc/my.cnf/etc/mysql/my.cnf,具体情况根据实际情况目录来),在 [mysqld] 部分添加以下行:

[mysqld]
innodb_force_recovery = 1

具体参数解释,可以查看文章详细解析innodb_force_recovery 参数
2. 逐级增加参数值:从1开始尝试启动MySQL。如果失败,停止服务,将值改为2,再尝试,以此类推,直到能启动为止(通常1到4已足够,不建议轻易尝试5或6)
3. 导出所有数据:一旦成功启动,立即使用 mysqldump或者是可视化工具,导出所有数据库。

mysqldump --all-databases --single-transaction --routines --triggers > /path/to/backup.sql

4.关闭服务,清理环境:停止MySQL服务,移除配置文件中的 innodb_force_recovery 设置。
5.彻底重建:清空MySQL数据目录 (/var/lib/mysql/),然后重新初始化一个新的MySQL实例。

#1.先停服务
systemctl stop mysqld
#2.删除数据目录(/var/lib/mysql)这一步一定要小心谨慎别删除错了,根据实际mysql目录来
rm -rf /var/lib/mysql/*
#3.重新初始化数据库
mysqld --initialize --console
#4.重新启动mysql
systemctl start mysqld
#5.查看临时密码
grep password /var/log/mysqld.log
#6.登录mysql
mysql -uroot -p
#7.然后修改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
#如果出现远程工具连接不上的报错情况
Host'gateway' is not allowed to connect to this MySQL server
#则需要登录mysql然后执行下面命令即可
USE mysql;
UPDATE user SET host='%' WHERE user='root';
FLUSH PRIVILEGES;

如果重建数据库的过程中仍然遇见

Job for mysqld.service failed because the control process exited with error code.
 See "systemctl status mysqld.service" and "journalctl -xe" for details.

则可以查看systemctl status mysqld.service
然后出现:

● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since 三 2026-06-17 11:17:03 CST; 16s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 17988 ExecStart=/usr/sbin/mysqld $MYSQLD_OPTS (code=exited, status=1/FAILURE)
  Process: 17961 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 17988 (code=exited, status=1/FAILURE)
   Status: "Server startup in progress"
    Error: 13 (Permission denied)
6月 17 11:17:03 90648dbab6ca mysqld[17988]: 2026-06-17T03:17:03.134102Z 0 [Warning] [MY-010141] [Server] Changed limits: max_connections...d 10000)
6月 17 11:17:03 90648dbab6ca mysqld[17988]: 2026-06-17T03:17:03.134112Z 0 [Warning] [MY-010142] [Server] Changed limits: table_open_cach...ed 4000)
6月 17 11:17:03 90648dbab6ca mysqld[17988]: 2026-06-17T03:17:03.424987Z 0 [Warning] [MY-010915] [Server] 'NO_ZERO_DATE', 'NO_ZERO_IN_DAT...release.
6月 17 11:17:03 90648dbab6ca mysqld[17988]: 2026-06-17T03:17:03.425074Z 0 [Warning] [MY-010091] [Server] Can't create test file /var/lib...wer-test
6月 17 11:17:03 90648dbab6ca mysqld[17988]: 2026-06-17T03:17:03.425184Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.27)...ss 17988
6月 17 11:17:03 90648dbab6ca mysqld[17988]: 2026-06-17T03:17:03.432231Z 0 [Warning] [MY-010091] [Server] Can't create test file /var/lib...wer-test
6月 17 11:17:03 90648dbab6ca systemd[1]: mysqld.service: main process exited, code=exited, status=1/FAILURE
6月 17 11:17:03 90648dbab6ca systemd[1]: Failed to start MySQL Server.
6月 17 11:17:03 90648dbab6ca systemd[1]: Unit mysqld.service entered failed state.
6月 17 11:17:03 90648dbab6ca systemd[1]: mysqld.service failed.
Hint: Some lines were ellipsized, use -l to show in full.

MySQL 服务(默认以 mysql 系统用户的身份运行)在尝试往你的新数据目录 /var/lib/mysql 写入测试文件时被系统拒绝了,因为没有读写权限。
这通常是因为在前面重建目录、或者执行 mysqld --initialize 初始化的时候,是以 root 身份执行的,导致该目录下新生成的基础数据文件归属成了 root,MySQL 自己反而写不进去了。

解决办法
只需要在终端执行以下命令,将整个数据目录的所有权递归地交还给 mysql 用户即可:

# 1. 递归赋予属主和属组
chown -R mysql:mysql /var/lib/mysql
# 2. 顺手修正一下基础权限(MySQL 出于安全要求,数据目录权限不能过于开放)
chmod 750 /var/lib/mysql
# 3. 再次尝试启动
systemctl start mysqld
执行完之后,再用 systemctl status mysqld.service 看一下,这次你应该能看到久违的绿色 active (running) 了。启动成功后,就可以使用初始密码登录

6.恢复数据:将之前导出的备份SQL文件重新导入新实例。

总结

先按照第一步尝试自动修复。 如果失败,再采用第二步的强制恢复模式来抢救数据。操作前千万记得先暂停MySQL服务,可以备份整个数据目录,以防操作失误造成进一步损失。

注:每个人遇到的情况可能都有所不同,这里仅提供我的解决方案

到此这篇关于MySQL Innodb表空间损坏导致MySQL无法启动问题修复解决的文章就介绍到这了,更多相关MySQL Innodb表损坏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文