排查专用 SQL 池的 tempdb 错误

适用对象:Azure Synapse Analytics

在专用 SQL 池中,tempdb 数据库用于临时表和中间空间进行数据移动(例如:随机移动、剪裁移动)、排序、加载、内存溢出和其他操作。 此外,与 tempdb 数据库交互的一个会话中未提交的事务将阻止日志刷新所有其他会话,从而导致日志文件填满。 由于 tempdb 数据库是共享资源,因此,大量消耗 tempdb 空间可能会导致其他用户的查询失败,并可能升级以防止建立新连接。

如果无法连接到专用 SQL 池,该怎么办?

如果没有现有连接来标识任何有问题的连接或查询,则解决无法创建新连接 的唯一方法是暂停恢复,或 缩放 专用 SQL 池。 此操作将终止导致此问题的用户事务,并在服务重启时重新创建 tempdb 数据库。

注意: 请务必为服务提供额外的时间来撤消所有正在运行的事务,因为暂停和缩放操作可能需要比正常时间更长才能在此方案中完成。

排查完整的 tempdb 数据文件问题

步骤 1:确定填充 tempdb 数据库的查询

请确保在执行查询时标识填充 tempdb 数据库的查询,除非已将日志记录组件实现到 ETL 框架或审核专用 SQL 池语句。 在大多数情况下,并非总是在发生问题的时间范围内执行的最长运行查询是 tempdb 空间不足错误的原因。 运行以下查询以获取长时间运行的查询的列表:

SELECT TOP 5 *
FROM sys.dm_pdw_exec_requests
WHERE status = 'running'
ORDER BY total_elapsed_time desc;

获得相当可疑的查询后,请尝试以下选项之一:

  • 终止 语句。
  • 尝试防止任何其他工作负荷进一步消耗 tempdb 空间,以便长跑者可以完成。

步骤 2:防止重复

确定并针对负责任的查询采取操作后,请考虑实施缓解措施以防止问题重复出现。 下表显示了 tempdb 完整错误的最常见原因的缓解措施:

原因 说明 缓解措施
分布式计划不当 为给定查询生成的分布式计划可能会无意中引入高频率数据移动,因为表统计信息维护不佳。 更新相关表的统计信息 ,并确保定期维护这些表。
聚集列存储索引 (CCI) 运行状况不佳 它由于内存溢出而占用 tempdb 空间。 重新生成 CCIs 并确保定期维护它们。
大型事务 在数据移动操作期间,大量 CREATE TABLE AS SELECT (CTAS)INSERT SELECT 语句填满 tempdb。 CTASINSERT SELECT 语句分解为多个较小事务。
内存分配不足 分配的内存不足(通过资源类或工作负荷组)的查询可能会溢出。tempdb 使用更大的资源类或具有更多资源的工作负载组执行查询。
最终用户外部表查询 针对外部表的查询对于最终用户查询来说不是最佳选择,因为引擎需要在处理数据之前将整个文件读入 tempdb 将数据加载到永久表中,然后将用户查询定向到该表。
整体资源不足 你可能会发现,专用 SQL 池在高活动期间接近其最大 tempdb 容量。 请考虑将专用 SQL 池与上述任何缓解措施结合使用。

排查完整的 tempdb 事务日志文件问题

tempdb 事务日志通常仅在客户端/用户填满时:

  • 打开显式事务,但从未发出 COMMITROLLBACK
  • 设置 IMPLICIT_TRANSACTION = ON (尤其是对于使用 AutoCommit 功能的 JDBC 客户端和工具)。

步骤 1:确定打开的事务

有问题的连接可能来自具有打开事务但处于“空闲”状态的客户端。 运行以下查询来帮助识别此方案:

SELECT *
FROM sys.dm_pdw_exec_sessions
WHERE is_transactional = 1
AND status = 'Idle';

注意:并非所有由于此查询而返回的连接都必须有问题。 在执行之间至少运行两次查询,并在执行之间超过 15 分钟,并查看处于此状态的连接。

步骤 2:缓解和防止问题

确定哪些客户端持有打开的事务后,请与用户一起更改两者:

  • 驱动程序配置(例如:JDBC AutoCommit 设置设置为 off,设置 IMPLICIT_TRANSACTIONS = ON
  • 即席查询行为(例如:不正确地执行BEGIN TRAN/COMMITROLLBACK

或者,可以考虑创建一个自动化过程来定期检测此方案并 终止 任何潜在的有问题的会话。

资源