MySQL8 表异常崩溃导致的MySQL服务无法启动问题修复

395 阅读3分钟

若遇到如下类似问题,则可参考本文进行修复

[ERROR] [MY-011011] [Server] Failed to find valid data directory.
[ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
[ERROR] [MY-010119] [Server] Aborting
[System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.40)  MySQL Community Server - GPL.

前提条件

  1. 数据库版本完全一致 (大版本与小版本完全一致)
  2. MYD, MYI, sdi 文件结构完整并已备份到本地

该方案类似数据库迁移导出方案,不同环境之间存在差异,仅供参考

步骤 1:修复表

检查本地表副本,若表存在崩溃等错误,需要先对表根据引擎分情况进行表修复, 没有错误则跳过该步骤

MyISAM 表损坏

myisamchk -r -q *.MYI

InnoDB 表损坏

InnoDB 拥有内部恢复机制,若数据库崩溃了,InnoDB 通过从最后一个时间戳开始运行日志文件,若 InnoDB 自行修复失败,那么数据库将不能启动。

恢复等级配置如下:

innodb_force_recovery = 4

InnoDB 恢复等级

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):不执行前滚的操作。

步骤 2:创建完全一致的数据库

新开一台服务器,在新的服务器搭建数据库环境,创建数据库,该步骤需要保证数据库名,字符集和排序规则完全一致, 字体等设置完全一致,否则可能出现乱码等一系列问题。

步骤 3:关闭导入目录限制

查询 secure_file_priv 限制状态

show variables like "%secure%";

若不为空则需在配置文件加入如下配置并重启数据库

[mysqld]
secure_file_priv=""

步骤 4:上传对应数据库表文件

将修复过的本地副本表文件上传到服务器 MySQL 数据目录 下对应的数据库目录。 请注意,此处仅上传 MYIMYD 文件 例如若数据库为 web1 , 则参考位置为 /var/lib/mysql/web1,上传完请确保所有文件权限正常,MySQL 用户组至少应具备读写权限。

一般情况下 RPM 安装的 MySQL 相关目录如下所示:

数据目录:/var/lib/mysql/ 配置文件模板:/usr/share/mysql 客户端工具目录:/usr/bin 日志目录:/var/log/ pid, sock 文件:/tmp/

在 MySQL 数据目录下,上传所有的 sdi 文件到一个单独但可以被数据库索引到的目录,你可以新建一个 import 目录, 完整文件路径则为 /var/lib/mysql/import/*.sdi

步骤 5:执行表导入操作

连接数据库,选择目标数据库

use <database_name>;

执行 mdi 导入操作

IMPORT TABLE FROM '<上传的 sdi 文件完整路径, 可以使用通配符>';
IMPORT TABLE FROM '/var/lib/mysql/import/*.sdi';

检查

步骤 5 完成后重启 MySQL 服务, 重新连接数据库, 检查表结构、表数据是否正常