•  

checkpoint 检查点

checkpoint,即检查点。在undolog中写入检查点,表示在checkpoint前的事务都已经完成commit或者rollback 了,也就是检查点前面的事务已经不存在数据一致性的问题了。那这个checkpoint如何去实现呢。其实实现的机制很简单,就是周期性的往 undolog里面写入。当然这个写入肯定不是随随便便的往里写,在往里写的时候,肯定要检查前面的事务是否完成。

这个时候就会带来一个问题,因为数据库是一直在运行的,也就是事务是在不断启动的,同时可能有n个事务已经处于开始状态。而在检查点往里写的时候,可能又有新的事务启动了,如果让检查点一直等到没有新的事务启动而且前面所有的事务又都提交过了估计很难,那基本检查点就不用往里写了。所以,在这种情况下,只能是在检查点往里写的时候,停止接受新事务,等待已启动的事务提交完毕,然后检查点写入完毕。然后继续接受新事务。类似于这样:例如,现在有T1 T2两个事务,则undolog中写入:

undolog
start T1
<T1,A,x>
start T2
<T2,B,y>

这时到了检查点的周期,要往里写入检查点了,就得等到T1,T2全部提交完毕,然后写入检查点chkpoint。也就是如果现在有一个T3要开启,是无法开启的。系统处于夯住状态。写入完后,开启T3,日志记录如下:

undolog
start T1
<T1,A,x>
start T2
<T2,B,y>
end T1
end T2
chkpoint
start T3

这时候,如果系统挂掉了,故障恢复管理器会从undolog的尾部向前进行扫描,扫描到checkpoint后,就不会往前扫描了,因为前面的事务都已经提交过了,不存在数据一致性问题。所以只需要从checkpoint开始重做即可。

这样固然是好,省掉了需要undolog从头开始扫描的麻烦,但是这样做的缺点也很明显,那就是在写入checkpoint的过程中,系统是出于夯住状态的,所有的写入都要暂停。那能否有一种更好的方法既可以写入checkpoint又不需要系统暂停呢,必须的,当然有,这就是下面要讲的非静态检查点。

非静态检查点

非静态检查点是相对于静态检查点而来的,上文中所提到的就属于静态检查点,因为在检查点写入的同时,系统是不能写入的。而非静态检查点的引入,就是要解决这个问题。

非静态检查点的策略是在写入chkpoint的同时,会记录下当前活跃的事务。比如,当前状态下,T1和T2都是活跃状态,那么undolog中会被写入start checkpoint(T1,T2),这时整体系统仍然是正常写入的,也就是说在这条log写入后,仍然可以继续开启其他事务。当T1,T2完成后,会写入end checkpoint的记录。例如如下记录:

undolog
start T1
<T1,A,x>
start T2
<T2,B,y>
start checkpoint(T1,T2)
start T3
end T1
end T2
end chkpoint
start checkpoint(T3)
end T3
end chkpoint

上面这个日志记录就是,在T1,T2开始后,undolog中写入了start checkpoint(T1,T2)的检查点,而这时仍然是可以接受其他事务的开始的,这时有了T3事务的开启。

通过这种机制,可以有效避免在检查点写入时需要停掉服务的弊端,但现在问题又来了,这样写检查点固然是好,但恢复管理器如何通过这样的 undolog去进行数据恢复操作呢?因为,如果检查点是静止的,那找到checkpoint后,就不必再往前找了,而现在不一样了,因为找到end checkpoint后,前面仍可能有未完成的事务,那这时数据恢复是如何恢复的呢?

在这种情况下,数据库宕机后,恢复管理器仍然会从尾往前进行扫描undolog,如果遇到了“end chkpoint”,这时并不代表checkpoint前所有的事务都已经提交了,但我们可以知道,所有未提交的事务都是在上一个start checkpoint之后,所以会继续往前找,一直找到start checkpoint,找到start checkpoint后,比如是start checkpoint(T1,T2),因为先前已经找到了end chkpoint,所以T1,T2这两个事务已经可以保证数据一致性了,需要重做的就是在start checpoint(T1,T2)到end chkpoint间的这一些非T1,T2事务,这些是需要重做的,所以要把这些进行重做。

还有另外一种情况,就是恢复管理器在扫描时,先遇到了start checkpoint(T1,T2)的日志,在这种情况下,我们首先知道了T1,T2或许是未完成的事务,那这时需要在start checkpoint之后找到是否有某个事务的end语句,如果有,说明这个事务是完成了,如果没有,就说明没有完成,那就要从check point再往后寻找,找到这个事务的start,然后从start之后往后重做。说得比较罗嗦,我们上个例子来说明下这种情况。

例如,数据库宕机后,开始扫描undolog,得到以下片段:

undolog
start T1
<T1,A,15>
start T2
<T2,B,39>
start checkpoint(T1,T2)
start T3
<T3,C,40>
end T1
<T3,C,50>

这时,恢复管理器拿到这个片段后进行扫描,在遇到end chkpoint前遇到了start checkpoint(T1,T2),这说明了,T1,T2是可能未完成事务的,而且在这之前还遇到了T3的start,没有end T3,也没有任何T3的检查点的开始,这说明了T3一定是未完成事务的,所以T3一定是要重做的。先前为什么说T1,T2是可能未完成事务的呢?因为遇到了start checkpoint(T1,T2),没有遇到end chkpoint,并不代表T1和T2就一定是未完成的,可能有一个已经commit过了,因为两个都没有commit,所以才导致了没有end chkpoint,所以这时找start下面的日志,发现了“end T1”,说明了T1的事务是已经完成了的。那只需要找T2的开启然后开始重做就可以了,然后就通过start checkpoint(T1,T2)再往上找,找到了start T2,然后开始重做T2,也就是这个日志里,T2和T3是需要重做的,然后重做掉。 (注:刚才先说了做T3,然后有说了重做T2,并不代表真正的顺序就是这样,实际上恢复管理器是先分析出需要重做的事务,然后一块做掉的。)

数据库事务故障恢复undo日志检查点的更多相关文章

  1. 理解数据库中的undo日志、redo日志、检查点

    数据库存放数据的文件,本文称其为data file. 数据库的内容在内存里是有缓存的,这里命名为db buffer.某次操作,我们取了数据库某表格中的数据,这个数据会在内存中缓存一些时间.对这个数据的 ...

  2. 数据库中的undo日志、redo日志

    MySQL中有六种日志文件,分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志(errorlog).慢查询日志(slow query log).一 ...

  3. undo日志

    InnoDB’s Undo 前言 Undo log是InnoDB MVCC事务特性的重要组成部分.当我们对记录做了变更操作时就会产生undo记录,Undo记录默认被记录到系统表空间(ibdata)中, ...

  4. (转)对SQLSERVER数据库事务日志的疑问

    本文转载自桦仔的博客http://www.cnblogs.com/lyhabc/archive/2013/06/10/3130856.html 对SQLSERVER数据库事务日志的疑问 摸不透SQLS ...

  5. mysql事务、redo日志、undo日志、checkpoint详解

    转载: https://zhuanlan.zhihu.com/p/34650908 事务: 说起mysql innodb存储引擎的事务,首先想到就是ACID(不知道的请google),数据库是如何做到 ...

  6. 数据库篇:mysql日志类型之 redo、undo、binlog

    前言 可以说mysql的多数特性都是围绕日志文件实现,而其中最重要的有以下三种 redo 日志 undo 日志 binlog 日志 关注公众号,一起交流:微信搜一搜: 潜行前行 1 redo日志 in ...

  7. Mysql数据库的用户和日志管理

    Mysql数据库的用户和日志管理 数据库的用户管理 1.mysql用户账号管理 用户账号 user@host user:账户名称 host:此账户可通过哪些客户端主机请求创建连接线程,可以是ip.主机 ...

  8. MySQL 数据库事务与复制

    好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适. 最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类. 结合实际工作中碰到的问题,以寻找答案的方式 ...

  9. Atitit 数据库事务实现原理

    Atitit 数据库事务实现原理   1.1. 自己在程序中实现事务操作. 如果只是需要事务的话,你自己给mongo操作加上事务功能就可以啦..数据库事务只不过是他自己实现了而已..如果数据库不支持事 ...

随机推荐

  1. Javascript中的Bind 、Call和Apply

    看以下代码: var bind = Function.prototype.call.bind(Function.prototype.bind); 第一眼看上去,我能猜出它究竟是用来做什么的.它把x.y ...

  2. C++ 学习基础一

    1.预处理器指示符如果文件名用尖括号“<”和”>”括起来的,则表示该文件是工程或标准头文件,查找过程会检查预定义的目录.如果文件名用双引号括起来,则表示该文件是用户自定义的头文件,查找该文 ...

  3. 001MSP430概述

    1.MSP430系列单片机的特点 (1)超低功耗:生来就是为超低功耗设计的,从CPU内核结构到片上外设,以及整个芯片的生产制造都是本着超低功耗的原则来进行的,所以是一款实实在在的超低功耗单片机: (2 ...

  4. Solaris的vi

    进入输入模式i: 在光标之前插入a: 在光标之后插入o: 在下面新建一行输入I: 光标移动到本行首插入A: 光标移动到本行末尾插入O: 在上面新建一行输入 移动光标M:移到屏幕中间一行的行首L:移到屏 ...

  5. css style与class之间的区别,cssclass

    问题描述:    网页点击[导出]按钮后,将页面table内容另存成excel文件,却发现无法保存表格样式 分析过程: 1.table表格用class,而不是style.导出时并没有导出class定义 ...

  6. 第一章:1-06、 试将TCP/IP和OSI的体系结构进行比较。讨论其异同之处?

    <计算机网络>谢希仁著第四版课后习题答案答:(1)OSI和TCP/IP的相同点是二者均采用层次结构,而且都是按功能分层.(2)OSI和TCP/IP的不同点:①OSI分七层,自下而上分为物理 ...

  7. PHP基础笔记汇总

    一.PHP简介PHP:超文本预处理器(译者注:PHP: Hypertext Preprocessor,递归命名)PHP 是一种服务器端的脚本语言,类似 ASPPHP 文件的文件后缀是 ".p ...

  8. pos机抹零功能

    抹零功能设置包括抹分-0.抹角-1.抹元-2. 前台界面和逻辑代码如下 //抹零设置 2016/8/16 QT if (sweepCents.Checked==true) { BusinessClas ...

  9. 史上最全Vim快捷键键位图(入门到进阶)

    经典版 下面这个键位图应该是大家最常看见的经典版了. 对应的简体中文版 其实经典版是一系列的入门教程键位图的组合结果,下面是不同编辑模式下的键位图. 入门版 基本操作的入门版. 进阶版 增强版 下图是 ...

  10. excute和query

    query(update goods set is_delete=1 where goods_id=13)总是出错??为什么, excute(update goods set is_delete=1 ...