昨天维护的网站数据库无法启动,执行 mysqld start , 控制台报错:“The server quit without updating PID file (/var/lib/mysql/mysql.pid).[失败]”
查询log error日志,报错如下图:
明确提示,应该从 forcing-innodb-recovery 入手
在my.cnf文件配置参数
innodb_force_recovery = 1
innodb_purge_thread=0
注意: innodb_purge_thread 参数的设置为0 ,以免在配置别的值后,数据库启动会一直报错 InnoDB: Waiting for the background threads to start
force_recovery 几个取值的意义:
1 (SRV_FORCE_IGNORE_CORRUPT)
尽管检测到了损坏的页扔强制服务器运行。一本情况设置为该值即可,然后dump出库表进行重建。
2 (SRV_FORCE_NO_BACKGROUND)
阻止master thread和任何purge thread运行。若崩溃发生在purge环节则使用该值
3 (SRV_FORCE_NO_TRX_UNDO)
崩溃恢复后不运行事务回滚
4 (SRV_FORCE_NO_IBUF_MERGE)
阻止插入缓冲合并操作。如果可能导致崩溃则不要做这些操作。不要进行统计操作。该值可能永久损坏数据文件。若使用了该值,则将来要删除和重建辅助索引。
5 (SRV_FORCE_NO_UNDO_LOG_SCAN)
启动数据库时不查看undo日志。此时InnoDB甚至把未完成的事务按照提交处理。该值可能永久性的损坏数据文件。
6 (SRV_FORCE_NO_LOG_REDO)
恢复时不做redo log roll-forward。使数据库页处于废止状态,继而可能引起B树或者其他数据库结构更多的损坏。
在值小于等于3时可以通过SELECT来dump表,可以drop或者create表。MySQL5.6.27后大于3的值也支持DROP TABLE;
如果事先知道哪个表导致了崩溃则可drop掉这个表。如果碰到了由失败的大规模导入或大量ALTER TABLE操作引起的runaway rollback,则可kill掉mysqld线程然后设置 innodb_force_recovery为3使数据库重启后不进行rollback。然后删除导致runaway rollback的表;
如果表内的数据损毁导致不能dump整个表内容。那么附带ORDER BY primary_key DESC 从句的查询或许能够dump出损毁部分之后的部分数据;
若使用更高的innodb_force_recovery值,那么一些损坏的数据结构可能引起复杂的查询无法运行。此时可能只能运行最基本的SELECT * FROM T语句。
需要注意的是,这仅是紧急情况下的一种补救,不能依赖于这个办法,最好的办好还是做好数据备份工作,包括全备份和日志备份。确定要使用该方案是要确保有原始损坏数据的副本。4以上的值可能永久导致数据文件损坏。务必在测试环境测试通过后再在生产环境使用。
最后重启数据库即可,重启数据库之后,再把my.cnf 中的相关新增参数去掉即可。