文章目录
概述
- 事务管理:恢复、并发控制
- 恢复:保证事务在发生故障时满足ACID准则
- 并发控制:保证事务在并发执行时满足ACID标准
恢复引论
- 解决故障的措施:提高可靠性、恢复
- 恢复技术:恢复数据库到一致状态
- 数据丢失:用后备副本,可能会造成冗余
- 分离:
- 单纯以后备副本为基础的恢复技术
- 以后备副本和运行记录为基础的恢复
- 基于多副本的恢复技术
单纯以后备副本为基础的恢复技术
-
从文件系统继承而来,周期性的把磁盘上的数据库转储(dump)到脱机存放的磁带上
- 缩短周期?理论可行,实际不行。因为周期压的太短,会导致数据库只进行取副本操作而无法完成正常的事务
- 解决:增量转储
-
增量转储:只存储上次存储之后已经改变了的信息
-
优点:实现简单,不增加数据库正常运行时的开销
-
缺点:不能恢复到数据库的最近一致的状态
-
适用于文件系统以及小型的不重要的数据库系统。
-
以后备副本和运行记录为基础的恢复
-
运行记录:log, 也叫journal,由系统维护,一般包括前像、后像、事务状态
-
前像:
- 物理块更新前的映像
- 以块为单位
- 撤销undo:使数据库恢复到更新前的状态
-
后像
- 物理块更新后的映像
- 以块为单位
- 重做redo:使数据库恢复到更新之后的状态
-
前像后像和事务的关系
前像 后像 修改 有 有 插入 无 有 删除 有 无 -
事务状态:记录每个事物的状态,便于在恢复时做不同的处理
- 提交(commit):事务成功执行
- 回卷(rollback):消除事务对数据库的影响
- 至少要区分事务是否提交
-
实现方法:去除最近后备副本,根据运行记录
- 未提交:前像回卷,向后恢复,做undo
- 已提交:后像重做,向前恢复,做redo
基于多副本的恢复技术
-
利用具有独立失效模式的多个副本互为备份,多用于分布式系统
-
写数据时,两个磁盘写入相同内容
-
镜像磁盘系统
运行记录的结构
- 存储要点:避免与数据库一起被损坏
- 运行记录(log)一般不能和数据库放在同一磁盘上
- log基本内容
- 活动记录表ATL: 记录所有正在执行,尚未提交的事务的标识符(transaction identifier—TID)。
- 提交事务表CTL: 记录所有已提交事务的标识符。
- 提交时,先将要提交事务的TID加入CTL,再从ATL中删除相应的TID。否则,一旦发生故障,该事务的状态将丢失
- 前像文件:
- 可以看成一个堆文件。
- 每个物理块有个块标识符BID(block identifier)
- BID由TID、关系名和逻辑块号组成。逻辑块号在关系中是唯一的。
- 如果一个事务需要卷回,可以在前像文件中找出该事务的所有前像块,按照逻辑块号写入到关系的对应块,从而消除该事务对数据库的影响。
- undo满足幂等律
- 后像文件:
- 结构与前像文件类似
- 在恢复时,可按提交事务表中的事务次序,按逻辑块号,写入其后像。这相当于按提交的次序重做各个事务。
- redo满足幂等律
- log文件规模减小
- 不保留已提交事务的前像
- 有选择的保留后像
- 合并后像:对给定逻辑块号的物理块,如多次更新,可只保留最近的后像
更新事务的执行与恢复
规则
-
提交规则: 后像必须在事务提交前,写入非易失性存储器(DB或log)。
-
先记后写(LAR):如果后像在事务提交前写入数据库,则必须把前像先写入log
策略
-
后像在事务提交前完全写入DB
TID →active list B.I →Log (按Log Ahead Rule) A.I →DB ┇ TID →commit list delete TID from active list
commit list active list operation 1 undo(还没有提交) 1 1 从ATL中删除TID(已完成事务) 1 nothing(已完成事务提交及之后的任务) -
后像在事务提交后写入数据库
TID →active list A.I →Log (按commit rule) ┇ TID →commit list A.I →DB delete TID from active list
commit list active list operation 1 从ATL表中删除TID 1 1 redo, 从ATL表中删除TID 1 nothing -
后像在事务提交前后写入数据库
TID →active list A.I, B.I →Log (按2 rules) A.I →DB (partially done) ┇ TID →commit list A.I →DB (completed) delete TID from active list
commit list active list operation 1 undo 1 1 redo, 从ATL中删除TID 1 nothing - 有利于磁盘负载均衡
消息处理
-
message:事务给用户发送的有影响的消息
-
在事务结束前,消息不能发出,只有等事务结束后才能发出
-
消息发送委托消息管理(message manager–MM)子系统执行:为每个事务建立消息队列
- 事务正常结束前,允许事务增加和删除;
- 一旦事务结束,MM就把消息存于不易失存储器中
- 当事务正常结束时(包括提交和回卷),事务通知MM发送消息
- 当事务因故障被撤销时,MM将把该事务的消息丢弃
-
MM采用“发送-确认”机制
失效类型及恢复对策
事务失效
- 事务由于不可预知的原因而夭折
- 事务失效时DB未被破坏,系统控制在手
- 且事务失效一定发生在事务提交前
- 恢复措施
- MM丢弃该事务的消息队列;
- 如果需要,进行undo操作;
- 从ATL删除该事务的TID,释放该事务所占资源
系统失效
-
系统(OS、DBMS)崩溃,需要重启
-
DB未被破坏,系统失去控制
-
举例:掉电、除数据库存储介质以外的软、硬件故障等
-
恢复措施
- 重新启动OS和DBMS;
- 恢复DB致一致状态
- 对未提交的事务进行undo操作
- 对已提交的事务进行redo操作
-
当数据库恢复到一致状态后,才允许用户访问数据库
-
检查点机制
-
动机:
- 活动事务表(ATL)的长度是有限的;由于累积效应,提交事务表(CTL)可能很长
- CTL表不可以即改即删,为了在介质失效的情况下仍可以做恢复
- 由于事务可以在提交前和提交后将数据的后像分别写入数据库,因而对CTL中的事务只能全部做redo,很费时(可能CTL中的很多事务已经完成将后像写入数据库,但鉴别代价很大)
- 活动事务表(ATL)的长度是有限的;由于累积效应,提交事务表(CTL)可能很长
-
定义:DBMS每隔一定时间在运行记录中设置一个检查点(checkpoint—CP),在检查点,DBMS强制写入所有已提交事务的后像
-
过程
- 暂停事务的执行;
- 写入上一个CP以后所提交事务的后像;
- 在log的CTL中记下检查点;
- 恢复事务的执行
-
特点
- 十分影响系统的正常运行
- 只有在发生系统失效时,才能减少redo工作量
-
介质失效
- 磁盘发生故障,数据库被破坏
- 恢复措施
- 修复系统,必要时更新磁盘;
- 如果系统(OS和DBMS)崩溃,重新启动系统;
- 加载最近后备副本;
- 用log中的后像重做取最近后备副本后提交的所有事务。
并发控制
并发
-
串行访问:事务顺序执行
-
并发访问:DBMS可同时接纳多个事务,事务可在时间上重叠执行
- 交叉并发:单CPU系统,各个事务交叉使用CPU。
- 同时并发:多CPU系统,多个事务在CPU中同时运行。
目的
- 提高系统资源利用率;
- 改善短事务响应时间。
问题
-
丢失更新,写写冲突(由两个事务对同一数据并发写入引起)
-
读脏数据,读写冲突(一个事物读取了另一个更新事务尚未提交的数据)
-
不可复现:由两个事务对同一数据并发读写引起
原则
-
调度:假设数据库系统中,某一时刻并发执行的事务集为{T1,T2,…Tn},调度(Schedule)S是对n个事务所有操作的顺序的一个安排
-
操作:在S中,不同事物的操作可以交叉,但必须保持各个事务的操作的原有次序。
- 操作是调度的基本单位!
-
目标等价:如果其中两个调度S1和S2,在数据库的任何初始状态下,所有读出的数据都一样,留给数据库的最终状态也一样,则称S1和S2是等价的
-
冲突等价
- 冲突操作:与写操作有关
- 读写冲突
- 写写冲突
- 冲突操作的执行次序会影响执行结果,不冲突操作的次序可以互换,不致影响执行结果
- 凡是通过调换S中不冲突操作得到的新的调度,称为S的冲突等价调度。
- 冲突等价一定目标等价,反之未必
- 冲突操作:与写操作有关
-
可串行化:若调度S在数据库中产生的效果,与这组事务的某个串行执行序列的结果相同
-
例:S‘是串行调度,所以S是冲突可串行化的,也是目标可串行化的
-
冲突可串行化一定时目标可串行化,反之未必
-
是并发控制的正确性准则
-
问题:不同的调度→不同的等价串行序列→不同的执行结果?(n!)
- 目标可串行化是NP难问题
-
前驱图
-
有向图G=<V,E>
- V——顶点的集合,包含所有参与调度的事务。
- E——边的集合,通过分析冲突操作来决定。如果下列条件之一成立,可在E中加边Ti→Tj:
- Ri(x)在Wj(x)之前
- Wi(x)在Rj(x)之前
- Wi(x)在Wj(x)之前
-
如果有环路,则该调度不可串行化;否则,可串行化
-
构造方法
- 由于无环路,必有入度为0的顶点。将它们及其有关的边从图中移去并将这些顶点存入一个队列。
- 对剩下的图作同样处理,不过移出的顶点要队列中已有顶点之后。
- 重复1,2直至所有顶点移入队列为止。
-
举例:对{T1,T2,T3,T4}的一个调度s, S= W3(y)R1(x)R2(y)W3(x)W2(x)W3(z)R4(z)W4(x) 它是否可串行化?
小结
- 调度:是系统对n个并发事务的所有操作的顺序的一个安排。
- 目标等价:两个调度s1和s2,如果在同样的初始条件下执行,对数据库产生的效果完全相同,则称s1和s2是目标等价的。
- 冲突操作:R-W、W-W。冲突操作的执行顺序会影响执行效果。
- 不冲突操作:
- R-R
- 虽有写操作,但作用对象不同,如Ri(x)和Wj(y)。
- 冲突等价:凡是通过调换s中的不冲突操作所得的新调度,称为s的冲突等价调度。
- 性质:如两调度是冲突等价的,则一定是目标等价的;反之未必正确。
- 串行化也分为目标可串行化和冲突可串行化
- 例1:对事务集{T1,T2,T3}的一个调度s, s=R2(x)W3(x)R1(y)W2(y)→R1(y)R2(x)W2(y)W3(x)=s’ 因为s’是串行调度,所以s是冲突可串行化的。
- 例2:s=R1(x)W2(x)W1(x)W3(x) 无冲突等价调度,但却可以找到一个调度s’ s’=R1(x)W1(x)W2(x)W3(x) 与s目标等价。
- 并发控制:对并发执行的事务加以控制,使之按某种可串行化的调度序列来执行
加锁协议
(S)锁
-
读和写只有一种锁
-
排他性:一个数据对象同时只能被一个事务加锁
-
相容矩阵
已有/待加 NL X NL Y Y X Y N -
问题:连锁卷回
- 原因:过早释放锁
- 解决:写操作的锁保持到事务结束
- 读操作的锁过早释放不会造成连锁卷回,但可能造成读值不可复现
两端封锁协议
- 两段封锁协议(two-phase locking protocol, 2PL):加锁动作都在释放锁动作之前
-
第一段:所拥有的锁逐步增长
-
第二段:所拥有的锁逐步缩减
-
一旦开始释放锁,就不能再对任何数据对象加锁
-
合式:well formed, 先加锁,后操作
-
如果所有事务满足2PL 和well formed,则他们的任何调度都是可串行化的(serializable)
-
Well-formed+2PL+unlock update at EOT: 可串行化,可恢复(不会有多米诺现象)
-
Well-formed+2PL+holding all locks to EOT: 严格的两端封锁事务
(S,X)锁
-
设置有两种锁
- S锁:share locks,用于读访问
- X锁:eXclusive locks, 用于写访问
-
相容矩阵
已有/待加 NL S X NL Y Y Y S Y Y N X Y N N -
问题
- 不断有事务对对象申请S锁,导致X锁申请迟迟无法批准,也称为活锁
- 解决:先申请,先服务
(S,U,X)锁
-
减少排他时间,提高并发度,减少死锁
-
更新三阶段
- 从磁盘中读出老的内容
- 在内存中更新
- 写入修改后的内容
-
除写入阶段外,被更新的数据对象是可以被其他事务访问的
-
思想:更新时先申请U锁,写入时U锁升级为X锁
-
相容矩阵
已有/待加 NL S U X NL Y Y Y Y S Y Y Y N U Y Y N N X Y N N N -
问题:
- 不断有事务对对象申请S锁,导致U锁升级到X锁的申请迟迟无法批准,也称为活锁
- 解决:先申请,先服务
死锁检测和预防
- 死锁:循环等待,没人能获得全部资源
- 防:不允许发生
- 治:在发生后检测死锁,发现后处理死锁
- 活锁:
- 不借助外力可以自愈
死锁检测
-
超时:某事务等待时间超过某个定值,便认为发生了死锁,该事务被终止
- 死锁发生后,等待一段时间才能被发现
- 可能出现误判
- 时限太大:发现死锁的滞后时间太长
- 时限太小:被误判的事务数增多
-
等待图:
-
V — 事务集 {Ti|Ti is a transaction in DBS (i=1,2,…n)
-
E - {<Ti,Tj>|Ti waits for Tj (i ≠ j)}
-
节点:事务
-
边:等待关系,有向边
-
有环路说明发生死锁
-
维护等待图和检测回路的开销较大,一般使用周期性检测
-
死锁处理
- 选取牺牲事务:最年轻、回卷代价最小等标准
- 终止牺牲事务释放所有资源
- 该事务等待一段时间
- 重启动该事务:用户或系统执行
死锁防止
- 一次性申请所有锁
- 将数据对象编号,按照序号加锁
- 一旦冲突,便停止相关事务
- 回卷重执
死锁与加锁机制
- 死锁:性能指标
- 加锁机制:保证事务结果正确
回卷重执策略
-
等待死亡
- 年老等年轻
- 年轻事务作为牺牲品
- 若TA比TB老,TA等待 ,
- 否则 TA“死亡”, i.e. 隔一段时间, TA 将重运行(仍用原时间标记)
-
击伤等待
- 年轻等年老
- 年轻事务作为牺牲品
- 若TA比TB年轻,TA等待 ,
- 否则,TA “击伤” TB, i.e. TB 被终止,隔一段时间,将重运行(仍用原时间标记)