我们如何读取SQL Server事务日志,我知道使用DBCC日志(数据库,4),它现在将生成日志输出我想解码日志记录,这是十六进制格式。
0x00003E001C000000A500000001000200BE040000000006021D0000000100000018000000(仅一部分数据)
是否有任何方法以文本格式读取它或将十六进制数据转换为text.i想要制作一个可以读取log的工具。第三方工具可用,即ApexSQL,但它们是付费工具。
您可以使用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')
对于delete
和insert
操作IIRC,[RowLog Contents 0]
包含插入和删除的整行。更新有点复杂,因为只能记录部分行。
要解码此行格式,您需要了解SQL Server内部存储行的方式。本书Microsoft SQL Server 2008 Internals详细介绍了这一点。你也可以下载SQL Server Internals Viewer来帮助解决这个问题(我相信Mark Rasmussen的Orca MDF的源代码也可用,它可能有一些代码来解码内部行格式)。
有关在TSQL中执行此操作的示例,请参阅this blog post,它表明只要项目的目标有限,就可以从日志中提取有用的信息。编写一个完整的日志阅读器,可以应对对象中的模式更改以及稀疏列(以及下一版本中的列存储索引)之类的内容,但这可能会带来大量工作。
有几种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。结果是十六进制输出,除非你有一个十六进制编辑器,否则很难解释
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. CREATE TABLE #hex([hex_Value] varbinary NULL)
步骤2.将数据插入表中,将示例插入到#hex值(0x300008000F000000030000020015001B00536976754D79736F7265)
步骤3.选择LTRIM(RTRIM(CONVERT(VARCHAR(max),REPLACE(hex_Value,0x00,0x20))))FROM #hex
试试这个。
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
这可以获得数据库事务(如插入,更新,删除),事务时间和对象名称。
希望能有所帮助。
我无法理解您的需求,但您可以通过Lumigent LogExplorer等工具提取日志中的数据。我不知道还有另外一种方法可以做你想做的事情。