SQL Server 2005事务日志条目:LOP_Format_Page

3

我正在调查一个与ETL处理相关的问题,尽管数据库设置为批量记录模式(并非伪简单但真正的批量记录),但日志仍然会大幅度扩展。

使用 ::fn_dblog(null,null) 函数检查事务日志操作和操作上下文后,发现日志扩展主要是由 LOP_FORMAT_PAGE 操作在 LCX_Heap 上下文中记录导致的。(对于单个数据加载,该操作占据了 97% 的扩展,出现在日志中超过 600k 次。)

问题是,lop_format_page 记录了 SQL 所做的什么操作?

如果能够理解导致此结果的原因 / 影响链条,并根据需要修改 ETL,则应该能够反向推导逻辑。

我不指望有多少人遇到过这个问题,因为操作和上下文的可用细节很少或者没有。

3个回答

4

你说得没错,这确实是非常少(甚至没有!)文档记录的。我在日志中进行了一些探索,并做了大量的日志缩减工作(主要是确保批量插入确实被批量执行!)。因此,我知道这可能很难追踪。

根据我在上下文中看到LOP_FORMAT_PAGE的最佳猜测是,它正在清除一个新页面--例如当分裂索引页面时,一旦该页面已满并且需要创建另一个条目。因此,如果这个假设是正确的,您可能需要追踪一下可能导致大量新页面分配的原因。

你知道在ETL中发生了哪些操作,而你又看到了日志扩展吗?了解这个上下文将会有所帮助--如果可能,请将这些信息添加到您的问题中。

此外,你能在测试环境中运行和变化你的ETL代码吗?与其弄清楚这个晦涩的日志记录定义,不如通过注释一些步骤(或限制受影响的行数),然后看看哪个更改使问题消失,来隔离问题可能更容易。


上下文是LCX_Heap,所以我猜测这是在ETL过程中而不是索引过程中,因为上下文应该是LCX_Clustered。堆页面不应该分裂,只能向前移动行,所以我认为这不是页面分裂操作/转发操作 - 但我可以理解你的想法。代码位于客户端站点的防火墙后面,因此我无法直接访问日志/控制环境 - 只能提交脚本。我的直觉告诉我SSIS包没有完全使用批量记录模式,但我还没有找到具体原因。 - Andrew
嗯,我最初跳过了LCX_Heap部分,感谢您纠正我。是否有任何代码在ETL的一部分中删除聚集索引?或者最初将表创建为堆,然后稍后创建聚集索引?换句话说,即使最终模式是所有聚集索引,ETL中是否存在任何“短暂堆”?或者在构建索引时使用SORT_IN_TEMPDB选项?或者SELECT....INTO tempdb表?等等--我并不是说这些中的任何一个会导致问题,只是提出一些想法。 - Justin Grant
此外,我在使用SSIS和日志增长方面遇到了糟糕的经历。其中一个案例是由于在ETL开始时启动并包含每个操作的事务。我通过在包步骤中设置Transaction=NotSupported来解决了这个问题。另一个案例是我没有正确配置插入任务,因此它们没有最小记录。但是,这两种情况似乎都与您的行为不符,您在日志中看到页面格式而没有行插入。您还可以尝试将日志记录或时间戳插入ETL代码中,以便您可以将其与事务日志记录相关联。 - Justin Grant
1
最终答案是,备份过程异常漫长,导致系统在数据传输期间进行备份,从而迫使日志将数据加载视为完全记录的任务。 - Andrew
1
啊,明白了。感谢您跟进解决这个谜团。 - Justin Grant
显示剩余2条评论

0

我原以为LOP_FORMAT_PAGE只是用于格式化页面。但它实际上可以包含完整的页面数据,如果数组的数量是1;或者是页面数据的一部分(包括表头和记录),同时第二个数组包含相对于页面末尾的记录偏移量。


0

我认为你和Justin已经找到了答案,但它并不是很复杂。

ETL过程(提取、转换、加载)正在将数据加载到数据库中。自然地,随着页面填满,需要在堆上分配新的页面。


1
情况并不简单 - 日志增长超过数据增长相当多,例如,2GB的数据扩展已生成5GB的日志 - 每页行数相当高,而且大部分增长都是此操作,但无文档可参考。 - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接