一个小例子揭示事务日志的工作原理
来源:互联网 发布:js传值给input 编辑:程序博客网 时间:2024/06/05 06:43
在事务日志中,数据变化被记录在一个连续的日志记录中,且每一个记录都有一个编号,叫做日志序列编号(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是递增的), 实际情况可能与此有所不同。
- 一个小例子揭示事务日志的工作原理
- 一个事务的例子
- THINKPHP中一个事务回滚的小例子
- CGLib动态代理原理及实现的一个小例子
- 添加默认路由的一个小例子以及原理
- @Resource注解原理和一个简单的小例子
- 一个小的例子
- c# 学习笔记之九 事件(event)的使用,一个简单例子揭示机理
- jfinal事务小例子,事务,是要自己写的,框架可以代劳部分工作,但是不能替代你写事务,程序员是要做工作的
- 一个Web Service 自动事务的例子
- 一个Web Service 自动事务的例子
- sqlite处理事务的一个例子
- 一个验证的小例子
- spss的一个小例子
- 一个JNI的小例子
- 一个JDBC的小例子
- SwingWorker的一个小例子
- 一个dwr的小例子
- UIImageView 圆角
- iTunes的使用
- SQL Server的一些问题
- MSSQL2005和MSSQL2008删除或压缩数据库日志
- tar.xz压缩文件解压
- 一个小例子揭示事务日志的工作原理
- 实战ASP.NET访问共享文件夹(含详细操作步骤)
- 2012-05-15
- 文档编辑器的使用
- Qt出现错误 “undefined reference to `vtable for XXXXX.XXX”
- Wpf - TemplateParts
- 三种东西永远不要放到数据库里
- centos 安装 Adobe Flash Player
- VS2008中如何加载DotNetBar进行编程