目录
11.1 事务的基本概念
事务的定义
事务(Transaction)是用户定义的数据操作序列,这些操作被作为一个完整的、不可分割的工作单元来执行。在一个事务内的操作要么全部执行,要么全部不执行。
事务和程序是两个不同的概念:
事务:是数据库中用于实现数据操作的一种基本单元。在关系数据库中,一个事务可以是一条SQL语句、一组SQL语句,甚至是整个程序中的部分操作。
程序:通常包含多个事务
事务是数据库系统中实现恢复和并发控制的基本单位
事务的开始与结束
事务的开始与结束可以由用户显式控制或由系统隐式划分:
1. 显式方式
通过以下语句明确标识事务的范围:
BEGIN TRANSACTION;
开始事务COMMIT;
提交事务(事务成功完成)ROLLBACK;
回滚事务(事务中止并撤销其操作)
BEGIN TRANSACTION;
SQL语句1;
SQL语句2;
COMMIT;
BEGIN TRANSACTION;
SQL语句1;
SQL语句2;
ROLLBACK;
2. 隐式方式
当用户没有显式定义事务时,数据库管理系统(DBMS)会按照默认规则自动划分事务。例如,在某些系统中,每条SQL语句会被视为一个事务
事务的ACID特性
事务具有以下4个基本特性,简称为ACID:
原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation)
持续性(Durability)
1. 原子性
事务是数据库的逻辑工作单位,事务中包含的所有操作要么全部完成,要么全部不执行。如果事务中途因某种原因失败,则系统会撤销事务的所有已执行操作,数据库回到事务开始前的状态。
2. 一致性
事务的执行使数据库从一个一致性状态变到另一个一致性状态。
一致性状态:数据库中只包含已成功提交事务的结果。
不一致状态:事务中断或故障导致部分修改已写入数据库,数据库可能处于不正确状态。
3. 隔离性
事务的执行不被其他事务干扰
每个事务内部的操作及使用的数据对其他并发事务是隔离的。
并发执行的事务之间不能相互影响。
4. 持续性(永久性)
事务一旦提交,对数据库的修改应该是永久性的。
提交后的事务结果在数据库中得到保存,即使系统出现故障也不应该影响其结果
破坏ACID特性的因素
ACID特性可能被以下两类因素破坏:
1. 并发干扰
多个事务并行运行时,不同事务的操作可能交叉执行。
破坏特性:隔离性和一致性
2. 各种故障
事务在运行过程中被强行停止。
破坏特性:原子性、持久性和一致性
DBMS事务处理的任务就是分别采用恢复机制和并发控制解决以 上两类问题
11.2 数据库恢复概述
在数据库系统中,故障是不可避免的,主要包括以下几类:
- 计算机硬件故障:如磁盘损坏、电源故障等。
- 软件错误:如操作系统或数据库管理系统(DBMS)的漏洞、程序异常等。
- 操作员失误:如误删除数据、误操作等。
- 恶意破坏:如病毒攻击、未授权用户的恶意操作等。
故障会对数据库系统造成以下影响:
- 事务运行中断:导致正在运行的事务未正常完成,影响数据的正确性。
- 数据库损坏:可能导致数据部分或全部丢失,破坏数据库的完整性和一致性。
数据库恢复的目标是通过技术手段将数据库从错误状态恢复到某一已知的正确状态(即一致性状态或完整性状态)
数据库的恢复由DBMS的恢复子系统完成,主要任务包括:
- 检测故障:识别故障类型并判断影响的范围。
- 回滚未完成事务:撤销所有未提交事务的操作,恢复数据库一致性。
- 重做已提交事务:确保已提交事务的操作永久反映在数据库中。
11.3 故障的种类
1. 事务内部的故障
事务在运行过程中未正常终止即中断,可能由预期原因或非预期原因引发。
预期原因
业务规则要求终止:如违反了特定逻辑约束。
输入数据错误:导致无法完成事务的正确处理。
违反完整性约束:如违反主键、外键或唯一性限制。
非预期原因
事务内部的大多数故障是不可预测的,主要包括:
运算溢出:如除以零、数据溢出等。
并发事务死锁:系统检测到死锁,主动终止某些事务。
违反系统完整性限制:如违反系统级约束或逻辑条件。
故障结果
未到达终点:事务未能到达提交点(COMMIT)或显式回滚点(ROLLBACK)。
数据库状态不正确:可能存在未完成操作导致的不一致性。
恢复机制撤销事务(UNDO):强行回滚事务【撤销事务已作出的所有修改,确保数据库状态恢复至事务未启动前的状态】
2. 系统故障
定义
软故障,指因某种事件导致系统停止运行并需要重新启动,但数据库本身未被破坏。
系统正常运行突然中断,所有事务非正常终止。
数据库完整性未被直接破坏,但内存中数据库缓冲区数据丢失。
故障影响
未完成事务:可能部分修改已写入数据库,造成不一致性。
已完成事务:可能部分或全部修改尚未写入物理数据库,修改丢失。
恢复机制
回滚未完成事务:撤销所有非正常终止事务的操作(UNDO)。
重做已完成事务:将所有已提交事务的操作重新应用于数据库(REDO)。
3. 介质故障
硬故障,指外存设备损坏,导致数据库部分或全部被破坏。
常见原因:磁盘损坏,磁头碰撞,强磁场干扰
破坏性强,可能导致数据库部分或全部丢失
影响正在存取相关数据的所有事务
恢复机制
利用冗余数据重建被破坏的数据库部分
恢复过程依赖于定期备份和日志文件
4. 计算机病毒
人为故障,指恶意程序通过繁殖和传播对计算机系统(包括数据库)造成危害。
故障影响
数据库被破坏
数据不正确,可能由于事务非正常终止引发
恢复机制
通过冗余数据重建被破坏或不正确的数据
采用防病毒措施和安全机制避免进一步损害
如何恢复?
恢复操作的基本原理:冗余 利用存储在系统别处的冗余数据来重建数据库中已被破坏或不正确的那部分数据
恢复的实现技术:复杂 ,一个大型数据库产品,恢复子系统的代码要占全部代码的 10%以上
11.4 恢复的实现技术
如何建立冗余数据
冗余数据是数据库故障恢复的基础
主要通过以下两种方式建立:
(1)数据转储(Backup)
数据库管理员定期将整个数据库复制到磁带、磁盘或其他存储介质的过程,称为转储。
保存的副本称为后备副本(Backup)或后援副本
用于在发生故障时恢复数据库
静态转储:在无事务运行的情况下执行
动态转储:与用户事务并发运行
(2)登记日志文件(Logging)
在数据库运行过程中,将事务对数据库的所有修改记录到日志文件中。
作用:
通过日志文件跟踪事务的执行状态。
配合转储副本,恢复数据库到一致性状态
数据转储
(1)静态转储
在无运行事务时进行。
转储期间禁止对数据库进行任何操作。
转储数据保证一致性。
优点:实现简单。副本数据正确有效。
缺点:降低数据库的可用性:转储必须等待当前运行事务完成。新事务必须等转储操作结束。
(2)动态转储
转储操作与用户事务并发进行。
允许在转储期间对数据库进行访问和修改。
优点:提高数据库可用性:不用等待运行事务完成。不影响新事务运行。
缺点:可能导致副本数据不一致:在转储期间,某些事务可能修改数据,导致部分数据未更新至副本。
动态转储的故障恢复原理
问题:动态转储得到的副本可能存在数据不一致问题。
解决方法:
在动态转储期间,记录所有事务对数据库的修改操作到日志文件。
恢复过程:
使用动态转储副本作为基础。
重做日志文件中的修改操作,将数据库恢复到某一时刻的正确状态。
海量转储与增量转储
海量转储每次转储整个数据库的所有数据,无论数据是否更新。
转储的副本完整全面。恢复过程简单,直接利用后备副本即可。占用较多存储空间,转储时间较长。
适用场景:数据库规模较小,更新频率不高。恢复过程对效率要求较高。
增量转储仅转储上次转储后发生变更的数据(包括新增、修改、删除的部分)。
数据转储量小,时间短。占用存储空间少,效率高。恢复时需结合之前的转储副本,操作复杂。
适用场景:数据库规模大,更新频率高。存储和转储时间成本敏感的场合。

登记日志文件
(1)以记录为单位的日志文件
每条日志记录包含以下内容:
事务标识:标识哪个事务进行了操作
操作类型:标明是插入、删除还是更新
数据前值:更新前的数据值(旧值)
数据后值:更新后的数据值(新值)
(2)以数据块为单位的日志文件
每条日志记录包含以下内容:
事务标识:标识哪个事务进行了操作。
被更新的数据块:指明更新操作所涉及的存储块。
日志文件的主要用途包括:
事务故障恢复:当事务发生故障时,通过日志文件撤销(UNDO)或重做(REDO)事务的操作。
系统故障恢复:记录事务的修改情况,确保系统故障后能够回滚未完成的事务或重做已提交事务。
协助介质故障恢复:结合后备副本恢复已破坏的数据。

登记的次序严格按并发事务执行的时间次序:必须先写日志文件,后写数据库 (Write Ahead Logging,WAL)
11.5 恢复策略
事务故障的恢复
通过日志文件的内容,撤销(UNDO)事务已对数据库进行的修改。
特点:由系统自动完成,用户无需干预,对用户是透明的。
步骤
反向扫描日志文件
从最后向前扫描日志文件,查找该事务的更新操作。执行逆操作
根据日志记录,将“更新前的值”写入数据库。
插入操作:若“更新前的值”为空,相当于删除操作。
删除操作:若“更新后的值”为空,相当于插入操作。
修改操作:用“修改前值”代替“修改后值”。
重复处理
持续反向扫描,查找并处理该事务的所有更新操作。处理完成
当读到该事务的“开始标记”时,事务故障的恢复完成。
系统故障的恢复
数据库不一致状态的原因
未完成事务:未完成事务的更新操作可能已经写入数据库。
已提交事务:已提交事务的更新操作可能仅保存在缓冲区,未写入数据库。
恢复方法
撤销(UNDO)未完成的事务。
重做(REDO)已完成的事务。
步骤
系统重新启动时自动完成
正向扫描日志文件
建立两类队列:
撤销队列(UNDO):包括故障发生时尚未完成的事务,仅有“BEGIN TRANSACTION”记录,无对应的“COMMIT”记录。
重做队列(REDO):包括故障发生前已提交的事务,既有“BEGIN TRANSACTION”记录,也有“COMMIT”记录。
撤销未完成的事务
反向扫描撤销队列中的事务操作。
对每个撤销事务执行逆操作,将“更新前的值”写入数据库。
重做已完成的事务
正向扫描重做队列中的事务操作。
对每个重做事务执行重做操作,将“更新后的值”写入数据库。
介质故障的恢复
恢复方法
重装数据库
装入最新的后备数据库副本,使数据库恢复到最近一次转储时的一致性状态:对于静态转储,数据库即处于一致性状态。
对于动态转储,需要同时装入转储时刻的日志文件副本,并利用系统故障恢复方法(REDO+UNDO)将数据库恢复到一致性状态。
重做已完成的事务
装入有关的日志文件副本(转储结束时的日志文件副本)。
首先扫描日志文件,找出故障发生时已提交的事务并记录到重做队列。
正向扫描日志文件,对重做队列中的事务进行重做操作,将“更新后的值”写入数据库。
介质故障的恢复需要数据库管理员的介入:重装最近转储的数据库副本和相关日志文件副本。执行数据库管理系统提供的恢复命令。具体恢复操作:由数据库管理系统自动完成