问题
现象很简单,数据库服务器被宕机,当然是在没有停数据库服务的情况下。
机器重启后,试图重启 MySQL 服务,无果,查看错误日志:
解决过程
刚开始的重点放在了这段日志上:
It 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 中添加如下配置:
[mysqld]
innodb_force_recovery = 1
其中后面的值设置为 1、如果 1 不能启动成功,再逐步增加为 2/3/4 等。直到能启动 mysql 为止!!!
Forcing InnoDB Recovery 提供了 6 个等级的修复模式,需要注意的是值大于 3 的时候,会对数据文件造成永久的破坏,不可恢复。六个等级的介绍摘抄如下:
1. (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.
2. (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.
3. (SRV_FORCE_NO_TRX_UNDO)
Does not run transaction rollbacks after crash recovery.
4. (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.
5. (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.
6. (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
/usr/local/mysql/bin/mysqld_safe -user=mysql&
1
重启成功后,测试数据库是否可以正常连接:mysql -uroot -p123456
数据备份
恢复模式数据库是只读的,当然和恢复级别相关。
现在需要做的是将数据库数据备份,然后清除之前的错误数据,最后再从备份数据中进行恢复。
mysqldump -uroot -p123456 --all-databases > all_mysql_backup.sql
原数据清理或备份
清理数据前需要先将数据库服务停止。
将数据库的 data 目录进行备份,相当于恢复到数据库刚安装完成时的状态。
mkdir data-bak
cd data
mv * ../data-bak/
数据恢复
数据库初始化
因为所有的数据都已删除掉,因此需要进行 MySQL 的初始化。
cd /usr/local/mysql
./scripts/mysql_install_db --user=mysql&
备份数据恢复
登录 MySQL:
mysql -u root -p123456
登录后,在数据库中执行下列语句,即可恢复数据:
source /app/all_mysql_backup.sql
恢复后对数据进行检查。
评论