SQL 2016 SQL Server 断言:文件:<pageref.cpp>,行 = 951 断言失败

Sir*_*lot 8 sql-server sql-server-2016

我目前正在将我们的数据仓库从 SQL 2012 升级到 SQL 2016。我的旧数据仓库和新数据仓库并行运行。

我的 ETL 过程(由第 3 方在 SSIS 中开发的框架)在 2012 年成功运行了 2 年多,但在 2016 年失败。到目前为止,数据库和 ETL 过程是相同的。

两个服务器都是在 VMWare 上运行的虚拟机。旧服务器是带有 24Gb RAM 的 Win 2008。SQL 2012 标准版 最大内存设置为 16Gb。新服务器是带有 64Gb RAM 的 Win 2012。SQL 2016 开发。最大内存设置为 50Gb。新 DW 运行 v13.0.1601.5 RTM 开发者版(64 位)。

在运行我的 ETL 过程时,使用 SQL 合并到维度或事实表的加载步骤失败并显示以下错误。

全文:

描述:SQL Server 断言:文件:, line=951 Failed Assertion = 'IS_OFF (BUF_MINLOGGED, m_buf->bstat) || pageModifyType != PageModifyType_Contents || GetPagePtr()->IsTextPage()'。此错误可能与时间有关。如果重新运行语句后错误仍然存​​在,请使用 DBCC CHECKDB 检查数据库的结构完整性,或重新启动服务器以确保内存中的数据结构未损坏。

按照建议,我运行了 DBCC 并且没有发现错误。我也重新启动了 SQL。然后我重新启动了 ETL 过程并得到了同样的错误。

我对此错误的搜索表明,这是SQL 2008、2012 和 2014 中的已知错误,并在随后的修补程序和累积更新中修复。所以看到它在 2016 年重新出现,我有点惊讶。

我发现的链接说,如果数据库处于简单或大容量日志恢复模式,尝试插入时它会影响 SSIS。(我在简单恢复模式下运行)

建议的解决方法是将 Db 恢复模式更改为 FULL。我已经尝试过这个并且它有效,但它不是数据仓库的解决方案。

有没有其他人在 2016 年遇到过这个问题?

任何人都可以建议替代解决方法吗?

更新:

26/7/2016:我应用了关键更新 KB3164398 (v13.0.1708.0),但问题仍然存在。

27/7/2016:我已应用累积更新 CU1 KB3164674 (v13.0.2149.0)。

2016 年 3 月 8 日:我们最小的立方体在一夜之间发生了错误。CU1 没有解决这个问题。今天我在 MS Connect 上报告了这个错误,而且我还记录了与 Microsoft 的支持电话。

2016 年 12 月 8 日:MS-Support 最初做出回应,但回应是“我们没有解决方案”。支持人员将与他的同事讨论并回复我。8天后,我还没有收到他的消息。

虽然我没有“修复”,但我们确实找到了适合我们的解决方法。请参阅我发布的答案。

29/9/2016。我上周申请了CU2。在 Thursay,我们不小心运行了一个旧版本的合并,它再次失败并出现相同的错误。所以.. CU2 也没有修复它。

23/1/2017:我应用了2016 SP1 CU1,我相信这已经解决了这个问题。具体KB3205964

wBo*_*Bob 2

查看知识库,您有几个选项/解决方法:

  1. 切换到完整恢复模式。您说“这对于仓库来说不是一个很好的选择”,但这实际上只是定期设置事务日志备份(例如 15 分钟)然后将其丢弃的问题。SSIS/维护计划有用于执行此操作的库存任务。您将丢失批量记录的事务,但我从未发现这些事务对运行时产生了很大的影响,只是日志大小不同。你甚至可以将日志备份到nul,这里我不会描述。如果您不确定该怎么做,请询问当地的 DBA。磁盘空间和事务日志备份保留是比致命错误更容易解决的问题。当这个问题最终得到解决后,您可以切换回来。
  2. 知识库提到“单个分布式事务中的多个 BULK INSERT 语句”。从您的问题中不清楚您的批量插入是如何设置的。您是否使用 SSIS 来运行使用该MERGE命令的“执行 SQL”任务?这里“多个批量插入”是什么意思?有没有一种方法可以将您的方法转换为单个批量插入,例如一次一个?例如,在 SSIS 中,您可以临时将“MaxConcurrentExecutables”设置为 1,看看是否有帮助。将其绑定到配置变量,以便您稍后可以将其更改回来。显然,这会减慢速度,但您更希望 ETL 完成而不是快速失败。并行处理事情是一种很好的模式,也是 SSIS 的真正优势,但是您只能以最慢的组件的速度运行;假设您有 10 个维度需要一分钟,一个事实需要一个小时,您的 ETL 在并行运行一小时内完成,或者串行运行 1 小时 10 分钟内完成。
  3. MERGE很好,但确实有一些问题。您可以考虑转换回INSERT/ UPDATE。您还应该根据此处使用HOLDLOCKwith 。你用这个提示吗?如果您这样做,对这个问题有什么影响吗?我们在早期的 SQL 2014 版本中遇到了一个问题,即在列存储中使用可组合 DML(子句)会导致这种断言 - 我让他们从维度中删除列存储索引,这是他们在没有告诉我的情况下添加的。MERGEMERGEOUTPUT
  4. 您正在进行什么样的交易处理?有时,使用 ETL,只需重新运行即可重复该位置。有时您需要它失败并回滚。您是如何实施的?可以更改,使其不是“单一分布式事务”吗?

祝你好运。