1.事务的基本概念
事务
所谓事务是用户定义的一个数据库操作序列,这些操作要么全做,要么不做,是一个不可分割的工作单位。
事务的开始和结束可以由用户显示控制。如果用户没有显示定义事务,则由数据库管理系统按默认规定自动划分事务。
在SQL中定义事务的语句一般有以下三条:
-- 开启事务
BEGIN TRANSACTION;
-- 事务提交
COMMIT
-- 事务回滚
ROLLBACK
事务的特性ACID
事务具有四个特性:原子性(Atomicity)、 一致性(Consistency)、 隔离性(Isolation)、持续性(Durability)
原子性
事务是数据库的逻辑工作单位,事务中包括的操作要么全做,要么不做(关注状态:要么成功要么失败,不存在部分成功状态)。
一致性
一致性也是事务中包括的操作要么成功,要么失败。这看起来跟原子性是一样的。但是一致性与原子性不同的是,一致性关注的是数据的可见性,中间状态的数据对外部不可见,只有最初状态和最终状态的数据对外可见。例如A要从银行转账100给B,原子性关注的是这一整个操作是否正确成功执行,而一致性关注的是账户A有没有成功扣款,账户B有没有成功入账,账户A应该和账户B保持一致性。
隔离性
一个事务的执行不能被其他事务干扰。
持续性
持续性也称永久性,指一个事务一旦提交,那么它对数据库中数据改变将是永久的。
2.故障的种类
尽管数据库系统中采取了各种各样的措施来防止数据的安全性和完整性遭到破坏,保证事并发的正确执行。但是有一些故障是不可避免的。数据库中可能发生的故障大致可以分为以下几类。
- 事务内部故障:事务内部的故障是非预期的,是不能由应用程序处理的,如运算溢出、并发事务等。
- 系统故障:系统故障是指造成系统停止运转的任何事件,使得系统重新启动
- 介质故障:系统故障称为软故障,介质故障称为硬故障(硬盘损坏、磁场干扰等)。
- 计算机病毒
3.恢复的实现技术
恢复机制涉及的两个关键问题是:如何建立冗余数据,以及如何利用这些冗余数据实现数据库恢复。建立冗余数据最常用的技术是数据转储和登记日志文件。
数据转储
数据转储即数据库管理员定期将整个数据库备份的过程,这些备份后的数据称为后备副本或后援副本。
转储可以分为静态存储和动态存储。
- 静态存储是在系统中无运行事务时进行转储操作,可以得到一个完整的副本数据。
- 动态存储时允许对数据进行修改,即转储和用户事务可以并发进行。不保证得到的数据准确有效。
数据存储的两种方式分别可以在两种方式下进行:
海量转储: 每次转储全部数据库
增量转储: 只转储上次转储后更新过的数据
海量转储与增量转储比较
从恢复角度看,使用海量转储得到的后备副本进行恢复往往更方便
如果数据库很大,事务处理又十分频繁,则增量转储方式更实用更有效
登记日志文件
1.日志文件的格式和内容
日志文件是用来记录事务对数据库的更新操作的文件。不同的数据库采用的日志文件格式并不完全一样。概况起来主要有两种格式:以记录为单位的日志文件和以数据块为单位的日志文件。
以记录为单位的日志文件需要登记的内容包括:
- 各个事务的开始标记(BEGIN TRANSACTION)
- 各个事务的结束标记(COMMIT或ROLLBACK)
- 各个事务的所有更新操作
以上均作为日志文件中的一个日志记录 (log record)。
以记录为单位的日志每条日志记录的内容包括如下:
- 事务标识(标明是哪个事务)
- 操作类型(插入、删除或修改)
- 操作对象(记录ID、Block NO.)
- 更新前数据的旧值(对插入操作而言,此项为空值)
- 更新后数据的新值(对删除操作而言, 此项为空值)
对于以数据块为单位的日志文件包括:事务标识和被更新的数据块
2.日志文件的作用
日志在数据恢复中可以用来进行事务故障恢复和系统故障恢复等,具体作用:
- 事务故障恢复和系统故障恢复必须用日志文件。
- 在动态转储方式中必须建立日志文件,后备副本和日志文件结合起来才能有效地恢复数据库。
- 静态转储中也可以利用日志确保数据恢复到某一时刻的正确状态。
3.登记日志文件
为保证数据库是可恢复的,登记日志文件时必须遵循两条规则:
- 登记的次序严格按照并发事务执行的时间次序。
- 必须先写日志文件,后写数据库
为什么要先写日志后写数据库?
因为写日志和写数据库是两个不同的操作,在这两个操作之间可能发生故障,即两个操作只完成了一个。即先写数据库,而日志没有写,这种情况下,以后就不能恢复这个修改了。
4.恢复策略
当系统运行时发生故障需要利用副本和日志恢复,但是要注意的是不同的故障恢复策略和方法是不同的。
事务故障恢复
这种故障是指事务在运行至正常终点前被停止,这时恢复子系统应利用日志文件撤销事务已对数据库进行的修改。
恢复步骤是:
- 反向扫描日志,查找事务的更新操作
- 对更新的值做如下操作:插入操作->删除插入数据,修改操作->用修改之前的值代替后值,删除操作->插入操作。
- 直到读到对应事务开始的标记
系统故障恢复
系统故障造成数据库不一致状态原因有两个:一个是未完成事务对数据库的更新已经写入数据,二是已经提交的事务对数据的更新可能还留在缓存中。解决方案是撤销故障发生时未完成的事务,重做已完成事务。
恢复步骤:
- 正向扫描日志,找出故障发生前已经提交的事务,将其标识记入重做队列,找出故障发生时尚未完成的事务,标识记录撤销队列
- 对撤销队列中的各个事务进行撤销处理
- 对从左队列的各个事务进行重做处理
介质故障恢复
发生介质故障后,磁盘上的物理数据和日志数据文件被破坏,这是最严重的的一种故障,恢复方法是重装数据库,然后重做已经完成的事务。
5.具有检查点的恢复技术
利用日志技术恢复子系统必须搜索日志确定哪些事务需要重做哪些需要撤销,这将会浪费大量的时间。为了解决这个问题引入了检查点记录,检查点记录即增加一个从新开始的文件,并让恢复子系统在登录日志文件期间动态的维护日志。
检查点记录内容包括:
- 建立检查点时刻所有正在执行的任务清单
- 这些事务最近一个日志记录的地址
动态维护日志的方法是:周期性的执行建立检查点、保存数据库状态操作。具体步骤如下:
- 将当前日志缓冲区中的所有日志记录写入磁盘的日志文件
- 在日志文件中写入一个检查点记录
- 将当前数据缓冲区的所有数据记录写入磁盘数据库中
- 把检查点记录在日志文件中的地址写入一个重新开始的文件
恢复子系统可以定期或不定期设定检查点,或者按照某种规则设定检查点保存数据库状态。
子系统恢复的策略:
- 再检查点之前进行事务提交,这种情况数据已经写入数据库,不用处理
- 在检查点到系统故障之间提交,这种情况数据库可能还在缓冲区没写入数据库,需要重做
- 在发生故障时事务还没有提交的,进行撤销处理。
undo日志用于记录事务开始前的状态,用于事务失败时的回滚操作;redo日志记录事务执行后的状态,用来恢复未写入data file的已成功事务更新的数据。
系统使用检查点方法进行恢复的步骤:
- 从重新开始文件中找到最后一个检查点记录在日志文件中的地址,由改地址在日志文件中找到最后一个检查点的记录。
- 由该检查点记录得到检查点建立时刻所有正在执行的事务清单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操作
使用检查点的优点:缩短扫描日志时间改善恢复效率
6.数据库镜像
数据库镜像即可以很好的解决介质故障,即准备多块硬盘利用数据库镜像实时将一块硬盘的数据备份到多块硬盘。