一个小例子揭示事务日志的工作原理

来源:互联网 发布:js传值给input 编辑:程序博客网 时间:2024/06/05 06:43
2012-03-13 11:02

  

在事务日志中,数据变化被记录在一个连续的日志记录中,且每一个记录都有一个编号,叫做日志序列编号(Log Sequence Number, LSN)。

    在事务日志中,每一个日志记录都被存储在一个虚拟日志文件中。事务日志可以有任意多个虚拟日志文件,数量的多少取决于数据库引擎,而且每个虚拟日志文件的大小也不是固定的。

   如上图所示,活动区间(active portion)的日志就是包含我们事务的区域。这区间就是完整恢复数据库所需要的。当更多的事务被创建时,活动区间的日志也会随着增长。

那么当CheckPoint被执行时,会发生什么变化呢?答案是:所有有变化的数据写到数据文件中,然后创建一个检查点记录(CheckPoint record)。

    现在,由事务1,2,3所导致的变化将会被写到数据文件中。因为事务3没有被提交,所以活动区间日志的范围变成了从LSN50到LSN52之间。如果使用简单恢复模型的话,那么LSN45到LSN49之间区域可以被重用,因为那些记录已经不再需要了。

当SQL Server把虚拟日志文件1和2作为可重用区域时,事务日志也相应被截断(Truncate)。需要注意的是,物理日志大小也会随着变动。如果数据库运行在完整或是批量日志恢复模型下,那么从LSN45到49之间的区域将被删除(delete),而且直到事务日志被备份后,这段区域的空间才会被重用。

那么当更新的事务被创建时,又会发生什么呢?在简单模式下,日志的起始空间将会被重用。

  在完整或是批量日志恢复模型下,事务日志的空间则会被扩展。

 假如事务日志是一个固定大小的日志,那么在SQL Server2000系统中,你会收到如下错误信息:

Server: Msg 9002, Level 17, State 6, Line 1
The log file for database 'AdventureWorks' is full. Back up the transaction log for the database to free up some log space.

  在SQL Server 2005里面,错误会显示为:

Msg 9002, Level 17, State 4, Line 1
The transaction log for database 'AdventureWorks' is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases

注意:并不是说运行在简单恢复模式下的数据库永远都不会遇到9002的错误。如果你有一个很长的、正在运行的、未提交的事务,那么你的事务日志依然会被填满,因为SQL Server不能删除任何一个已经开始运行之后被创建的日志。也就是说,活动区间里面的日志从事务起始时被记录,并且已经没有活动区间可以被删除或是重用了。

  所以,要保持你的事务日志基本处理一个可管理的范围:

  • 当更改已经被确认或是由于错误导致的回滚已经完成时,要马上提交的你事务。
  • 如果数据库运行在完整或是批量日志恢复模型下的话,要定期备份你的事务日志

   为了找出数据库中最起始的活动事务,特别是事务起始时间时,就可以使用DBCC OPENTRAN命令,例如:

DBCC OPENTRAN

结果为:

Transaction information for database 'AdventureWorks'.
Oldest active transaction:
SPID (server process ID) : 52
UID (user ID) : 1
Name : user_transaction
LSN : (754:531:1)
Start time : Jul 14 2008 5:43:55:390PM

        为了找出每一个数据库已经使用的日志空间大小,可以使用DBCC SQLPERF命令:

DBCC SQLPERF(LOGSPACE)

  为了找出事务日志使用了多少虚拟日志数量,可以使用DBCC LOGINFO命令。它显示的细节内容就是你当前所连接数据库的内容,下面就是AdventureWorks数据库的输出:

    从上图我们可以得到如下信息:你的事务日志中有四个虚拟日志文件(一行一个),且所有虚拟日志文件包括在一个单一的物理文件中 (FileId=2)。第一,二,三的虚拟日志文件大小是458752比特,最后一个虚拟日志文件的大小是712704比特。1~3虚拟文件从来没有被使用或是重用过(Status=0), 第四个虚拟日志文件正在被使用(Status=2)。虚拟日志文件在物理上的布局具有连接的编号(FSeqNo是递增的), 实际情况可能与此有所不同。

 

 

原创粉丝点击