> For the complete documentation index, see [llms.txt](https://lewiszlw.gitbook.io/notebooks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lewiszlw.gitbook.io/notebooks/blogs/history/shu-ju-ku-hui-fu-ji-shu.md).

# 数据库恢复技术

## 事务的基本概念

事务是一系列的数据库操作，是数据库应用程序的基本逻辑单元。事务处理技术主要包括数据库恢复技术和并发控制技术。

事务是用户定义的一个数据库操作序列，这些操作要么全做，要么全不做，是一个不可分割的工作单位。

事务和程序比较

* 两个概念
* 在关系数据库中，一个事务可以是一条SQL语句、一组SQL语句或整个程序。
* 一个程序通常包含多个事务

显式定义：

* COMMIT表示提交，即提交事务的所有操作，将事务中所有对数据库的更新写回到磁盘上的物理数据库中去

```sql
BEGIN TRANSACTION
.....
COMMIT;
```

* ROLLBACK表示回滚，系统将事务中对数据库的所有已完成的操作全部撤销，回滚到事务开始时的状态。

```sql
BEGIN TRANSACTION
......
ROLLBACK;
```

隐式定义：

* 当用户没有显式地定义事务时，DBMS按缺省规定自动划分事务

事务的ACID特性：

* 原子性（Atomicity） 事务是数据库的逻辑工作单位，事务中包括的诸操作要么都做，要么都不做。
* 一致性（Consistency） 事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
* 隔离性（Isolation） 一个事务的执行不能被其他事务干扰。
* 持续性（Durability ） 一个事务一旦提交，它对数据库中数据的改变就应该是永久性的。

## 数据库恢复概述

故障是不可避免的

* 系统故障：计算机软、硬件故障
* 人为故障：操作员的失误、恶意的破坏等

数据库的恢复（Recovery）：把数据库从错误状态恢复到某一已知的正确状态（亦称为一致状态或完整状态）。

## 故障的种类

1. 事务内部的故障

* 有的是可以通过事务程序本身发现的
* 有的是非预期的（大多）
* 事务故障的恢复：撤消事务（UNDO）

1. 系统故障 系统故障称为软故障，是指造成系统停止运转的任何事件，使得系统要重新启动。

* 影响
  * 整个系统的正常运行突然被破坏
  * 所有正在运行的事务都非正常终止
  * 不破坏数据库
  * 内存中数据库缓冲区的信息全部丢失
* 系统故障的常见原因
  * 特定类型的硬件错误（如CPU故障）
  * 操作系统故障
  * DBMS代码错误
  * 系统断电
* 系统故障的恢复
  * 发生系统故障时，事务未提交 恢复策略：强行撤消（UNDO）所有未完成事务
  * 发生系统故障时，事务已提交，但缓冲区中的信息尚未完全写回到磁盘上。 恢复策略：重做（REDO）所有已提交的事务

1. 介质故障 介质故障称为硬故障，指外存故障

* 常见
  * 磁盘损坏
  * 磁头碰撞
  * 操作系统的某种潜在错误
  * 瞬时强磁场干扰
* 介质故障的恢复
  * 装入数据库发生介质故障前某个时刻的数据副本
  * 重做自此时始的所有成功事务，将这些事务已提交的结果重新记入数据库

1. 计算机病毒

* 一种人为的故障或破坏，是一些恶作剧者研制的一种计算机程序
* 可以繁殖和传播
* 危害
  * 破坏、盗窃系统中的数据
  * 破坏系统文件

各类故障，对数据库的影响有两种可能性

* 一是数据库本身被破坏
* 二是数据库没有被破坏，但数据可能不正确，这是由于事务的运行被非正常终止造成的

恢复操作的基本原理：冗余

* 利用存储在系统其它地方的冗余数据来重建数据库中已被破坏或不正确的那部分数据

## 恢复的实现技术

建立冗余数据最常用的技术是数据转储和登记日志文件。

### 数据转储

转储是指DBA将整个数据库复制到磁带或另一个磁盘上保存起来的过程，备用的数据称为后备副本或后援副本。

静态转储

* 在系统中无运行事务时进行的转储操作
* 转储开始时数据库处于一致性状态
* 转储期间不允许对数据库的任何存取、修改活动
* 得到的一定是一个数据一致性的副本
* 优点：实现简单
* 缺点：降低了数据库的可用性
  * 转储必须等待正运行的用户事务结束
  * 新的事务必须等转储结束

动态转储

* 转储操作与用户事务并发进行
* 转储期间允许对数据库进行存取或修改
* 优点
  * 不用等待正在运行的用户事务结束
  * 不会影响新事务的运行
* 动态转储的缺点
  * 不能保证副本中的数据正确有效

另一种分类

* 海量转储: 每次转储全部数据库
* 增量转储: 只转储上次转储后更新过的数据
* 海量转储与增量转储比较
  * 从恢复角度看，使用海量转储得到的后备副本进行恢复往往更方便
  * 但如果数据库很大，事务处理又十分频繁，则增量转储方式更实用更有效

数据存储有两种方式，分别可以在两种状态下进行，因此数据转储方法可以分为4类：动态海量转储、动态增量转储、静态海量转储、静态增量转储。

### 登记日志文件

日志文件(log)是用来记录事务对数据库的更新操作的文件

日志文件的格式

* 以记录为单位的日志文件
* 以数据块为单位的日志文件

以记录为单位的日志文件内容

* 各个事务的开始标记(BEGIN TRANSACTION)
* 各个事务的结束标记(COMMIT或ROLLBACK)
* 各个事务的所有更新操作

以记录为单位的日志文件，每条日志记录的内容

* 事务标识（标明是哪个事务）
* 操作类型（插入、删除或修改）
* 操作对象（记录内部标识）
* 更新前数据的旧值（对插入操作而言，此项为空值）
* 更新后数据的新值（对删除操作而言, 此项为空值）

以数据块为单位的日志文件，每条日志记录的内容

* 事务标识（标明是那个事务）
* 被更新的数据块

基本原则

* 登记的次序严格按并发事务执行的时间次序
* 必须先写日志文件，后写数据库

## 恢复策略

### 事务故障的恢复

事务故障的恢复由系统自动完成，对用户是透明的，不需要用户干预。

事务故障的恢复步骤

1. 反向扫描文件日志（即从最后向前扫描日志文件），查找该事务的更新操作。
2. 对该事务的更新操作执行逆操作。即将日志记录中“更新前的值” 写入数据库。
3. 继续反向扫描日志文件，查找该事务的其他更新操作，并做同样处理。
4. 如此处理下去，直至读到此事务的开始标记，事务故障恢复就完成了。

### 系统故障的恢复

系统故障造成数据库不一致状态的原因

* 未完成事务对数据库的更新已写入数据库
* 已提交事务对数据库的更新还留在缓冲区没来得及写入数据库

恢复方法

* Undo 故障发生时未完成的事务
* Redo 已完成的事务

系统故障的恢复步骤

1. 正向扫描日志文件（即从头扫描日志文件）

* 重做(REDO) 队列: 在故障发生前已经提交的事务 这些事务既有BEGIN TRANSACTION记录，也有COMMIT记录
* 撤销 (Undo)队列:故障发生时尚未完成的事务 这些事务只有BEGIN TRANSACTION记录，无相应的COMMIT记录

1. 对撤销(Undo)队列事务进行撤销(UNDO)处理

* 反向扫描日志文件，对每个UNDO事务的更新操作执行逆操作
* 即将日志记录中“更新前的值”写入数据库

1. 对重做(Redo)队列事务进行重做(REDO)处理

* 正向扫描日志文件，对每个REDO事务重新执行登记的操作
* 即将日志记录中“更新后的值”写入数据库

### 介质故障的恢复

这是最严重的一种故障，恢复方法：

1. 重装数据库
2. 重做已完成的事务

恢复步骤

1. 装入最新的后备数据库副本（离故障发生时刻最近的转储副本），使数据库恢复到最近一次转储时的一致性状态。
2. 装入有关的日志文件副本（转储结束时刻的日志文件副本），重做已完成的事务。

## 具有检查点的恢复技术

具有检查点（checkpoint）的恢复技术

* 在日志文件中增加检查点记录（checkpoint）
* 增加重新开始文件
* 恢复子系统在登录日志文件期间动态地维护日志

检查点记录的内容

* 建立检查点时刻所有正在执行的事务清单
* 这些事务最近一个日志记录的地址

动态维护日志文件的方法： 周期性地执行如下操作：建立检查点，保存数据库状态。 具体步骤是： （1）将当前日志缓冲区中的所有日志记录写入磁盘的日志文件上 （2）在日志文件中写入一个检查点记录 （3）将当前数据缓冲区的所有数据记录写入磁盘的数据库中 （4）把检查点记录在日志文件中的地址写入一个重新开始文件

## 数据库镜像

数据库镜像

* 数据库管理系统自动把整个数据库或其中的关键数据复制到另一个磁盘上
* 数据库管理系统自动保证镜像数据与主数据的一致性。每当主数据库更新时，数据库管理系统自动把更新后的数据复制过去。

数据库镜像的用途

* 出现介质故障时
  * 可由镜像磁盘继续提供使用
  * 同时数据库管理系统自动利用镜像磁盘数据进行数据库的恢复
  * 不需要关闭系统和重装数据库副本
* 没有出现故障时
  * 可用于并发操作
  * 一个用户对数据加排他锁修改数据，其他用户可以读镜像数据库上的数据，而不必等待该用户释放锁

频繁地复制数据自然会降低系统运行效率，在实际应用中用户往往只选择对关键数据和日志文件镜像，不是对整个数据库进行镜像。

***

> 《数据库系统概论（第5版）》王珊 萨师煊 著
