mysqld:表mysql.plugin不存在_MySQL 表损坏修复

本文介绍了针对MyISAM和InnoDB存储引擎表损坏的修复方法,包括使用mysamchk、mysqlcheck工具,以及通过OPTIMIZE TABLE、创建新表等方式。同时分享了一个模拟和修复InnoDB表损坏的实验过程,涉及到修改ibd文件和使用特定服务器启动选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这周给自己放了个假,每天不好好学习技术,光去研究楚国800年,秦始皇是不是死于非命了。。 但是,在大家的督促下,我又来更新了! 上周,在单位里写数据库应急预案的文档,看到同事之前写的MySQL表损坏应急处理的相关内容。之前都没怎么了解过这块内容,所以就去网上搜了下,看了看官方文档,想着简单整理了一下。 导致MySQL表损坏的几种常见原因: 1.磁盘故障;2.服务器故障,异常关机等;3.mysql bug等。

不同存储引擎的表修复的方式也不一样。

对于MyISAM表,如果mysqld已经宕掉,且无法启动,那么可以通过mysiamchk工具来进行修复。如果mysqld仍在运行,或者可以重新启动,那么可以通过mysqlcheck工具来进行修复。

对于InnoDB表,如果只是索引部分被损坏,那么对于二级索引的损坏,可通过OPTIMIZE TABLE 命令来修复;如果是主键索引的损坏,可通过创建一张新表,将源表数据插入新表的方式来修复。如果是数据页被损坏,可以用SELECT... INTO OUTFILE 从数据库转储表等方式来修复。

然而,我实验做失败了,我既模拟不出刚刚好损坏索引页,也模拟不出刚刚好损坏数据页,只能暴力的vim 表的ibd文件,将错就错吧。。8ed123d7deaa3097e42aaed147ace52f.png

创建测试表t_crash,并插入100条记录

a1f6facc2da70a1c104afc69d2ca7037.png

update这个表(这一步好像没啥意义。。)

eab1b745cf0183fe7ccb3eb58b11a1de.png

接着,vim编辑t_crash.ibd,原t_crash.ibd文件,右下角为629d:

d3a6e423277ae1336072d11206b8123c.png

修改后的t_crash.ibd文件,右下角改成了627d:

4e128ed76c9d93a46a2798e8f4910152.png

select * from t_crash;看看会不会报错?

154412fe1824ceef7247b24e9ee314db.png

结果并没有,猜到原因了吗? 因为有缓存,MySQL里怎么清缓存?Flush tables是清不掉的哦, 有点麻烦,我还是直接重启下服务吧。 MySQL服务直接起不来,终于把自己搞死了。。 查看mysql-error.log

7d777670bfbf837ce27bb0b1a4d088f3.png

从错误日志中看到,不仅仅是一个数据页被损坏的问题了,表信息已经错乱了,数据库遇到了FATAL ERROR,挂掉了。根据error_log提示,打开 链接:https://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html。

191ac752b995a1a5f42090415c9f4c88.png

官方说,可以用 innodb_force_recovery 参数,来强制InnoDB 存储引擎启动,同时阻止后台操作运行,以便你能转储你的表。   WARNING: 只有在紧急情况下将innodb_force_recovery设为大于0的值,你才能启动InnoDB并转储表。在进行此操作之前,确保你有数据库的备份副本,以备需要重建它。4及以上的值可以永久破坏数据文件。只有在数据库的独立物理副本的成功地测试了设置,才能在生产服务器实例使用4及以上的innodb_force_recovery设置。当强制InnoDB恢复,你应该总是以innodb_force_recovery=1启动,且仅在需要时增加值。 innodb_force_recovery 的六种模式:
  • 1 (SRV_FORCE_IGNORE_CORRUPT)

即使服务器检测到一个损坏的页,也让服务器运行着;试着让SELECT * FROM tbl_name 跳过损坏的索引记录和页,这样有助于转储表。

  • 2 (SRV_FORCE_NO_BACKGROUND)

阻止主线程和任何清除线程的运行。如果崩溃会在清除操作中发生,该恢复值会阻止它。

  • 3 (SRV_FORCE_NO_TRX_UNDO)

崩溃恢复后不运行事务回滚。

  • 4 (SRV_FORCE_NO_IBUF_MERGE)

阻止插入缓冲合并操作。如果它们会导致崩溃,不要做这些。不计算表统计。这个值可以永久损坏数据文件。使用这个值后,准备号删除并重建所有辅助索引。

  • 5 (SRV_FORCE_NO_UNDO_LOG_SCAN)

启动数据库时不查看undo log,InnoDB 把未完成的事务视为已提交的。这个值可以永久损坏数据文件。数据库处于只读状态。

  • 6 (SRV_FORCE_NO_LOG_REDO)

不在恢复连接中做日志前滚。这个值可能永久损坏数据文件。数据库页被留在一个陈旧的状态,这反过来又可能带给B-trees和其它数据库结构更多的损坏。数据库处于只读状态。

设置innodb_force_recovery =1,启动数据库,依旧起不来。。(预料之中,因为我损坏的不仅仅是数据页。。)

f7b208de6887bbe26571541e59c0d849.png

设置innodb_force_recovery =4,启动数据库,虽然有一堆ERROR,但是数据库服务起来了!

cf237343cefe15fabf0740632876ef88.png

26acc735861f64651581e860f80a96f0.png

再去select被损坏的表,报错:ERROR 1812:Tablespace is missing for  table XXX。出现ERROR 1812的几种可能情况: 1.数据文件的用户属组或权限错误 ;  2.数据文件的路径错误; 3.数据文件损坏或者被删了 很显然,现在是数据文件被损坏,不可能有什么转储表这种操作了,为了让数据库服务正常启动,我先把这个表删除了,之后再通过备份恢复回来。

4b6cbd717a87917da0a4ecb4b72aba44.png

设置innodb_force_recovery =0,重启数据库,MySQL服务运行正常。 接着做备份恢复就完事了~
昨天晚上,文章写到一半,写不下去了,一直在纠结一个问题,如果主库发生了表损坏的情况,直接主备切换下,备库对外提供服务不就好了吗? 干嘛还非要设置 innodb_force_recovery,强制把innodb起起来呢?睡了一觉,其实我也没想明白?但是,在整个实验的过程中,也了解了很多知识点,所以就简单写了下。 过两天去咨询下师傅,有结果了再来继续分享。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值