数据库恢复技术(事物、三种更新策略以及恢复策略)

数据库恢复技术(事物、三种更新策略以及恢复策略)

  • 数据库恢复所要达到的目标
  • 数据库为了达到目标的恢复策略
  • 事务和日志的基本内容
    • 事务的基本内容
    • 日志的基本内容
  • 更新数据库规则和三种更新策略
    • 数据库更新规则
    • 三种更新策略
  • 数据库恢复技术小结

数据库恢复所要达到的目标

  • 1、希望尽可能的减少发生故障的次数。
          作为数据库来说,我肯定是想尽可能的减少犯病的次数,最好就没有嘛。
  • 2、在出现故障的时候,能够通过一些方式进行故障恢复。
          比如说当我数据库正在访问的时候,突然停电了,这就可能导致数据库的内容不一致了。这里要涉及到数据库一致性的内容,后面会用实例具体分析。

数据库为了达到目标的恢复策略

在说恢复策略之前我们先想一个问题——要想达到上面的目标,数据库要怎么去做呢?

首先是减少发生故障的次数,这方面主要是要加强数据库的数据规范和存取规范,相当于是要有规矩整个过程才能有条不紊不容易出错嘛,也容易理解。这个在后面的事务中会有提及。

之后是关于故障恢复的问题,数据库肯定要做些什么才能帮助我们更好的恢复数据库,有以下两个方面的考察:

  • 1、数据库要发现所有的故障。就算有的故障数据库处理不了,但是至少也得有个报错信息。
  • 2、数据库要有冗余。这里的冗余指的是数据库的备份,和数据冗余要区分开来。

而数据库恢复策略,主要针对当数据库发现故障之后所做的应对策略。比如停电之后,重启数据库,数据库的重启动恢复(后面会提到,这里可以简单理解成数据库的通过这个方式发现故障就行了)发现了故障,之后该怎么做,数据库对此有以下三种策略:
       1、周期性转储
       2、周期性转储+增量转储
       3、周期性转储+日志
下面分别对这三种策略进行分析说明。

  • 首先是周期性转储,简单点说,就是一段时间对数据库进行一次备份,这样当发生故障的时候就可以根据之前的备份对数据库进行恢复了。下面给张图方便理解。(灵魂画师(doge))
    数据库恢复技术(事物、三种更新策略以及恢复策略)_第1张图片
    这里可以看出,虽然可以在备份点进行备份,但是从备份点到故障点中间的这一部分用户的操作就丢失了,这肯定不是我们所希望的。

  • 那我们再来看看第二种策略,周期性转储+增量转储。这种策略在第一种策略基础上做了改进:记录了自从上次备份之后变化的那一部分的记录,也就是增量转储的部分。还是以下图为例:
    数据库恢复技术(事物、三种更新策略以及恢复策略)_第2张图片
    增量转储也是周期性存储的,如果每时每刻都进行增量性转储是不现实的,代价很大。所以增量转储点到故障点之间依然有数据丢失的部分,虽然相较于单一的周期性转储来说优化了许多,但也仍有瑕疵。

当然无论是做什么事情,都是一个循序渐进的过程。前面的两种方式为我们后续想法的提出做了很好的铺垫:如果增量转储点能够每时每刻做,那不就可以使得增量转储点到故障点之间没有数据丢失了?
事实上雀氏如此。增量转储点是 你操作完之后,我才重新把你变化的部分记录,比如 你插入了两次数据,并让数据库做了相应改变之后,我才记录。如果数据库在你插入的过程中故障了,就恢复不了(因为没有记录,你之前的操作也丢失了,除非去手动恢复,不然数据库没有信息来源)。
那只要现在我把你每一步操作都先提前记录下来,放到一个非挥发性存储器中(就类似硬盘这种断点之后数据不会丢失的存储器,像内存就是挥发性的)这样恢复的时候岂不是想怎么恢复就怎么恢复了。(为所欲为)

  • 这样就提出了第三点:周期性转储+日志。这种方式在企业级的数据库中得到了广泛使用。日志(log)记录了自上次备份以来,用户的所有改变,为了更好的能为数据库恢复服务,日志也有相应的数据结构,其中 前项负责记录操作之前的老值(before information,简称B.I),后项负责记录操作之后的新值(after information,简称A.I)。

有了日志后我们分析以下的情况:当发生故障的时候,事务完成但是没有写入到数据库中,就可以在事务log中找到新值A.I更新数据库即可。

事务和日志的基本内容


事务的基本内容

在说恢复策略的时候,我们不止一次提到事务这个概念,那什么是事务呢?——事务简单的说就是一组操作的集合,而这一组操作是一个整体,即要么同时都完成要么同时都完成不了
什么意思呢?——举个例子:
假设以去银行转账为例:
对A账户操作 取100元到B账户上,即对A:money = money - 100;
对B账户操作 之前取的钱会同步到B账户上,即对B:money = money + 100;
这两个操纵要不取钱存钱都成功完成了,要不就都没干,不会出现A扣了钱,B没加钱的情况。这也就是事务的第一个性质:原子性
那事务有什么性质呢,下面介绍事务的四个特性:
       1、原子性——Atomicity
       2、保持一致性—— Consistency
       3、隔离性——Isolation
       4、持久性——Durability
下面分别对事务的四个特性进行分析:事务的四个特性——ACID

  • 原子性。上面的例子也已经分析过了,即事务内部的操作要么都成功要么都不成功。
  • 保持一致性。就是事务执行前后都会是合法的数据状态,不会违背任何数据的完整性约束。什么意思呢?还是举个例子:
    现在我有个表student{
       int ID;
       char(9) name;
       int age;
    }
    要求插入的时候必须有学生的ID和姓名。下面假设插入的过程中,插入了ID之后断电了,名字没插入,那如果这个事务成功了,那么就会违背数据的完整性约束了,所以根据事务的保持一致性原则,这个事务就不会成功。
  • 隔离性。这个性质是针对事务的并发的,在实际的过程中,由于要充分利用CPU的资源,对事物要进行并发处理,那也就意味着并发的事务之间不能相互干扰,对每个事务来说,好像自己是独占数据库一样,能够正确无误的完成自己的工作。举个例子:
    事务T1:     事务T2:
      read(A.x)
               read(A.x)
      A.x = 5;
               A.x = 3*A.x;
      write(A.x)
               write(A.x)
    这里就发现一个问题:事务T1的操作最后根本没有效果,就好像从来没有操作过一样,因为它的结果会被事务T2覆盖掉,这就是事务之间互相干扰了,这就违背了事务的隔离性(这只是其中一个例子)。
  • 持久性。只要事务成功完成,它对数据库的影响是持久的。这个也好理解,因为数据库是非挥发性存储器,所以只要之后不改动这个事务造成的影响,它就能一直存在。

日志的基本内容

之前在恢复策略中讲到最重要的恢复策略:周期性转储+日志,它的核心便是日志。那么日志里面到底记录了什么东西呢,日志又是怎么记录事务信息的呢?我们从以下两个方面考察:

  • 事务的创建。事务被数据库创建出来后,会有对应的事务标识号TID唯一标识一个事务。(比如说用时间戳表示事务TID)
  • 两大事务列表。在数据库中,Commit list事务提交列表,储存已经提交的TID组成的列表;Active list活跃事务列表,存储正在进行工作的TID组成的列表。
    有了上面的内容,我们就很好的知道了日志到底要存储什么内容了。首先日志要存储事务的TID以便知道到底是哪个事务;其次日志要记录这个事务修改数据库之前的内容,和修改数据库之后的内容,即要记录旧值和新值。这样在遇到恢复的时候,如果之前没有写完,找到新值写完就可以恢复;如果之前写到一半故障了,找到旧值就可以恢复了。下面上个图方便理解:
    数据库恢复技术(事物、三种更新策略以及恢复策略)_第3张图片

更新数据库规则和三种更新策略


数据库更新规则

因为要考虑到数据库的恢复,所以数据库的更新肯定不能随意,要基于一定的规则之上,下面介绍在更新数据库的时候任何数据库都必须遵循的两条规则:

  • 1.提交规则(Commit Rule)——CR规则
  • 2.日志在前规则(Log Ahead Rule)——LAR规则

下面分别详细介绍这两种规则:
1、提交规则:所谓提交规则就是在做数据库提交更新之前,新值A.I必须写入到非挥发性介质中(可以是日志、磁盘,甚至是数据库,只要是可以长期存储的介质即可)。
2、日志在前规则:在修改数据库之前,老值必须先记录到日志中,再做修改。

三种更新策略

由此规则,我们提出三种更新数据库的策略。

  • 1、新值在提交事务之前写入数据库
  • 2、新值在提交事务之后再写入数据库
  • 3、新值即在提交事务之前写入数据库,又在提交事务之后写入数据库

下面详细介绍这三种更新策略。

  • 首先是第一种策略:新值在提交事务之前写入数据库。事务再被数据库创建后,事务的TID就加入到 [1]活跃事务列表(Active list) 中,之后对于每一条记录,将[2.1]B.I旧值记录到日志log中(LAR规则),将[2.2]新值写入到数据库中(CR规则),直到[3]遇到commit提交命令后,将事务的TID加入到事务提交列表(Commit list)中,最后将[4] 事务的TID从活跃事务列表(Active list)中移除。流程图如下:(这里A.I->数据库后面还会有很多别的操作,不修改数据库的内容,这里简化表示了)
    数据库恢复技术(事物、三种更新策略以及恢复策略)_第4张图片
    这一种更新策略在数据库遇到故障之后进行重启动恢复要怎么做呢?(重启动恢复就是在数据库重启的时候,数据库如何检查出故障并且恢复的过程)

首先检查每个事务的两张表Commit list和Active list。
1、如果Commit list中有记录,那只需要检查这个事务在Active list中有没有删干净就行了,因为在前面的操作中已经写到数据库中了;
2、如果Commit list中没有记录,Active list有记录,那就进行undo回滚操作。之后将事务从Active list中删除即可。(这里想想为什么要从Active list中删除TID——因为这个事务并不是正在工作了)

Commit list Active list 操作
没有 什么都不做
把TID从Active list中删除
没有 undo+把TID从Active list中删除

这里补充undo回滚操作redo重做操作
这里通俗点说:所谓undo,就是利用日志里的旧值对数据库进行恢复。redo就是利用数据库的日志,将之前的操作重新再做一遍以达到事务完成的状态。(关于redo在第二种策略中有详细介绍,这里知道有这玩意就行)

上面的第二步undo,就是认为事务没有完成,所以需要回退到这个事务还没有开始的状态。

针对上面每个事务,就有疑惑了:我从数据库建立到现在,那有那么多的事务,如果我每个事务都查一遍,那万一有100万个事务得搞到什么时候?
这个雀氏是一个问题,所以数据库会设置检查点。是数据库周期性自动的设置的,在检查事务的时候就会从上一个检查点处开始,这样就可以解决这个问题了。

  • 第二种策略:新值在提交事务之后再写入数据库
    事务再被数据库创建后,事务的TID就加入到 [1]活跃事务列表(Active list) 中,之后对于每一条记录,将[2.1]B.I旧值记录到日志log中(LAR规则),将[2.2]A.I新值写入到日志log中(CR规则),直到[3]遇到commit提交命令后,将事务的TID加入到事务提交列表(Commit list)中,这个时候进行[4]新值的写入,最后将[5] 事务的TID从活跃事务列表(Active list)中移除。流程图如下:
    数据库恢复技术(事物、三种更新策略以及恢复策略)_第5张图片
    之后重启动恢复的时候同样也是检查两张表,不过这一次和第一种策略略有不同:
    1、如果Commit list中有记录,那么需要进行redo操作,因为在前面的操作中还没有写到数据库中了;之后如果Active list中有记录将事务从中删除即可。
    2、如果Commit list中没有记录,Active list有记录,把TID从Active list中删除。因为之前都没有写,所以不需要进行undo操作。
Commit list Active list 操作
没有 redo
redo+把TID从Active list中删除
没有 把TID从Active list中删除
  • 第三种策略:新值即在提交事务之前写入数据库,又在提交事务之后写入数据库。这种策略考虑到了并发操作。
    事务再被数据库创建后,事务的TID就加入到 [1]活跃事务列表(Active list) 中,之后对于每一条记录,将[2.1]B.I旧值记录到日志log中(LAR规则),将[2.2]A.I新值写入到日志log中(CR规则),之后设置一个后台进程(优先级比较低那种),[3]在磁盘空闲的时候就往数据库里面写,[4]遇到commit提交命令后,将事务的TID加入到事务提交列表(Commit list)中,这个时候进行[5]新值的写入,最后将[6] 事务的TID从活跃事务列表(Active list)中移除。流程图如下:
    数据库恢复技术(事物、三种更新策略以及恢复策略)_第6张图片
    重启动恢复的时候同样也是检查两张表,但这次因为在前面的操作中也写了,就处于写了一部分没写一部分的状态,所以分析会略有不同。
    1、如果Commit list中有记录,那么需要进行redo操作,因为在前面的操作中还没有写到数据库中了;之后如果Active list中有记录将事务从中删除即可。
    2、如果Commit list中没有记录,Active list有记录,那需要进行undo操作,因为之前写了,认为没有提交,事务不成功,因此要进行undo操作。之后将事务从Active list中删除即可。
Commit list Active list 操作
没有 redo
redo+把TID从Active list中删除
没有 undo+把TID从Active list中删除

数据库恢复技术小结

一、数据库恢复目标

  • 1、减少发生故障——事务
  • 2、出现故障进行故障恢复——恢复策略+数据库更新规则+三种更新策略

二、事务
  四大特性:ACID
  1 原子性  2 一致性   3 隔离性  4 持久性

三、恢复策略
  最重要的便是 周期性转储+日志。
  日志存 TID+B.I+A.I

四、数据库更新规则

  • 1.提交规则(Commit Rule)——CR规则
  • 2.日志在前规则(Log Ahead Rule)——LAR规则

五、三种更新策略

  • 1、新值在提交前写
  • 2、新值在提交后写
  • 3、新值在提交前后都写(我全都要hh)

你可能感兴趣的:(数据库,数据库)