乐趣区

关于数据库:数据库系统概论王珊第十章数据库恢复技术第四五六七节数据库恢复技术和数据库镜像

  • pdf 下载:明码 7281
  • 专栏目录首页:【专栏必读】(考研复试)数据库系统概论第五版(王珊)专栏学习笔记目录导航及课后习题答案详解

一:数据库复原的实现技术

复原机制波及的两个关键点就是

  • 如何建设冗余数据
  • 如何利用冗余数据实现数据库复原

其中建设冗余数据最罕用的技术是

  • 数据转储
  • 注销日志文件

(1)数据转储(备份)

数据转储:指 DBA 定期手动或者 DBMS 定期主动将整个数据库复制到存储介质上保存起来的过程。这些备用的数据称之为后备正本。当数据库受到毁坏后能够将后备正本从新装入,然而重装后的正本只能将数据库复原到转储时的状态,要想复原到故障产生时的状态,必须从新运行自转储当前的所有更新事物。因而,转储常和日志配合应用

  • 例如,零碎在 $T_{a}$ 时刻进行运行事务,进行数据库转储,在 $T_{b}$ 时刻转储结束,失去 $T_{b}$ 时刻的数据库一致性正本。零碎运行到 $T_{f}$ 时刻产生故障。为复原数据库,首先由数据库管理员重装数据库后备正本,将数据库复原至 $T_{b}$ 时刻的状态,而后从新运行自 $T_{b}$~$T_{f}$ 时刻的所有更新事务,这样就把数据库复原到故障产生前的统一状态

A:转储的分类

①:依照零碎是否运行事物时分类

动态转储:是在零碎中无运行事务时进行的转储操作。即转储操作开始的时刻数据库处于一致性状态,而转储期间不容许 (或不存在) 对数据库的任何存取、批改流动。显然,动态转储失去的肯定是一个数据一致性的正本

  • 长处:实现简略
  • 毛病:转储时必须期待正在运行的用户事物完结能力进行。升高了数据库的可用性

动静转储:是指转储期间容许对数据库进行存取或批改,也即转储和用户事物能够并发执行

  • 长处:不必期待正在运行的事物,加强了数据库的可用性
  • 毛病:转储完结时后援正本上的数据库并不能保障正确无效

因而,对于动静转储,还须要建设日志文件(log file)。这样后备正本加上日志文件就能把数据库复原到某一时刻的正确状态了

②:按转储的范畴分类

海量转储:每次转储全副数据库

增量转储:每次只转储上一次转储后更新过的数据


根据上述两种分类形式,进行组合,因而共有如下四种转储

(2)注销日志文件

日志文件:是用来记录事物对数据库更新操作的文件。次要有两种格局

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

A:日志文件的内容

对于以记录为单位的日志文件

日志文件中须要注销的内容包含:

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

每个事物的开始、完结标记和每个更新操作均为一个日志记录,其内容次要包含

  • 事务标识(表明是哪个事务)
  • 操作的类型(插入、删除或批改)
  • 操作对象(记录外部标识)
  • 更新前数据的旧值(对插入操作而言,此项为空值)
  • 更新后数据的新值(对删除操作而言,此项为空值)

对于以块为单位的日志文件:日志记录的内容包含事务标识和被更新的数据块。因为将更新前的整个块和更新后的整个块都放入日志文件中,操作类型和操作对象等信息就不用放入日志记录中了

B:日志文件的作用

日志文件在数据库复原中起着十分重要的作用,能够用来进行事务故障复原和系统故障复原,并帮助后备正本进行介质故障复原。具体作用是:

  • 事务故障 复原和 系统故障 复原必须用日志文件
  • 动静转储形式 中必须建设日志文件,后备正本和日志文件联合起来能力无效地 复原数据库
  • 动态转储形式 中也能够建设日志文件,当数据库破坏后可从新装入后备正本
    把数据库复原到转储完结时刻的正确状态,而后利用日志文件把 已实现的事务进行重做解决 ,对 故障产生时尚未实现的事务进行撤销解决。这样不用从新运行那些已实现的事务程序就可把数据库复原到故障前某一时刻的正确状态

针对每一种故障,日志文件的作用如下

  • 事物故障:利用日志撤销(UNDO)未实现事物
  • 系统故障:利用日志撤销(UNDO)未实现事物;重做(REDO)已实现事物
  • 介质故障:利用日志和正本复原
  • 动态转储正本 + 日志复原到故障产生前
  • 动静转储正本 + 转储期间日志,能够先复原到备份时的一致性状态,而后再利用备份后的日志还原数据

C:注销日志文件

为保障数据库是可复原的,注销日志文件时必须遵循两条准则:

  • 注销的秩序严格按并发事务执行的工夫秩序
  • 必须先写日志文件,后写数据库(Write Ahead Logging,WAL)

二:复原策略

(1)事物故障的复原

事务故障的复原是由 零碎主动实现 的,对用户是 通明 的。零碎的复原步骤是:

  1. 反向扫描 日志文件 (即从最初向前扫描日志文件),查找该事务的 更新 操作
  2. 对该事务的更新操作执行 逆操作 ,行将日志记录中“ 更新前的值“ 写入数据库。这样,如果记录中是插入操作,则相当于做删除操作(因而时“更新前的值 ” 为空); 若记录中是删除操作,则做插入操作; 若是批改操作,则相当于用批改前值代替批改后值
  3. 持续反向扫描日志文件,查找该事务的其余更新操作,并做同样解决
  4. 如此解决上来,直至读到此事务的 开始标记,事务故障复原就实现了
LOGFILE.seek(0,SEEK_END);
Repeat
     LOGFILE.ReverseRead(R);
     if R.ID=T AND R. Type=WRITE then
     begin
         if R.BI IS null then 执行 delete 语句,删除被插入的对象
         else if R.AI is null then 执行 insert 语句,插入被删除的对象
         else 执行 update 语句,数据对象的值从 AI 改回 BI
     end;
 Until R.ID=T AND R.type=STRAT;

(2)系统故障的复原

系统故障的复原是由零碎在 重新启动时主动实现的 不须要用户干涉,其步骤为

  1. 正向扫描 日志文件 (即从头扫描日志文件),找出在故障产生前曾经提交的事务
    (这些事务既有BEGIN TRANSACTION 记录,也有 COMMIT 记录),将其事务标识记入 重做队列 (REDO-LIST)。同时找出 故障产生时尚未实现的事务 (这些事务只有BEGINT RANSACTION 记录,无相应的 COMMIT 记录),将其事务标识记入 撤销队列(UNDO-LIST)
  2. 对撤销队列中的各个事务进行撤销 (UNDO) 解决 :反向扫描日志文件,对每个撤销事务的更新操作执行逆操作行将日志记录中“ 更新前的值”写入数据库
  3. 对重做队列中的各个事务进行重做 (REDO) 解决 :正向扫描日志文件,对每个重做事务从新执行日志文件注销的操作,行将日志记录中“ 更新后的值”写入数据库

(3)介质故障的复原

  • 装入 最新的数据库后备正本 (离故障产生时刻最近的转储正本),使数据库复原 到 最近一次转储时 的一致性状态
  • 装入相应的日志文件正本(转储完结时刻的日志文件正本),重做已实现的事务:即首先扫描日志文件,找出故障产生时已提交的事务的标识,将其记入重做队列; 而后正向扫描日志文件,对重做队列中的所有事务进行重做解决。行将日志记录中“更新后的值”写入数据库

三:具备检查点的复原技术

(1)一个问题

利用日志技术进行数据库复原时,复原子系统必须搜寻日志,确定哪些事务须要重做,哪些事务须要撤销。一般来说,须要查看所有日志记录。这样做有两个问题

  • 搜寻整个日志将消耗大量的工夫
  • 很多须要重做解决的事务实际上曾经将它们的更新操作后果写到了数据库中,然而复原子系统又从新执行了这些操作,节约了大量工夫

为了解决这些问题,引入 具备检查点的复原技术

(2)概述

具备检查点的复原技术:这种技术在日志文件中减少了一类新的记录——检查点记录,减少一个从新开始文件,并让复原子系统在登录日志文件期间动静保护日志。检查点记录内容包含

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

其中从新开始文件用来记录各个检查点记录在日志文件中的地址

动静保护日志文件的办法:周期性地执行建设检查点、保留数据库状态的操作。具体步骤为:

  1. 将以后日志缓冲区中的所有日志记录写入磁盘的日志文件上
  2. 在日志文件中写入一个检查点记录
  3. 将以后数据库缓冲区的所有数据记录写入磁盘的数据库中
  4. 把检查点记录在日志文件中的地址写入一个从新开始文件

应用检查点办法能够改善复原效率。当事务 T 在一个检查点之前提交,T 对数据库所做的批改肯定都已写入数据库,写入工夫是在这个检查点建设之前或在这个检查点建设之时。这样,在进行复原解决时,没有必要对事务 T 执行重做操作。

(3)利用检查点的复原技术

零碎呈现故障时,复原子系统将依据事务的不同状态采取不同的复原策略,如下图

  • $T_{1}$:在检查点之前提交
  • $T_{2}$:在检查点之前开始执行,在检查点之后故障点之前提交
  • $T_{3}$:在检查点之前开始执行,在故障点时还未实现
  • $T_{4}$:在检查点之后开始执行,在故障点之前提交
  • $T_{5}$:在检查点之后开始执行,在故障点时还未实现
  • $T_{3}$ 和 $T_{5}$ 在故障产生时还未实现,所以予以撤销;
  • $T_{2}$ 和 $T_{4}$ 在检查点之后才提交,它们对数据库所做的批改在故障产生时可能还在缓冲区中,尚未写入数据库,所以要重做;
  • $T_{1}$ 在检查点之前已提交,所以不用执行重做操作

零碎应用检查点办法进行复原的步骤是:

①:从从新开始文件中找到 最初一个检查点记录在日志文件中的地址 ,由该地址在日志文件中找到 最初一个检查点记录

②:由该检查点记录失去检查点建设时刻所有 正在执行的事务清单ACTIVE-LIST。建设如下两个事物队列

  • UNDO-LIST:须要执行 UNDO 操作的事物汇合
  • REDO-LIST:须要执行 REDO 操作的事物汇合

③:从检查点开始 正向扫描日志文件

  • 如果有 新开始 的事物 $T_{i}$,则把 $T_{i}$ 临时放入UNDO-LIST
  • 如果有 新提交 的事物 $T_{j}$,则把 $T_{j}$ 从 UNDO-LIST 移到REDO-LIST
  • 反复,直到扫描日志文件完结

④:对 UNDO-LIST 中的每个事物 执行 UNDO 操作 ;对REDO-LIST 中每个事物 执行 REDO 操作


用上图所示的例子,复原步骤如下

①:建设ACTIVE-LIST,很显著ACTIVE-LIST={$T_{2}$,$T_{3}$}。而后初始化UNDO-LIST={$T_{2}$,$T_{3}$},REDO-LIST={}

②:从检查点开始正向扫描日志文件

  • 第一个读到的是事物 $T_{4}$ 建设,退出UNDO-LIST
  • 第二个读到的是事物 $T_{2}$ 提交,那么把 $T_{2}$ 从 UNDO-LIST 挪动到REDO-LIST
  • 第三个读到的是事物 $T_{5}$ 建设,退出UNDO-LIST
  • 第四个读到的是事物 $T_{5}$ 提交,那么把 $T_{5}$ 从 UNDO-LIST 挪动到REDO-LIST

③:对 UNDO-LIST 中的每个事物执行 UNDO 操作;对 REDO-LIST 中每个事物执行 REDO 操作

四:数据库镜像

数据库镜像:主动地将整个数据库或其中要害数据复制到另一个磁盘上。须要留神,在理论利用中,只对要害数据和日志文件进行镜像,而不是对整个数据库进行镜像

  • 用于数据库复原 :当呈现 介质故障 时,可由镜像磁盘持续提供应用,同时 DBMS 主动利用镜像磁盘数据进行数据库的复原,不须要关闭系统和重装数据库正本
  • 进步数据库可用性 :在 没有呈现故障 时,当一个用户对某个数据加排他锁进行批改时,其余用户能够读镜像数据库的数据,而不用期待该用户开释锁
退出移动版