数据库系统知识总结(六):事务、并发控制与故障恢复

六、事务、并发控制与故障恢复

1、事务的ACID特性

所谓事务就是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。

- 原子性

原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。

- 一致性

一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务开始前是一个一致状态,事务结束后是另一个一致状态,事务将数据库从一个一致状态转移到另一个一致状态。

- 隔离性

从字面上来说,独立性是其中最难理解的一点,但如果结合Oracle中的undo,也就不难理解了。所谓的独立性就是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务还未提交,它所访问的数据就不受未提交事务的影响。换句话说,一个事务的影响在该事务提交前对其它事务是不可见的。

注意:这里的Isolation跟隔离级别(Isolation Level)是无关的。

- 持续性

持久性也不难理解,是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
这个大神

2、数据库系统的几种故障及其恢复方式

- 事务内部的故障

事务内部故障可分为预期的和非预期的,其中大部分的故障都是非预期的。预期的事务内部故障是指可以通过事务程序本身发现的事务内部故障; 非预期的事务内部故障是不能由事务程序处理的,如运算溢出故障、并发事务死锁故障、违反了某些完整性限制而导致的故障等。

在不影响其他事务运行的情况下,强行回滚该事务,即撤销该事务已经做出的任何对数据库的修改,使得该事务好像根本没有启动一样。这类恢复操作称为事务撤销

- 系统故障

系统故障也称为软故障,是指数据库在运行过程中,由于硬件故障、数据库软件及操作系统的漏洞、突然停电灯情况,导致系统停止运转,所有正在运行的事务以非正常方式终止,需要系统重新启动的一类故障。这类事务不破坏数据库,但是影响正在运行的所有事务。

待计算机重新启动之后,对于未完成的事务可能写入数据库的内容,回滚所有未完成的事务写的结果;对于已完成的事务可能部分或全部留在缓冲区的结果,需要重做所有已提交的事务(即撤销所有未提交的事务,重做所有已提交的事务)。

- 介质故障

介质故障也称为硬故障,主要指数据库在运行过程中,由于磁头碰撞、磁盘损坏、强磁干扰、天灾人祸等情况,使得数据库中的数据部分或全部丢失的一类故障。

介质故障的软件容错:使用数据库备份及事务日志文件,通过恢复技术,恢复数据库到备份结束时的状态。
介质故障的硬件容错:采用双物理存储设备,使两个硬盘存储内容相同,当其中一个硬盘出现故障时,及时使用另一个备份硬盘。

- 计算机病毒故障

计算机病毒故障是一种恶意的计算机程序,它可以像病毒一样繁殖和传播,在对计算机系统造成破坏的同时也可能对数据库系统造成破坏(破坏方式以数据库文件为主) 。

使用防火墙软件防止病毒侵入,对于已感染病毒的数据库文件,使用杀毒软件进行查杀,如果杀毒软件杀毒失败,此时只能用数据库备份文件,以软件容错的方式恢复数据库文件。

3、具有检查点的恢复技术

在日志文件中增加一类新的记录——检查点记录,增加一个重新开始文件,并让恢复子系统在登陆日志文件期间动态地维护日志。

检查点记录的内容包括

  • 建立检查点时刻所有正在执行的事务清单
  • 这些事务最近一个日志记录的地址

周期性地执行建立检查点、保存数据库状态的操作

- 动态维护日志文件的步骤包括

  1. 将当前日志缓冲中的所有日志记录写入磁盘的日志文件上
  2. 在日志文件中写入一个检查点记录
  3. 将当前数据缓冲的所有数据记录写入磁盘的数据库中
  4. 把检查点记录在日志文件中的地址写入一个“重新开始文件”

- 系统使用检查点方法进行恢复的步骤是

  1. 从重新开始文件(见第11题的图)中找到最后一个检查点记录在日志文件中的地址,由该地址在日志文件中找到最后一个检查点记录。
  2. 由该检查点记录得到检查点建立时刻所有正在执行的事务清单ACTIVE一LIST。
    这里建立两个事务队列:
  • UNDO一LIST:需要执行undo操作的事务集合;
  • REDO一LIST:需要执行redo操作的事务集合。
    把ACTIVE一LIST暂时放入UNDO一LIST队列,REDO队列暂为空。
  1. 从检查点开始正向扫描日志文件:
    ①如有新开始的事务T*,把T*暂时放入UNDO一LIST队列;
    ②如有提交的事务毛,把毛从UNDO一LIST队列移到REDO一LIST队列,直到日志文件结束;
  2. 对UNDO一LIST中的每个事务执行UNDO操作,对REDO一LIST中的每个事务执行REDO操作。

UNDO 撤销 ,REDO重做

4、并发操作可能产生的三种数据不一致性

数据库系统知识总结(六):事务、并发控制与故障恢复
事务是并发操作的基本单位

- 丢失修改

两个事务T1和T2读入同一个数据并修改,T2提交的结果破坏了T1提交的结果,导致了T1的修改被丢失。典型例子:买飞机票或者火车票的例子,一个航班100张票,两个窗口同时卖,结果写进数据库本来是98张,可是是99张,只减少了1张。

- 不可重复读

不可重复读指的是事务T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取的结果。
分为以下三种情况:

  1. 事务T1读取了某一数据后,事务T2对其做了修改,当事务T1再次读数据时,得到了与前一次不同的值。
  2. 事务T1读取了某一数据后,事务T2删除了其中的记录,当事务T1再次读数据时,发现某些记录神秘消失了。
  3. 事务T1读取了某一数据后,事务T2插入了一些新的记录,当事务T1再次读数据时,发现多了一些记录。
    后两种操作叫做幻影现象。

- 读“脏”数据

读“脏”数据只得是事务T1修改了某一数据,并将其写回磁盘,事务T2读取某一数据后,T1由于某种原因撤销了操作,恢复原值,这时T2读到的数据就和数据库中的数据不一致,称为读“脏”数据。
数据库系统知识总结(六):事务、并发控制与故障恢复产生以上三种现象的原因是并发操作破坏了事务的隔离性。为了应对这些数据不一致性,主要技术主要有:封锁,时间戳,乐观控制法。

5、X锁、S锁、封锁协议

封锁就是并发控制的一个非常重要的技术。
基本的封锁分两种:排他锁(简称X锁)和共享锁(简称S锁)

- 排他锁

排他锁又称为锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。

- 共享锁

共享锁又称为锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。
数据库系统知识总结(六):事务、并发控制与故障恢复

- 封锁协议

1 一级封锁协议

一级封锁协议是指,事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。

一级封锁协议可以防止丢失修改,并保证事务T是可恢复的。

2 二级封锁协议

二级封锁协议是指,在一级封锁协议基础上增加事务T在读数据R之前必须先对其加S锁,读完后即可释放S锁。

二级封锁协议出防止了丢失修改,还可以进一步防止读“脏”数据。

3 三级封锁协议

三级封锁协议是指,在一级封锁协议的基础上增加事务T在读数据R之前必须先对其加S锁,直到事务结束才释放。

三级封锁协议出防止了丢失修改和读“脏”数据外,还可以进一步防止了不可重复读。
数据库系统知识总结(六):事务、并发控制与故障恢复
数据库系统知识总结(六):事务、并发控制与故障恢复

6、活锁、死锁

- 活锁

如果事务T1封锁了数据R,事务T2又请求封锁R,于是T2等待。T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待。然后T4又请求封锁R,当T3释放了R上的封锁之后系统又批准了T4的请求,…,T2有可能永远等待,这就是活锁的情形。

避免活锁的简单方法是采用先来先服务的策略。

- 死锁

如果事务T1封锁了数据R1,T2封锁了数据R2,然后T1又请求封锁R2,因T2已封锁了R2,于是T1等待T2释放R2上的锁。接着T2又申请封锁R1,因T1已封锁了R1,T2也只能等待T1释放R1上的锁。这样就出现了T1在等待T2,而T2又在等待T1的局面,T1和T2两个事务永远不能结束,形成死锁。
数据库系统知识总结(六):事务、并发控制与故障恢复
详细

7、可串行性并发调度

- 可串行化调度

多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行它们时的结果相同,我们称这种调度策略为可串行化(Serializable)的调度。

可串行性(Serializability)是并发事务正确性的准则。按这个准则规定,一个给定的并发调度,当且仅当它是可串行化的,才认为是正确调度。

比如,两个事务的并发调度的某一执行方式,与先执行T1后执行T2(或先执行T2后执行T1)的结果是一样的,称这一调度符合可串行化调度。

- 冲突可串行化调度

冲突操作是指不同的事务对同一个数据的读写操作和写写操作
有些冲突操作是可以交换次序的,有些冲突操作不能交换次序。
一个调度能将冲突的操作调节成类似串行化的操作,就是改变事务操作顺序。

8、两段锁协议

两段锁协议规定所有的事务应遵守的规则:

① 在对任何数据进行读、写操作之前,首先要申请并获得对该数据的封锁。
② 在释放一个封锁之后,事务不再申请和获得其它任何封锁。

即事务的执行分为两个阶段:

第一阶段是获得封锁的阶段,称为扩展阶段。
第二阶段是释放封锁的阶段,称为收缩阶段。

作者:Mat的学习过程
来源:****
原文:https://blog.****.net/aigoogle/article/details/25804285
版权声明:本文为博主原创文章,转载请附上博文链接!

9、封锁粒度

封锁对象的大小称为封锁粒度

讲的不错