数据库笔记-事务管理

事务概述

事务是由一系列操作序列构成的程序执行单元,这些操作要么都做,要么都不做,是一个不可分割的工作单位。

SQL中的事务
  • 事务以Begin transaction开始,以Commit或 Rollback结束
  • Commit表示提交,事务正常结束.
  • Rollback表示事务由于某种原因而正常退出,撤消事务已做的操作,回滚到事务开始时状态.
事物的特性(ACID)
原子性(Atomicity)

事务在逻辑上是数据库的最基本工作当元,一个事务中包含的操作,要么全部执行并正常结束;要么什么都不做,当作此事务从未发生过。

原子性由恢复机制实现

一致性(Consistency)

事务执行的结果必须是使数据库从一个一致性状态转变到另一个一致性状态。如果在事务执行的过程中,由于硬件或软件等原因导致事务的执行中断,就会造成数据库的不一致性。因此事务的原子性是一致性的保证

数据库的一致性状态由用户来负责,由并发控制机制实现。

隔离性(Isolation)

数据库系统中多个事务可以被同时执行(并发执行)并必须保证一个事务的执行不能被其他事务干扰,即一个事务内部的操作及其使用的数据对其他的事务是隔离的,这样事务都感受不到系统中有其他事务在并发执行。

对任何一对事务T1,T2,在T1看来,T2要么在T1开始之前已经结束,要么在T1完成之后再开始执行。

隔离性通过并发控制机制实现。

持久性(Durability)

持久性是指一个事务一旦提交(即正常完成),他对数据库中的数据改变就是持久的,即使数据库因故障而受到破坏,DBMS也能正常恢复。

持久性通过恢复机制实现

ACID特性可能被以下两种情况遭到破坏

  • 多个事务并发执行时,各自的操作交叉执行
  • 由于各种故障导致事务中断
事务日志

如果提交了一个事务,SQL Server就会在事务日志中记录所有有关该事务的信息。

为一个事务记录的数据总量取决于以下几个方面:

  • 更改的数据量
  • 受影响的索引量
  • 作为事务的结果,必须分配或释放的页的数量

事务日志条目

  • 开始条目
  • 记录数据修改
  • 进行数据修改
  • 提交事务
  • 将日志页转存于磁盘

更新一条记录,日志文件将增加:

  • 一个数据删除记录,包括原有行中所有数据
  • 一个数据插入记录,包括修改后行中所有数据
  • 一个受该事务影响的每个索引的索引删除记录
  • 一个受该事务影响的每个索引的索引插入记录
  • 一个用于每个新数据或索引页的页分配记录,和一个用于每个释放数据或索引页的页释放记录

并发控制技术

并发可能出现的问题
丢失更新

当访问相同数据项的两个数据以某种范式交替执行时,就可能发生丢失更新问题。

两事务T1,T2恰好都执行修改了同一条数据而出现丢失更新

在这里插入图片描述

读“脏”数据

事务更新某个数据项,接着由于某种原因被撤销了,然而所更新的项在恢复到原值前,另一个事务读取了该项。

不可重复读

事务T1需要两次读取同一个数据,但是这两次的操作的间隔中,另一个事务T2改变了该数据的值。T1两次读取到的数据项值不同。

在这里插入图片描述

封锁

事务T在对某个数据对象操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不能更新此数据对象。

锁的类型
  • 排它锁(X锁):一个事务对某个数据成功地加了排它锁后,其他事务就不能对此对象加锁,也不能对此对象执行任何操作,只有该事务才能执行读和修改地操作。
  • 共享锁(S锁):一个事务对某个数据成功地加了共享锁后,其他食物不能对该对象加上X锁,但是可以加上自己的S锁。即该对象不能被加上X锁,但是可以被多个事务加上各自的S锁。所有对此对象加上S锁地事务只能读取对象,不能修改对象。

某数据对象上有一个X锁,则仅有此一个锁;若有一个S锁,则不可能有X锁,但是有可能有多个S锁

三级封锁协议
一级封锁
  • 任一事务在修改某数据之前,必须对其加上自己的X锁,直至事务结束才能释放之。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)

一级封锁布不采用S锁,不修改数据时时不需要加锁的。因此以及封锁解决了丢失更新的问题,但是不能保证可重复度和不读“脏”数据。

二级封锁
  • 一级封锁
  • 任一事务在读取某数据(不修改)前,必须对其加上S锁,读完后即可释放S锁。

二级封锁不能保证可重复读

三段封锁
  • 一级封锁
  • 任一事务在读取某数据(不修改)前,必须加上S锁,直至事务结束才释放此S锁。

三级封锁把上面的三个问题都解决了

并发调度的可串行性
  • 可串行性准则:多个事务并发执行的结果是正确的,当且仅当其结果与按某个次序串行的执行各事务所得到的结果相同。
  • 正确调度:一个给定的并发调度,当且仅当它是可串行化的。

注意两个串行结果不一定一样。

二段锁协议

一个事务在读、写任何数据前必须首先申请并获取对该数据的封锁;一旦一个事务释放了封锁,则该事务就不能在申请任何封锁。

明显特征:在事务的前面部分将逐步申请并获得各中加锁(而没有释放锁的操作),在后面部分将逐步释放锁(而没有加锁申请)

若所有事务均遵守两段锁协议,则这些事务的所有并行调度都是可串行化的。

两段锁协议是可串行化调度的充分条件而不是必要条件

数据库恢复技术

故障的种类
  • 事务内部故障

    • 预期的

      • 可通过事务程序本身发现(显式COMMIT或ROLLBACK)
    • 非预期的(事务故障)

      • 不能由应用程序处理的,如运算溢出、并行事务发生死锁而被选中撤销该事务等
  • 系统故障(软故障)

    • 指造成系统停止运转的任何事件,使得统要重新启动
    • 中央处理器故障、操作系统故障、突然停电
  • 介质故障(硬故障)

    • 外存故障,磁盘的磁头,瞬时的磁干扰
  • 计算机病毒

恢复技术的基本原理:冗余。数据库中任何一部分的数据,可以根据存储在系统别处的冗余数据来重建

恢复机制的两个关键:

  • 建立冗余数据
  • 根据冗余数据恢复数据库

恢复的最常用方法:转储和日志文件

数据转储
  • 定期把整个数据库复制到磁带、另一个磁盘或光盘保存起来,作为后备副本或后援副本(更通俗的叫法:备份文件)
  • 转储周期(备份周期)
  • 静态转储和动态转储
    • 静态转储:在系统没有事务运行的情况下进行转储
    • 动态转储:允许事务并发执行的转储(不能保证转储后的副本是正确有效的:在动态转储前,有一个事务将数据修改)
  • 海量转储和增量转储
    • 海量转储:数据库全部数据对象
    • 增量转储:只转储上次海量转储后更新的数据
登记日志文件
  • 日志文件的格式和内容;记录为单位和数据块为单位,有三类记录
    • 每个事务开始时,必须在日志文件中登记一条该事务的开始记录
    • 每个事务结束时,必须在日志文件中登记一条该事务的结束记录(注明COMMIT,ROLLBACK)
    • 任一事务的任一次对数据库的更新,都必须在日志文件中登入一条记录,其格式为(<事物标识>,<操作类型>,<更新前的数据旧值>,<更新后的数据新值>),<操作类型>中有插入、删除和修改三种类型。
  • 日志文件的作用:用来记录对数据库每一次更新活动的文件
  • 登记日志文件:“先写日志文件”的原则
    • 事务每一次对数据库的更新都必须写入日志文件
    • 必须先把日志记录写到日志文件中,在执行操作
故障策略
  • 事务故障的恢复
    • 发生后由系统自动完成
  • 系统故障的恢复
    • 重启系统,由系统自动完成
  • 介质故障的恢复
    • 由DBA重装数据库
  • 具有检查点的恢复技术
  • 数据库镜像
恢复事务故障

利用日志文件撤销此事务对数据库所作更新

  • 反向扫描日志文件,查找该事务的记录
  • 若找到的记录为改事务的开始记录,则UNDO结束;否则执行该记录的逆操作,继续反向扫描,直到找到事务的开始

上述操作系统自动完成

恢复系统故障

系统停止运转的任何事件,使得系统要重新启动。

为保证数据一致性,恢复子系统必须在系统重新启动时:

  • 让所有非正常终止的事务回滚,强行撤消(UNDO)所有未完成事务;
  • 重做(REDO)所有已提交的事务,以将数据库真正恢复到一致状态。

利用日志文件恢复事务的过程分为二步:

  • 从头扫描日志文件,找出哪些事务在故障发生时已经结束(这些事务有BEGIN TRANSACTION和COMMIT记录),哪些事务尚未结束(这些事务有BEGIN TRANSACTION记录,无COMMIT记录)。
  • 对尚未结束的事务进行撤销(也称UNDO)处理,对已经结束的事务进行重做(REDO)处理。

UNDO处理的方法:反向扫描日志文件,对每个UNDO事务的更新操作执行反操作。

REDO处理的方法:正向扫描日志文件,重新执行登记的操作。

利用转储和日志文件可以有效的恢复数据库。

系统故障的恢复是由系统在重新启动时自动完成的,不需要用户干预。系统的恢复步骤是:

  • 正向扫描日志文件(即从头扫描日志文件)
    找出在故障发生前已经提交事务,将其事务标识记入重做(REDO)队列。
    同时找出故障发生时尚未完成的事务,将其事务标识记入撤消队列。
  • 对撤消队列中的各个事务进行撤消(UNDO)处理。方法是,反向扫描日志文件,对每个UNDO事务的更新操作执行逆操作。
  • 对重做队列中的各个事务进行重做(REDO)处理。方法是:正向扫描日志文件,对每个REDO事务重新执行日志文件登记的操作。
介质故障恢复

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

介质故障的恢复需要DBA介入。DBA需要重装最近转储的数据库副本和有关的各日志文件副本,然后执行系统提供的恢复命令即可,具体的恢复操作由DBMS完成。

  • 装入最新的数据库后备副本(离故障发生时刻最近的转储副本),使数据库恢复到最近一次转储时的一致性状态。
    对于动态转储的数据库副本,还须同时装入转储开始时刻的日志文件副本,利用恢复系统故障的方法(即REDO+UNDO),才能将数据库恢复到一致性状态。
  • 装入相应的日志文件副本(转储结束时刻的日志文件副本),重做已完成的事务。
具有检查点的恢复技术

利用日志技术进行数据库恢复时,需要检查所有日志记录。存在两个问题:

  1. 搜索整个日志将耗费大量的时间。
  2. 需要REDO处理很多已经将操作结果写到数据库中的操作,浪费了大量时间。

具有检查点的恢复技术:在日志文件中增加一类新的记录–检查点记录(checkpoint),增加一个重新开始文件,并让恢复子系统在登录日志文件期间动态地维护日志。

检查点记录的内容包括:

  1. 建立检查点时刻所有正在执行的事务清单。
  2. 这些事务最近一个日志记录的地址。
动态维护日志文件

动态维护日志文件的方法是,周期性地执行如下操作:建立检查点,保存数据库状态。

具体步骤是:

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

恢复子系统可以定期或不定期地建立检查点保存数据库状态。

具体步骤
  1. 从重新开始文件中找到最后一个检查点记录在日志文件中的地址,由该地址在日志文件中找到最后一个检查点记录。
  2. 由该检查点记录得到检查点建立时刻所有正在执行的事务清单ACTIVE-LIST。 建立两个事务队列: UNDO-LIST;REDO-LIST。把ACTIVE-LIST暂时放入UNDO-LIST队列,REDO队列暂为空。
  3. 从检查点开始正向扫描日志文件 如有新开始的事务Ti,把Ti暂时放入UNDO-LIST队列;如有提交的事务Tj,把Tj从UNDO-LIST队列移到REDO-LIST队列;
  4. 对UNDO-LIST中的每个事务执行UNDO操作, 对REDO-LIST中的每个事务执行REDO操作

数据库镜像

介质故障是对系统影响最为严重的一种故障。

许多数据库管理系统提供了数据库镜像(Mirror)功能用于数据库恢复。即根据DBA的要求,自动把整个数据库或其中的关键数据复制到另一个磁盘上。

DBMS自动保证镜像数据与主数据的一致性。

一旦出现介质故障,可由镜像磁盘继续提供使用,同时DBMS自动利用镜像磁盘数据进行数据库的恢复,不需要关闭系统和重装数据库副本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值