如何查看被截断的日志
如果数据库做了日志备份操作,则日志会被截断,然后原来活动的VLF会被重用。使用sys.fn_dblog将会看不到任何被截断的日志。那如何查看日志备份中的日志呢?使用fn_dump_dblog读取日志备份的内容。它的输出和sys.fn_dblog是一样的,所以进行查询过滤时也可以跟其一样。
use master
go
backup log logtest to disk='d:\logtest.trn';
go
select [Current LSN], [Operation], [AllocUnitName], [Transaction Name]
from fn_dump_dblog (
NULL, NULL, 'DISK', 1, 'D:\logtest.trn',
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT)
where [Transaction ID]='0000:00000367'
go
当[Lock Infomation]的内容无用时
前面我们使用[Lock Infomation]的内容帮助我们定位和分析日志操作,但是如果数据操作没有单独锁定某个行时(e.g.锁升级和使用表提示锁定表),则它的内容对我们的帮助就很少了。
delete top(1) from demotable with (tablockx);
select [Current LSN], [Operation], [Transaction ID],
[AllocUnitName], [Page ID], [Slot ID], [Lock Information]
from fn_dblog(null, null)
where [transaction id]='0000:0000036a'
上面的删除使用tablockx表提示,使得删除是直接对表使用X锁,而不是行锁。这样在[Lock Information]就没有包含键锁的HASH值(Lockres)。如图,我们现在能获取到Page ID、Slot ID和Object ID,但是不能定位到行。
但是日志的有效工作负载还是包含了所有的内容,因此可以通过搜索[Log Record]或者 [RowLog Contents 0~5] 来找到具体的行。
最小化日志操作也会让查找日志变得更困难。最小化日志操作的日志内容只扫描了某个页包含了最小华日志操作,SQL Server必需保证它在事务提交前被刷新到磁盘。在相关日志中只看到LOP_FORMAT_PAGE操作及其操作(最小化日志操作)的Page ID。最小化日志只有INSERT、blob .WRITE和WRITETEXT/UPDATETEXT操作,其它的操作都会完整记录日志,这样分析日志要分析的内容就少了很多。有一种情况会增加操作的日志量:更新事务复制中的发布表的数据。
实践时的注意事项
本文的例子的日志量非常少,搜索起来也很快。在真实环境中可能要透过数百万行日志才能找到所需要的日志记录,当然会很慢。最好将sys.fn_dblog返回的日志行先存到表中,然后建立需要的索引,这样查询时会快很多。使用sys.fn_dblog时如果能传入开始和结束的LSN,也会让其它返回速度快一些。注意,如果传入不正确的LSN给sys.fn_dblog,则会导致服务器内核转储( server core dump ),在生产环境这会导致SQL Server僵死一会儿。
DDL 修改
分析DDL修改的思路跟分析数据修改的一样。数据库对象是存储于一个或多个系统表中的数据,所有DDL修改最终会通过修改系统表的数据而完成。这样会让所有的DDL修改在分析日志时看起来差不多,例如LOP_INSER_ROWS操作插入数据到sys.syschhobjs,它可能是CREATE TABLE,也可能是CREATE VIEW或者CREATE PROC,甚至CREATE TABLE foo和CREATE TABLE bar的日志看起来是一样的。
DDL操作和DML操作两者修改数据时的主要区别在于使用不同锁。DDL使用元数据锁(Metedata Lock),一般情况,DDL会以包含Object ID的SCH_M锁开始。
另外,分析日志中DDL,要与特定的版本和更新相匹配。不同的版本、SP甚至CU,元数据表和元数据表结构可能会不同。
利用OBJECT ID
找出某个对象的DDL具体操作的最好方法是通过找出在对象上请求SCH_M锁的事务。先通过OBJECT_ID()得对象的ID,然后在[Lock Information]列中匹配搜索模式N'%SCH%