一个小例子揭示事务日志的工作原理
2012-05-15 11:25
453 查看
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是递增的), 实际情况可能与此有所不同。 |
相关文章推荐
- Struts2+Ibatis+Spring.30(完整例子,含3.0事务配置,OSCache缓存配置,JreeChart配置,log4j日志输出Sql,对一个表实现完整的查询,批量删除,添加,更新)
- .net下 存储过程、事务处理 的一个小例子
- 【一个不错的oracle数据库诊断例子,值得学习一下】Oracle数据库诊断案例-redo log日志组处于高激活状态
- 一个简单的Spring4和MyBatis事务的例子(很详细)
- 一个jdbc的例子(包含sql语句的批处理,事务处理,数据绑定prepare,)
- 一个日志文件读取并入库的小例子
- c#学习笔记之九 事件(event)的使用,一个简单的例子揭示其设计理念
- c# 学习笔记之九 事件(event)的使用,一个简单例子揭示机理
- 一个jdbc的例子(包含sql语句的批处理,事务处理,数据绑定prepare)
- Java并发编程(六) 一个日志服务的例子
- Android日志服务例子,将日志记录在文件中并每天生成一个日志文件
- 一个简单的例子说明TPS和事务响应时间的关系
- 使用jdbc来保存log4j日志信息的一个例子
- 一个事务的例子
- spring对hibernate提供的事务管理的一个实用的例子
- 通过事务日志恢复SqlServer数据库到一个特定的时间点
- 一个事务的例子
- 一个简单的存储过程使用事务的例子
- 使用LOG4J记录程序日志的一个例子
- 一个Web Service 自动事务的例子