•  

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. 加链接太麻烦?使用 linkit 模块提升用户编辑体验

    在制作网站内容时,适当地添加链接会非常用利于网站内容的SEO.加入链接的文章可以让访客了解到更多相关内容,从而提升文章的质量.被链接到的内容也能因此获得更多的访问和关注.只不过,在内容编辑时添加链接却 ...

  2. fastCGI (二)各方优劣

    1. 克服 CGI 的瓶颈 1.1 令人头痛的效率问题 拜 CGI 之赐,网站不再只有固定不变的图形和文字,藉由程序动态产生的网页可以让网站好象『活』了起来.小从简单的网页计数器,留言版,大至处理众多 ...

  3. number对象,bom对象

    number对象 新创建一个number的对象,toFixed是精确到位数 var num =new Number('123.1231'); console.log(num.toFixed(1)); ...

  4. C++临时变量的生命周期

    C++ 中的临时变量指的是那些由编译器根据需要在栈上产生的,没有名字的变量.主要的用途主要有两类: 1) 函数的返回值, 如: string proc() { return string(" ...

  5. TCP/IP详解学习笔记(2)-- 数据链路层

    1.概述      数据链路层属于计算机网络的底层,使用的信道主要有点对点信道和广播信道两种类型.      在TCP/IP协议族中,数据链路层主要有三个目的:           1)为IP模块发送 ...

  6. MVC 百度地图的基本使用

    最近做的这个项目里面为了方便路线查询,将百度地图的插件加到了项目里,效果图如下: 下面我就把我的步骤贴出来: 第一步:进网站 http://developer.baidu.com/map/注册 第二步 ...

  7. 【Linux】基于Bind_DLZ和MySQL数据的DNS搭建

    参考:http://www.linuxfromscratch.org/blfs/view/cvs/server/bind.html 参考:http://bind-dlz.sourceforge.net ...

  8. Java 单测 回滚

    Java 在单测的时候 需要做回滚 设置如下: 需要添加以下 注解 在类上 defaultRollback = true : 为 默认全部回滚 defaultRollback = false : 为 ...

  9. Linux之通配符与转义字符

    通配符: *:代表任意字符,可以为空字符 ?:代表一个字符,不可以为空字符 转义字符: \

  10. SVN创建资源与分支详解

    创建分支的意义: 简单说,分支就是用于区分开发版本与当前发布版本的. 1. 主干负责新功能的开发 2..分支负责修正当前发布版本的bug(对于可以放入下个发布版本的改进性bug可以直接在主干上开发) ...