事务的定义
事务: 用户定义的一个数据库操作序列, 要么全做要么全不做, 是一个不可分割的工作单位(原子行为序列)
事务与程序是两个概念, 一个事务可以是一条/一组SQL语句或整个程序, 一个程序通常包含多个事务.
事务是恢复和并发控制的基本单位.
显式定义方式:
当用户没有显式定义事务时系统会按照默认方式自动划分事务.
事务的ACID特性:
- Atomicity → 原子性(要么全做要么全不做)
- Consistency → 一致性(必须从一个一致性状态变到另一个一致性状态, 只包含事务成功提交的结果)
不一致的状态: 事务执行到一半被打断时的系统状态
- Isolation → 隔离性(事务之间的执行互不干扰, 一个事务内部的操作和使用的数据对其他并发事务隔离)
- Durability → 持续性(一个事务一旦提交, 则对数据库中数据的改变就应该是永久的, 其他操作或故障不会影响该事务的执行结果)
事务处理的任务: 保证事务的ACID特性
破坏ACID特性的因素: 事务的并发运行, 事务在运行时被意外强行中止
故障和数据库恢复
故障恢复的过程, 日志, 检查点需要知道
故障恢复: 把数据库从错误状态恢复到某一已知的正确状态(一致状态)的功能.
恢复子系统是DBMS的一个重要组成部分
故障种类
- 事务内部故障
- 由于SQL代码产生
- 不可预期(运算溢出, 由于死锁被撤销, 违反完整性约束条件...)
- 没有达到预期终点(COMMIT/ROLLBACK), 数据库可能处于不正确状态
- 恢复: 事务撤销(强行回滚到执行前)
- 系统故障
- 软故障, 造成系统停止运转的事件(CPU故障, 断电, DBMS代码错误等), 使得系统需要重启
- 整个系统正常运行被破坏, 所有运行的事务都非正常终止, 内存中缓冲信息全部丢失
- 不破坏数据库(在磁盘中)
- 一些尚未完成事务的部分结果已经送入磁盘, 数据库可能处于不正确状态 → 事务撤销
- 已经提交的事务可能有部分在内存缓冲区尚未写回磁盘 → 事务重做(重做已提交的事务)
- 介质故障
- 硬故障, 指外存故障(磁盘损坏)
- 破坏数据库, 影响正在存取这部分数据的所有事务
- 可能性小, 破坏性大
- 计算机病毒
- 人为的故障或破坏
影响: 破坏数据库本身/数据不正确
恢复
基本原理: 利用存储在系统别处的冗余数据重建被破坏或不正确的数据
实现复杂
关键问题: 如何建立冗余数据(数据转储, 登记日志文件), 如何利用冗余数据实施恢复
转储和日志
需要知道
转储: 定期将整个数据库复制到其他存储介质上保存起来(另外保存一份副本). 备用的数据文本称为后备副本, 数据库遭到破坏之后可以将后备副本重新装入, 恢复到转储时的状态(而要想恢复到故障发生时的状态必须重做自转储到故障时所有的更新事务).
转储类型
- 静态转储:
- 在系统中没有正在运行的事务时进行的转储操作
- 转储开始时数据库处于一致性状态, 转储期间数据库不允许存取/修改
- 得到的一定是一个满足一致性的副本
- 优点: 实现简单
- 缺点: 降低可用性, 转储等待事务结束, 事务等待转储结束
- 动态存储
- 转储操作与用户事务并发进行, 转储期间允许存取/修改
- 优点: 转储不用等待事务, 事务不用等待转储
- 缺点: 不保证数据正确
- 使用动态转储的副本进行恢复: 把动态转储期间各事务对数据库的修改活动登记下来建立日志文件, 使用后备副本加上日志文件将数据库恢复到某一时刻的正确状态.
日志文件: 用来记录事务对数据库的更新操作的文件, 一个日志记录包含事务的开始标记, 结束标记, 所有更新操作.
日志文件可以分为以记录为单位(包含事务标识, 操作类型, 操作对象, 旧值, 新值)和以数据块为单位(包含事务标识, 被更新的数据块)的日志文件.
具体作用:
- 事务故障恢复和系统故障恢复必须使用日志文件.
- 动态转储方式必须建立日志文件, 需要与后备副本结合使用.
- 静态转储方式中也可以建立日志文件, 用于记录转储点到故障点的所有操作以备还原

登记日志文件的两条准则:
- 登记次序严格按照并发事务执行的时间次序
- 必须先写日志后写数据库, 确保已进行的修改都登记了
转储策略
- 海量转储: 每次转储全部数据库, 恢复更方便
- 增量转储: 只转储上次转储后更新过的数据, 适用于数据库规模大, 事务处理频繁的情况
恢复策略
没有太多东西, 和转储日志是正反面, 不做要求
具有检查点的恢复技术
需要知道
恢复的问题:
- 搜索整个日志太费时
- 重做处理浪费大量时间
具有检查点的恢复技术:
- 在日志文件中增加检查点记录
- 增加重新开始文件
- 恢复子系统在登录日志文件期间动态维护日志
- 将当前日志缓冲区的所有日志记录写入磁盘的日志文件
- 在日志文件中写入一个检查点记录
- 将当前数据缓冲区的所有数据记录写入磁盘的数据库
- 将检查点记录在日志文件中的地址写入一个重新开始文件
- 循环执行以上步骤
检查点记录的内容:
- 建立检查点时刻所有正在执行的任务清单
- 这些事务的日志记录的地址
上述流程决定, 对于每一个通过重新开始文件找到的检查点, 其建立时DBMS中已提交的事务都已经被写到磁盘. 恢复时只要重做或撤销通过重新开始文件找到的最后一个检查点对应的日志记录的行为, 即可完成恢复.
重新开始文件的内容: 各个检查点记录在日志文件中的地址

恢复子系统定期/不定期建立检查点, 保存数据库状态.
利用检查点的恢复策略:
- 从重新开始文件中找到最后一个检查点记录在日志文件中的地址,由该地址在日志文件中找到最后一个检查点记录
- 由该检查点记录得到检查点建立时刻所有正在执行的事务清单ACTIVE-LIST
- 建立两个事务队列(UNDO-LIST, REDO-LIST), 把ACTIVE-LIST暂时放入UNDO-LIST队列,REDO队列暂为空.
- 从检查点开始正向扫描日志文件,直到日志文件结束. 如有新开始的事务Ti ,把Ti暂时放入UNDO-LIST队列. 如有提交的事务Tj,把Tj从UNDO-LIST队列移到REDO-LIST队列;直到日志文件结束. (回滚未提交, 重做已提交)
- 对UNDO-LIST中的每个事务执行UNDO操作
- 对REDO-LIST中的每个事务执行REDO操作
数据库镜像
不做重点