你的位置:首页 > 软件开发 > 数据库 > SQL Server中的事务日志管理(2/9):事务日志架构概述

SQL Server中的事务日志管理(2/9):事务日志架构概述

发布时间:2015-10-16 16:00:08
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的。你只要确保每个数据库都有正确的备份。当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时。这系列文章会告诉你每个DBA应该知道的具体细节。虽然我们想回避它,去讨论下事务日志的内部结构 ...

当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的。你只要确保每个数据库都有正确的备份。当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时。这系列文章会告诉你每个DBA应该知道的具体细节。


虽然我们想回避它,去讨论下事务日志的内部结构和内部运行机制,但适当的理解下日志维护技术是有益的。这个话题在Paul Randal的讲座《理解SQL Server里的日志和恢复》里已经讲得很透彻,另外Kalen Delaney的《深入解析Microsoft SQL Server 2008》书里也有很详细的讲解,因此在这里我们将会简单介绍。

虚拟日志文件(Vitual Log Files(VLF))

事务日志文件是连续的文件;换句话说,SQL Server是连续写事务日志的(不像数据文件,它是随机写入的,因为数据是在随机的数据页里修改的)。

存储注意事项

在写入数据和日志文件的不同方式意味着它们也会有不同的存储注意事项,例如对于存储各个文件类型的硬盘,要配置合适的RAID,这个会在以后的文章里介绍。

每个插入日志文件的日志记录会用逻辑序列号(Logical Sequence Number(LSN))标记。当数据库和它关联的日志文件第一次创建时,第1条日志记录标志着逻辑文件的开始,同时也是物理文件的开始。LSN接下来也是自增长;最近增加的日志记录总会有最大的LSN,也标志着逻辑文件的结束(等下会详细讲解)。所有日志记录与提供的事务在LSN链(LSN chain)里链接,LSN上有指针前后指向当前操作的成功的和进行中的事务操作。

在内部,SQL Server把事务日志文件分成许多所谓的虚拟日志文件(virtual log files(VLFs))段。图1描述了8个VLFs组成的事务日志,还有标记了日志的活动部分。

SQL Server中的事务日志管理(2/9):事务日志架构概述

2.1 有8个VLFs的日志记录

在第1篇文章里我们提到,任何与打开事务相关日志记录都需要回滚的可能。另外,在数据库里还有很多其他使用事务日志的活动(包括复制,镜像和修改数据快照),也需要保持事务日志记录直到这些活动已经处理。在图2.1里显示的最小LSN的日志记录,是定义为“用作成功的数据库范围回滚或数据库里其他活动和操作的最老记录“。有时候它们也称为日志“头”。

活动日志记录的原因

活动事务可以让日志记录活动,除此之外,还有很多原因让它活动。这个在接下来的文章都会谈到。

现在可以说,如果一条日志记录对于任何事务或活动需要的话,这个日志记录就是活动的,它对应的VLF也是活动的一部分。

如图2.1所示,最近的日志记录总有最大LSN,这标志着日志的逻辑尾。接下来的记录都会写在日志逻辑尾。在最小LSN和和最大LSN之间的文件部分称为活动日志(active log)

活动日志不包含“活动”(例如打开)事务的细节,这很重要。例如,假设有个开始于上午9点,持续30分钟执行的打开事务(T1)日志记录定义了最小LSN。如果接下来的事务(T2)开始于上午9点10分,结束于9点11分,它还会是活动日志的一部分,因为相关日志记录的LSN比最小LSN大。在上午9点30分,当T1提交时,对于开始于上午9点25分的打开事务(T3)的日志记录会有新的最小LSN。到这时,对于T2的日志记录不会是活动日志的一部分。

任何包含活动日志任何部分的VLF都被认为是活动VLF。例如,图2.1的VLF3就是个活动VLF,即使它包含的大部分日志记录不是活动日志的一部分。一旦事务开始并提交,我们可以(简单)想象出日志头会在图2.1里从左往右移动,因此刚才包含活动记录部分的VLFS现在变成了不活动(VLF1和VLF2),刚才没用到的(VLF8)的VLFS会变成活动日志部分。

标记一个VLF为“不活动”具体做什么取决于数据库使用的恢复模式,接下来我们会谈到。

日志截断与空间重用

这里要注意的重点是日志文件里截断的最小单位不是各个日志记录或日志块,是VLF。如果在VLF里的一条日志记录还是活动日志部分,那么整个VLF被认为是活动的且不能被截断(cannot be truncated)

一把来说,一个VLF会是2个物理状态的1个:活动(active)或不活动(inactive)。但是,基于VLF的可能不同“行为”,我们可以分出4个逻辑状态:

  1. 活动(Active)——这个状态的VLF是活动的,因为它至少包含活动日志部分的一条记录,因此它需要被回滚或其他目的。
  2. 可恢复(Recoverable)——这个状态的VLF是不活动的,但没被截断或备份,空间不可以重用。
  3. 可重用(Reusable)——这个状态的VLF是不活动的,它已被截断或备份,空间可以重用。
  4. 未使用(Unused)——这个状态的VLF是不活动的,在它里面还没有被记录的日志记录。

把一个VLF标记为不活动——按照我们的逻辑状态,这表示从状态2切换到状态3——被称为日志截断(log truncation)。

这个日志截断什么时候发生取决于使用的恢复模式。当数据库在简单(Simple)恢复模式时,活动的VLF在检查点操作时变成不活动。当检查点发生时,缓存中的任何脏页写回到硬盘,然后日志中的空间变成可重用。

但是,在完整(FULL)或大容量日志(BULL LOGGED)模式里,只有日志备份可以把活动的VLF变成不活动。这样的话,一旦日志备份已完成备份,任何VLFs不在需要是不活动的,因此是可重用的。

在图2.2,我们看看到检查点(或日志备份)的结果,VLF1和VLF2已被截断且是不活动。活动日志的开始现在是VLF3的开始,VLF8还从未用过,因此它是不活动的(状态4)。

SQL Server中的事务日志管理(2/9):事务日志架构概述

2.2 截断后,有8个VLF的事务日志

下一个要考虑的问题,当活动日志到达VLF7尾时会发生什么。日志文件中空间简单来想都是反复被重用的,尽管有让空间重用模式变得相当专制的复杂因素,对此在这个系列文章里我们不会深入探讨。

不过,在最简单的情况下,一旦日志的逻辑尾到达VLF尾,SQL Server会开始重用接下来顺序的不活动VLF。在图2.1,会是VLF8。当VLF8满了,它会回绕重用VLF1和VLF2。如果没有更多的可用VLF,日志会需要自动增长,增加更多的VLF。由于自动增长被停用或磁盘提供的日志文件满了(没磁盘空间了),活动日志的逻辑尾会遇上日志文件的逻辑尾,事务日志满了,就会发生9002错误。

这个架构解释了原因,例如,一个长时间运行的事务,或由于某个原因复制的事务没有发送到派发的数据库,或者是丢失连接的镜像,还有其它的原因,会造成日志增长非常大。例如,考虑下图2.2,关联最小LSN的事务非常长时间运行。日志已经包裹了,填满了VLF1,VLF2和VLF8,没有不活动的VLF了。即使在最小LSN后的每个事务已提交,在这些VLFs没有可重用的空间,因为所有的的VLF还是活动日志部分。

我们很容易演示这个例子。首先,重新执行1.1代码删除和重建TestDB数据库。

 1 USE master ; 2 IF EXISTS ( SELECT name 3       FROM  sys.databases 4       WHERE  name = 'TestDB' )  5   DROP DATABASE TestDB ; 6 CREATE DATABASE TestDB ON 7 ( 8  NAME = TestDB_dat, 9  FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\TestDB.mdf'10 ) LOG ON11 (12  NAME = TestDB_log,13  FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\TestDB.ldf'14 ) ;15 DBCC SQLPERF(LOGSPACE) ;

原标题:SQL Server中的事务日志管理(2/9):事务日志架构概述

关键词:sql

sql
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。