绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
监控业务SQL消耗TEMP空间的几种常见方法-来自一线监控需求
2021-01-19 10:59:06


近经常遇到temp空间不足的问题,因为是重要系统,所以也监控了改表空间的使用率。但是近零点之后告警频繁
就需要分析哪些用户的哪些SQL造成了temp空间被耗尽,对于这个问题的思路有三个方式
1 如果是正在执行的SQL或者执行过的SQL依然在内存可以通过脚本查询。
2 如果是过去已经执行的SQL可以通过dba_hist视图查询,这个视图主要是通过等待事件定位,进而看改SQL的执行计划
分析执行计划是否优。
3 通过创建监控job,定制更加详细的阈值来监控用户和SQL相关信息

下面我们演示改三种方式如何定位SQL。如果是重要系统,我们还是推荐使用第三种方式更严谨。
我们先创建两个测试表
create table a as select * from all_objects;
create table b as select * from all_objects;
exec dbms_stats.gather_table_stats(user,'A');
exec dbms_stats.gather_table_stats(user,'B);
select num_rows,table_name from user_tables where table_name in ('A','B');

1 正在执行的SQL可以通过脚本查询

执行SQL:

SQL> select userenv('sid') from dual;

USERENV('SID')
--------------
48

SQL> select * from a,b order by 1,2;

查询消耗temp的SQL以及消耗多少UNdo

col username for a20
col tablespace for a20
col osuser for a20
col sql_text for a50

SELECT a.username, a.sid, a.serial#, a.osuser, b.tablespace, b.blocks, c.sql_text
FROM v$session a, v$tempseg_usage b, v$sqlarea c
WHERE a.saddr = b.session_addr
AND c.address= a.sql_address
AND c.hash_value = a.sql_hash_value
ORDER BY b.tablespace, b.blocks;

USERNAME SID SERIAL# OSUSER TABLESPACE BLOCKS SQL_TEXT
-------------------- ---------- ---------- -------------------- -------------------- ---------- --------------------------------------------------
TEST 48 31322 oracle TEMP 24192 select * from a,b order by :"SYS_B_0",:"SYS_B_1"

2 通过dba_hist或者v$active_session_history查询

SQL> select sql_id,event,count(*) from v$active_session_history where event like '%temp%' and sample_time >to_date('202101191000','yyyymmddhh24mi') group by sql_id,event order by count(*)

SQL_ID EVENT COUNT(*)
-------------------------- -------------------------------------------------- ----------
c6b0wtrqr9xnu direct path write temp 1
根据需求可以通过ASH查询其他字段信息,比如用户ID,program等待,具体维度自己根据需求添加吧。
后面可以进一步查询执行计划,分析哪里消耗了temp空间,看是否可以调优了。
SQL> select * from table(dbms_xplan.display_cursor('c6b0wtrqr9xnu'))

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
SQL_ID c6b0wtrqr9xnu, child number 0
-------------------------------------
select * from a,b order by :"SYS_B_0",:"SYS_B_1"

Plan hash value: 2084382175

--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | 393M(100)| |
| 1 | SORT ORDER BY | | 5045M| 1174G| 1480G| 393M (1)| 04:15:57 |
| 2 | MERGE JOIN CARTESIAN| | 5045M| 1174G| | 25M (1)| 00:16:53 |
| 3 | TABLE ACCESS FULL | A | 71033 | 8671K| | 367 (1)| 00:00:01 |
| 4 | BUFFER SORT | | 71034 | 8671K| | 393M (1)| 04:15:57 |
| 5 | TABLE ACCESS FULL | B | 71034 | 8671K| | 365 (1)| 00:00:01 |
--------------------------------------------------------------------------------------

3 通过job定制抓取消耗TEMP空间的SQL。
参考MOS: How Can Temporary Segment Usage Be Monitored Over Time? (Doc ID 364417.1)
(1) 创建表
CREATE TABLE TEMP_SEG_USAGE(
DATE_TIME DATE,
USERNAME VARCHAR2(30),
SID VARCHAR2(6),
SERIAL# VARCHAR2(6),
OS_USER VARCHAR2(30),
SPACE_USED NUMBER,
SQL_TEXT VARCHAR2(1000));

(2) 创建存储过程
CREATE OR REPLACE PROCEDURE TEMP_SEG_USAGE_INSERT IS
BEGIN
insert into TEMP_SEG_USAGE
SELECT sysdate,a.username, a.sid, a.serial#, a.osuser, b.blocks, c.sql_text
FROM v$session a, v$tempseg_usage b, v$sqlarea c
WHERE b.tablespace = 'TEMP'
and a.saddr = b.session_addr
AND c.address= a.sql_address
AND c.hash_value = a.sql_hash_value
AND b.blocks*(select block_size from dba_tablespaces where tablespace_name = b.tablespace) > 1024*1024
ORDER BY b.tablespace, b.blocks;
COMMIT;
END;
/

-- Schedule job for every 5 minute with DBMS_SCHEDULER.

BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'MONITOR_TEMP_USAGE_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN TEMP_SEG_USAGE_INSERT; END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=MINUTELY;INTERVAL=5',
end_date => NULL,
enabled => TRUE,
comments => 'Job created to monitor temp usage.');
END;
/

执行频率以及执行消耗TEMP空间的阈值根据实际自己调整吧。

分享好友

分享这个小栈给你的朋友们,一起进步吧。

Oracle运维新鲜事-技术与管理各占半边天
创建时间:2020-08-04 11:34:57
本技术栈旨在分享技术心得,运维趣事,故障处理经验,调优案例,故障处理涉及集群,DG,OGG,大家生产中遇到的问题基本都会囊括了,我会发布生产库遇到的故障,希望在交流中互助互益,共同提高,也希望大家讨论,如果您有生产中遇到的集群问题,也可以在这里提出来,一起讨论,现实中也帮助不少同学解决了生产库的故障。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • Abraham林老师
    栈主
  • 小雨滴
    嘉宾
  • hawkliu
    嘉宾
  • u_97a59a25246404
    嘉宾

小栈成员

查看更多
  • 栈栈
  • dapan
  • 小菜鸟___
  • hwayw
戳我,来吐槽~