第六章 事务管理 影响事务ACID特性的因素: 强行中止事务 并发事务的交叉执行 6.1 恢复引论 故障对数据库的影响 数据库本身被破坏 数据库无破坏,数据不正确 恢复的基本原理:冗余 分类: (1)后备复本 转储(Dump)-静态转储/动态转储;海量转储/增量转储 问题:最近一致状态 (2) 后备复本+运行记录(日志) 前像(Before Image BI) 后像(After Image AI) 事务状态 (3)多复本 6.2运行记录结构 运行记录的主要内容 前像文件 后像文件 活动事务列表(ATL) 已提交事务列表(CTL) 策略 6.3更新事务的执行与恢复 6.3.1更新事务的执行规则 提交规则:后像在事务提交前应写入非易失存储器中; 先记后写:如果事务在提交前将后像写入DB,则应先把前像写入运行记录。 6.3.2更新事务的执行方案 后像在事务提交前全部写入数据库 ① TID → ATL ② BI → LOG ③ AI → DB ④ TID → CTL ⑤ 从ATL删除TID 后像在事务提交后写入数据库 ① TID → ATL ② AI → LOG ③ TID → CTL ④ AI → DB ⑤ 从ATL删除TID 后像在事务提交前后写入数据库 ① TID → ATL ② AI,BI → LOG ③ AI → DB(部分) ④ TID → CTL ⑤ AI → DB(全部) ⑥ 从ATL删除TID 6.4消息处理 事务运行结束后发送的消息 事务运行中发送的消息 6.5故障类型及恢复方法 (1)事务故障(undo) (2)系统故障(redo + undo)check point (3)介质故障(redo) 6.6并发控制引论 (1)丢失更新 (2)不可重复读 (3)读“脏”数据 原因:写操作 写-写,读-写 6.7并发事务调度 6.7.1目标可串行化调度 目标等价调度 目标可串行化调度 6.7.2冲突可串行化调度 冲突操作 冲突等价调度 冲突可串行化调度 冲突等价调度一定是目标等价调度,反之不成立 6.7.3冲突可串行化判定 目标可串行化:NP完全问题 冲突可串行化:前趋图 6.8加锁协议 6.8.1分类 (1) X锁 读、写排他锁 效率 (2) S、X锁 S:共享 读 X:排他 写 (3) S、U、X锁 6.8.2两阶段封锁协议(2PL) 申请封锁阶段(增长阶段) 释放封锁阶段(缩减阶段) 合式事务:遵守先加锁,后操作原则的事务 定理:如果所有事务都是合式,两阶段事务,则他们的任何调度都是可串行化的。 严格的两阶段封锁协议 6.9活锁和死锁 6.9.1活锁 无限等待 6.9.2死锁 事务间互相占用资源 解决死锁问题的方法: 允许死锁发生 预防、避免死锁发生 6.9.3死锁的检测和处理 检测方法: (1)超时法 (2)等待图法(有向图) 无限等待问题 6.9.4死锁的防止 OS中的方法不完全适用于DBMS 时间标记(timestamp) (1)等待-死亡策略(wait-die) if ts(T1)<ts(T2) then T1 waits else { rollback T1; restart T1 with same ts } (2)击伤-等待策略(wound-wait) if ts(T1)>ts(T2) then T1 waits else { rollback T2; restart T2 with same ts } 6.10多粒度封锁(Granularity) 封锁对象:逻辑单元,物理单元 封锁力度:封锁对象的大小 封锁粒度与系统并发程度和系统开销密切相关 多粒度封锁:显式封锁,隐式封锁 封锁检查: 意向锁: IS锁(意向共享锁) IX锁(意向排他锁) SIX锁(共享意向排他锁) 相容矩阵 锁的强弱关系 6.11基于时间标记的并发控制技术 6.11.1基本的时间标记协议 事务:时间标记; 数据项:时间标记(tr,tw) 事务读/写数据的处理: (1)事务T读数据D if ts(T)< tw(D):D已被年轻事务重写,拒绝T的Read(D),用新的ts重启T if ts(T)>=tw(D):执行Read(D),tr(D)=max(ts(T),tr(D)) (2) 事务T写数据D if ts(T)<tr(D) :D已被年轻事务读过,拒绝T的Write(D),用新的ts重启T if ts(T)<tw(D):T写一个过时的数据给D,拒绝执行,用新的ts重启T if ts(T)>=tr(D) and ts(T)>=tw(D) :执行Write(D),修改 tw(D)=ts(T) Thomas写入规则: if ts(T)<tr(D) then rollback T and restart with new ts(T) else if ts(T)>=tw(D) then { write(D); tw:=ts(T) } else ignore Write(D) 6.11.2多版本并发控制 数据D存在多个复本,每个版本的Di都具有tr(Di),tw(Di) 版本选择:tw(Di)<=ts(T),且Di是满足条件的最新的数据 (1)读:Di即为读取值,修改tr(Di)=max(tr(Di),ts(T)) (2)写:tr(Di)<=ts(T),满足可串行化条件,生成新版本 tr(Di)>ts(T),rollback T 多版本并发控制评价 6.12乐观并发控制技术 事务执行分为三个阶段: (1)读阶段 (2)检验阶段 (3)写阶段 检验:利用时间标记检查是否可串行化。