现象
现象很简单,数据库服务器被宕机,当然是在没有停数据库服务的情况下。
机器重启后,试图重启MySQL服务,无果,查看错误日志:
1 | 170920 0:30:17 InnoDB: Assertion failure in thread 140107687212800 in file /export/home/pb2/build/sb_0-2629600-1291399482.5/mysql-5.5.10/storage/innobase/include/fut0lst.ic line 83 |
解决过程
刚开始的重点放在了这段日志上:1
2
3
4It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 406067 K
bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
以为是MySQL的一些参数设置有问题,结合Google结果,对/etc/my.cnf
进行了修改,仍无果。问题解决之后想来,因为之前MySQL是运行正常的,因此配置一般不会有问题,当时也是“病急乱投医”了。
1. Forcing InnoDB Recovery
设置恢复模式启动mysql,在 /etc/my.cnf中添加如下配置:1
2[mysqld]
innodb_force_recovery = 1
其中后面的值设置为1、如果1不能恢复,再逐步增加为2/3/4等。直到能启动mysql为止!!!
Forcing InnoDB Recovery提供了6个等级的修复模式,需要注意的是值大于3的时候,会对数据文件造成永久的破坏,不可恢复。六个等级的介绍摘抄如下:
- SRV_FORCE_IGNORE_CORRUPT
Lets the server run even if it detects a corrupt page. Tries to make SELECT * FROM tbl_name jump over corrupt index records and pages, which helps in dumping tables. - SRV_FORCE_NO_BACKGROUND
Prevents the master thread and any purge threads from running. If a crash would occur during the purge operation, this recovery value prevents it. - SRV_FORCE_NO_TRX_UNDO
Does not run transaction rollbacks after crash recovery. - SRV_FORCE_NO_IBUF_MERGE
Prevents insert buffer merge operations. If they would cause a crash, does not do them. Does not calculate table statistics. This value can permanently corrupt data files. After using this value, be prepared to drop and recreate all secondary indexes. - SRV_FORCE_NO_UNDO_LOG_SCAN
Does not look at undo logs when starting the database: InnoDB treats even incomplete transactions as committed. This value can permanently corrupt data files. - SRV_FORCE_NO_LOG_REDO
Does not do the redo log roll-forward in connection with recovery. This value can permanently corrupt data files. Leaves database pages in an obsolete state, which in turn may introduce more corruption into B-trees and other database structures.
恢复模式下启动MySQL
1 | /usr/local/mysql/bin/mysqld_safe -user=mysql& |
重启成功后,测试数据库是否可以正常连接:mysql -uroot -p123456
数据备份
恢复模式数据库是只读的,当然和恢复级别相关。
现在需要做的是将数据库数据备份,然后清除之前的错误数据,最后再从备份数据中进行恢复。1
mysqldump -uroot -p123456 --all-databases > all_mysql_backup.sql
原数据清理或备份
清理数据前需要先将数据库服务停止。
将数据库的data目录进行备份,相当于恢复到数据库刚安装完成时的状态。1
2
3mkdir data-bak
cd data
mv * ../data-bak/
数据恢复
数据库初始化
因为所有的数据都已删除掉,因此需要进行MySQL的初始化。1
2cd /usr/local/mysql
./scripts/mysql_install_db --user=mysql&
备份数据恢复
登录MySQL:1
mysql -u root -p123456
登录后,在数据库中执行下列语句,即可恢复数据:1
source /app/all_mysql_backup.sql
恢复后对数据进行检查。