数据库原理(七)事务管理

本文详细探讨了数据库管理系统中的恢复技术,包括基于单一副本、运行记录和多副本的恢复策略,强调了日志文件在恢复过程中的关键作用。此外,还介绍了并发控制的目的、原则和各种加锁协议,以及死锁的检测、预防和处理方法,确保事务在并发执行时的正确性和一致性。
摘要由CSDN通过智能技术生成

概述

  • 事务管理:恢复、并发控制
  • 恢复:保证事务在发生故障时满足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文件规模减小
    • 不保留已提交事务的前像
    • 有选择的保留后像
    • 合并后像:对给定逻辑块号的物理块,如多次更新,可只保留最近的后像

更新事务的执行与恢复

规则

  1. 提交规则: 后像必须在事务提交前,写入非易失性存储器(DB或log)。

  2. 先记后写(LAR):如果后像在事务提交前写入数据库,则必须把前像先写入log

策略

  1. 后像在事务提交前完全写入DB

    TID →active list
    B.I →Log		(按Log Ahead Rule)
    A.I →DB
    ┇
    TID →commit list
    delete TID from active list
    
    commit listactive listoperation
    1undo(还没有提交)
    11从ATL中删除TID(已完成事务)
    1nothing(已完成事务提交及之后的任务)
  2. 后像在事务提交后写入数据库

    TID →active list
    A.I →Log	(按commit rule)
    ┇
    TID →commit list
    A.I →DB 
    delete TID from active list
    
    commit listactive listoperation
    1从ATL表中删除TID
    11redo, 从ATL表中删除TID
    1nothing
  3. 后像在事务提交前后写入数据库

    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 listactive listoperation
    1undo
    11redo, 从ATL中删除TID
    1nothing
    • 有利于磁盘负载均衡

消息处理

  • 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中的很多事务已经完成将后像写入数据库,但鉴别代价很大)
    • 定义:DBMS每隔一定时间在运行记录中设置一个检查点(checkpoint—CP),在检查点,DBMS强制写入所有已提交事务的后像

      检查点

    • 过程

      • 暂停事务的执行;
      • 写入上一个CP以后所提交事务的后像;
      • 在log的CTL中记下检查点;
      • 恢复事务的执行
    • 特点

      • 十分影响系统的正常运行
      • 只有在发生系统失效时,才能减少redo工作量

介质失效

  • 磁盘发生故障,数据库被破坏
  • 恢复措施
    • 修复系统,必要时更新磁盘;
    • 如果系统(OS和DBMS)崩溃,重新启动系统;
    • 加载最近后备副本;
    • 用log中的后像重做取最近后备副本后提交的所有事务。

并发控制

并发

  • 串行访问:事务顺序执行

    串行访问

  • 并发访问:DBMS可同时接纳多个事务,事务可在时间上重叠执行

    并发访问

    • 交叉并发:单CPU系统,各个事务交叉使用CPU。
    • 同时并发:多CPU系统,多个事务在CPU中同时运行。

目的

  1. 提高系统资源利用率;
  2. 改善短事务响应时间。

问题

  1. 丢失更新,写冲突(由两个事务对同一数据并发写入引起)

    丢失更新

  2. 读脏数据,读冲突(一个事物读取了另一个更新事务尚未提交的数据)

    脏数据

  3. 不可复现:由两个事务对同一数据并发读引起

    读值不可复现

原则

  • 调度:假设数据库系统中,某一时刻并发执行的事务集为{T1,T2,…Tn},调度(Schedule)S是对n个事务所有操作的顺序的一个安排

  • 操作:在S中,不同事物的操作可以交叉,但必须保持各个事务的操作的原有次序。

    • 操作是调度的基本单位!
  • 目标等价:如果其中两个调度S1和S2,在数据库的任何初始状态下,所有读出的数据都一样,留给数据库的最终状态也一样,则称S1和S2是等价的

  • 冲突等价

    • 冲突操作:与写操作有关
      • 读写冲突
      • 写写冲突
    • 冲突操作的执行次序会影响执行结果,不冲突操作的次序可以互换,不致影响执行结果
    • 凡是通过调换S中不冲突操作得到的新的调度,称为S的冲突等价调度。
    • 冲突等价一定目标等价,反之未必
  • 可串行化:若调度S在数据库中产生的效果,与这组事务的某个串行执行序列的结果相同

    • 例:S‘是串行调度,所以S是冲突可串行化的,也是目标可串行化的

      可串行化举例

    • 冲突可串行化一定时目标可串行化,反之未必

      可串行化举例2

    • 是并发控制的正确性准则

    • 问题:不同的调度→不同的等价串行序列→不同的执行结果?(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)锁

  • 读和写只有一种锁

  • 排他性:一个数据对象同时只能被一个事务加锁

  • 相容矩阵

    已有/待加NLX
    NLYY
    XYN
  • 问题:连锁卷回

    • 原因:过早释放锁
    • 解决:写操作的锁保持到事务结束
    • 读操作的锁过早释放不会造成连锁卷回,但可能造成读值不可复现

两端封锁协议

  • 两段封锁协议(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, 用于写访问
  • 相容矩阵

    已有/待加NLSX
    NLYYY
    SYYN
    XYNN
  • 问题

    • 不断有事务对对象申请S锁,导致X锁申请迟迟无法批准,也称为活锁
    • 解决:先申请,先服务

(S,U,X)锁

  • 减少排他时间,提高并发度,减少死锁

  • 更新三阶段

    • 从磁盘中读出老的内容
    • 在内存中更新
    • 写入修改后的内容
  • 除写入阶段外,被更新的数据对象是可以被其他事务访问的

  • 思想:更新时先申请U锁,写入时U锁升级为X锁

  • 相容矩阵

    已有/待加NLSUX
    NLYYYY
    SYYYN
    UYYNN
    XYNNN
  • 问题:

    • 不断有事务对对象申请S锁,导致U锁升级到X锁的申请迟迟无法批准,也称为活锁
    • 解决:先申请,先服务

死锁检测和预防

  • 死锁:循环等待,没人能获得全部资源
    • 防:不允许发生
    • 治:在发生后检测死锁,发现后处理死锁
  • 活锁:
    • 不借助外力可以自愈

死锁检测

  1. 超时:某事务等待时间超过某个定值,便认为发生了死锁,该事务被终止

    • 死锁发生后,等待一段时间才能被发现
    • 可能出现误判
    • 时限太大:发现死锁的滞后时间太长
    • 时限太小:被误判的事务数增多
  2. 等待图:

    • V — 事务集 {Ti|Ti is a transaction in DBS (i=1,2,…n)

    • E - {<Ti,Tj>|Ti waits for Tj (i ≠ j)}

    • 节点:事务

    • 边:等待关系,有向边

    • 有环路说明发生死锁

    • 维护等待图和检测回路的开销较大,一般使用周期性检测

死锁处理

  1. 选取牺牲事务:最年轻、回卷代价最小等标准
  2. 终止牺牲事务释放所有资源
  3. 该事务等待一段时间
  4. 重启动该事务:用户或系统执行

死锁防止

  1. 一次性申请所有锁
  2. 将数据对象编号,按照序号加锁
  3. 一旦冲突,便停止相关事务
  4. 回卷重执

死锁与加锁机制

  1. 死锁:性能指标
  2. 加锁机制:保证事务结果正确

回卷重执策略

  1. 等待死亡

    • 年老等年轻
    • 年轻事务作为牺牲品
    • 若TA比TB老,TA等待 ,
    • 否则 TA“死亡”, i.e. 隔一段时间, TA 将重运行(仍用原时间标记)
  2. 击伤等待

    • 年轻等年老
    • 年轻事务作为牺牲品
    • 若TA比TB年轻,TA等待 ,
    • 否则,TA “击伤” TB, i.e. TB 被终止,隔一段时间,将重运行(仍用原时间标记)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值