一、概述
- InnoDB是MySQL的存储引擎之一,因此InnoDB的启动和关闭,更精确的是指在MySQL实例的启动过程中对InnoDB存储引擎的处理过程
二、数据库的关闭(innodb_fast_shutdown参数)
- 在数据库关闭时,参数innodb_fast_shutdown影响着表的存储引擎为InnoDB的行为
- 该参数的取值如下:
- 0:在MySQL数据库关闭时,InnoDB需要完成所有的full purge和merge insert buffer,并且将所有的脏页刷新回磁盘。这需要一些时间,有时甚至需要几个小时来完成。如果在进行InnoDB升级时,必须将这个参数调为0,然后再关闭数据库
- 1(默认值):表示不需要完成上述的fullpurge和merge insert buffer操作,但是在缓冲池中的一些数据脏页还是会刷新回磁盘
- 2:表示不完成full purge和merge insert buffer操作,也不将缓冲池中的数据脏页写回磁盘,而是将日志都写入日志文件。这样不会有任何事务的丢失,但是下次MySQL启动时,会进行恢复操作(recovery)
show variables like 'innodb_fast_shutdown'\G;
保证数据库的数据正常
- 当正常关闭MySQL数据库时,下次的启动应该会非常“正常”
- 但是如果没有正常地关闭数据库,如用kill命令关闭数据库,在MySQL数据库运行中重启了服务器,或者在关闭数据库时,将参数innodb_fast_shutdown设为了2,下次MySQL启动时都会对InnoDB存储引擎的表进行恢复操作
三、数据库的恢复(innodb_force_recovery参数)
- 该参数影响整个InnoDB存储引擎恢复的状况
- 注意:将该参数设置为大于0后,用户可以对表进行select、create、drop操作,但insert、update、delete这类DML操作是不允许的
取值如下:
- 该参数默认值为0:代表当发生需要恢复时,进行所有的恢复操作。当不能进行有效恢复时,如数据页发生了corruption,MySQL数据库可能发生宕机(crash),并把错误写入错误日志中去
- 该参数还可以设置为下面几种值,大的数字表示包含了前面所有小数字表示的影响,如下:
- 1(SRV_FORCE_IGNORE_CORRUPT):忽略检查到的corrupt页
- 2(SRV_FORCE_NO_BACKFROUND):阻止Master Thread线程的运行,如Master Thread线程需要进行full purge操作,而这会导致crash
- 3(SRV_FORCE_NO_TRX_UNDO):不进行事务的回滚操作
- 4(SRV_FORCE_NO_IBUF_MERGE):不进行插入缓冲的合并操作
- 5(SRV_FORCE_NO_UNDO_LOG_SCAN):不查看撤销日志(undo log),InnoDB存储引擎会将未提交的事务视为已提交
- 6(SRV_FORCE_NO_LOG_REDO):不进行前滚的操作
show variables like 'innodb_force_recovery'\G;
- 在某些情况下,可能并不需要进行完整的恢复操作:因为用户自己知道怎么进行恢复。比如在对一个表进行alter table操作时发生意外了,数据库重启时会对InnoDB表进行回滚操作,对于一个大表来说这需要很长时间,可能是几个小时。这时用户可以自行进行恢复,如可以把表删除,从备份中重新导入数据到表,可能这些操作的速度远远快于回滚操作
四、演示案例(验证数据库的宕机恢复)
- 现在做一个实验,模拟故障的发生
- 第一步:在第一个会话中(session),对一张接近1000万行的InnoDB存储引擎表进行更新操作,但是完成后不要马上提交
- start transaction开启事务
- update命令执行之后会产生大量的UNDO日志(undo log)
- 第二步:人为的杀掉MySQL数据库服务器(通过kill命令模拟宕机操作)
- 第三步:下次MySQL启动时会对之前的update事务进行回滚操作,而这些信息都会记录在错误日志文件(默认后缀名为err)中。如果查看错误日志文件,可以看到如下结果:
- 可以看到,采用默认的策略(即innodb_force_recovery设为0),InnoDB会在每次启动后对发生问题的表进行恢复操作,通过错误日志文件,可知这次回滚操作需要回滚8867280行记录,差不多总共进行了9分钟
- 第四步:重新做一次实验,此次在启动MySQL之前,将参数innodb_force_recovery设为3,然后观察InnoDB是否还会进行回滚操作,查看错误日志文件,内容如下:
- 这里出现了“!!!”,InnoDB警告已经将innodb_force_recovery设置为3,不会进行回滚操作了,因此数据库很快启动完成