打开LDF文件并查看LDF文件内容

每个SQL Server数据库都会映射一组操作系统文件。这些文件存储数据和日志信息。一个数据库都会有它自己的独立文件,并且数据和日志信息不会混合在同一个文件中。
同时数据存储在一个MDF文件里,所有的事务和每个对SQL Server数据库修改的事务都会被存储在一个LDF文件里- 一个事务日志文件是数据库的一个非常重要的组成部分。从概念上来讲,日志文件是一串日志记录。物理上,日志记录被存储在一个或一组物理LDF文件里实现为事务日志。

LDF文件最初的目的是提供ACID特性- 原子性、一致性、隔离性和持久性

  • 原子性:如果事务的一部分失败了,那么整个事务都会失败,数据库状态并不会更改
  • 一致性:任何事务使数据库从一个合法状态带到另一个状态
  • 隔离性:变更数据库状态的那些并行事务的执行就像是串行执行一样,一个接着一个
  • 持久性:一旦事务提交,事务就需要持久化,即使是发生错误、断电、还是宕机

一个LDF文件存储了足够信息来重播或回滚变更,或者恢复数据库到一个特定时间点。因此,由于有多种审计或恢复的要求,通常会有打开LDF文件并查看它存储的内容的需要。但是要查看LDF文件内容是一个不容易的任务。

有几个SQL Server函数和命令(例如 fn_dblog, fn_dump_dblog和DBCC PAGE)能提供查看LDF文件内容的方法。然而,当您使用它们的时候您需要一些重要的T-SQL知识,一些是没有文档记载的,它们提供的结果也比较难转换为人们可以阅读的格式。下面是使用SQL Server函数和命令查看LDF文件内容的例子:

  1. 这里是一个例子使用fn_dblog 来读取一个联机事务日志,只能只显示129列结果集中的7个列

    Using fn_dblog to read an online transaction log

  2. fn_dump_dblog 函数通常用来读取本地联机事务日志或本地压缩备份。结果是相似点:

    Using fn_dump_dblog to open LDF file

    不幸的是,对于fn_dblog 和fn_dump_dblog 这两个函数没有官方文档记载。要翻译这些列,您需要熟悉内部结构和数据格式、标志位和一行数据里它们的所有号码

  3. DBCC PAGE通常被用来读取数据库联机文件MDF和LDF的内容。结果是一个十六进制输出,除非您有一个十六进制编辑器,否则很难解读里面的内容

    Using DBCC PAGE to read MDF and LDF files

使用ApexSQL Log 作为一个LDF文件读取器

ApexSQL Log一个SQLServer 联机事务日志读取器 ,它能读取联机事务日志,分离的事务日志和事务日志备份(本地的还是已压缩的)。

另外显示一个LDF文件的逻辑内容, ApexSQL Log 也提供了一些额外的特性比如 创建Undo/Redo脚本,DML操作的行历史 还有更多

要打开并查看LDF文件使用 ApexSQL Log:

  1. 连接到LDF文件所属数据库:

    Connecting to the database that the LDF file belongs to

  2. 下一步是添加包含了您需要查看的信息的LDF文件备份或者已分离LDF文件。确保它们来自于一个 完整的日志链。一个日志链是一个连续的事务日志备份序列。
    它开始于一个完整数据库备份仅接着所有后续的通过审计的事务日志备份。如果它被破坏了,只有在丢失的最后一个备份前的日志中的事务能够显示完整的信息(例如架构和对象名,或者一行历史)

    不像插入和删除操作,它们会完整记录进去LDF文件,更新操作会以最小日记的方式记录–只记录变更的那部分内容,新值和旧值。当记录更新操作,SQL Server不会完
    记录数据行的前后状态,它只记录发生在数据行上的增量变更。例如,如果一个单词“log”被更新为“blog”,一般来说,SQL Server只在索引0记录额外的字母“B”。
    对于ACID目的这个动作已经足够了,但是对于要显示整行数据的前后变化状态是不够的。所以,为了理解真正发生的变更,ApexSQL Log 必须要从剩下的事务日志/事务日志备份和联机数据库数据重构变更发生的上下文信息。

    要完成这件事,它部署了各种不同的互补技术来重构数据行状态,其中一个就是使用完整的日志链来进行重构。指定完整的日志链,连同最新的完整备份和差异备份,
    让 ApexSQL Log来重构UPDATE语句的上下文从最后一次备份更新行状态那个时间重构所有对那行造成影响的所有操作。在我们的例子里, ApexSQL Log 会找到在最后一次备份时数据行的状态,查看那个字段值是“log”,并从那里得出结论在索引0位置记录的更改 额外字段值“b”已经转变为字段值“blog”。

    此外,一条日志链可以加快读取事务速度仅仅使用几个事务日志备份文件代替一个单独的联机事务日志,联机事务日志会被所有的事务日志备份使用的空间大几倍。
    另外,一个已分离的LDF文件也可以作为读取源头-ApexSQL Log 会分析所有提供的源头为了提供保存在LDF文件里的事务的准确信息。

    要做事务日志分析就需要在“Select SQL logs to analyze”步骤使用添加按钮

    Using the Transaction logs tab

  3. 使用数据库备份tab窗格提供的事务最开始的完整日志链开头的那个完整数据库备份

    Selecting database backups to be analyzed

  4. 在过滤设置步骤中使用时间范围部分,指定当您感兴趣的那个操作执行的那段时间。还有收窄必要的操作范围可以加速处理的过程。

    Filter setup - open LDF file

  5. 当所有这一切都设置好之后,使用“打开”按钮开始读取LDF文件的处理过程

    所有事务,根据提供的过滤选项和资源,在处理完毕之后将会显示在ApexSQL Log的主窗格里

关于LDF文件读取的结论

就像前面描述的那样,有不同的方法来打开一个LDF文件,它们大部分做的都是-打开它。尽管要获取到可阅读的信息和有效利用这些信息是比较棘手的。

另一方面,除了简单的打开一个LDF文件, ApexSQL Log 会加上要处理的值。您能够读取通过读取事务日志来查看受影响的对象的操作类型、架构和对象名,操作执行的时间,执行操作的那个用户的用户名等一些更多的东西。

对比只是简单打开LDF文件,ApexSQL Log 处理一个LDF文件的主要优势有:

  • 通过链接能够显示友好可读的信息,并且能从129个列里读取出能解析的数据(转换十六进制和二进制值)
  • 将不同的LDF文件链接在一起
  • 为了提供对每个事务的更详细信息,它能够合并联机和备份文件(包括数据库和LDF文件)
  • 完全重构UPDATE操作,包括旧的字段值和新的字段值
  • 对于DML操作能展现一个完整的数据行变更历史,包括执行每个操作的登录用户,事务执行时间
  • 为了保存资源和加快处理速度可以预先过滤将要读取的信息
  • 即使表不再存在依然能够通过映射旧的(被删除的)表的ID来恢复表数据
  • 不需要T-SQL脚本知识就能够处理和显示LDF文件内容

超越读取,ApexSQL Log还能提供以下功能:

  • grid窗格排、分组、过滤和高级搜索能够让您用无数种方式操作您的数据
  • 除了grid窗格渲染 –ApexSQL Log 能够转换CSV、HTML、XML、SQL数据帮助您管理数据导出和保存grid窗格的内容用于后续分析
  • 能够创建脚本来回滚或者回放SQL Server事务– 这对于数据库恢复场景是比较有用的当丢失了数据之后需要进行还原,或者数据/架构的变更需要去回滚,不需要还原整个数据库
  • 所有特性都有官方文档支持
  • 技术支持更多

作者:Ivan Stankovic

翻译者: 林勇桦

July 2, 2015