读取SQL Server事务日志

问题描述 投票:8回答:6

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

0x00003E001C000000A500000001000200BE040000000006021D0000000100000018000000(仅一部分数据)

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

sql-server-2008 sql-server-2005
6个回答
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,它表明只要项目的目标有限,就可以从日志中提取有用的信息。编写一个完整的日志阅读器,可以应对对象中的模式更改以及稀疏列(以及下一版本中的列存储索引)之类的内容,但这可能会带来大量工作。


3
投票

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

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

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

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

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


2
投票
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


1
投票

步骤1. CREATE TABLE #hex([hex_Value] varbinary NULL)

步骤2.将数据插入表中,将示例插入到#hex值(0x300008000F000000030000020015001B00536976754D79736F7265)

步骤3.选择LTRIM(RTRIM(CONVERT(VARCHAR(max),REPLACE(hex_Value,0x00,0x20))))FROM #hex

For more Information go through this link


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


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

希望能有所帮助。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.