以前有个log explorer能读日志,但不支持2008
所以找了篇事务日志文件格式文章,留待研究
http://book.51cto.com/art/201001/181081.htm
当日志文件大小超过预期的时候,数据库管理员自然会想去看看日志文件中到底存放了些什么信息。SQL Server有一条"DBCC LOG"命令可以帮助我们解释日志文件中的信息。它的语法是:
DBCC LOG(, )
:目标数据库编号。可以用sp_helpdb得到。
:DBCC LOG命令翻译和解释日志记录的方式。
一般来讲,使用"3"这个格式参数输出比较详细。
下面我们通过一个很简单的表格操作来看看SQL Server是怎么组织事务日志记录的。
首先,我们在范例数据库AdventureWorks里面创建一个只有一个int类型字段的表格。然后将数据库日志文件清空。接着运行DBCC LOG命令。找到这时日志文件的最后一条记录。
use adventureworks
go
create table a (a int)
go
checkpoint
go
backup log adventureworks WITH NO_LOG
--2008中需改为 DBCC SHRINKFILE (N'adventureworks_Log' , 1)
go
dbcc log(adventureworks,3)
go
--接着,我们在表格里插入一条记录。
insert into a values (1)
go
dbcc log(adventureworks,3)
go
结果中(见图1-26)可以看到三条关于这个Insert的记录。
--sql2008中增加了20几条记录
图1-26 DBCC LOG结果中3条和INSERT动作相关的记录 |
我们再插一条记录。
- insert into a values (100)
- go
- dbcc log(5,3)
- go
可以看到新的3条记录(见图1-27)。新的记录有不同的LSN编号。
图1-27 新的3条和INSERT动作相关的记录 |
从这些记录里,我们可以看到刚才做的INSERT的事务,它的起始时间,刚才连接的SPID,以及其他一些信息。SQL Server完全可以通过这些记录把INSERT重做,或者撤销。
我们把这两条记录都改成2。这次出现了6条记录(见图1-28)。
- update a set a = 2
- go
图1-28 和UPDATE动作相关的6条记录 |
从这些记录可以看出,虽然只是一条UPDATE语句,但是实际上SQL Server并没有记录语句本身。它记录的是两条被修改的数据原来的值和现在的值。
因此我们可以发现,SQL Server的日志记录有以下特点:
1. 日志记录的是数据的变化,而不是记录用户发过来的操作。
在这一点上,日志记录的定位很清楚。它只是为了保证数据库一致性。所以它记录的信息对SQL Server来讲很有意义。但是如果想要通过它来倒推出用户刚才发过来的语句,可以说是不可能的。
2. 每条记录都有它唯一的编号(LSN),并且记录了它属于的事务号。
这种设计便于事务的重新提交和回滚。
3. 日志记录的行数和实际修改的数据量有关。
SQL Server会为每一条记录的修改保存日志记录。如果单个语句修改的行数非常多,那它所带来的日志行数也就会非常多。所以日志增长的速度不仅和事务的多少有关,还和事务所带来的数据的修改量有关。
4. 日志记录了事务发生的时间,但是不保证记录下了发起这个事务的用户名,更不记录发起者的程序名称。
5. SQL Server能够从日志记录里面读到数据修改前的值和修改后的值。但是对管理者来讲,直接从日志记录里面是很难了解其修改过程的。
讨论这些的原因,是因为很多用户希望能从日志文件里倒推出数据库曾经发生的异常操作。比如,是谁恶意或不小心删掉了一些重要数据,或者是谁在某个时间段发起了一个庞大的事务。由于SQL Server日志定位不是做用户行为监视和记录,而是在对性能影响最小的前提下保证事务一致性,所以它记录的内容是面向数据库服务,而不是面向用户的。换句话说,它记录的东西只要SQL Server自己能读懂就可以了,而没有考虑要给用户去访问和理解。所以使用者很难用事务日志来达到倒推的目的。
市场上有一些第三方的工具宣称能从SQL Server的日志文件中完成一些推断工作。他们能够更进一步地解释日志记录,并且做一些自动化的工作(例如,帮助用户回滚一个误操作)。但是如果有什么内容DBCC LOG看不到,这些工具应该也很难看到。所以如果要监视用户的行为,还是要开启SQL Server自己的监视工具,比如SQL Trace或XEvents等。