Linux MySQL服务异常断电恢复方法

异常断电无法启动原因

现在MySQL一般都是用的innodb这种存储引擎,在开始一个事务进行数据的修改时,数据会首先写入到InnoDB的重做日志(redo log),到了一定的程度(例如,达到了特定的时间间隔或日志大小)才会写入到硬盘的文件中。


如果这个时候服务突然崩溃了,例如断电。然后再重新启动MySQL得时候,MySQL会检测到InnoDB数据文件和重做日志之间存在不一致性,然后就会通过一些方法来使得硬盘上的数据何redo log中的数据一致,如果重做日志本身受到损坏就没法完成这个数据的恢复过程,无法保证数据的一致性,MySQL就不给启动。


解决方法

1、启用 innodb_force_recovery

设置 innodb_force_recovery 参数后,InnoDB引擎会尝试跳过某些操作,从而忽略一些错误来启动数据库,当innodb_force_recovery的值从4开始时,数据库就会变为只读模式。


innodb_force_recovery可以设置6个值

  • 0:默认值。不采取特殊措施

  • 1 :让服务器忽略某些潜在的损坏页面错误

  • 2 :阻止主线程的运行,这避免了创建新的 redo log 项

  • 3 :不执行事务回滚操作

  • 4 :阻止插入缓冲区的合并操作

  • 5 :不查看撤销日志,这意味着不会尝试恢复任何未完成的事务

  • 6 :不执行 redo 日志回放

当使用 innodb_force_recovery 选项时,通常先将其值设为1,并尝试重启服务。如果服务启动失败,则逐步将该值从1增加到6,每次修改后尝试重新启动服务。


例如:

[mysqld]
innodb_force_recovery=6

2、检查数据表

MySQL服务正常启动用后,使用mysqlcheck检查是否表是否损坏,如果损坏进行修复

mysqlcheck -u [username] -p --auto-repair --check --all-databases

说明:

  • --auto-repair 选项会在检测到问题时自动尝试修复表

  • --check 选项用于检查表的完整性

  • --all-databases 选项确保检查所有数据库中的所有表


如果指向检查特定的数据库:

mysqlcheck -u [username] -p  [database_name]

如果向修复特定数据库的所有表

mysqlcheck -u [username] -p --repair [database_name]

如果想修复特定数据库的特定表:

mysqlcheck -u [username] -p --repair [database_name] [table_name]

3、数据备份

如果检查无误后,通过mysqldump工具备份数据库,如果数据量不是太大的情况,可以直接使用全备份。

mysqldump -uroot -p  -A -F --single-transaction --flush-privileges --default-character-set=utf8   > mysqlall_back.sql

4、重置数据目录

先停止MySQL服务,然后将原有的数据目录进行重命名,并且重新创建一个数据目录。

例如:假设MySQL的数据目录为/var/lib/mysql

mv /var/lib/mysql /var/lib/mysql_bak

mkdir /var/lib/mysql

chown mysql:mysql /var/lib/mysql

5、初始化基本数据

使用mysqld --initialize 或 mysqld --initialize-insecure 初始化mysql的基本数据。

# 初始化得root用户无密码,可以无密码登录
mysqld --initialize-insecure

# 这个命令会为root用户创建一个临时随机密码 在MySQL错误日志中找到这个随机生成的临时密码
mysqld --initialize

说明:

mysqld --initialize 和 mysqld --initialize-insecure 是从MySQL 5.7.6 开始引入的,用以替代旧的mysql_install_db工具

初始化基本数据注意事项:

1、需要确保MySQL的数据目录是空的,即里面没有任何内容

2、需要确保MySQL服务的进行是停止状态,不然只会再数据目录生成部分文件。例如:只会生成一个auto.conf文件

3、需要确保MyQL配置文件中的 innodb_force_recovery 选项不是启用状态

4、用户必须有足够的权限来创建、写入和修改MySQL的数据目录中的文件和子目录,所以可以用root用户身份来执行,如果不成功就用mysql用户来下执行。sudo -u mysql mysqld --initialize-insecure

6、重启MySQL

重新启动MySQL服务

systemctl start mysql.service

7、数据还原

将上面备份的数据进行还原

sudo systemctl start mysql.service

mysql -uroot -p < mysqlall_back.sql

重新导入数据能恢复正常的原因

1、 清除损坏数据: 在导入数据之前,您通常会首先清空或删除原始数据库中的所有数据。这意味着所有的损坏数据、损坏的索引和其他可能的问题都将被移除。

2、 重建数据: 重新导入数据时,数据文件将从头开始重新创建。这意味着任何受损的数据页、损坏的索引或其他底层结构都会被新的、整洁的结构替代。

3、 重新生成redo log: 从备份重新导入数据时,MySQL会在事务提交时写入新的redo log条目。因此,任何受损的、旧的redo log条目都会被忽略,并且不会影响新导入的数据。

posted on 2023-09-12 18:55  背对背依靠  阅读(452)  评论(0编辑  收藏  举报