有几种情况需要手动检查和排除InnoDB的故障:
InnoDB附带了几种有用的方法,可以通过MySQL和状态日志文件,information_schema查询以及InnoDB引擎的直接报告来帮助故障排除过程。
InnoDB 系统故障问题通常可归因于硬件限制或配置错误,其中超出了缓冲区或日志的可用限制。
InnoDB虽然通常是用于高流量事务环境的非常稳定的数据库引擎,但并非没有缺陷。
有时缓冲区崩溃、发生未知错误或出现其他可能导致数据库停机的问题。
我们可以依靠 ACID 合规性来确保在发生崩溃时不会丢失任何数据。
如果您已将InnoDB设置为使用符合ACID的设置,则除非发生外部问题,否则不会丢失数据。
外部问题包括InnoDB认为它已将数据写入磁盘,但使用非电池备份缓存的软件RAID机制或RAID系统尚未将更改完全写入磁盘。
当 InnoDB 因进程故障而崩溃时,ib_data日志文件不会刷新到磁盘,并且某些事务可能尚未完成 COMMIT 阶段。理想情况下,当MySQL在崩溃后启动时,InnoDB将开始崩溃恢复过程,并给予足够的时间,它将完成而不会出错。
我们可以通过观察MySQL错误日志来查看崩溃恢复过程处于什么状态。
$> sudo tail -f
在观察输出时,我们可以看到InnoDB为崩溃恢复所经历的步骤:
1.在接受连接之前,InnoDB将启动日志重做操作
将未从缓冲池刷新的任何数据更改应用于 InnoDB 表空间文件。如果没有等待写入的更改,则将跳过此步骤。这将通过时间戳和完成百分比进度更新在日志文件中引用。如果我们的服务器配置了大量重做日志或 I/O 资源相对较慢,则此过程可能需要大量时间。具有大型日志的高度活跃的服务器需要 30 分钟或更长时间才能完成此过程的情况并不少见。
2. 事务回滚:在系统故障之前未完成的任何事务都将发出回滚,以便数据保持一致。
3.索引页读取和缓冲区合并:InnoDB将读取索引页并合并挂起的共享表空间,将缓冲区更改插入二级索引。此操作并行执行。
4.删除清除过程:所有标记为删除但在崩溃之前未被删除将被清除以保持数据一致。
如果InnoDB在此过程中遇到任何错误,我们可以将错误代码与文档一起引用,并按照解决问题的建议进行操作。如果我们遇到未记录的问题,此文件的输出也可用于提交错误报告。
如果InnoDB无法完成重做日志崩溃恢复过程,则必须启动数据恢复过程。
这涉及强制InnoDB以几种可选状态之一启动,以便检索我们的数据。这些恢复模式不会修复导致崩溃的根本问题,也不会将InnoDB修复到可以重新启动并继续正常运行的状态。恢复模式仅允许我们登录MySQL并从InnoDB表中导出数据,以便我们可以将该数据导入其他地方正常运行的InnoDB实例中,或者在修复MySQL后将其正确启动。
InnoDB提供了几个级别的操作限制来帮助数据恢复过程。如果InnoDB通过这些模式中的任何一种启动,它将忽略任何通过INSERT,UPDATE或DELETE查询更改或添加数据的尝试。
我们与数据库交互的唯一选择是通过 SELECT、DROP 和 CREATE。
理想情况下,在数据恢复过程中,最好从最低恢复模式开始并尝试恢复数据;如果数据无法恢复或InnoDB无法以较低的设置启动,则我们增加该值并重试。在某些情况下,我们可以通过消除过程来确定InnoDB的问题,方法是尝试以不同的恢复模式启动引擎,同时查看错误日志并将进度与其他恢复模式进行比较。以下是一些InnoDB崩溃恢复模式:
启用恢复模式的过程如下:
main my.cnf
文件,并添加或更改 innodb_force_recovery = N
的值,其中 N 是前面提到的状态之一。* 3.通过 tail -f
命令在一个终端中观察 MySQL 错误日志。* 4.以 mysq1 用户身份运行时,通过命令行启动 MySQL 服务器进程。不要使用操作系统服务控件来启动MySQL:sudo -u mysql mysqld
,这将允许我们在进程完成恢复步骤时看到进程的所有输出。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周期和内存的信息,否则这些信息将分配给处理事务。
最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。
有需要的小伙伴,可以点击下方卡片领取,无偿分享