mysqldump 无法导出所有数据
环境
环境:docker、mysql 5.7
使用 mysqldump 备份数据库,总是在备份到 16G 的时候备份失败,去 /var/log/mysql 中并没有找到相关的错误日志。通过 docker ps 发现 mysql 发生了重启,通过 docker logs 查看到了 mysql 的崩溃日志,如下:
错误日志
1 | 2022-02-11T09:01:21.513263Z 0 [ERROR] InnoDB: Database page corruption on disk or a failed file read of page [page id: space=54, page number=1318229]. You may have to recover from a backup. |
关键信息:
InnoDB:磁盘上的数据库页面损坏,或页面[page id:space=54,page number=1318229]的文件读取失败。您可能需要从备份中恢复。
原因可能是最近的虚拟机环境重设,然后多次 copy 了 mysql docker volume 的文件,在 copy 过程中文件发生了损坏。
解决方案
设置 my.cnf 的 innodb_force_recovery=1
,然后重启 mysql,再次运行 mysqldump,发现可以正常导出数据。
innodb_force_recovery
参数的详细解释:
Mysql 文档-Forcing InnoDB Recovery
innodb_force_recovery
取值范围 1-6:
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)
防止插入缓冲区的合并操作。如果它们会导致崩溃,则不做这些操作。不计算表的统计数据。这个值会永久地破坏数据文件。在使用这个值之后,要准备放弃并重新创建所有的二级索引。将InnoDB设置为只读。
5 (srv_force_no_undo_log_scan)
在启动数据库时不查看撤销日志。InnoDB甚至将不完整的事务视为已提交。这个值会永久地破坏数据文件。将InnoDB设置为只读。
6 (srv_force_no_log_redo)
不做与恢复有关的重做日志滚动。这个值会永久地破坏数据文件。使数据库页面处于过时的状态,这反过来又可能给B树和其他数据库结构带来更多的损坏。将InnoDB设置为只读。