排查专用 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 空间。 重新生成 CCI 并确保定期维护它们。
大型事务 在数据移动操作期间,大量的 CREATE TABLE AS SELECT (CTAS)INSERT SELECT 语句会填满 tempdb。 CTASINSERT SELECT 语句分解为多个较小的事务。
内存分配不足 通过资源类或工作负荷组) 分配内存不足 (的查询可能会溢出到 tempdb 使用更大的 资源类 或具有更多资源的 工作负荷组 执行查询。
最终用户外部表查询 针对外部表的查询不是最终用户查询的最佳选择,因为引擎需要在处理数据之前将整个文件读取到 tempdb 中。 将数据加载 到永久表,然后定向用户查询。
总体资源不足 你可能会发现专用 SQL 池在高活动期间已接近其最大 tempdb 容量。 请考虑将专用 SQL 池与上述任何缓解措施结合使用来纵向扩展。

对完整的 tempdb 事务日志文件进行故障排除

tempdb 事务日志通常仅在客户端/用户出现以下任一情况时才会填满:

  • 打开显式事务,但从不发出 COMMITROLLBACK
  • 设置 IMPLICIT_TRANSACTION = ON (,特别是针对使用自动提交功能的 JDBC 客户端和工具) 。

步骤 1:识别未结事务

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

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

注意:并非所有因此查询而返回的连接都必然有问题。 在两次执行之间超过 15 分钟的情况下至少运行两次查询,并查看哪些连接保持此状态。

步骤 2:缓解和防止问题

确定哪些客户端持有未结事务后,请与用户一起更改其中一个或两者:

  • 驱动程序配置 (例如:JDBC AutoCommit 设置为 off,用于设置 IMPLICIT_TRANSACTIONS = ON)
  • 即席查询行为 (例如:在没有) 的情况下COMMIT/ROLLBACK执行错误BEGIN TRAN

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

资源