tempdb 争用(SQL Server)
症状
PAGELATCH_UP/EX 等待,tempdb 分配页(PFS/GAM/SGAM)上的争用,整体变慢。
1. 确认争用
tempdb 系统页(例如 2:1:1)上的 PAGELATCH 等待表明存在分配争用。
SQL Server
SELECT session_id, wait_type, wait_duration_ms, resource_description
FROM sys.dm_os_waiting_tasks
WHERE wait_type LIKE 'PAGELATCH%' AND resource_description LIKE '2:%'
ORDER BY wait_duration_ms DESC;2. 分解 tempdb 使用情况
谁在使用多少 tempdb?是内部对象(排序/哈希溢出)、版本存储,还是用户对象?
SQL Server
SELECT * FROM sys.dm_db_file_space_usage;
SELECT TOP 10 session_id, user_objects_alloc_page_count, internal_objects_alloc_page_count
FROM sys.dm_db_task_space_usage ORDER BY internal_objects_alloc_page_count DESC;3. 修正文件配置
为 tempdb 使用多个大小相同的数据文件,数量等于 CPU 核数(最多 8 个)。SQL 2016+ 在安装时即推荐这样做;旧版本使用跟踪标志 1117/1118。将文件放在快速磁盘上(本地 NVMe)。
4. 找出失控查询
带有大量排序/哈希溢出的查询会使 tempdb 暴涨。针对内存授予不足或计划糟糕的查询;通过索引/计划减少溢出。
SQL Server
SELECT TOP 10 t.text, mg.requested_memory_kb, mg.granted_memory_kb
FROM sys.dm_exec_query_memory_grants mg CROSS APPLY sys.dm_exec_sql_text(mg.sql_handle) t
ORDER BY mg.requested_memory_kb DESC;5. 其他数据库中的类似问题
同样的“临时空间争用”在 Oracle 中对应 TEMP 表空间(v$tempseg_usage / v$sort_usage),在 PostgreSQL 中对应 temp_files 和 work_mem 溢出。根本解决办法始终相同:修复发生溢出的查询并加快临时空间。