我们如何读取SQL Server事务日志,我知道使用DBCC日志(数据库,4)并且它将生成日志输出现在我想解码日志记录,这是十六进制格式。
0x00003E001C000000A500000001000200BE040000000006021D0000000100000018000000(仅一部分数据)
是否有任何方法以文本格式读取它或将十六进制数据转换为text.i想要制作一个可以读取log的工具。第三方工具可用,即ApexSQL但它们是付费工具。
答案 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')
对于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,其中表明只要项目的目标有限,就可以从日志中提取有用信息。编写一个完整的日志阅读器,可以处理对象中的模式更改以及稀疏列(以及下一版本中的列存储索引)之类的事情,但这可能是一项巨大的工作。
答案 1 :(得分: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 :(得分: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