Oracle – Monitor TEMP Tablespace

Monitor TEMP Tablespace with a DBMS_SCHEDULER job

I was faced with a situation in which a process (Oracle pl/sql procedure within a package, scheduled outside Oracle in the evenings) was exhausting the TEMP tablespace. In order to investigate, the following procedure was used to monitor TEMP tablespace usage during the period of time the job was executed. This allowed quick identification of the offending user and SQL that was causing TEMP tablesace exhaustion.

Code is quick and dirty, no exception handling. I’m assuming the executing user has all the required privileges. There are other ways to investigate this, but this works.

Create a table to store data

CREATE TABLE TEMPDATA
(
  CTIME       TIMESTAMP(6) WITH TIME ZONE,
  TABLESPACE  VARCHAR2(30),
  TEMP_SIZE   VARCHAR2(41),
  INSTANCE    NUMBER,
  SID_SERIAL  VARCHAR2(81),
  USERNAME    VARCHAR2(30),
  PROGRAM     VARCHAR2(48),
  STATUS      VARCHAR2(8),
  SQL_ID      VARCHAR2(13)
)

Create the procedure

CREATE OR REPLACE procedure colltempdata as
begin

begin
    insert into tempdata
    SELECT systimestamp ctime,
           b.tablespace,
           ROUND(((b.blocks*p.value)/1024/1024),2)||'M' AS temp_size,
           a.inst_id as Instance,
           a.sid||','||a.serial# AS sid_serial,
           NVL(a.username, '(oracle)') AS username,
           a.program,
           a.status,
           a.sql_id
    FROM   sys.gv$session a,
           sys.gv$sort_usage b,
           sys.gv$parameter p
    WHERE  p.name  = 'db_block_size'
    AND    a.saddr = b.session_addr
    AND    a.inst_id=b.inst_id
    AND    a.inst_id=p.inst_id;
end;

end;
/

Create a job to execute the procedure

In this example, execute every minute for a specfied time period

begin
    DBMS_SCHEDULER.CREATE_JOB (
         job_name             => 'colltempdatajob6',
         job_type             => 'PLSQL_BLOCK',
         job_action           => 'begin colltempdata;commit;end;',
         start_date           => timestamp '2018-07-04 21:30:00',
         repeat_interval      => 'FREQ=MINUTELY;INTERVAL=1;',
         end_date             => timestamp '2018-07-04 22:45:00',
         enabled              => TRUE);
end;

SQL to display jobs, check size of data, and query the collected data

-- display job details
select job_name, start_date, run_count, last_start_date, next_run_date  from dba_scheduler_jobs where job_name like 'COLLTEMPDATAJOB%' order by start_date

-- check size of data
select sum(bytes)/1024/1024/1024 from dba_segments where segment_name = 'TEMPDATA'

-- Query data collected
select * from tempdata order by ctime desc

Leave a Reply

Your email address will not be published. Required fields are marked *