Undo / TempDB / 临时空间压力
Undo/回滚空间、临时(temp)空间或 TempDB 承受压力。我们确定压力所在,并深入到根本原因,例如大型排序/哈希、长查询/长事务或空间泄漏。
压力在哪里:undo、temp,还是 tempdb 争用?
通过查看空间使用情况对压力来源进行分类:是 undo/回滚表空间正在被填满,通用临时(temp)空间被填满,还是在 MSSQL 中出现了 TempDB 页分配 latch 争用?
SELECT tablespace_name, ROUND(used_percent,1) AS used_pct
FROM dba_tablespace_usage_metrics
WHERE tablespace_name LIKE '%UNDO%' OR tablespace_name LIKE 'TEMP%';- Undo/回滚空间正在被填满(ORA-01555 / ORA-30036)
- 临时(temp)空间正在被填满(排序/哈希溢出)
- TempDB 分配 latch 争用(PFS/GAM/SGAM)
是什么在消耗 undo?
Undo 压力通常分为两类:长查询需要旧的 undo 来实现其开始时刻的一致性读(ORA-01555),或者长/未结束的事务产生大量 undo,填满空间并导致 ORA-30036。
SELECT s.sid, s.username, t.used_ublk*8/1024 AS undo_mb, s.status, t.start_time
FROM v$transaction t JOIN v$session s ON s.taddr=t.addr
ORDER BY undo_mb DESC;
SELECT MAX(maxquerylen) AS longest_query_sec, MAX(tuned_undoretention) AS tuned_retention FROM v$undostat;- 长查询需要旧的 undo(ORA-01555)
- 长/未结束的事务正在累积 undo(ORA-30036)
是什么在填满临时空间?
Temp 压力要么来自大型排序/哈希操作溢出到磁盘(正常但规模巨大),要么来自单个会话持续占用 temp(未关闭的游标、泄漏、永不结束的查询)。
SELECT s.sid, s.username, u.tablespace, u.blocks*8/1024 AS temp_mb, u.sqladdr
FROM v$tempseg_usage u JOIN v$session s ON s.saddr=u.session_addr
ORDER BY temp_mb DESC;- 大型排序/哈希操作正在溢出到磁盘
- 单个会话占用 temp(泄漏/未关闭的游标)
TempDB 争用是分配问题还是容量问题?
MSSQL TempDB 中会出现两种不同的问题:PFS/GAM/SGAM 页上的 PAGELATCH 争用(大量小型临时对象),或大型排序/version store 在容量上填满 TempDB。
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:%';
SELECT COUNT(*) AS tempdb_data_files FROM sys.master_files WHERE database_id=2 AND type=0;- PFS/GAM/SGAM latch 争用
- 大型排序/version store 正在填满 TempDB
根本原因:长查询 + undo 不足(ORA-01555)
长查询进行一致性读所需的旧 undo,因保留期已过或空间不足而被覆盖。
根本原因:长/未结束的事务填满了 undo(ORA-30036)
单个巨型 DML 或延迟提交的未结束事务产生了过多的 undo;UNDO 表空间无法扩展,引发 ORA-30036。
根本原因:大型排序/哈希正在填满临时空间
放不进内存的大型排序/哈希/group by 操作溢出到临时空间,并可能将其填满。
根本原因:会话占用临时空间(泄漏)
由于未关闭的游标、永不结束的查询或打开的临时表,单个会话不释放临时空间。
根本原因:TempDB PFS/GAM/SGAM latch 争用
当许多会话同时创建小型临时对象时,TempDB 的分配映射页(PFS/GAM/SGAM)上会出现 PAGELATCH 争用。