天天看点

人人都是 DBA(VI)SQL Server 事务日志

原子性(Atomicity)

一致性(Consistency)

隔离性(Isolation)

持久性(Durability)

事务日志(Transaction Log)存储的是对数据库所做的更改信息,让 SQL Server 有机会恢复数据库。而恢复(Recovery)的过程就是使数据文件与日志保持一致的过程。任何在日志中指示已经提交的数据更改必须出现在数据文件中,任何未标记为提交的更改不能出现在数据文件中。

预写日志(Write-ahead Logging)功能确保在真正发生变化的数据页写入磁盘前,始终先在磁盘中写入日志记录,使得任务回滚成为可能。写入事务日志(Transaction Log)是同步的,即 SQL Server 必须等它完成。但写入数据页可以是异步的,所以可以在缓存中组织需要写入的数据页进行批量写入,以提高写入性能。

事务日志用于保证 SQL Server 在语句或系统出现故障时的可恢复性,并允许将备份的日志应用到数据库上。但事务日志并没有提供很好的可读性,实际上读取事务日志通常也不会获取到太多有用信息。更推荐的跟踪记录机制是使用 SQL Server Profiler 等工具,以筛选和捕获有用的信息。

比如,我们使用下面的 SQL 来创建一张简单的 Table,来尝试观察事务日志的变化。

插入一条记录。

使用 DBCC LOG 命名可以先观察产生的序列。

人人都是 DBA(VI)SQL Server 事务日志

使用系统提供的函数 sys.fn_dblog 来查看当前的事务日志记录,可以列出很多详细信息,这里只显示了几个常用的列。

人人都是 DBA(VI)SQL Server 事务日志

事务日志总是连续的并且是顺序的,按照 LSN(Log Sequence Number)的顺序排列。从查询的尾部可以查看 AllocUnitName 操作的数据表名称。

人人都是 DBA(VI)SQL Server 事务日志

对应的 Operation 是 LOP_INSERT_ROWS,Context 是 LCX_HEAP,也就是插入数据到堆表。同时发现 Page ID 是 0001:00000078,也就是十进制的 120 号页面。

可以使用 DBCC PAGE 命令查看 Page 页信息。

可以看出上面的 SQL 语句 Insert 了数据 Id = 1, Name = Dennis Gao, Phone = 88888888。

不管为事务日志定义多少个物理文件,SQL Server 总是把日志当成连续流(Contiguous Stream)来对待。当 DBCC SHRINKDATABASE 命令确认日志可以缩小多少时,它不是单独考虑每个日志文件,而是根据整个日志来确定可压缩大小。

人人都是 DBA(VI)SQL Server 事务日志

SQL Server 数据库的事务日志是通过虚拟日志文件(VLF:Virtual Log File)来管理的,VLF 的大小由 SQL Server 根据日志的总大小和日志增量大小来决定,不能通过配置指定。如果 VLF 数量变多会导致数据库性能下降,所以需要指定合理的日志文件初始大小和增长步长,防止过多的 VLF 的产生。

SQL Server 会根据如下规则来判断 VLF 的数量:

 日志大小 

 VLF 数量 

Size <= 1MB 

 将日志文件大小除以最小 VLF 大小(31KB*8KB)确定个数 

1MB < Size <= 64MB

 4 个

 64MB < Size <= 1GB 

 8 个

Size > 1GB

 16 个

当日志持续增长时,会使用相同的方式确定新添加的 VLF 的数量。日志总是以整个 VLF 为单位增长,而且缩小也只能到 VLF 的边界为止。

VLF 可以处于以下 4 种状态之一。

Active:日志的活动部分,从未提交事务的最小 LSN 开始,结束于最后一个写入的 LSN。

Recoverable:在最早的活动事务之前的那部分日志。

Reusable:如果日志已经被备份,则不需要最早活动事务之前的 VLF,可重用这些空间。日志截断或备份会将 Recoverable VLF 转换成 Reusable VLF。

Unused:未使用的部分。

人人都是 DBA(VI)SQL Server 事务日志

可以使用下面的 SQL 查询 VLF 的数量。

人人都是 DBA(VI)SQL Server 事务日志

可以使用 DBCC LOGINFO 命令进一步观察 VLF 的相关属相。

人人都是 DBA(VI)SQL Server 事务日志

SQL Server 可以配置多个物理日志文件当做一个序列流来对待。如果管理良好,定期备份或截断日志,可能永远都不会使用除第一个文件之外的其他日志文件。当需要新的 VLF 时,多个物理文件中都没有可用 VLF,则会以循环的方式把新的 VLF 添加到每个物理日志文件中。

人人都是 DBA(VI)SQL Server 事务日志

如果 SQL Server 设置了如下情况,则认为没有维护日志备份:

设置 SIMPLE 恢复模型,数据库会定期截断日志。

从未进行过完全数据库备份。

以上任何一种情况下,SQL Server 会处于自动截断模式(Auto Truncate Model)中,当数据库事务日志满时就会进行截断。这里的 "满" 指的是日志记录的数量比在系统启动过程中、在合理的时间内能够重做的数量多。

判断数据库是否在自动截断模式的最简单的方法是查询 sys.database_recovery_status 目录视图,如果 last_log_backup_lsn 列为空,则数据库就是处于自动截断模式。

人人都是 DBA(VI)SQL Server 事务日志

可以通过 DBCC SQLPERF 命名来查看日志文件大小。

人人都是 DBA(VI)SQL Server 事务日志

当然,也可以通过系统提供的目录视图来查看。

人人都是 DBA(VI)SQL Server 事务日志

《人人都是 DBA》系列文章索引:

 序号 

 名称 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15