读取SQL Server事务日志

时间:2012-01-26 06:10:13

标签: sql-server-2008 sql-server-2005

我们如何读取SQL Server事务日志,我知道使用DBCC日志(数据库,4)并且它将生成日志输出现在我想解码日志记录,这是十六进制格式。

0x00003E001C000000A500000001000200BE040000000006021D0000000100000018000000(仅一部分数据)

是否有任何方法以文本格式读取它或将十六进制数据转换为text.i想要制作一个可以读取log的工具。第三方工具可用,即ApexSQL但它们是付费工具。

6 个答案:

答案 0 :(得分:12)

您可以使用sys.fn_dblog来阅读事务日志。示例如下。

SELECT [RowLog Contents 0],
       [RowLog Contents 1],
       [Current LSN],
       Operation,
       Context,
       [Transaction ID],
       AllocUnitId,
       AllocUnitName,
       [Page ID],
       [Slot ID]
FROM sys.fn_dblog(NULL,NULL)
WHERE Context IN ('LCX_MARK_AS_GHOST', 'LCX_HEAP', 'LCX_CLUSTERED') 
AND Operation IN ('LOP_DELETE_ROWS', 'LOP_INSERT_ROWS') 

对于deleteinsert操作IIRC,[RowLog Contents 0]包含插入和删除的整行。更新有点复杂,因为只能记录部分行。

要解码此行格式,您需要了解SQL Server内部存储行的方式。这本书Microsoft SQL Server 2008 Internals详细介绍了这一点。你也可以下载SQL Server Internals Viewer来帮助解决这个问题(我相信Mark RasmussenOrca MDF的源代码也可用,大概有一些代码来解码内部行格式)

有关在TSQL中执行此操作的示例,请参阅this blog post,其中表明只要项目的目标有限,就可以从日志中提取有用信息。编写一个完整的日志阅读器,可以处理对象中的模式更改以及稀疏列(以及下一版本中的列存储索引)之类的事情,但这可能是一项巨大的工作。

答案 1 :(得分:3)

有几种SQL Server函数和命令(例如fn_dblog,fn_dump_dblog和DBCC PAGE)可能提供查看LDF文件内容的方法。但是,使用它们需要大量的T-SQL知识,有些是未记录的,并且它们提供的结果很难转换为人类可读的格式。以下是使用SQL Server函数和命令查看LDF文件内容的示例:

1 - 这是一个使用fn_dblog读取在线事务日志的示例,结果为129列(此处仅显示7个)

enter image description here

2 - fn_dump_dblog函数用于读取事务日志本机或本机压缩备份。结果类似:

enter image description here

不幸的是,没有官方文档可用于fn_dblog和fn_dump_dblog函数。要翻译列,您需要熟悉内部结构和数据格式,标志及其在行数据中的总数

3 - DBCC PAGE用于读取数据库在线文件的内容 - MDF和LDF。结果是十六进制输出,除非你有一个十六进制编辑器,否则很难解释

enter image description here

答案 2 :(得分:1)

Select * from sys.fn_dblog(NULL,NULL)
WHERE Context IN ('LCX_MARK_AS_GHOST', 'LCX_HEAP', 'LCX_CLUSTERED') 
AND Operation IN ('LOP_DELETE_ROWS', 'LOP_INSERT_ROWS') 

使用上面的查询获取与事务相关的所有信息。其中日志记录列显示您的实际记录,格式为十六进制格式。

检查此链接以将您的数据转换为人类可读的格式。 check here

答案 3 :(得分:1)

尝试一下。



    Select 
        b.Description,
        d.AllocUnitName,
        b.[Transaction ID],
        d.name,
        d.Operation,
        b.[Transaction Name],
        b.[Begin Time],
        c.[End Time]
    from (
        Select 
            Description,
            [Transaction Name],
            Operation,
            [Transaction ID],
            [Begin Time]
        FROM sys.fn_dblog(NULL,NULL) 
        where Operation like 'LOP_begin_XACT'
    ) as b
    inner join (
        Select 
            Operation,
            [Transaction ID],
            [End Time]
        FROM sys.fn_dblog(NULL,NULL)
        where Operation like 'LOP_commit_XACT'
    ) as c
    on c.[Transaction ID] = b.[Transaction ID]
    inner join (
        select 
            x.AllocUnitName,
            x.Operation,
            x.[Transaction ID],
            z.name
        FROM sys.fn_dblog(NULL,NULL) x
        inner join sys.partitions y
        on x.PartitionId = y.partition_id
        inner join sys.objects z
        on z.object_id = y.object_id
        where z.type != 'S'
    )as d
    on d.[Transaction ID] = b.[Transaction ID]
    order by b.[Begin Time] ASC


这可以获取数据库事务(例如插入,更新,删除),事务时间和对象名称。

希望可以提供帮助。

答案 4 :(得分:0)

我无法理解您的需求,但您可以通过Lumigent LogExplorer等工具提取日志中的数据。我不知道有什么方法可以做你想做的事。

答案 5 :(得分:0)

第1步。 CREATE TABLE #hex( [hex_Value] varbinary NULL )

第2步。 将数据插入表中,示例 插入#hex值(0x300008000F000000030000020015001B00536976754D79736F7265)

第3步。 SELECT LTRIM(RTRIM(CONVERT(VARCHAR(max),REPLACE(hex_Value,0x00,0x20)))) 来自#hex

For more Information go through this link