theme: cyanosis
InnoDB故障排除
有几种情况需要手动检查和排除InnoDB的故障:
- 性能或瓶颈问题
- 死锁或等待超时
- 进程故障或系统崩溃
InnoDB附带了几种有用的方法,可以通过MySQL和状态日志文件,information_schema查询以及InnoDB引擎的直接报告来帮助故障排除过程。
InnoDB 系统故障问题通常可归因于硬件限制或配置错误,其中超出了缓冲区或日志的可用限制。
InnoDB系统崩溃
InnoDB虽然通常是用于高流量事务环境的非常稳定的数据库引擎,但并非没有缺陷。
有时缓冲区崩溃、发生未知错误或出现其他可能导致数据库停机的问题。
我们可以依靠 ACID 合规性来确保在发生崩溃时不会丢失任何数据。
如果您已将InnoDB设置为使用符合ACID的设置,则除非发生外部问题,否则不会丢失数据。
外部问题包括InnoDB认为它已将数据写入磁盘,但使用非电池备份缓存的软件RAID机制或RAID系统尚未将更改完全写入磁盘。
当 InnoDB 因进程故障而崩溃时,ib_data日志文件不会刷新到磁盘,并且某些事务可能尚未完成 COMMIT 阶段。理想情况下,当MySQL在崩溃后启动时,InnoDB将开始崩溃恢复过程,并给予足够的时间,它将完成而不会出错。
我们可以通过观察MySQL错误日志来查看崩溃恢复过程处于什么状态。
$> sudo tail -f <data_dir>/<hostname>.err
在观察输出时,我们可以看到InnoDB为崩溃恢复所经历的步骤:
1.在接受连接之前,InnoDB将启动日志重做操作
将未从缓冲池刷新的任何数据更改应用于 InnoDB 表空间文件。如果没有等待写入的更改,则将跳过此步骤。这将通过时间戳和完成百分比进度更新在日志文件中引用。如果我们的服务器配置了大量重做日志或 I/O 资源相对较慢,则此过程可能需要大量时间。具有大型日志的高度活跃的服务器需要 30 分钟或更长时间才能完成此过程的情况并不少见。
2. 事务回滚:在系统故障之前未完成的任何事务都将发出回滚,以便数据保持一致。
3.索引页读取和缓冲区合并:InnoDB将读取索引页并合并挂起的共享表空间,将缓冲区更改插入二级索引。此操作并行执行。
4.删除清除过程:所有标记为删除但在崩溃之前未被删除将被清除以保持数据一致。
如果InnoDB在此过程中遇到任何错误,我们可以将错误代码与文档一起引用,并按照解决问题的建议进行操作。如果我们遇到未记录的问题,此文件的输出也可用于提交错误报告。
使用 InnoDB 崩溃恢复模式
如果InnoDB无法完成重做日志崩溃恢复过程,则必须启动数据恢复过程。
这涉及强制InnoDB以几种可选状态之一启动,以便检索我们的数据。这些恢复模式不会修复导致崩溃的根本问题,也不会将InnoDB修复到可以重新启动并继续正常运行的状态。恢复模式仅允许我们登录MySQL并从InnoDB表中导出数据,以便我们可以将该数据导入其他地方正常运行的InnoDB实例中,或者在修复MySQL后将其正确启动。
InnoDB提供了几个级别的操作限制来帮助数据恢复过程。如果InnoDB通过这些模式中的任何一种启动,它将忽略任何通过INSERT,UPDATE或DELETE查询更改或添加数据的尝试。
我们与数据库交互的唯一选择是通过 SELECT、DROP 和 CREATE。
理想情况下,在数据恢复过程中,最好从最低恢复模式开始并尝试恢复数据;如果数据无法恢复或InnoDB无法以较低的设置启动,则我们增加该值并重试。在某些情况下,我们可以通过消除过程来确定InnoDB的问题,方法是尝试以不同的恢复模式启动引擎,同时查看错误日志并将进度与其他恢复模式进行比较。以下是一些InnoDB崩溃恢复模式:
-
1 SRV_FORCE_IGNORE_CORRUPT:即使页面损坏,服务器也可以启动
-
2 SRV_FORCE_NO_BACKROUND:这将在不运行主 InnoDB 线程的情况下启动服务器
-
3 SRV_FORCE_NO_TRX_UNDO:这将在初始化期间跳过事务回滚过程
-
4 SRV_FORCE_NO_IBUF_MERGE:这将在初始化期间跳过插入缓冲区合并操作,并且不会生成任何 InnoDB 表的统计信息
-
5 SRV_FORCE_NO_UNDO_LOG_SCAN:这将忽略初始化期间的重做日志读取 + 应用过程,并将所有事务视为已提交,即使它们尚未完成
-
6 SRV_FORCE_NO_LOG_REDO:这将在初始化期间跳过重做日志过程
启用 InnoDB 恢复模式
启用恢复模式的过程如下:
-
- 确保 MySQL 处于脱机状态,并且没有子进程正在运行。
-
2.编辑
main my.cnf
文件,并添加或更改innodb_force_recovery = N
的值,其中 N 是前面提到的状态之一。 -
3.通过
tail -f
命令在一个终端中观察 MySQL 错误日志。 -
- 以 mysq1 用户身份运行时,通过命令行启动 MySQL 服务器进程。不要使用操作系统服务控件来启动MySQL:
sudo -u mysql mysqld
,这将允许我们在进程完成恢复步骤时看到进程的所有输出。
- 以 mysq1 用户身份运行时,通过命令行启动 MySQL 服务器进程。不要使用操作系统服务控件来启动MySQL:
-
- 一旦 MySQL 服务器进程启动并使我们能够登录,我们就可以通过 SELECT INTO OUTFILE 语句或其他形式的将数据备份到文件系统(例如 mysqldump)导出数据。
-
- (可选)如果我们没有其他服务器将数据迁移到,并且在停机窗口期间我们有时间重新导入数据,那么我们可以在拥有其内容的有效 SQL 转储文件后尝试修复问题表。在这种方法中,我们遵循以下过程:
-
- 完成上述前五个步骤,为每个所需的表生成一个 SQL 转储文件。
-
- 为损坏的表发出 DROP 命令。
-
3.关闭MySQL,然后删除强制恢复选项或将其注释掉。
-
4.启动 MySQL 服务器进程。如果服务器正确启动而没有错误并且我们可以登录,那么重新创建表并导入其数据是安全的。
利用InnoDB状态统计进行故障排除性能监控
InnoDB有许多可用的高级统计信息,我们可以将其用于故障排除和性能监控。
查询此信息的最简单方法是执行以下查询并读取输出:
mysq1> pager less;
mysq1> sHoW engine innodb status\g
如果您启用了 InnoDB 状态文件的配置变量:innodb_status_file
,此信息也会定期写入 InnoDB 状态文件。为了定期记录这些统计信息,我们需要创建多个表。
这些表不存储任何数据,但是当我们执行命令时,InnoDB将它们识别为开始将统计信息写入MySQL错误日志的信号。
可以在任何数据库中创建这些表,但最佳做法是在它们自己的架构中创建它们,以便它们不会与特定于应用程序的架构冲突。
InnoDB 每个监视器需要一个表,因此我们将执行以下查询来创建表:
mysq1> CREATE DATABASE innodb monitors; USE innodb monitors;
mysql> CREATE TABLE innodb_monitor (a INT) ENGINE=INNODB;
mysql> CREATE TABLE innodb_lock_monitor (a INT) ENGINE=INNODB;
mysq1> CREATE TABLE innodb_tablespace_monitor (a INT) ENGINE=INNODB;
mysql> CREATE TABLE innodb_table_monitor (a INT) ENGINE=INNODB;
如果我们需要阻止监视器写入错误日志,需要禁用的每个监视器的相应 DROP TABLE
查询。
如果未删除表,则监视器将继续运行,直到MySQL停止。
MySQL重新启动后,即使表存在,InnoDB监视器也不会再次启动。
如果我们希望启动监视器,则必须再次执行 CREATE TABLE
语句。
以下命令用于停止监视器并删除表:
mysql> USE innodb_monitors;
mysq1> DROP TABLE innodb_lock_monitor;
mysql> DROP TABLE innodb_monitor;
mysql> DROP TABLE innodb_monitors;
mysql> DROP TABLE innodb_table_monitor;
仅当特别需要故障排除时才应启用监视表。
在非常活跃的服务器上,定期信息,特别是锁监视器输出,将迅速填满错误日志,如果未使用记录的信息,错误日志将不必要地使用 I/O 资源。
此外,当启用监视器时,InnoDB确实会受到很小的性能影响,因为它正在处理和写入消耗CPU周期和内存的信息,否则这些信息将分配给处理事务。
本文正在参加「金石计划 . 瓜分6万现金大奖」
暂无评论内容