背景
一个测试人员对性能数据库进行性能压测 ,由于存储过程写的有问题,对一个大表进行大量更新为及时提交 ,见proc hang 住就kill 掉进程,然后长时间等待未果直接重启mysql 服务。之后错误日志中报错:
130516 20:47:36 InnoDB: Error: page 5 log sequence number 151 2771374516
InnoDB: is in the future! Current system log sequence number 131 3791365897.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
InnoDB: tablespace but not the InnoDB log files. See
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: for more information.
问题分析
根据错误提示:数据文件的LSN比redo log的LSN要大,当系统尝试使用Redo Log去修复数据页面的时候,发现Redo Log LSN比数据页面还小,所以导致错误。数据页的LSN在一般情况下,都是小于Redo Log的,因为在事物提交或按照 innodb_trx_commit 设置的方式提交时,先将事物顺序写入Redo Log , 然后后台线程按照 max_prt_dirty_page 参数设置的比例刷新或当系统检测到当10秒内系统会执行刷新脏页操作,所以,数据页的LSN正常情况下永远会比Redo Log 的LSN 小。
此次问题是正是由于数据库在kill 掉进程之后执行回滚操作,但是未等回滚执行完毕就kill -9 mysql 导致回滚崩溃。
解决方法
上述问题的解决方法 是设置innodb_force_recovery=3 或者4 ,需要逐个尝试。然后重启数据库服务 导出重要的数据,重建数据库。
innodb_force_recovery 可以设置为1-6,大的数字包含前面所有数字的影响。
1 (SRV_FORCE_IGNORE_CORRUPT): 忽略检查到的corrupt页。
2 (SRV_FORCE_NO_BACKGROUND): 阻止主线程的运行,如主线程需要执行full purge操作,会导致crash。
3 (SRV_FORCE_NO_TRX_UNDO): 不执行事务回滚操作。
4 (SRV_FORCE_NO_IBUF_MERGE): 不执行插入缓冲的合并操作。
5 (SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB存储引擎会将未提交的事务视为已提交。
6 (SRV_FORCE_NO_LOG_REDO): 不执行前滚的操作。
当设置参数值大于0后,可以对表进行select,create,drop操作,但insert,update或者delete这类操作是不允许的。当然即使innodb_force_recovery>0 ,你也可以DROP或CREATE表。如果某个表正在回滚而导致数据库崩溃,设置innodb_force_recovery为3,重启db 后,使得数据库被挂起而不需要回滚,然后舍弃导致失控回滚的表。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22664653/viewspace-762668/,如需转载,请注明出处,否则将追究法律责任。