秋招 基础知识之——数据库系统篇

内容参考《数据库系统概论》(第五版)。

事务处理技术

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

事务和程序是两个概念,一般地讲,一个程序中包含多个事务。

事务的开始与结束可以由用户显式控制。如果用户没有显式地定义事务,则由数据库管理系统按默认规定自动划分事务。在SQL中,定义事务的语句一般有三条:

BEGIN TRANSACTION;
COMMIT;
ROLLBACK;

事务通常以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。

COMMIT表示提交,即提交事务的所有操作。具体说就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结束。

ROLLBACK表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续执行,系统将事务中对数据库的所有已完成的操作(指对数据库的更新操作)全部撤销,回滚到事务开始时的状态。

  • 事务的ACID特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持续性(Durability)。

(1)原子性:事务是数据库的逻辑工作单位,事务中包括的诸操作要么都做,要么都不做。

(2)一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。(因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统运行中发生故障,有些事务尚未完成就被迫中断,这些未完成的事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。可见一致性与原子性是密切相关的。)

(3)隔离性:一个事务的执行不能被其他事务干扰。即一个事务的内部操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

(4)持续性:也成永久性,指一个事物一旦提交,它对数据库中数据的改变就应该是永久性的。

保证事务ACID特性是事务管理的重要任务。事务ACID特性可能遭到破坏的因素有:

(1)多个事务并行运行时,不同事务的操作交叉执行;

(2)事务在运行过程中被强行停止。

因此数据库管理系统必须保证:(1)多个事务的交叉运行不影响这些事务的原子性;(2)被强行终止的事务对数据库和其他事务没有任何影响。

这些就是数据库管理系统中恢复机制和并发控制机制的责任。

一、数据库恢复技术

1、概述:

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

2、故障的种类:

(1)事务内部的故障:

有的是可以通过事务程序本身发现,有的是非预期的,不能由事务程序处理。

事物内部更多的故障是非预期的,是不能由应用程序处理的。如:运算溢出、并发事务发生死锁而被选中撤销该事务,违反了某些完整性限制而被终止等。

事务故障意味着事务没有达到预期的终点(COMMIT或者显式的ROLLBACK),因此,数据库可能处于不正确的状态。恢复程序要在不影响其他事务运行的情况下,强行回滚该事务,即撤销该事务已经做出的任何对数据库的修改,使得该事务好像根本没有启动一样。这类恢复操作称为事务撤销(UNDO)

(2)系统故障:

是指造成系统停止运转的任何事件,使得系统要重新启动。如:特定类型的硬件错误(CPU故障)、操作系统故障、DBMS代码错误、系统断电等。这类故障影响正在运行的所有事务,但不破坏数据库。此时主存内容,尤其是数据库缓存区(在内存)中的内容都被丢失,所有运行事务都非正常终止。发生系统故障时,一些尚未完成的事务的结果可能已送入物理数据库,从而造成数据库可能处于不正确的状态。为保证数据一致性,需要清除这些事务对数据库的所有修改。

恢复子系统必须在系统重新启动时让所有非正常终止的事务回滚,强行撤销所有未完成事务。

另一方面,发生系统故障时,有些已完成的事务可能有一部分甚至全部留在缓冲区,尚未写回到磁盘上的物理数据库中,系统故障使得这些事务对数据库的修改部分或全部丢失,这也会使数据库处于不一致状态,因此应将这些事务已提交的结果重新写入数据库。所以系统重新启动后,恢复子系统除需要撤销所有未完成的事务外,还需要重做(REDO)所有已提交的事务,以将数据库真正恢复到一致状态。

(3)介质故障:

系统故障常称为软故障(soft crash),介质故障称为硬故障(hard crash)。硬故障指外存故障,如磁盘损坏、磁头碰撞,瞬时强磁场干扰等。这类故障将破坏数据库或部分数据库,并影响正在存取这部分数据的所有事务。这类故障比前两类故障发生的可能性小得多,但破坏性最大。

(4)计算机病毒

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

恢复的基本原理十分简单,可以用一个词来概括:冗余

3、恢复的实现技术:

恢复机制涉及的两个关键问题是:如何建立冗余数据,以及如何利用这些冗余数据实施数据库恢复。

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

(1)数据转储:

是数据库恢复中采用的基本技术。转储即数据库管理员定期将整个数据库复制到磁带、磁盘或其他存储介质上保存起来的过程。这些备用的数据称为后备副本(backup)或后援副本。

转储可分为静态转储和动态转储。

  • 静态转储:在系统无运行事务时进行的转储操作。转存期间不允许对数据库的任何存取、修改活动。会降低数据库的可用性。
  • 动态转储:转出期间允许对数据库进行存取或修改。即转储和用户事务可以并发执行。可以克服静态转储的缺点,但是转储结束时后援副本上的数据并不能保证正确有效。为此,必须把转储期间各事务对数据库的修改活动登记下来,建立日志文件(log file)

转储还可以分为海量转储和增量转储两种方式。海量转储是指每次转储全部数据库;增量转储值每次只转储上一次转储后更新过的数据。


(2)登记日志文件:

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

①日志文件的格式和内容:

  • 日志文件的两种格式:以记录为单位的日志文件;以数据块为单位的日志文件。
  • 以数据块为单位的日志文件,日志记录的内容包括事务标识和被更新的数据块。更新前和更新后的整个数据块都放入日志文件中,操作类型和操作对象等信息就不必放入日志记录中了。
  • 以记录为单位的日志文件中需要等级的内容包括:

各个事务的开始标记、各个事务的结束标记、各个事务的所有更新操作。

这里每个事务的开始标记、每个事务的结束标记和每个更新操作均为日志文件中的一个日志记录。

每个日志记录的内容主要包括:

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

②日志文件的作用:用来进行事务故障恢复和系统故障恢复,并协助后备副本进行介质故障恢复。具体作用是:

  • 事务故障恢复和系统故障恢复必须用日志文件。
  • 在动态转储方式中必须建立日志文件,后备副本和日志文件结合起来才能有效地恢复数据库。
  • 在静态转储方式中也可以建立日志文件,当数据库毁坏后可重新装入后援副本把数据库恢复到转储结束时刻的正确状态,然后利用日志文件把已完成的事务进行重做处理,对故障发生时尚未完成的事务进行撤销处理。

③登记日志文件:

为保证数据库是可恢复的,登记日志文件时必须遵循两条原则:

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

4、恢复策略:

(1)事务故障的恢复:

事务故障是指事务在运行至正常终止点前被终止,这时恢复子系统应利用日志文件撤销(UNDO)此事务已对数据库进行的修改。事务故障的恢复是由系统自动完成的,对用户是透明的。系统的恢复步骤如下:

①反向扫描日志文件(从最后向前扫描日志文件),查找该事务的更新操作。

②对该事务的更新操作执行逆操作,即将日志记录中“更新前的值”写入数据库。

③继续反向扫描日志文件,查找该事务的其他更新操作,并做同样处理。

④如此处理下去,直至读到此事务的开始标记,事务故障恢复就完成了。

(2)系统故障的恢复

系统故障造成数据库不一致状态的原因有两个,一是未完成事务对数据库的更新可能已写入数据库,二是已提交事务对数据库的更新可能还留在缓冲区没来得及写入数据库。因此恢复操作就是要撤销故障发生时未完成的事务,重做已完成的事务。(系统故障的恢复是由系统在重新启动时自动完成的,不需要用户干预。)系统的恢复步骤如下:

①正向扫描日志文件(从从头扫描日志文件),找出在故障发生前已经提交的事务(这些事务既有BEGIN TRANSACTION记录,也有COMMIT记录),将其事务标识记入重做队列(REDO-LIST)。同时找出故障发生时尚未完成的事务(这些事务只有BEGINTRANSATION记录,没有响应的COMMIT记录),将其事务标识记入撤销队列(UNDO-LIST)。

②对撤销队列中的各个事务进行撤销(UNDO)处理。

进行撤销处理的方法是,反向扫描日志文件,对每个撤销事务的更新操作执行逆操作,即将日志记录中“更新前的值”写入数据库。

③对重做队列中的各个事务进行重做处理。

进行重做处理的方法是,正向扫描日志文件,对每个重做事务重新执行日志文件登记的操作,即将日志记录中“更新后的值”写入数据库。

(3)介质故障的恢复

发生介质故障后,磁盘上的物理数据和日志文件被破坏,这是最严重的一种故障,恢复方法是重装数据库,然后重做已完成的事务。

①装入最新的数据库后备副本(离故障发生时刻最近的转储副本),使数据库恢复到最近一次转储时的一致性状态。

②装入相应的日志文件副本(转储结束时刻的日志文件副本),重做已完成的事务。

5、具有检查点的恢复技术:

因为搜索日志耗费了大量时间,所以发展了具有检查点的恢复技术,可以改善效率。增加了一类新的记录:检查点记录。

检查点记录的内容包括:

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

6、数据库镜像:


二、并发控制

1、概述:

(1)并发操作带来的数据不一致性包括丢失修改、不可重复读、读“脏”数据。

  • 丢失修改:两个事物T1和T2读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致T1的修改被丢失。
  • 不可重复读:指事物T1读取数据后,事务T2执行更新操作,使T1无法再现前一次读取结果。具体包括以下三种情况:

①事务T1读取某一数据后,事务T2对其进行了修改,当事务T1再次读该数据时,得到与前一次不同的值。

②事务T1按一定条件从数据库中读取了某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录神秘地消失了。

③事务T1按一定条件从数据库中读取了某些数据记录后,事务T2插入了一些记录,当T1再次按相同条件读取数据时,发现多了一些记录。

后两种不可重复读也成为幻影现象。

  • 读“脏”数据:指事务T1修改某一数据并将其写回磁盘,事务T2读取同一数据后,T1由于某种原因被撤销,这时被T1修改过的数据恢复原值,T2读到的数据就与数据库中的数据不一致,则T2读到的数据就为“脏”数据,即不正确的数据。

(2)并发控制的主要技术有封锁(locking)、时间戳(timestamp)、乐观控制法(optimistic scheduler)和多版本并发控制(MVCC)等。

2、封锁:

基本的封锁类型有两种:排他锁(简称X锁)、共享锁(简称S锁)。

  • 排他锁又称为写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁为止。(这就保证了其他事务在T释放A上的锁之前不能再读取和修改A。)
  • 共享锁又称为读锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁为止。(这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。)

3、封锁协议:运用X锁和S锁时还需要约定一些规则(即封锁协议)。

(1)一级封锁协议:事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。

(事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。)

(2)二级封锁协议:在一级封锁协议基础上增加:事务T在读取数据R之前必须先对其加S锁,读完后即可释放S锁。

(3)三即封锁协议:在一级封锁协议基础上增加:事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放S锁。

4、活锁和死锁:封锁的方法可能引起活锁和死锁等问题。
(1)活锁:解决活锁的简单方法是采用先来先服务的策略。

(2)死锁:两个事务互相等待的局面,这两个事务永远不能结束,形成死锁。

解决死锁的两类方法:

①死锁的预防:有两种方法:

  • 一次封锁法:要求每个事物必须一次将所有要使用的数据全部加锁,否则就不能继续执行。(问题:会降低并发度。)
  • 顺序封锁法:预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实施封锁。(问题:成本高。)

②死锁的诊断与解除:

  • 超时法:如果一个事务的等待时间超过了规定的时限,就认为发生了死锁。(优点:实现简单;不足:一是可能误判死锁,二是时限若设置过长,则不能及时发现死锁)
  • 等待图法:事务等待图是一个有向图,结点为正在运行的事务,边为事务等待的情况。并发控制子系统周期性地生成事务等待图,并进行检测。

一般解除死锁的方法是:选择一个处理死锁代价最小的事务,将其撤销,释放此事务持有的所有的锁,使其他事务得以继续运行下去。

5、并发调度的可串行性:执行结果等价于串行调度的调度是正确的,叫可串行化调度。

(1)可串行化调度:多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行这些事务时的结果相同,称这种调度策略为可串行化调度。

可串行性是并发事务正确调度的准则。

(2)冲突可串行化调度:

冲突操作是指不同的事务对同一个数据的读写操作和写写操作:(其他操作是不冲突操作)

Ri(x)与Wj(x)  /*事务Ti读x,事务Tj写x,i不等于j*/

Wi(x)与Wj(x)  /*事务Ti写x,事务Tj写x,i不等于j*/

不同事务的冲突操作是不能交换的。同一事务的两个操作是不能交换的。

一个调度Sc在保证冲突操作的次序不变的情况下,通过交换两个事务不冲突操作的次序得到另一个调度Sc',如果Sc'是串行的,称调度Sc为冲突可串行化的调度。

若一个调度是冲突可串行化,则一定是可串行化的调度。反之则不一定。

6、两段锁协议:

为保证并发调度的正确性,DBMS采用两段锁协议的方法实现并发调度的可串行性。

两段锁协议是指所有事务必须分两个阶段对数据项加锁和解锁:

  • 在对任何数据进行读、写操作之前,首先要申请并获得对该数据的封锁;
  • 在释放一个封锁之后,事务不再申请和获得任何其他封锁。

注意:事务遵守两段锁协议是可串行化调度的充分条件,而不是必要条件。

且由于两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此遵守两段锁协议的事务可能发生死锁。

7、封锁的粒度:

封锁对象的大小称为封锁粒度。封锁对象可以是这样一些逻辑单元:属性值、属性值的集合、元组、关系、索引项、整个索引直至整个数据库;也可以是这样一些物理单元:页(数据页或索引页)、物理记录等。

封锁粒度与系统的并发度和并发控制的开销密切相关。封锁粒度越大,数据库所能够封锁的数据单元就越少,并发度就越小,系统开销就越小;反之,封锁的粒度越小,并发度越高,但系统开销也就越大。

在一个系统中同时支持多种封锁粒度供不同的事务选择,这种封锁方法称为多粒度封锁。

(1)多粒度封锁:

多粒度树:根结点是整个数据库,表示最大的数据粒度,叶结点表示最小的数据粒度。

下图为一个三级粒度树。


多粒度封锁协议允许多粒度树中的每个结点被独立地加锁。对一个结点加锁意味着这个结点的所有后裔结点也被加以同样类型的锁。

显示封锁是应事务的要求直接加到数据对象上的锁;隐式封锁是该数据对象没有被独立加锁,是由于其上级结点加锁而使该数据对象加上了锁。两种封锁的效果是一样的。这使得检查封锁之间冲突的效率很低,因此引入意向锁。

(2)意向锁:

意向锁的含义是:如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;对任一个结点加锁时,必须先对它的上层结点加意向锁。

①意向共享锁(IS锁):如果对一个数据对象加IS锁,表示它的后裔结点拟加S锁。

②意向排他锁(IX锁):如果对一个数据对象加IX锁,表示它的后裔结点拟加X锁。

③共享意向排他锁(SIX锁):如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁(它的后裔结点拟加X锁)。例如对某个表加SIX锁,则表示该事务要读整个表,同时会更新个别元组。

申请封锁时应该按自上而下的次序进行,释放封锁时则应该按自下而上的次序进行。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值