数据库原理(日志系统原理)[转]

ref:https://blog.csdn.net/whyangwanfu/article/details/1926367

事务的原语操作

在事务系统的运行当中,有三个地址空间供元素存储:

  • 磁盘空间
  • 缓冲区
  • 事务的局部地址空间。

一个简单的读、修改X元素操作的流程如:事务到缓冲中读取元素X,如果命中,则读取事务局部地址空间并返回,如果未命中,则先将相关页从磁盘读入缓冲区。事务在它的局部地址空间中修改元素X,然后写入缓冲区,再从缓冲区写入磁盘。当然缓冲区的数据也可能不是立即拷贝入磁盘的,这取决于具体的缓冲区管理策略。
为了便于描述,我们描述了4个操作原语:

  • INPUT(X):将包含数据库元素X的磁盘块拷贝到内存缓冲区
  • READ(X,t):将数据库元素X拷贝到事务的局部变量t。更准确地说,如果包含数据库元素X的块不在内存缓冲区中,则首先执行INPUT(X)。接着将X的值赋给局部变量t。
  • WRITE(X,t):将局部变量t的值拷贝到内存缓冲区中的数据库元素X。更准确地说,如果包含数据库元素X的块不在内存缓冲区中,则首先执行INPUT(X)。将着将t的值拷贝到缓冲区中的X。
  • OUTPUT(X):将包含X的缓冲区拷贝到回磁盘。

undo日志

如果系统崩溃,恢复管理器就被激活,检查日志以重建数据库的一致性状态。恢复时,有些事务的工作将会重做,它们写到数据库的新值会重写一次。而另外一些事务的工作将被撤消,数据库被恢复,将仿佛这些事务从来没执行过一样。

1. 概述

Undo日志是日志类型的一种,这类日志仅仅进行第二类修复。对于要被撤消的事务,因为不能肯定它对数据库的修改是否已经写到磁盘中,所以对于该事务的所有更新都将被撤消,数据库恢复到事务发生以前的状态。

2.日志记录

日志只允许以附加的方式写入数据。日志块最初在主存中创建,像数据块一样也由缓冲区管理,在确当的时刻,日志块会从缓冲区写入到磁盘。
关于undo记录形式有四种:

  • <START T>: 这一记录表示事务T开始
  • <COMMIT T>: 事务T已经完成。
  • <ABORT T>: 事务T不能成功执行。
  • <T, X, v>: 事务T改变了数据库元素X的值,元素X原来的值为v。

3.undo日志规则

要想让undo日志能使我们从系统故障中恢复,事务必须遵循两条规则。
规则 1)如果事务T改变了数据库元素X,那么形如<T, X, v>的日志记录必须在X的新值写到磁盘前写到磁盘
规则 2)如果事务提交,则其COMMIT日志记录必须在事务改变的所有数据库元素已写到磁盘后再写到磁盘,但应尽快。

简单概括,undo日志系统顺序如下:
1) 指明所改变数据库元素的日志记录
2) 改变的数据库元素自身
3) COMMIT日志记录。

4. 静态检查点

1) 停止接受新的事务
2) 等待所有当前的活动事务提交或终止,并且在日志文件中写COMMIT或ABORT记录。
3) 将日志刷新到磁盘
4) 写入日志记录<CKRT>,并再次刷新记录。
5) 重新开始接受新事务。
当恢复时,扫描到<CKRT>日志时,就不需要继续扫描日志记录了。

5. 动态检查点

静态检查点的缺点在与,可能需要很长时间等待活跃事务的完成,在用户系统看来似乎是静止了。非静态检查克服了该缺点,在做检查点时允许新事务进入。步骤如下:
1) 写入日志记录<START CKPT(T1,……,Tk)>.其中T1,……,Tk为活跃事务。
2) 等待T1,……,Tk每一个事务提交或终止,但允许其它事务开始。
3) 当T1,……,Tk都已完成时,写入日志记录<END CKPT>并刷新日志。

当系统发生故障时,从日志尾部开始扫描日志。根据扫描过程中先遇到<END CKPT>记录还是<START CKPT(T1,……,Tk)>记录,有两种情况。

1) 如果先遇到<END CKPT>记录。所有未完成的事务在<START CKPT(T1,……,Tk)>记录后开始,只要扫描到<START CKPT(T1,……,Tk)>就不需要继续扫描了。<START CKPT(T1,……,Tk)>前的记录是可以截断的。

2) 如果先遇到<START CKPT(T1,……,Tk)>,那么崩溃发生在检查点过程中。未完成事务只可能是到达<START CKPT(T1,……,Tk)>前遇到的那些,以及T1,……,Tk在崩溃前未完成的那些。因此只要继续扫描到未完成事务中最早的那个事务的开始就行了。
一个通常的规律是,一旦<END CKPT>记录到了磁盘,我们就可以将上一个<START CKPT>记录前的日志删除了。

redo日志

1.概述

Undo是恢复的一种策略,但不是唯一的策略。
Undo日志的一个潜在的问题是:在所有修改数据没有写到磁盘前,不允许提交该事务。
有时,让修改的数据页暂时缓冲在主存中,是可以节省磁盘IO的;只要在崩溃的时候有日志用来恢复。

2.redo日志的规则

Redo日志用新值表示数据元素的更新,而undo日志使用的是旧值。Redo日志的<T,X,v>表示:事务T为数据库元素X写入新值v。
Redo日志系统的规则只有一条:
规则1:在修改磁盘上任何数据库元素X之前,要保证所有与X这一修改相关的日志记录,包括更新记录<T,X,v>以及<COMMIT T>记录,都必须出现在磁盘上。
Redo日志顺序如下:
1) 指出被修改元素的日志记录
2) COMMIT日志记录
3) 改变的数据元素自身。

3.使用redo日志的恢复

对于redo日志,根据规则1,我们可以知道如果日志没有<COMMIT T>记录,则事务T的修改所做的所有的更新都没反映到磁盘上,就像事务T从来没有发生过一样。
如果发现记录<COMMIT T>记录,却不敢保证所有的数据库修改已经反映到磁盘上,这和undo日志是相反的。我们必须将事务T重做一次。
使用redo日志恢复,过程如下:

1) 确定提交事务

2) 从首部开始扫描日志,对遇到的每一<T,X,v>记录:

  • 如果T是未提交的事务,则什么也不做
  • 如果T是提交的任务,则为磁盘上数据库元素写入值v

3)对于每一个未完成的事务T,在日志中写入一个<ABORT T>记录并刷新日志

猜你喜欢

转载自www.cnblogs.com/dirge/p/11790041.html