数据库理论之事务与恢复技术

本文参考资源:

什么是事务?事务的四个特性、不考虑隔离会导致的三个问题以及四种隔离级别_数据库_cd546566850的博客-CSDN博客

基本概念

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

在关系数据库中,一个事务可以是一条或多条 SQL 语句, 也可以包含一个或多个程序。
一个程序通常包含多个事务

显式定义方式:

begin transaction
....
commit/rollback

隐式方式:

当用户没有显式地定义事务时,DBMS 按缺省规定自动划分事务(一句SQL语句一个事务)

AutoCommit 事务是 SQL Server 默认事务方式,

事务的特性ACID

  1. 原子性(atomicity): 一个事务是一个不可分割的工作单位,事务中包括的诸操作要
    么都做,要么都不做;
  2. 一致性(consistency): 事务必须使数据库从一个一致性状态变成另一个一致性状态。
  3. 隔离性(isolation):一个事务的执行不能被其他事务干扰。
  4. 持续性(durability): 也称永久性,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

不考虑隔离性会导致的三个问题

  1. 脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
  2. 不可重复读:一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好另一个事务更新了该数据,两次结果相异,不可被信任。通俗来讲就是:事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

  3. 幻读(虚读):一个事务执行两次查询,第二次结果集包含第一次中没有或某些行已经被删除的数据,造成两次结果不一致,只是另一个事务在这两次查询中间插入或删除了数据造成的。通俗来讲就是:例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读

解决办法(四种隔离级别)

  1. Read Uncommited(读取未提交内容)

读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。但是,读未提交产生了脏读,采用读提交可以解决脏读问题。

  1. Read Commited(读取提交内容)

读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。 读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但是,读提交两次查询会产生不同的查询结果,就会造成不可重复读问题,采用重复读可以解决此问题。

  1. Repeatable Read(重复读)

重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。重复读可以解决不可重复读问题。应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。采用Serializable可以解决幻读问题

  1. Serializable(可串行化)

Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

注意

  1. 大多数数据库默认的事务隔离级别是Read committed,比如Sql Server, Oracle。Mysql的默认隔离级别是Repeatable read,只会出现幻读。
  2. 隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。

  3. 设置数据库的隔离级别一定要是在开启事务之前。

数据库恢复技术

故障是不可避免的:
+ 系统故障:计算机软、硬件故障
+ 人为故障:操作员的失误、恶意的破坏等。

数据库的恢复:
+ 把数据库从错误状态恢复到某一已知的正确状态(亦称为一致状态或完整状态)

故障的种类

事务内部的故障 :

  1. 有的是可以通过事务程序本身发现的
  2. 有的 是非预期的,不能由应用程序处理(如运算溢出、死锁等)

后面,事务故障仅指非预期的故障

事务故障的恢复:UNDO 撤销

系统故障:

造成系统停止运转的任何事件,使得系统要重新启动。(硬件错误、断电等)

影响正在运行的所有事务,但不破坏数据库。此时内存,尤其是数据库缓冲区中的内容全部丢失,所有运行事务非正常终止。

恢复:
1. 未提交的事务:UNDO 撤销所有未完成的事务
2. 已提交的事务,但缓冲区内容未完全写入磁盘:REDO 重做所有已提交的事务

介质故障:

系统故障称为软故障,介质故障称为硬故障(外存故障,如磁盘损坏)

恢复:装入数据库发生介质故障前某个时刻的数据副本,REDO 自此时开始的所有成功事务,将这些事务已提交的结果重新写入

计算机病毒:

计算机病毒是一种人为的故障或破坏,是一些恶作剧者研制的一种计算机程序。可以繁殖和传播,并造成对计算机系统包括数据库的危害。

总之: 各类故障,对数据库的影响有两种可能性
+ 一是数据库本身被破坏
+ 二是数据库没有被破坏,但数据可能不正确,这是由于事务的运行被非正常终止造成的。

恢复的实现技术

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

恢复机制涉及的两个关键问题:
1. 如何建立冗余数据
- 数据转储 (backup)
- 日志文件 (logging)
2. 如何利用这些冗余数据实施数据库恢复

数据转储

转储是指 DBA 将整个数据库复制到其他存储介质上保存起来的过程,备用的数据称为后备副本或后援副本

  • 数据库遭到破坏后可以将后备副本重新装入
  • 重装后备副本只能将数据库恢复到转储时的状态

转储方式:

按不同的划分方法可以划分为静态/动态转储或海量/增量转储

静态转储

  1. 定义:在系统中无事务运行时进行的转储操作。 转储开始的时刻数据库处于一致性状态,而转储不允许对数据库的任何存取、修改活动。静态转储得到的一定是一个数据一致性的副本。
  2. 优点:实现简单
  3. 缺点:降低了数据库的可用性

转储必须等待正运行的用户事务结束才能进行;新的事务必须等待转储结束才能执行

动态转储

  1. 定义:转储期间允许对数据库进行存取或修改。转储和用户事务可以并发执行 。
  2. 优点:不用等待正在运行的用户事务结束;不会影响新事务的运行。
  3. 实现:必须把转储期间各事务对数据库的修改活动登记下来,建立日志文件
    后备副本加上日志文件就能把数据库恢复到某一时刻的正确状态 。

海量转储

  1. 定义:每次转储全部数据库
  2. 特点:从恢复角度,使用海量转储得到的后备副本进行恢复更方便一些。

增量转储

  1. 定义:每次只转储上一次转储后更新过的数据
  2. 特点:如果数据库很大,事务处理又十分频繁,则增量转储方式更实用更有效

日志文件

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

日志文件的格式:

  1. 以记录为单位:
    • 日志文件中需要登记的内容包括:
      1. 各个事务的开始标记(BEGIN TRANSACTION)
      2. 各个事务的结束标记(COMMIT 或 或 ROLLBACK)
      3. 各个事务的所有更新操作
        以上均作为日志文件中的一个日志记录
    • 每个日志记录的内容:
      1. 事务标识(标明是哪个事务)
      2. 操作类型(插入、删除或修改)
      3. 操作对象(记录内部标识)
      4. 更新前数据的旧值(对插入操作而言,此项为空值)
      5. 更新后数据的新值(对删除操作而言, 此项为空值)
  2. 以数据块为单位
    日志记录内容包括:
    1. 事务标识(标明是哪个事务)
    2. 被更新的数据块

日志文件的作用:
+ 进行事务故障恢复
+ 进行系统故障恢复
+ 协助后备副本进行介质故障恢复
1. 事务故障恢复和系统故障恢复必须用日志文件
2. 在动态转储方式中必须建立日志文件,后备副本和日志文件结合起来才能有效地恢复数据库
3. 静态转储方式中也可以建立日志文件(重新装入后备副本,然后利用日志文件把已完成的事务进行重做,对未完成事务进行撤销)

登记日志文件的基本原则:

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

(只要没有记录事务的结束标记,就算多记录了一条实际没有执行的语句,恢复之后也会回滚)

恢复策略

事务故障的恢复

事务故障:事务在运行至正常终止点前被终止

恢复方法:由恢复子系统应利用日志文件撤消(UNDO)此事务已对数据库进行的修改

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

事务故障的恢复步骤:
1. 反向扫描文件日志,查找该事务的更新操作。
2. 对该事务的更新操作执行逆操作。即将日志记录中 “ 更新前的值” ” 写入数据库 。
+ 插入操作,“更新前的值” 为空,则相当于做删除操作
+ 删除操作,“更新后的值” 为空,则相当于做插入操作
+ 若是修改操作,则相当于用修改前值代替修改后值
3. 继续反向扫描日志文件,查找该事务的其他更新操作,并做同样处理。
4. 如此处理下去,直至读到此事务的开始标记,事务故障恢复就完成了。

系统故障的恢复

系统故障可能导致未完成事务对数据库的更新已写入数据库,或已提交事务对数据库的更新还留在缓冲区没来得及写入数据库,只需要做对应的UNDO或REDO操作。

介质故障的恢复

  1. 重装数据库
    • 装入最新的后备副本,使数据库恢复到最近一次转储时的一致性状态(分为静态转储的副本和动态转储的副本,动态转储的副本还需配合日志文件做恢复)
  2. 装入有关的日志文件副本,重做已完成的事务

介质故障的恢复需要 DBA 介入

具有检查点的数据恢复

利用日志技术进行数据库恢复存在两个问题:
+ 搜索整个日志将耗费大量的时间
+ REDO 处理:事务实际上已经执行,又重新执行,浪费了大量时间

具有检查点的数据恢复技术在正常工作时周期性地执行如下操作:建立检查点,保存数据库状态。
具体步骤是:
1. 将当前日志缓冲区中的所有日志记录写入磁盘的日志文件上
2. 在日志文件中写入一个检查点记录
3. 将当前数据缓冲区的所有数据记录写入磁盘的数据库中
4. 把检查点记录在日志文件中的地址写入一个重新开始文件

数据库理论之事务与恢复技术

当事务 T 在一个检查点之前提交,T 对数据库所做的修改一定都已写入数据库

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/%e6%95%b0%e6%8d%ae%e5%ba%93%e7%90%86%e8%ae%ba%e4%b9%8b%e4%ba%8b%e5%8a%a1%e4%b8%8e%e6%81%a2%e5%a4%8d%e6%8a%80%e6%9c%af/

发表评论

电子邮件地址不会被公开。