事务
含义:用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位
地位:恢复和控制并发的基本单位
区分事务和程序,一个程序中包含多个事务
定义事务
事务的开始与结束可以由用户显式控制
若用户没有显式地定义事务,则由数据库管理系统按默认规定自动划分事务
语句
begin transaction;
commit;
提交,提交事务的所有操作,将事务中所有对数据库的更新写回到磁盘上的物理数据库中,正常结束
rollback;
回滚,将事务中对数据库的所有已完成的操作全部撤销,回滚到事务开始时的状态,异常结束
ACID 特性
原子性 A
事务是数据库的逻辑工作单位,事务中包括的诸操作,要么都做,要么都不做
一致性 C
正确性
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态
当数据库只包含成功事务提交的结果时,数据库处于一致性状态
隔离性 I
一个事务的执行不能被其他事务干扰
持续性 D
也称永久性
一个事务一旦提交,其对数据库中数据的改变就应该是永久性的
故障
各类故障对数据库的影响由两种可能性,一是数据库本身被破坏,二是数据库没有被破坏,但数据可能不正确,由于事务的运行被非正常终止造成的
恢复的基本原理:冗余,即数据库中任何一部分被损坏或不正确的数据可根据存储在系统别处的冗余数据重建
数据库恢复
定义:把数据库从错误状态恢复到某一已知的正确状态
恢复子系统是数据库管理系统的一个重要组成部分
数据库系统所采用的恢复技术是否行之有效,是衡量系统性能优劣的重要指标
恢复的实现技术
恢复机制涉及的两个关键问题:如何建立冗余数据,如何利用这些冗余数据实施数据库恢复
建立冗余数据最常用的技术:数据转储和登记日志文件
数据转储
地位:数据库恢复采用的基本技术
定义:数据库管理员定期地将整个数据库复制到磁带、磁盘或其他存储介质上保存起来的过程
后备副本 / 后援副本
当数据库遭到破坏后可以将后备副本重新装入,但重装后备副本只能将数据库恢复到转储时的状态,想要恢复到故障发生时的状态,必须重新运行自转储以后的所有更新事务
系统在 Ta 时刻停止运行事务,进行数据转储,在 Tb 时刻转储完毕,得到 Tb 时刻的数据库一致的副本
转储状态
- 静态转储:在系统中无运行事务时进行转储操作,静态转储得到的一定是一个数据一致性的副本 静态转储简单,但转储必须等待正运行的用户事务结束才能进行,新的事务必须等待转储结束才能执行,这会降低数据库的可用性
- 动态转储:转储期间允许对数据库进行存取或修改 必须把转储期间各事务对数据库的修改活动登记下来,建立日志文件,后援副本加上日志文件就能把数据库恢复到某一时刻的正确状态**【后援副本不记录转储期间对数据库进行的存取或修改】**
转储方式
- 海量转储:每次转储全部数据库
- 增量转储:每次只转储上一次转储后更新过的数据
从恢复角度看,使用海量转储得到的后备副本进行恢复会方便些
若数据库很大,事务处理十分频繁,使用增量转储方式更有效
日志文件
定义:记录事务对数据库的更新操作的文件
格式
不同数据库系统采用的日志文件格式不完全一样,主要有两种格式
以记录为单位的日志文件
日志文件中需要登记的内容:
- 各个事务的开始标记
- 各个事务的结束标记
- 各个事务的所有更新操作
以上均作为日志文件中的一个日志记录
每个日志记录的内容:
- 事务标识(标明是哪个事务)
- 操作的类型(插入、删除或修改)
- 操作对象(记录内部标识)
- 更新前数据的旧值(对插入操作而言,此项为空值)
- 更新后数据的新值(对删除操作而言,此项为空值)
以数据块为单位的日志文件
日志记录的内容:
- 事务标识
- 被更新的数据库
由于将更新前的整个块和更新后的整个块都放入日志文件中,故操作类型和操作对象等信息不必放入日志记录中
作用
- 事务故障恢复和系统恢复必须用日志文件
- 在动态转储方式中必须建立日志文件,后备副本和日志文件结合起来才能有效地恢复数据库
- 在静态转储方式中也可以建立日志文件,当数据库毁坏后可重新装入后援副本把数据库恢复到转储结束时刻的正确状态,然后利用日志文件把已完成的事务进行重处理,把故障发生时尚未完成的事务进行撤销处理
登记日志文件
为保证数据库是可恢复的,登记日志文件时必须遵循的两条规则:
- 登记的次序严格按并发事务执行的时间次序
- 必须先写日志文件,后写数据库
恢复策略
事务故障的恢复
事务故障是指事务在运行至正常终止点前被终止,此时恢复子系统应利用日志文件撤销此事务已对数据库进行的修改
事务故障的恢复由系统自动完成,对用户透明
系统的恢复步骤
- 反向扫描日志文件,查找该事务的更新操作
- 对事物的更新操作执行逆操作,即将日志记录中"更新前的值"写入数据库 【记录中是插入操作,相当于做删除操作;记录中是删除操作,则做插入操作;记录中是修改操作,则相当于用修改前值代替修改后值】
- 继续反向扫描日志文件,查找事务的其他更新操作,并做同样处理
- 如此处理下去,直至读到此事务的开始标志,事务故障恢复完成
系统故障的恢复
系统故障造成数据库不一致状态的原因有两个,一是未完成事务对数据库的更新可能已写入数据库,二是已提交事务对数据库的更新可能还留在缓冲区没来得及写入数据库,因此恢复操作是要撤销故障发生时未完成的事务,重做已完成的事务
系统故障的恢复是由系统在重新启动时自动完成的,不需要用户干预
系统的恢复步骤
- 正向扫描日志文件,找出在故障发生前已经提交的事务,将其事务标识记入重做队列;同时找出故障发生时尚未完成的事务,将其事务标识记入撤销队列
- 对撤销队列中的各个事务进行撤销处理
进行撤销处理的方法是:反向扫描日志文件,对每个撤销事务的更新操作执行逆操作,即将日志记录中"更新前的值"写入数据库
- 对重做队列中的各个事务进行重做处理
进行重做处理的方法是:正向扫描日志文件,对每个重做事务重新执行日志文件登记的操作,即将日志记录中"更新后的值"写入数据库
介质故障的恢复
发生介质故障后,磁盘上的物理数据和日志文件被破坏,这是最严重的一种故障,恢复方法是重装数据库,然后重做已完成的事务
介质故障的恢复需要数据库管理员介入 ,但数据库管理员只需要重装最近转储的数据库副本和有关的各日志文件副本,然后执行系统提供的恢复命令即可,具体的恢复操作仍由数据库管理系统完成
系统的恢复步骤
- 装入最新的数据库后备副本(离故障发生时刻最近的转储副本),使数据库恢复到最近一次转储时的一致性状态
- 装入相应的日志文件副本(转储结束时刻的日志文件副本),重做已完成的事务
具有检查点的恢复技术
检查点记录的内容
- 建立检查点时刻所有正在执行的事务清单
- 这些事务最近一个日志记录的地址
动态维护日志文件
动态维护日志文件的方法是,周期性地执行建立检查点、保存数据库状态的操作
具体步骤
- 将当前日志缓冲区中的所有日志记录写入磁盘的日志文件上
- 在日志文件中写入一个检查点记录
- 将当前数据缓冲区的所有数据记录写入磁盘的数据库中
- 把检查点记录在日志文件中的地址写入一个重新开始文件
恢复子系统可以定期或不定期地建立检查点,保存数据库状态。检查点可以按照预定的一个时间间隔建立,也可以按照某种规则建立检查点
使用检查点方法可以改善恢复效率
系统使用检查点方法进行恢复
具体步骤
- 从重新开始文件中找到最后一个检查点记录在日志文件中的地址,由该地址在日志文件中找到最后一个检查点记录
- 由该检查点记录得到检查点建立时刻所有正在执行的事务清单 active-list
这里建立两个事务队列:
-
- undo-list:需要执行 undo 操作的事务集合
- redo-list:需要执行 redo 操作的事务集合
把 active-list 暂时放入 undo-list 队列,redo 队列暂为空
- 从检查点开始正向扫描日志文件
-
- 如有新开始的事务 Ti ,把 Ti 暂时放入 undo-list 队列
- 如有提交的事务 Tj,把 Tj 从 undo-list 队列移到 redo-list 队列,直到日志文件结束
- 对 undo-list 中的每个事务执行 undo 操作,对 redo-list 中的每个事务执行 redo 操作
数据库镜像
许多数据库管理系统提供数据库镜像功能用于数据库恢复
数据库镜像通过复制数据实现,频繁地复制数据会降低系统运行效率
在实际应用中用户只选择对关键数据和日志文件进行镜像,而不是对整个数据库进行镜像