梳理下MySQL崩溃恢复过程
来源:互联网 发布:网络写手挣钱么 编辑:程序博客网 时间:2024/06/05 04:37
转自:http://www.cnblogs.com/xinysu/p/6586386.html
基于MySQL5.7版本,5.7版本在恢复过程做了优化,本文描述不考虑之前版本。
1 初始化崩溃恢复
数据库关闭只有2种情况,正常关闭,非正常关闭(包括数据库实例crash及服务器crash)。
正常关闭情况,所有buffer pool里边的脏页都会都会刷新一遍到磁盘,同时记录最新LSN到ibdata文件的第一个page中。而非正常关闭来不及做这些操作,也就是没及时把脏数据flush到磁盘,也没有记录最新LSN到ibdata file。
当我们重启数据库实例的时候,数据库做2个阶段性操作:redo log处理,undo log及binlog 处理。
1.1 redo log处理
- 打开系统表空间ibdata,读取第一个page中的LSN,若第一个页损坏,则依次往后面的page读,知道有个完整的page能够提供LSN,这个LSN当作上次shutdown时的checkpoint点,后续恢复,从这个LSN点开始恢复
- 进入redo log文件,读取第一个redo log文件头的checkpoint LSN, 并根据该LSN定位到redo日志文件中对应的位置,从该checkpoint点开始扫描,进行3次redo log文件扫描:
- 第一次,找 MLOG_CHECKPOINT日志
- 如果是正常关闭,这个日志是不做记录的,也就是扫描的过程中不回找到对应的MLOG_CHECKPOINT日志,不会进行接下来的两次扫描,因为属于正常关闭数据库服务,不需要考虑奔溃恢复情况;
- 如果是非正常关闭,则会查找到 MLOG_CHECKPOINT (如果是多个,则说明redo文件已损坏,恢复报错),获取MLOG_FILE_NAME中指定后续需要恢复的ibd文件;
- 第二次,从redo log读到的LSN,找到checkpoint点开始重复扫描存储日志对象
- 根据MLOG_CHECKPOINT日志,读取对应LSN之后的日志解析到hash表中,如果剩下的日志解析结束后还没有填满hash表格,则不需要进行第三次扫描;
- 进行到这里,则说明数据库是非正常关闭,会在errorlog中提示:Database was not shutdown normally!详见下图。
- 第三次,若第二次扫描hash表空间不足,则发起第三次扫描,清空hash表空间,重新从新的checkpoint点开始扫描
- 如果第二次扫扫描就把hash表填满,那么会先把hash表里边的记录重做到buffer pool中的数据页,然后再来加载redo log 记录到被清空的hash表中,hash表满后立即执行恢复操作,知道所有需要redo 的redo log 被应用结束。
恢复的过程中,注意两个点:打开ibd文件形式,读取数据库到buffer pool的改进。
根据hash表中的相应信息读取数据页, 读数据页的时候,5.7之前版本采用把所有表空间都打开,所有表格仅执行ReadOnly,5.7版本做了优化,新增了 MLOG_FILE_NAME 记录在checkpoint之后,所有被修改过的信息,根据这些信息,在恢复过程中,只需要打开相应的ibd文件即可,不涉及恢复的表格支持正常DML跟DDL操作,涉及恢复的表格则仅执行ReadOnly功能。
当把数据页读取到buffer pool中,以往版本是只读取对应的单个页面,而现在的是直接读取与该页面相邻的32个data page 也一起加载的buffer pool,因为一个数据页的修改,可能周围的页面也被修改,一次性读取,可以避免后面根据hash表中再重新读取其相邻的页面。1.2 undo log及binlog 处理
上一阶段中,把redo log中的操作都apply到数据页中,但是对于prepare状态的事务却还没有进行回滚处理,这个阶段则是针对prepare状态的事务进行处理,需要使用到binlog和undo log。
- 根据最后一个binlog文件,为啥不是所有binlog文件呢?因为每一个binlog文件切换的时候,都会确保当前binlog文件的所有操作已落盘,所以只需要考虑最后一个binlog文件。跟进最后一个binlog文件,获取所有可能没有提交事务的xid列表;
- 根据undo log中的 insert_undo_list,upddate_undo_list事务链,构建undo_list,在根据undo_list构建未提交事务链表;
- 从未提交事务链表中,提取出xid,凡是存在于xid列表中的,则需要提交,不存在的,则回滚。
整个恢复过程,可以参考下来自 www.sysdb.cn 网站作者 boyce 画的说明图,图片版权属于该作者,本处仅为引用分享给大家,作图很详细,一言不合开源码分析!遗憾的是,作者只写了2篇博文就停止更新了,心疼默哀十分钟.....
2 innodb关闭恢复涉及参数
2.1 关闭参数:innodb_fast_shutdown
数据库关闭的时候,innodb需要完成所有full purge何insert buffer操作,这需要一些时间,甚至几个小时完成
- 0
- 关闭时,需要完成所有full purge,insert buffer, flush dirty pages操作
- 做 innodb plugin升级时,会设置为0,再正常关闭数据库。
- 1
- 默认值,表示不需要完成full purge和insert buffer操作,但是缓冲池的脏数据需要刷新到磁盘
- 2
- 既不完成full purge和insert buffer操作,也不把缓冲池的脏数据刷新到磁盘,而是将日志写入日志文件,这样不回有数据丢失,但是下次mysql启动的时候,需要根据日志文件执行恢复操作
2.2 恢复参数:innodb_force_recovery
这里注意,数字越小,则忽略检查的内容越少,每个大的数字都包含了前面小数字忽略检查的内容。当参数设置大于0后,可以对表格进行DML操作,但是DDL操作时不允许的。
当innodb_force_recovery 值为1-3时,仅允许SELECT TABLE ,DROP or CREATE tables;innodb_force_recovery 值为>=4时,5.7.17之前版本支持DROP TABLE,5.7.18后版本不支持。
参数说明如下图:
3 测试情况
3.1 默认配置测试:innodb_fast_shutdown=1,innodb_force_recovery=0
3.1.1 操作过程
1 #1 tailf error.log查看mysql错误日志,动态滚动查看 2 mysql> show global variables like 'log_error'; 3 tailf /data/mysql/mysql3310/data/error.log 4 5 #2 测试库中开启事务,insert 10w行记录,不提交事务 6 mysql> begin;insert into orders select * from orders.orders limit 100000; 7 Query OK, 0 rows affected (0.00 sec) 8 9 Query OK, 100000 rows affected (37.55 sec)10 Records: 100000 Duplicates: 0 Warnings: 011 12 #3 查找mysql进程号,杀进程13 [root@localhost opt]# ps axu | grep mysql14 [root@localhost opt]# kill -9 mysql的进程号15 16 #4 启动mysql服务17 mysqld --defaults-file=/data/mysql/mysql3310/mysql3310.cnf &18 19 #5 到tailf error.log窗口查看错误
3.1.2 error log解析
3.2 innodb_fast_shutdown=1,innodb_force_recovery=3
3.2.1 操作过程
1 #1 tailf error.log查看mysql错误日志,动态滚动查看 2 mysql> show global variables like 'log_error'; 3 tailf /data/mysql/mysql3310/data/error.log 4 5 #2 测试库中开启事务,insert 10w行记录,不提交事务 6 mysql> begin;insert into orders select * from orders.orders limit 100000; 7 Query OK, 0 rows affected (0.00 sec) 8 9 Query OK, 100000 rows affected (37.55 sec)10 Records: 100000 Duplicates: 0 Warnings: 011 12 #3 查找mysql进程号,杀进程13 [root@localhost opt]# ps axu | grep mysql14 [root@localhost opt]# kill -9 mysql的进程号15 16 #4 在cnf文件中指定innodb_force_recovery=3,启动服务,检查是否修改成功17 [root@localhost ~]# vim /data/mysql/mysql3310.cnf18 #添加innodb_force_recovery参数设置19 [mysqld]20 innodb_force_recovery=321 22 #5 启动mysql服务23 [root@localhost ~]# mysqld --defaults-file=/data/mysql/mysql3310.cnf &24 25 #6 到tailf error.log窗口查看错误26 #发现没有进行undo操作,同时全库仅支持select drop create,不支持其他所有操作
3.2.2 error log解析
1 2017-03-17T15:12:14.317391Z 0 [Note] mysqld (mysqld 5.7.14-log) starting as process 32094 ... 2 2017-03-17T15:12:14.430101Z 0 [Note] InnoDB: PUNCH HOLE support not available 3 2017-03-17T15:12:14.430586Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins 4 2017-03-17T15:12:14.430732Z 0 [Note] InnoDB: Uses event mutexes 5 2017-03-17T15:12:14.430874Z 0 [Note] InnoDB: GCC builtin __sync_synchronize() is used for memory barrier 6 2017-03-17T15:12:14.430993Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.3 7 2017-03-17T15:12:14.431084Z 0 [Note] InnoDB: Using Linux native AIO 8 2017-03-17T15:12:14.433127Z 0 [Note] InnoDB: Number of pools: 1 9 2017-03-17T15:12:14.434016Z 0 [Note] InnoDB: Not using CPU crc32 instructions10 2017-03-17T15:12:14.443970Z 0 [Note] InnoDB: Initializing buffer pool, total size = 9G, instances = 8, chunk size = 128M11 2017-03-17T15:12:16.158820Z 0 [Note] InnoDB: Completed initialization of buffer pool12 2017-03-17T15:12:16.380118Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().13 2017-03-17T15:12:16.409819Z 0 [Note] InnoDB: Highest supported file format is Barracuda.14 2017-03-17T15:12:16.478403Z 0 [Note] InnoDB: Log scan progressed past the checkpoint lsn 89893566142015 2017-03-17T15:12:16.478579Z 0 [Note] InnoDB: Doing recovery: scanned up to log sequence number 89893566142916 2017-03-17T15:12:16.532923Z 0 [Note] InnoDB: Doing recovery: scanned up to log sequence number 89893566142917 2017-03-17T15:12:16.533063Z 0 [Note] InnoDB: Database was not shutdown normally!18 2017-03-17T15:12:16.533105Z 0 [Note] InnoDB: Starting crash recovery.19 2017-03-17T15:12:17.052734Z 0 [Note] InnoDB: 1 transaction(s) which must be rolled back or cleaned up in total 100000 row operations to undo20 2017-03-17T15:12:17.053009Z 0 [Note] InnoDB: Trx id counter is 571801621 2017-03-17T15:12:17.321987Z 0 [Note] InnoDB: Last MySQL binlog file position 0 37774, file name bin_log.00001622 2017-03-17T15:12:17.460435Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"23 2017-03-17T15:12:17.460673Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables24 2017-03-17T15:12:17.461075Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...25 2017-03-17T15:12:17.512923Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.26 2017-03-17T15:12:17.516337Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.27 2017-03-17T15:12:17.516617Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.28 2017-03-17T15:12:17.518732Z 0 [Note] InnoDB: 5.7.14 started; log sequence number 89893566142929 2017-03-17T15:12:17.518789Z 0 [Note] InnoDB: !!! innodb_force_recovery is set to 3 !!!30 2017-03-17T15:12:17.519305Z 0 [Note] InnoDB: Loading buffer pool(s) from /data/mysql/mysql3310/data/ib_buffer_pool31 2017-03-17T15:12:17.521217Z 0 [Note] Plugin 'FEDERATED' is disabled.32 2017-03-17T15:12:17.694697Z 0 [Note] Recovering after a crash using /data/mysql/mysql3310/logs/bin_log33 2017-03-17T15:12:17.694882Z 0 [Note] Starting crash recovery...34 2017-03-17T15:12:17.695070Z 0 [Note] Crash recovery finished.35 2017-03-17T15:12:18.197454Z 0 [Warning] Failed to set up SSL because of the following SSL library error: SSL context is not usable without certificate and private key36 2017-03-17T15:12:18.197584Z 0 [Note] Server hostname (bind-address): '*'; port: 331037 2017-03-17T15:12:18.197804Z 0 [Note] IPv6 is available.38 2017-03-17T15:12:18.197910Z 0 [Note] - '::' resolves to '::';39 2017-03-17T15:12:18.197981Z 0 [Note] Server socket created on IP: '::'.40 2017-03-17T15:12:18.391615Z 0 [Note] InnoDB: Buffer pool(s) load completed at 170317 23:12:1841 2017-03-17T15:12:18.414950Z 0 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.42 2017-03-17T15:12:18.415223Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.43 2017-03-17T15:12:18.415340Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.44 2017-03-17T15:12:18.446935Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.45 2017-03-17T15:12:18.520569Z 0 [Note] Event Scheduler: Loaded 0 events46 2017-03-17T15:12:18.521680Z 0 [Note] mysqld: ready for connections.47 Version: '5.7.14-log' socket: '/tmp/mysql3310.sock' port: 3310 MySQL Community Server (GPL)48 2017-03-17T15:13:03.125686Z 2 [ERROR] InnoDB: innodb_force_recovery is on. We do not allow database modifications by the user. Shut down mysqld and edit my.cnf to set innodb_force_recovery=0
- 梳理下MySQL崩溃恢复过程
- 梳理下MySQL崩溃恢复过程
- mysql崩溃数据恢复
- MySQL数据恢复过程
- MySQL数据恢复过程
- 崩溃恢复
- MySQL Cluster恢复过程记
- 系统崩溃后 oracle 9i数据文件恢复过程
- 系统崩溃后 oracle 9i数据文件恢复过程!
- innodb崩溃后的恢复过程--重做和回滚
- mysql数据库下损坏数据的恢复操作其过程总结
- Linux下mysql备份 恢复
- Linux下mysql备份 恢复
- Linux下mysql备份 恢复
- Linux下mysql备份 恢复
- Linux下mysql备份 恢复
- Linux下mysql备份 恢复
- Linux下mysql备份 恢复
- 二位翁无
- java并发中的CyclicBarrier
- CTU Open Contest 2016 Hot Air Ballooning
- Kotlin 类与继承
- HDU 4734 f(x)
- 梳理下MySQL崩溃恢复过程
- shell执行spark-submit
- C ++ 语言指针
- CTU Open Contest 2016 Colorful Tribune(附测试数据)
- html+css+js 简易展开收起效果
- 声明式异常处理: exception-mapping 元素
- Excel文件密码破解小工具
- 手把手教你在CentOS7安装Java JDK和配置环境变量
- 【剑指offer】【41】找出升序数组中和为给定值的两个数字