广告
返回顶部
首页 > 资讯 > 数据库 >MySQL数据库意外掉线后数据该怎么恢复
  • 646
分享到

MySQL数据库意外掉线后数据该怎么恢复

2024-04-02 19:04:59 646人浏览 安东尼
摘要

Mysql数据库意外掉线后数据该怎么恢复,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。InnoDB如果发生意外宕机了,数据会丢

Mysql数据库意外掉线后数据该怎么恢复,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

InnoDB如果发生意外宕机了,数据会丢么?

对于这个问题,稍微了解一点mysql知识的人,都会斩钉截铁的回答:不会!

为什么?

他们也会毫不犹豫地说:因为有重做日志(redo log),数据可以通过redo log进行恢复。

回答得很好,那么InnoDB怎样通过redo log进行数据恢复的,具体的流程是怎样的?

估计能说清楚这个问题的人所剩不多了,更深入一点:除了redo log,InnoDB在恢复过程中,还需要其他信息么?比如是否需要binlog参与?undo日志在恢复过程中又会起到什么作用?

到这里,可能很多人会变得疑惑起来:数据恢复跟undo有半毛钱的关系?

其实,InnoDB的数据恢复是一个很复杂的过程,这个恢复过程需要redo log、binlog、undo log等参与。这里把InnoDB的恢复过程主要划分为两个阶段:

第一阶段主要依赖于redo log的恢复;

而第二阶段,恰恰需要binlog和undo log的共同参与。

接下来,我们来具体了解下整个恢复的过程:

一、依赖redo log进行恢复

第一阶段,数据库启动后,InnoDB会通过redo log找到最近一次checkpoint的位置,然后根据checkpoint相对应的LSN开始,获取需要重做的日志,接着解析获取的日志并且保存到一个哈希表中,最后通过遍历哈希表中的redo log信息,读取相关页进行恢复。

InnoDB的checkpoint信息保存在日志文件中,即ib_logfile0的开始2048个字节中,checkpoint有两个,交替更新,checkpoint与日志文件的关系如下图:

MySQL数据库意外掉线后数据该怎么恢复

(checkpoint位置)

checkpoint信息分别保存在ib_logfile0的512字节和1536字节处,每个checkpoint默认大小为512字节,InnoDB的checkpoint主要由3部分信息组成:

checkpoint no:主要保存的是checkpoint号,因为InnoDB有两个checkpoint,通过checkpoint号来判断哪个checkpoint更新。

checkpoint lsn:主要记录了产生该checkpoint是flush的LSN,确保在该LSN前面的数据页都已经落盘,不再需要通过redo log进行恢复。

checkpoint offset:主要记录了该checkpoint产生时,redo log在ib_logfile中的偏移量,通过该offset位置就可以找到需要恢复的redo log开始位置。

通过以上checkpoint的信息,我们可以简单得到需要恢复的redo log的位置,然后通过顺序扫描该redo log来读取数据,比如我们通过checkpoint定位到开始恢复的redo log位置在ib_logfile1中的某个位置,那么整个redo log扫描的过程可能是这样的:

MySQL数据库意外掉线后数据该怎么恢复

(redo log扫描过程)

Step 1:从ib_logfile1的指定位置开始读取redo log,每次读取4 * page_size的大小,这里我们默认页面大小为16K,所以每次读取64K的redo log到缓存中,redo log每条记录(block)的大小为512字节。

Step 2:读取到缓存中的redo log通过解析、验证等一系列过程后,把redo log的内容部分保存到用于恢复的缓存recv_sys->buf,保存到恢复缓存中的每条信息主要包含两部分:(space,offset)组成的位置信息和具体redo log的内容,我们称之为body。

Step 3:同时保存在恢复缓存中的redo信息会根据(space,offset)计算一个哈希值后保存到一个哈希表(recv_sys->addr_hash)中,相同哈希值、不同(space,offset)用链表存储,相同的(space,offset)用列表保存,可能部分事务比较大,redo信息一个block不能保存,所以,每个body中可以用链表链接多body的值。

redo log被保存到哈希表中之后,InnoDB就可以开始进行数据恢复,只需要轮询哈希表中的每个节点获取redo信息,根据(space,offset)读取指定页面后进行日志覆盖。

在上面整个过程中,InnoDB为了保证恢复的速度,做了几点优化

优化1:

在根据(space,offset)读取数据页信息到buffer pool的时候,InnoDB不是只读取一张页面,而是读取相邻的32张页面到buffer pool。这里有个假设,InnoDB认为,如果一张页面被修改了,那么其周围的一些页面很有可能也被修改了,所以一次性连续读入32张页面可以避免后续再重新读取。

优化2:

在Mysql5.7版本以前,InnoDB恢复时需要依赖数据字典,因为InnoDB根本不知道某个具体的space对应的ibd文件是哪个,这些信息都是数据字典维护的。而且在恢复前,需要把所有的表空间全部打开,如果库中有数以万计的表,把所有表打开一遍,整个过程就会很慢。那么MySQL5.7在这上面做了哪些改进呢?

其实很简单,针对上面的问题,InnoDB在redo log中增加了两种redo log的类型来解决。

MLOG_FILE_NAME

用于记录在checkpoint之后,所有被修改过的信息(space,filepath);

MLOG_CHECKPOINT

则用于标志MLOG_FILE_NAME的结束。

上面两种redo log类型的添加,完美解决了前面遗留的问题,redo log中保存了后续需要恢复的space和filepath对。所以,在恢复的时候,只需要从checkpoint的位置一直往后扫描到MLOG_CHECKPOINT的位置,这样就能获取到需要恢复的space和filepath。在恢复过程中,只需要打开这些ibd文件即可。当然由于space和filepath的对应关系通过redo存了下来,恢复的时候也不再依赖数据字典。

这里需要强调的是MLOG_CHECKPOINT在每个checkpoint点中最多存在一次,如果出现多次MLOG_CHECKPOINT类型的日志,则说明redo已经损坏,InnoDB会报错。

最多存在一次,那么会不会有不存在的情况?

答案是肯定的,在每次checkpoint过后,如果没有发生数据更新,那么MLOG_CHECKPOINT就不会被记录。所以只要查找下redo log最新一个checkpoint后的MLOG_CHECKPOINT是否存在,就能判定上次MySQL是否正常关机。

5.7版本的MySQL在InnoDB进行恢复的时候,也正是这样做的,MySQL5.7在进行恢复的时候,一般情况下需要进行最多3次的redo log扫描:

1、首先对redo log的扫描,主要是为了查找MLOG_CHECKPOINT,这里并不进行redo log的解析。如果你没有找到MLOG_CHECKPOINT,则说明InnoDB不需要进行recovery,后面的两次扫描可以省略;如果找到了MLOG_CHECKPOINT,则获取MLOG_FILE_NAME到指定列表,后续只需打开该链表中的表空间即可。

2、下一步的扫描是在第一次找到MLOG_CHECKPOINT基础之上进行的,该次扫描会把redo log解析到哈希表中,如果扫描完整个文件,哈希表还没有被填满,则不需要第三次扫描,直接进行recovery就结束。

3、最后是在第二次基础上进行的,第二次扫描把哈希表填满后,还有redo log剩余,则需要循环进行扫描,哈希表满后立即进行recovery,直到所有的redo log被apply完为止。

redo log全部被解析并且apply完成,整个InnoDB recovery的第一阶段也就结束了,在该阶段中,所有已经被记录到redo log但是没有完成数据刷盘的记录都被重新落盘。

然而,InnoDB单靠redo log的恢复是不够的,这样还是有可能会丢失数据(或者说造成主从数据不一致)。

因为在事务提交过程中,写binlog和写redo log提交是两个过程,写binlog在前而redo提交在后,如果MySQL写完binlog后,在redo提交之前发生了宕机,这样就会出现问题:binlog中已经包含了该条记录,而redo没有持久化。binlog已经落盘就意味着slave上可以apply该条数据,redo没有持久化则代表了master上该条数据并没有落盘,也不能通过redo进行恢复。

这样就造成了主从数据的不一致,换句话说主上丢失了部分数据,那么MySQL又是如何保证在这样的情况下,数据还是一致的?这就需要进行第二阶段恢复。

二、binlog和undo log共同参与

前面提到,在第二阶段恢复中,需要用到binlog和undo log,下面我们就来看下具体的恢复逻辑是怎样的?

其实该阶段的恢复中,也被划分成两部分:第一部分,根据binlog获取所有可能没有提交事务的xid列表;第二部分,根据undo中的信息构造所有未提交事务链表,最后通过上面两部分协调判断事务是否可以提交。

MySQL数据库意外掉线后数据该怎么恢复

(根据binlog获取xid列表)

如上图所示,MySQL在第二阶段恢复的时候,先会去读取最后一个binlog文件的所有event信息,然后把xid保存到一个列表中,然后进行第二部分的恢复,如下:

MySQL数据库意外掉线后数据该怎么恢复

(基于undo构造事务链表)

我们知道,InnoDB当前版本有128个回滚段,每个回滚段中保存了undo log的位置指针,通过扫描undo日志,我们可以构造出还未被提交的事务链表(存在于insert_undo_list和update_undo_lsit中的事务都是未被提交的),所以通过起始页(0,5)下的solt信息可以定位到回滚段,然后根据回滚段下的undo的slot定位到undo页,把所有的undo信息构建一个undo_list,然后通过undo_list再创建未提交事务链表trx_sys->trx_list。

基于上面两步, 我们已经构建了xid列表和未提交事务列表,那么在这些未提交事务列表中的事务,哪些需要被提交?哪些又该回滚?

判断条件很简单:凡是xid在通过binlog构建的xid列表中存在的事务,都需要被提交。换句话说,所有已经记录binlog的事务,需要被提交,而剩下那些没有记录binlog的事务,则需要被回滚

三、回顾优化

通过上述两个阶段的数据恢复,InnoDB才最终完成整个recovery过程,回过头来我们再想想,在上述两个阶段中,是否还有优化空间?比如第一阶段,在构造完哈希表后,事务的恢复是否可以并发进行?理论上每个hash node是根据(space,offset)生成的,不同的hash node之间不存在冲突,可以并行进行恢复。

或者在根据哈希表进行数据页读取时,每次读取连续32张页面,这里读取的32张页面,可能有部分是不需要的,也同时被读入到Buffer Pool中了,是否可以在构建一颗红黑树,根据(space,offset)组合键进行插入,这样如果需要恢复的时候,可以根据红黑树的排序原理,把所有页面的读取顺序化,并不需要读取额外的页面。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网数据库频道,感谢您对编程网的支持。

您可能感兴趣的文档:

--结束END--

本文标题: MySQL数据库意外掉线后数据该怎么恢复

本文链接: https://www.lsjlt.com/news/61281.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL数据库意外掉线后数据该怎么恢复
    MySQL数据库意外掉线后数据该怎么恢复,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。InnoDB如果发生意外宕机了,数据会丢...
    99+
    2022-10-18
  • 应该怎么样备份与恢复mysql数据库
    下文主要给大家带来应该怎么样备份与恢复mysql数据库,希望这些内容能够带给大家实际用处,这也是我编辑应该怎么样备份与恢复mysql数据库这篇文章的主要目的。好了,废话不多说,大家直接看下文吧。数据库备份方...
    99+
    2022-10-18
  • 怎么恢复MySQL数据库
    今天就跟大家聊聊有关怎么恢复MySQL数据库,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。数据库恢复是指以备份为基础,与备份相对应的系统维护和管理操...
    99+
    2022-10-18
  • gitlab删库后怎么恢复数据
    随着互联网的高速发展,开源项目的代码托管平台也越来越多,GitLab作为其中的佼佼者吸引了众多用户。然而,随着代码提交量的增多,GitLab也不时出现一些问题。尤其是删库事件,一旦发生,对于团队的影响不可估量。本文将重点介绍GitLab删库...
    99+
    2023-10-22
  • Mysql数据库delete删除后数据恢复报告
    数据库环境部署与故障原因: 本次恢复的数据库安装在客户本地服务器上,服务器操作系统为windows2008 r2 。在当前环境内安装有mysql5.6单实例,引擎类型为innodb,表内数据存储所使用表空间...
    99+
    2022-10-18
  • MySQL数据库怎么增量恢复数据
    本篇内容介绍了“MySQL数据库怎么增量恢复数据”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、场景概述...
    99+
    2022-10-18
  • 服务器硬盘掉线,重启后数据同步了怎么恢复
    【服务器数据恢复故障介绍】数据恢复中心近期接到客户服务器数据恢复案例并成功恢复,经客户许可后现将数据恢复过程分享给大家,下面简单介绍一下本次服务器数据恢复的故障情况。客户使用的是某品牌的服务器,搭配了多块硬盘组成一组raid5磁盘阵列,作为...
    99+
    2023-06-04
  • MySQL数据库误删除后如何恢复
    这篇文章将为大家详细讲解有关MySQL数据库误删除后如何恢复,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。首先,要确保mysql开启了binlog日志功能。...
    99+
    2022-10-18
  • MySQL数据库中怎么恢复误删除数据
    本篇文章为大家展示了MySQL数据库中怎么恢复误删除数据,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1. 找到binlog恢复数据的前提是必须开启Mysql的bi...
    99+
    2022-10-18
  • MySQL数据库InnoDB数据恢复工具怎么用
    小编给大家分享一下MySQL数据库InnoDB数据恢复工具怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一款开源的MySQ...
    99+
    2022-10-19
  • SQL Server数据库崩溃后怎么恢复
    这篇文章主要讲解了“SQL Server数据库崩溃后怎么恢复”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SQL Server数据库崩溃后怎么恢复”吧!任何...
    99+
    2022-10-18
  • MySQL数据怎么恢复
    这篇文章主要讲解了“MySQL数据怎么恢复”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL数据怎么恢复”吧!1、前言数据恢复的前提的做好备份,且开启...
    99+
    2022-10-18
  • 重装操作系统后mysql的数据库怎么恢复
    本篇内容主要讲解“重装操作系统后mysql的数据库怎么恢复”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“重装操作系统后mysql的数据库怎么恢复”吧!以carn...
    99+
    2022-10-18
  • Mysql误删除数据库怎么恢复
    这篇文章主要讲解了“Mysql误删除数据库怎么恢复”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Mysql误删除数据库怎么恢复”吧! ...
    99+
    2022-10-18
  • 怎么备份和恢复MySQL数据库
    这篇文章主要介绍“怎么备份和恢复MySQL数据库”,在日常操作中,相信很多人在怎么备份和恢复MySQL数据库问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么备份和恢复MyS...
    99+
    2022-10-18
  • 操作MySQL误删数据库备份该如何恢复
    下文主要给大家带来操作MySQL误删数据库备份该如何恢复,希望这些内容能够带给大家实际用处,这也是我编辑操作MySQL误删数据库备份该如何恢复这篇文章的主要目的。好了,废话不多说,大家直接看下文吧。&nbs...
    99+
    2022-10-18
  • mysql数据库误删除后的数据恢复操作过程是怎样的
    这篇文章给大家介绍mysql数据库误删除后的数据恢复操作过程是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。在日常运维工作中,对于mysql数据库的权限的规避,SQL审核优化、数...
    99+
    2022-10-18
  • sql数据库删除数据怎么恢复
    小编给大家分享一下sql数据库删除数据怎么恢复,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!SQL Server中误删除数据的恢复本来不是件难事,从事务日志恢复即可。但是,这个恢复需要有两个前...
    99+
    2022-10-18
  • 数据库数据误删除怎么恢复
    小编给大家分享一下数据库数据误删除怎么恢复,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!恢复数据库数据误删除的方法:首先运行Recovery for SQL Server,并在recover中...
    99+
    2022-10-18
  • Oracle数据库数据丢失怎么恢复
    这篇文章主要介绍“Oracle数据库数据丢失怎么恢复”,在日常操作中,相信很多人在Oracle数据库数据丢失怎么恢复问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Oracle...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作