一:事务系统
1. 事务的工作模型
事务必须满足原子性,所封装的操作或者全做或者全不做。
事务管理系统需要做两件事,1) 让日志系统产生日志,2) 保证多个事务并发执行,满足ACID 特性。
事务系统工作模型,见图1 。
如图,事务管理管理器控制查询处理器的执行、控制日志系统以及缓冲区。日志在缓冲区生成,日志管理器在一定的时候控制缓冲区的刷盘操作。当系统崩溃的时候,恢复管理器就被激活,检查日志并在必要时利用日志恢复数据。
2. 事务的原语操作
在事务系统的运行当中,有三个地址空间供元素存储:1) 磁盘空间、2) 缓冲区、3) 事务的局部地址空间。
一个简单的读、修改X 元素操作的流程如:事务到缓冲中读取元素X ,如果命中,则读取事务局部地址空间并返回,如果未命中,则先将相关页从磁盘读入缓冲区。事务在它的局部地址空间中修改元素X ,然后写入缓冲区,再从缓冲区写入磁盘。当然缓冲区的数据也可能不是立即拷贝入磁盘的,这取决于具体的缓冲区管理策略。
为了便于描述,我们描述了五个操作原语:
1) INPUT(X) :将包含数据库元素X 的磁盘块拷贝到内存缓冲区
2) READ(X,t) :将数据库元素X 拷贝到事务的局部变量t 。更准确地说,如果包含数据库元素X 的块不在内存缓冲区中,则首先执行INPUT(X) 。接着将X 的值赋给局部变量t 。
3) WRITE(X,t) :将局部变量t 的值拷贝到内存缓冲区中的数据库元素X 。更准确地说,如果包含数据库元素X 的块不在内存缓冲区中,则首先执行INPUT(X) 。将着将t 的值拷贝到缓冲区中的X 。
4) OUTPUT(X) :将包含X 的缓冲区拷贝到回磁盘。
3. 应用
假设银行系统数据库中有两个元素,元素A( 表示用户1 的余额,值为1000 ,单位:RMB) 与元素B( 表示用户2 的余额,值为500 ,单位:RMB) 。这时候用户1 需要向用户2 转帐50 元。相应的过程为:
A := A – 50;
B := B + 50;
执行之前,两个用户的总余额为1500(1000+500) ,两个操作执行成功之后总余额还是1500(950+550) 。处于一致性状态。
如果只有前一条执行成功,那总额只为1450(950+50) 。处于不一致状态。
为了避免这种不一致状态,我们需要将这两个操作封装成一个事务T 。
我们将这两个操作分解为原语操作。如下:
READ(A,t); t := t-50; WRITE(A,t);
READ(B,t); t := t+50; WRITE(B,t);
OUTPUT(A); OUTPUT(B) // 这两个OUTPUT 原语操作由缓冲区管理器发出。
表1 给出了这8 个原语操作的执行步骤,给出了每一步中A 和B 的内存值、磁盘拷贝的值以及事务T 地址空间中局部变量t 的值
表1 : 一个事务的步骤及其对内存和磁盘的影响
步骤
|
动作
|
t
|
内存A
|
内存B
|
磁盘A
|
磁盘B
|
1
|
READ (A,t )
|
1000
|
1000
|
|
1000
|
500
|
2
|
t := t-50
|
950
|
1000
|
|
1000
|
500
|
3
|
WRITE(A,t)
|
950
|
950
|
|
1000
|
500
|
4
|
READ (B,t )
|
500
|
950
|
500
|
1000
|
500
|
5
|
t := t+50
|
550
|
950
|
500
|
1000
|
500
|
6
|
WRITE(B,t)
|
550
|
950
|
550
|
1000
|
500
|
7
|
OUTPUT (A )
|
550
|
950
|
550
|
950
|
500
|
8
|
OUTPUT (B )
|
550
|
950
|
550
|
950
|
550
|
在表1 中不难发现,只要所有的这些步骤都执行成功,数据库的一致性就能得到保持。如果在执行OUTPUT(A) 前系统发生了故障,那么磁盘上存储的数据库不会受到任何影响,就好象事务T 从来没有发生过一样。但是如果故障在OUTPUT(A) 后而在OUTPUT(B) 前发生,那么数据就会处于 不一致状态( 从表中可以看出,磁盘中A 为950 ,B 为500) 。我们不能防止这种情况的发生,但可以安排当这些情况发生时对问题进行修复----- 或者A 为1000 、B 为为500 ,或者A 为950 ,B 为550 。
二:undo 日志
1. 概述
日志是日志记录的一个序列。在多事务的数据库系统中,每个事务有若干个操作步骤。每个日志记录记载有关某个事务已做的某些情况。几个事务的行为可以是“ 交错的” ,因此可能是一个事务的某个步骤被执行,并且其效果被记录到日志中,接着执行另外一个事务的某个步骤并记入日志,接着可能接着做第一事务的下一个步骤,也可能执行另外一个事务的某个步骤。依次类推。事务的交错执行使日志更复杂,因为仅在事务结束后记载事务的全过程是不够的。
如果系统崩溃,恢复管理器就被激活,检查日志以重建数据库的一致性状态。恢复时,有些事务的工作将会重做,它们写到数据库的新值会重写一次。而另外一些事务的工作将被撤消,数据库被恢复,将仿佛这些事务从来没执行过一样。
Undo 日志是日志类型的一种,这类日志仅仅进行第二类修复。对于要被撤消的事务,因为不能肯定它对数据库的修改是否已经写到磁盘中,所以对于该事务的所有更新都将被撤消,数据库恢复到事务发生以前的状态。
2. 日志记录
日志只允许以附加的方式写入数据。日志块最初在主存中创建,像数据块一样也由缓冲区管理,在确当的时刻,日志块会从缓冲区写入到磁盘。
关于undo 记录形式有四种:
1) : 这一记录表示事务T 开始
2) : 事务T 已经完成。
3) : 事务T 不能成功执行。
4) : 事务T 改变了数据库元素X 的值,元素X 原来的值为v 。
3.undo 日志规则
要想让undo 日志能使我们从系统故障中恢复,事务必须遵循两条规则。
规则1) 如果事务T 改变了数据库元素X ,那么事务的日志记录必须在X 的新值写到磁盘前写到磁盘
规则2) 如果事务提交,则其COMMIT 日志记录必须在事务改变的所有数据库元素已写到磁盘后再写到磁盘,但应尽快。
简单概括,undo 日志系统顺序如下:
1) 指明所改变数据库元素的日志记录
2) 改变的数据库元素自身
3) COMMIT 日志记录。
4. 应用
对于前面所举的例子(A 转帐50 元给B 帐号) ,如果使用了undo 日志系统,则相关的工作流程如表2 如下。
表2 :undo 日志系统的工作原理
步骤
|
动作
|
t
|
内存A
|
内存B
|
磁盘A
|
磁盘B
|
undo 日志
|
1
|
|
|
|
|
|
|
<START T>
|
2
|
READ (A,t )
|
1000
|
1000
|
|
1000
|
500
|
|
3
|
t := t-50
|
950
|
1000
|
|
1000
|
500
|
|
4
|
WRITE(A,t)
|
950
|
950
|
|
1000
|
500
|
<T, A, 1000>
|
5
|
READ (B,t )
|
500
|
950
|
500
|
1000
|
500
|
|
6
|
t := t+50
|
550
|
950
|
500
|
1000
|
500
|
|
7
|
WRITE(B,t)
|
550
|
950
|
550
|
1000
|
500
|
<T, B, 500>
|
8
|
FLUSH LOG
|
|
|
|
|
|
|
9
|
OUTPUT (A )
|
550
|
950
|
550
|
950
|
500
|
|
10
|
OUTPUT (B )
|
550
|
950
|
550
|
950
|
550
|
|
11
|
|
|
|
|
|
|
<COMMIT T>
|
12
|
FLUSH LOG
|
|
|
|
|
|
|
在表2 ,我们可以看到FLUSH LOG 这个命令。该命令的用于强制将还没有刷盘日志记录写到磁盘上。对于步骤8 执行之前,三个undo 记录(,,) 是存储在缓冲区中的( 这样描述是为将问题简单化) ,执行步骤8 之后,三条undo 记录便写入了磁盘日志文件。在步骤12 再次执行FLUSH LOG 命令时,只将未刷盘的日志记录写入磁盘。
步骤9 、10 ,在前面已经描述过,是将数据库元素的修改从缓冲区写入到磁盘文件,因为WRITE 操作仅仅是将修改反应到缓冲区中( 这样描述也是为了将问题简单化) 。
关注步骤8 ,执行完步骤8 之后,将满足undo 的规则1( 如果事务T 改变了数据库元素X ,那么形如的日志记录必须在X 的新值写到磁盘前写到磁盘) 。在我们真正将数据库元素A 与B 的修改反应到磁盘前,我们已经将它们对应的与写入到磁盘日志文件。
关注步骤11 与步骤12 ,执行它们将满足undo 的规则2( 如果事务提交,则其COMMIT 日志记录必须在事务改变的所有数据库元素已写到磁盘后再写到磁盘,但应尽快) 。我们已经将数据库元素A 与B 的修改反应到磁盘上,接着可以写入来表示事务T 的成功执行,但是该日志记录还在缓冲区中,所以我们在步骤12 执行FLUSH LOG 进行日志刷盘。
5. 使用undo 日志进行数据库的恢复
现在假设系统故障发生了。有可能给定事务的某些数据库更新已经写到磁盘上,而同一事务的另外一些更新尚未到达磁盘。如果这样,事务的执行就不是原子的,数据库状态就可能不一致。这时候,我们就有必要使用日志将数据库恢复到一致的状态。
比如,在表2 中,如果故障发生在步骤9 之后、步骤10 之前。数据库的状态就是不一致的。
恢复管理的第一个任务就是将事务划分为已经提交事务和未提交事务。如果在日志中,根据undo 的规则2 ,事务
- 大小: 4.6 KB
分享到:
相关推荐
深入理解数据库日志系统原理
微软 SQL-Server 2000 相关阅读材料 包括: SQL Server与Oracle 存储引擎内幕 深入理解数据库日志系统原理 等等
本书是著名的操作系统内核专家Mark Russinovich和David Solomon撰写的Windows操作系统原理的最新版著作,全面和深入地阐述了Windows操作系统的整体结构以及内部工作细节。本书针对Windows Server 2003、Windows XP...
1.3.2 理解并发控制 14 1.3.3 多版本 19 1.3.4 数据库独立性? 25 1.3.5 “怎么能让应用运行得更快?” 41 1.3.6 DBA与开发人员的关系 45 1.4 小结 46 第2章 体系结构概述 47 2.1 定义数据库和实例 48 2.2 ...
- 论文:涵盖了整个Java ASP Web系统的基础知识,设计意图、需求概述、系统结构与设计哲学、相关技术的深入探索等。学生可以从论文中理解项目的全局构想和关键设计决策。 - 设计文档:详细梳理了系统的构建过程,...
一直挖掘binlog日志,然后发送到从库的IO线程,IO线程接收到日志流后,写入relay log,另一个线 程SQL线程,会读取该relay log内容,然后对sql语句进行重放. 本文主要给大家介绍的是关于MySQL主从复制线程状态转变的...
最近在写Mycat专题,由于不少小伙伴最近要出去面试,问我能不能简单写下MySQL的主从复制原理和注意事项,因为在之前的面试中被问到了这些问题。我:可以啊,安排上了!! 主从复制原理 (1) Master 将数据改变记录到...
MySQL 复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新、删除等等)。每个从服务器从主服务器接收主服务器已经记录到其二进制日志的保存的更新,以便从服务器可以对其数据拷贝执行相同的更新。 将主...
深入理解JDK动态代理本质 企业级高并发缓存解决方案 性能优化之Oracle语句优化雾区 前后台数据验证架构源码级解析 session跨域共享 JAVANIO原理详解 高并发数据库(Mysql数据库性能优化) 软件质量管控 企业常用框架...
阅读本书可以帮助数据库管理与开发人员更深入地理解SQL Server的原理和运行规律,以提高解决问题的能力。 作者简介 · · · · · · 徐海蔚,于2000加入微软亚太区全球技术支持中心企业支持及开发部,数据库支持组...
阅读本书可以帮助数据库管理与开发人员更深入地理解SQL Server的原理和运行规律,以提高解决问题的能力。 作者简介 · · · · · · 徐海蔚,于2000加入微软亚太区全球技术支持中心企业支持及开发部,数据库支持组...
阅读本书可以帮助数据库管理与开发人员更深入地理解SQL Server的原理和运行规律,以提高解决问题的能力。 作者简介 · · · · · · 徐海蔚,于2000加入微软亚太区全球技术支持中心企业支持及开发部,数据库支持组...
深入理解Oracle架构,能够让我们在Oracle的路上走的更远。OracleRDBMS架构图一般我们所说的Oracle指的是OracleRDBMS(RelationaldatabasesManagementsystem),一套Oracle数据库管理系统,也称之为OracleServer。而...
通过学习Spring Boot,我了解了其核心思想和基本原理,以及如何构建RESTful Web服务、使用数据库、进行事务管理等。我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程...
深入理解JavaScript语言原理;熟练的使用JavaScript对HTML DOM进行编程;熟练掌握JavaScript对象对象封装技巧,为后续的JavaScript学习打下坚实的基础。 Servlet/JSP Servlet生命周期及Servlet服务器、Tomcat...
通过学习Spring Boot,我了解了其核心思想和基本原理,以及如何构建RESTful Web服务、使用数据库、进行事务管理等。我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程...
此次将长期的思考、感悟,多年的系统开发、设计和团队管理经验,以及深入分析众多项目实战的宝贵成果和盘托出,力求将编程思想与具体实践融为一体,提炼出适合于广大读者快速理解和彻底掌握.NET软件开发的最佳学习...