MySQL数据库如何应对故障恢复与数据恢复回滚

一个最基本的数据库,应当可以做到以下几点

  • 数据持久化,可以将数据保存到磁盘,服务重启数据依然存在。

  • 可以按照某种关系存储数据,如果你用过IO流,那么你会发现整理数据也是一件复杂的事情。我是该追加写呢还是找到某条数据位置再进行写呢?这是个很复杂的问题。

  • 快速查找。你想想自己如果将数据写入txt,那又如何高效的去找到某条数据?支持随机查找吗?

  • 故障恢复与数据回滚,倘若你的服务断电了,如何确保数据一定是写入到文件的?若是误删或误改了某条数据,你又如何进行恢复?

MySQL的架构

关于MySQL的简单架构图。

图片

MySQL大致可以分为服务层与存储引擎层。在单独抽离了存储引擎层后,你可以选择合适的引擎,例如InnoDb,MyIsam,Memory等等。

关于不同的存储引擎,使用的方式可能不同。我主要想讲的是InnoDb引擎,MySQL 5.5 版本后默认的存储引擎。

MySQL的日志系统

MySQL有三大日志,分别是重做日志(redo log),二进制日志(bin log),以及回滚日志(undo log)。这三个日志非常重要,学习MySQL数据库一定免不了要和他们打交道。

bin log

bin log是Server层的日志,无论使用的是什么引擎,都可以使用这种日志。这个日志记录的是逻辑日志,就是SQL语句。例如insert into table set xx = xx 在bin log中记录的也是这样的一条SQL。而且bin log 采用的是追加写的形式,也即是说在写完一个bin log文件之后,不会覆盖前面的,而是新开一个文件继续追加写。

redo log

redo log 是存储引擎InnoDB所提供的日志模块。个日志记录的是,物理日志。记录的是当前SQL在哪一个数据页上将什么数据修改为了什么数据。

关于redo log,我很喜欢林晓斌老师在《MySQL实战45讲》中讲的例子,酒馆的账本与黑板的例子。在古时候的酒馆中,老板会有一本账本,以及身后的一块黑板。倘若今天有人去喝酒,赊账。在很忙的时候,老板会将这条记录写在黑板上,后续等到酒馆打烊了,不忙的时候,才将这个记录写进自己的账本中。

事实上,在MySQL也是这么做的,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。

而黑板和账本配合的整个过程,其实就是 MySQL中常说到的 WAL (Write-Ahead Logging)技术,WAL 的全称是 ,它的关键点就是先写日志,再写磁盘,也就是先写黑板,等不忙的时候再写账本。

具体来说,当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log(黑板)里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做,这就像酒馆打烊之后老板做的事。

如果今天赊账的不多,掌柜可以等打烊后再整理。但如果某天赊账的特别多,黑板写满了,又怎么办呢?这个时候掌柜只好放下手中的活儿,把粉板中的一部分赊账记录更新到账本中,然后把这些记录从粉板上擦掉,为记新账腾出空间。

与此类似,InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么这块“黑板”总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写,如下面这个图所示。

图片

write pos 是当前记录的位置,一边写一边后移。checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

write pos 和 checkpoint 之间的是“黑板”上还空着的部分,可以用来记录新的操作。如果 write pos 追上 check point,表示“黑板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。

有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe。

要理解 crash-safe 这个概念,可以想想我们前面赊账记录的例子。只要赊账记录记在了粉板上或写在了账本上,之后即使掌柜忘记了,比如突然停业几天,恢复生意后依然可以通过账本和粉板上的数据明确赊账账目。

undo log

undo log 记录的是与执行SQL相反的SQL。例如,在user表,id为1的用户age为32,那么执行update table user set age = 45 where id = 1,那么undo log中则会记录update table user set age = 32 where id = 1,如果执行的是delete语句,那么相应的,它会记录一条insert语句。

undo log是MySQL用于事务模块的重要日志,其中的MVCC(多版本并发控制技术)就与undo log版本链强相关。这篇文章重点不在此,因此不再多说。

MySQL如何做数据恢复

假如在今天的12点钟,你误删了一个表。这种情况下该怎么恢复数据?首先,在使用MySQL时,通常会对其进行全量备份。一般是一天、三天或每周一次。

  • 那么此时应当找到最近的一次全量备份放入临时库中。

  • 找到从全量备份的那一刻开始,将bin log重放到误操作今天的12点钟。

  • 如此你便拿到了误操作之前的数据,此时你可以将临时库中的数据按需要恢复回去。

MySQL如何做到故障恢复?(Crash-Safe的能力)

在InnoDB引擎下,MySQL支持事务。因此故障恢复还需要考虑到已提交的数据与未提交的数据。单独靠bin log 或 redo log 是无法保证crash-safe的。

两阶段提交

一条update语句的简单执行过程

我们再来看执行器和 InnoDB 引擎在执行这个简单的 update 语句时的内部流程。

  1. 执行器先找向存储引擎找到 id = 1 这一行。id 作为主键,存储引擎直接用B+树搜索找到这一行。如果id=1 这行所在的数据页已经在内存中,就直接返回给执行器;否则就先从磁盘读入内存中,再返回。

  2. 执行器拿到存储引擎给的行数据,把这个值加上 1,比如原来是 n,现在为 n+1,得到了一行新的数据,再调用存储引擎的接口写入这一行新的数据。

  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。

  4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。

  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交commit状态。

图片

最后三步看起来有点复杂,InnoDB将 redo log 的写入分为了两个步骤:prepare阶段和commit阶段,这就是两阶段提交

图中白色框表示是在 InnoDB引擎内部执行的,绿色框表示的是在执行器中执行的。

为什么日志需要“两阶段提交”。

由于 redo log 与 bin log 是两个层单独的日志,如果不采用两阶段提交的方式,要么是先写 redo log 再写 bin log,或采用反的顺序。

下面看看这两种方式会出现什么问题。

仍然使用用前面的 update 语句来做例子。假设当前 id=1 的行,字段 a 的值是 0,再假设执行 update 语句过程中在写完第一个日志后,第二个日志还没有写完期间发生了 crash,会出现什么情况呢?

  1. 先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 a 的值是 1。但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 a 的值就是 0,与原库的值不同。

  2. 先写 binlog 后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 a 的值是 0。但是 binlog 里面已经记录了 “把 a 从 0 改成 1” 这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这一行 a 的值就是 1,与原库的值不同。

可以看到,如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。

简单说,redo log 和 binlog 都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。

总结

学习了挺久的MySQL,突然又对其的数据恢复和故障恢复起了兴趣,往深入了解又发现了之前一些之前无法理解的问题突然迎刃而解了。

  • MySQL的数据恢复与故障恢复依赖着几个日志,bin log 与 redo log。bin log 是逻辑日志,记录的是原始SQL语句,redo log 是InnoDB引擎支持的,是物理日志,记录了在哪个数据页修改了哪些数据,并且redo log 是循环写日志。

  • MySQL需要按照一定时间进行全量备份,这样我们可以依靠最近一次全量备份点,以及从该点开始记录的bin log进行数据重放恢复

  • MySQL在使用了InnoDB引擎后,支持了事务,因此故障恢复需要确保可以区分已提交事务与未提交事务。这个依赖于redo log 的二阶段提交。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/233663.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为工业企业介绍新版 PT ISIM

🏭 我们发布了新版 PT Industrial Security Incident Manager - 4.4,这是一款深度流程流量分析系统。 以下是主要变化的简要概述 🖥 新增 microView Sensor 它安装在紧凑型工业 PC 上,设计用于小型自动化设施:6-10 …

Linux系统的常见命令十一,文本编辑器(vi和vim)

目录 vi命令vim命令vi命令与vim命令的区别 本文主要介绍Linux系统的文本编辑器命令vi和vim,还有它们之间的区别。 vi命令 vi是Linux和其他类Unix操作系统中最常用的文本编辑器之一,它的功能强大且灵活,可以通过键盘快捷键来完成大量的编辑操…

Electron+Ts+Vue+Vite桌面应用系列:TypeScript常用语法详解

文章目录 1️⃣ TypeScript常用讲解1.1 使用1.2 字符串1.3 数字1.3 布尔1.4 数组1.5 元组1.6 枚举1.7 any1.8 void1.9 object1.10 函数指定返回值的类型1.11 联合类型1.12 类型断言1.13 接口1.14 函数类型1.15 类类型1.16 泛型 2️⃣ 类2.1 类的基本写法2.2 类的继承2.3 类的修…

探索使用Quarkus和MicroProfile 构建Kubernetes原生微服务的秘诀!

Kubernetes Native Microservices with Quarkus and MicroProfile 是一个基于Kubernetes原生微服务的开发框架,它结合了Quarkus和MicroProfile的优点,提供了一个高效、可扩展、易于管理的微服务解决方案。 Quarkus是一个针对Java虚拟机(JVM&…

S32DS的project explore窗口怎么打开?

1.选择Window->Show View->Other 2.选择General->project explore 就可以啦!

【Openstack Train安装】六、Keystone安装

OpenStack是一个云计算平台的项目,其中Keystone是一个身份认证服务组件,它提供了认证、授权和目录的服务。其他OpenStack服务组件都需要使用Keystone来验证用户的身份和权限,并且彼此之间需要相互协作。当一个OpenStack服务组件接收到用户的请…

电源适配器测试要求是什么?电源自动化测试系统如何助力测试?

电源适配器又叫外置电源,是一种小型便携式电子设备及电子电器的供电电源变换设备,它可以将交流电转换为设备所需的直流电,常见于手机、笔记本电脑、路由器、灯条等小型电子产品上。 为了保证电源适配器的质量,确保其可以为电子设备…

atmega16单片

今天主要给大家介绍一下ATmega16,ATmega16是基于增强的AVR RISC结构的低功耗8 位CMOS微控制器。由于其先进的指令集以及单时钟周期指令执行时间,ATmega16 的数据吞吐率高达1 MIPS/MHz,从而可以减缓系统在功耗和处理速度之间的矛盾。 从市场角…

认证鉴权方案

现在一般使用比较多的认证方式有四种: SessionTokenSSO单点登录OAtuth登录1.Cookie + Session 最常见的就是 Cookie + Session 认证。 Session,是一种有状态的会话管理机制,其目的就是为了解决HTTP无状态请求带来的问题。 当用户登录认证请求通过时,服务端会将用户的信息存…

【Openstack Train安装】七、glance安装

Glance是为虚拟机的创建提供镜像的服务,我们基于Openstack是构建基本的IaaS平台对外提供虚拟机,而虚拟机在创建时必须为选择需要安装的操作系统,Glance服务就是为该选择提供不同的操作系统镜像。Glance提供Restful API可以查询虚拟机镜像的me…

海光信息荣获ESG金牛科技引领奖!

11月24日,由中国证券报、中国国新控股有限责任公司、南通市人民政府联合主办的”2023金牛企业可持续发展论坛暨第一届国新杯ESG金牛奖颁奖典礼”在江苏南通举行,“国新杯ESG金牛奖”多项获奖名单同期揭晓。海光信息凭借卓越的技术创新实力与行业影响力&a…

SAP 如何检查已安装的SAP UI5 版本

第一个方法是直接从FLP中查看 但是部分高版本的FLP中没有这个about, 那么在当前界面可以使用:CTRL ALT SHIFT S 查看当前版本 根据此版本,去进行你的UI5的开发吧