不同存储引擎的表修复的方式也不一样。
对于MyISAM表,如果mysqld已经宕掉,且无法启动,那么可以通过mysiamchk工具来进行修复。如果mysqld仍在运行,或者可以重新启动,那么可以通过mysqlcheck工具来进行修复。
对于InnoDB表,如果只是索引部分被损坏,那么对于二级索引的损坏,可通过OPTIMIZE TABLE 命令来修复;如果是主键索引的损坏,可通过创建一张新表,将源表数据插入新表的方式来修复。如果是数据页被损坏,可以用SELECT... INTO OUTFILE 从数据库转储表等方式来修复。
然而,我实验做失败了,我既模拟不出刚刚好损坏索引页,也模拟不出刚刚好损坏数据页,只能暴力的vim 表的ibd文件,将错就错吧。。
创建测试表t_crash,并插入100条记录
接着,vim编辑t_crash.ibd,原t_crash.ibd文件,右下角为629d:
修改后的t_crash.ibd文件,右下角改成了627d:
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,启动数据库,依旧起不来。。(预料之中,因为我损坏的不仅仅是数据页。。)昨天晚上,文章写到一半,写不下去了,一直在纠结一个问题,如果主库发生了表损坏的情况,直接主备切换下,备库对外提供服务不就好了吗? 干嘛还非要设置 innodb_force_recovery,强制把innodb起起来呢?睡了一觉,其实我也没想明白?但是,在整个实验的过程中,也了解了很多知识点,所以就简单写了下。 过两天去咨询下师傅,有结果了再来继续分享。。