数据库的日志

摘要:
用于记录所有事务以及每个事务对数据库所做的更改。您可能需要使用事务日志将数据库恢复到一致状态。确认提交),然后将其写入数据库记录。重做通常用于恢复已确认但未写入数据库的数据。已写入重做但未写入数据库的数据将被重做。数据库系统如何确认哪些数据需要重做或撤消?系统中通常有一个表或控制文件来记录检查点和检查日志,以重建数据库的一致性状态。

数据库都具有事务日志,用于记录所有事务以及每个事务对数据库所做的修改。事务日志是数据库的重要组件,如果系统出现故障,则可能需要使用事务日志将数据库恢复到一致状态。删除或移动事务日志以前,必须完全了解此操作带来的后果。
事务日志支持以下操作:

    恢复个别的事务。
    在 SQL Server 启动时恢复所有未完成的事务。
    将还原的数据库、文件、文件组或页前滚至故障点。
    支持事务复制
    支持备份服务器解决方案。

那时有两个痛点:1,某个用户电脑忽然断电,数据写入不完整,导致大家都不能用了;2、多个用户对同一条记录进行写操作,或读与写不致,或ID增量重号。

现在的数据库系统(Oracel、DB2、MS sql、Mysql等)都支持多用户,所有的数据库系统(包括Exchange),都是把数据先写到日志中,等某个时机(比如:确认commit)后再写到数据库记录中,日志是数据库最重要的数据之一,理解日志是相当重要的。为什么要用日志呢?就是要解决Foxfro多用户的痛点一啊。
日志一般分成Undo与Redo:Undo一般用于事务的取消与回滚,记录的是数据被修改前的值,Redo一般用于恢复已确认但未写入数据库的数据,记录的是数据修改后的值,例如:数据库忽然断电重启,数据库启动时一般要做一致性检查,会把已写到Redo的数据但未写入数据库的数据重做一遍。

数据库系统如何来确认哪些数据需要redo或undo呢?那就需要一个检查点(checkpoint),在系统中一般有一个表或一个控制文件来记录检查点,日志是按顺序一直写下去的,检查点设置后,只需要比对检查点之后的数据就可以了。

 二:undo日志

  1.概述

  日志是日志记录的一个序列。在多事务的数据库系统中,每个事务有若干个操作步骤。每个日志记录记载有关某个事务已做的某些情况。几个事务的行为可以是“交错的”,因此可能是一个事务的某个步骤被执行,并且其效果被记录到日志中,接着执行另外一个事务的某个步骤并记入日志,接着可能接着做第一事务的下一个步骤,也可能执行另外一个事务的某个步骤。依次类推。事务的交错执行使日志更复杂,因为仅在事务结束后记载事务的全过程是不够的。

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

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

  2.日志记录

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

  关于undo记录形式有四种:

  1) : 这一记录表示事务T开始

  2) : 事务T已经完成。

  3) : 事务T不能成功执行。

  4) <t, v="" x,="">: 事务T改变了数据库元素X的值,元素X原来的值为v。

  3.undo日志规则

  要想让undo日志能使我们从系统故障中恢复,事务必须遵循两条规则。

  规则1)如果事务T改变了数据库元素X,那么形如<t, v="" x,="">的日志记录必须在X的新值写到磁盘前写到磁盘

  规则 2)如果事务提交,则其COMMIT日志记录必须在事务改变的所有数据库元素已写到磁盘后再写到磁盘,但应尽快。

  简单概括,undo日志系统顺序如下:

  1) 指明所改变数据库元素的日志记录

  2) 改变的数据库元素自身

  3) COMMIT日志记录。

 5.使用undo日志进行数据库的恢复

  现在假设系统故障发生了。有可能给定事务的某些数据库更新已经写到磁盘上,而同一事务的另外一些更新尚未到达磁盘。如果这样,事务的执行就不是原子的,数据库状态就可能不一致。这时候,我们就有必要使用日志将数据库恢复到一致的状态。

  比如,在表2中,如果故障发生在步骤9之后、步骤10之前。数据库的状态就是不一致的。

  恢复管理的第一个任务就是将事务划分为已经提交事务和未提交事务。如果在日志中,根据undo的规则2,事务T所做的全部改变在此之前已经写到磁盘上,因此当故障发生时,该事务T不可能导致数据库的不一致状态。

  然而,假设在日志中,只有记录,而没有与之相匹配的记录。那么就有可能在崩溃前,事务的某些修改已经反应到磁盘上,而另外一些修改可能未发生或者还在缓冲区中。这种情况下,T是一个未完成的事务,因为必须被撤消。也就是说,T所做的任何修改都必须恢复为原来的值。Undo的规则1使该想法可以成为可能,因为在修改数据刷盘之前,日志文件中已经保存了修改数据的原先值。对于<t, v="" x,="">,只需要将X的值恢复为v就行了(我们不必检查数据库中X现有值是否为v)。

  日志中可能有一些未提交的事务,并且甚至可能有一些未提交的事务修改了X,所以恢复时采用从日志文件尾向前扫描。在扫描过程中记住所有有或记录的事务T。同时在随后的扫描中,如果它看见<t, v="" x,="">,则:

  1) 如果T的COMMIT记录已被扫描到,则什么也不做。

  2) 否则,将数据库中元素X的值改为v。在做完这些操作后,为以前未中止且未完成的每个事务T写入一个日志记录,然后刷新日志。

  对于表2,作如下分析:

  1)崩溃在第12步后发生。因为日志记录已经写入日志文件。当恢复时,不需要处理T事务。

  2)崩溃发生在11步和12步之间。日志中记录了三条记录:、<t, 1000="" a,="">以及<t, 500="" b,="">。当恢复管理进行向后扫描时,首先遇到记录<t, 500="" b,="">,于是它将B在磁盘上的值存为500。接着它遇到记录<t, 1000="" a,="">,于是它将A在磁盘上的值存为1000。最后记录被写到日志中且日志被刷新。

  3)崩溃发生在第8步和第11步之间。情况2一样。

  4)崩溃发生在第8步之前。日志系统中只有一条记录:。记录被写到日志中且日志被刷新。(实际上,在实际系统中,可能其他的事务执行FLUSH LOG操作,而将事务T的日志记录写入磁盘中,如果是这样的话,日志中可能已经写入<t, 1000="" a,="">和<t, 500="" b,="">,对于这种情况,执行情况2的恢复就行。实际上这些细节不影响undo的恢复效用,为了简单起见,忽视这些情况)。

  6.静态检查点

  正如我们所看到的那样,恢复时需要检查整个日志。当采用undo类型的日志时,一旦日志记录被写入日志文件,事务T的日志记录就可以忽视了。但是此时事务T却不能截断日志,因为事务是交替执行的,如果这时将日志截断,可能丢失活动着的事务的日志记录。  

Undo是恢复的一种策略,但是不是唯一的策略。

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

  2.redo日志的规则

  Redo日志用新值表示数据元素的更新,而undo日志使用的是旧值。Redo日志的<t,x,v>表示:事务T为数据库元素X写入新值v。

  Redo日志系统的规则只有一条:

  规则1:在修改磁盘上任何数据库元素X之前,要保证所有与X这一修改相关的日志记录,包括更新记录<t,x,v>以及记录,都必须出现在磁盘上。

  Redo日志顺序如下:

  1) 指出被修改元素的日志记录

  2) COMMIT日志记录

  3) 改变的数据元素自身。

4.使用redo日志的恢复

  对于redo日志,根据规则1,我们可以知道如果日志没有,则事务T的修改所做的所有的更新都没反映到磁盘上,就像事务T从来没有发生过一样。

  如果发现记录记录,却不敢保证所有的数据库修改已经反映到磁盘上,这和undo日志是相反的。我们必须将事务T重做一次。

  使用redo日志恢复,过程如下:

  1) 确定提交事务

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

  (a):如果T是未提交的事务,则什么也不做。

  (b):如果T是提交的任务,则为磁盘上数据库元素写入值v

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

  1) 如果故障发生在第9步以后,记录已被刷新到磁盘。恢复时,遇到记录<t, a,="" 950="">,为磁盘上的A写入值950。遇到记录<t, b,="" 550="">,为磁盘上的B写入值550。

  2) 如果故障发生在第9步之前,如果已经到达磁盘,则恢复过程同情况1。如果未到达磁盘,T被做为未完成事务,磁盘上的A和B不作任何修改,最后将一条写入日志并刷盘。

在线重做日志与归档日志。
ONLINE Redo log
在线重做日志(online redo log )主要用于:Oracle数据库所在服务器突然掉电、突然重启或者执行shutdown abort等命令使得在服务器重新启动之后,Oracle数据库没有办法正常的启动实例。此时,在线重做日志就派上了用场,Oracle会使用在线重做日志,把数据库恢复到服务器掉电前的那一个时刻,从而使得数据库能正常的启动起来 。
在Oracle数据库中,默认情况下,至少会有两个重做日志组,而且每个组里面至少包含了一个重做日志文件。日志组不会自动增加,在一个写满之后,会自动去写下一个。在下一个被写满之后会又从第一个开始写起。
Archive redo log
归档日志(archive log)主要用于硬件级别的错误:磁盘的坏道导致无法读写、写入的失败、磁盘受损导致数据库数据丢失。这就要使用归档日志文件,通过归档日志文件,把数据库恢复到归档日志所在的时间点上然后再通过在线重做日志文件把数据库恢复到当前的时间点上。
对于归档日志文件,可以理解为在线重做日志文件的备份。即当一个重做日志文件被填满了之后,归档日志文件就会把其备份保留一份。(因为上面说了,在线重做日志文件会自动的覆盖)所以,归档日志文件就是旧的在线日志文件的备份。

免责声明:文章转载自《数据库的日志》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇深入理解JavaScript闭包scrapy爬虫成长日记之将抓取内容写入mysql数据库下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

如何导出远程oracle数据库中的表结构

从远程oracle数据库上导出指定表的表结构语句有两种方法: 方法一:通过sql语句获得 1,make sure that you can connect the remote database. 2,enter into the sqlplus,and execute the command: select dbms_metadata.getddl('T...

Spark Partition

分区的意义 Spark RDD 是一种分布式的数据集,由于数据量很大,因此它被切分成不同分区并存储在各个Worker节点的内存中。从而当我们对RDD进行操作时,实际上是对每个分区中的数据并行操作。Spark根据字段进行partition类似于关系型数据库中的分区,可以加大并行度,提高执行效率。Spark从HDFS读入文件的分区数默认等于HDFS文件的块数(...

SQLSERVER TRUNCATE 运用

SQLSERVER TRUNCATE DELETE DROP运用 TRUNCATE TABLE删除表中的所有行,而不记录单个行删除操作。 语法TRUNCATE TABLE name 参数name 是要截断的表的名称或要删除其全部行的表的名称。 注释TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全...

在linux上oracle服务启动停止详细

转至:https://www.cnblogs.com/baihuitestsoftware/articles/6365431.html 在CentOS 6.3下安装完Oracle 10g R2,重开机之后,你会发现Oracle没有自行启动,这是正常的,因为在Linux下安装Oracle的确不会自行启动,必须要自行设定相关参数,首先先介绍一般而言如何启动or...

JPA学习(二、JPA_基本注解)

框架学习之JPA(二)JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。 Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。 学习...

用javaweb写一个注册界面,并将数据保存到后台数据库(全部完成)(课堂测试)

一、题目:WEB界面链接数据库 1.考试要求:       1登录账号:要求由6到12位字母、数字、下划线组成,只有字母可以开头;(1分) 2登录密码:要求显示“• ”或“*”表示输入位数,密码要求八位以上字母、数字组成。(1分) 3性别:要求用单选框或下拉框实现,选项只有“男”或“女”;(1分) 4学号:要求八位数字组成,前四位为“2018”开头,输入自...