One of the most interesting features of temporary tables is that undo segments are also stored in regular undo tablespaces, and their undos are in turn protected by redo, which can cause some problems.
1) Writing to the undo tablespace requires the database to be opened in read-write mode. Therefore, temporary tables cannot be used in read-only databases and physical standby databases.
2) Temporary tables store temporary data, which do not need to be restored when restoring the database, so it is not necessary to waste redo to protect them.
3) The undo of the temporary table occupies the table space that meets the undo retention time.
In Oracle12c, the undo data of temporary tables is allowed to be stored in the temporary table space, which makes the temporary table can be used in the physical standby database and read-only database, because the temporary table does not need to generate redo.
1. Enable/disable temporary undo
In Oracle12c, the undo segment of the temporary table is managed by the regular undo tablespace by default. Temporary undo is enabled or disabled at the session or system level via the TEMP_UNDO_ENABLED parameter.
-- session level
ALTER SESSION SETTEMP_UNDO_ENABLED = TRUE;
ALTER SESSION SETTEMP_UNDO_ENABLED = FALSE;
-- system level
CONN sys@pdb1 AS SYSDBA
ALTER SYSTEM SETTEMP_UNDO_ENABLED = TRUE;
ALTER SYSTEM SETTEMP_UNDO_ENABLED = FALSE;
The following are the precautions for temporary undo.
1) The temporary undo function is only available when the COMPATIBLE parameter is set to 12.0.0 or higher.
2) Once the session has created some temporary undo, no matter whether you use regular or temporary undo, how to set the TEMP_UNDO_ENABLED parameter will not help, unless you exit the session, during which there will be no error.
3) Temporary undo is the default setting on the standby database, so no matter how the TEMP_UNDO_ENABLED parameter is set on the standby database, it has no effect.
2. Monitor temporary undo
Regular undo activity is monitored through the V$UNDOSTAT view. In Oracle12c, the V$TEMPUNDOSTAT view was added to monitor temporary undo activity. The following is tested by creating a temporary table.
CONN test/test@pdb1
DROP TABLE g_t_tab PURGE;
CREATE GLOBAL TEMPORARY TABLEg_t_tab (
c1 NUMBER,
c2 VARCHAR2(20)
)
ON COMMIT DELETE ROWS;
Make sure the user has access to the V$TEMPUNDOSTAT view.
CONN sys@pdb1 AS SYSDBA
GRANT SELECT ONv_$tempundostat TO test;
The following test creates a session, loads some data into a temporary table, and then checks for changes in redo and undo usage. Temporary undo is not used in the following example.
CONN test/test@pdb1
SET AUTOTRACE ON STATISTICS;
--Download Data
INSERT INTO g_t_tab
WITH data AS (
SELECT 1 AS c1
FROM dual
CONNECT BY level < 10000
)
SELECT rownum,TO_CHAR(rownum)
FROM data a, data b
WHERE rownum <= 1000000;
1000000 rows created.
Statistics
----------------------------------------------------------
46 recursive calls
15346 db block gets
2379 consistent gets
16 physical reads
2944564 redo size
855 bytes sent via SQL*Net to client
986 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1000000 rows processed
SQL>
SET AUTOTRACE OFF
-- Check the undo generated by the transaction
SELECT t.used_ublk,
t.used_urec
FROM v$transaction t,
v$session s
WHERE s.saddr = t.ses_addr
AND s.audsid = SYS_CONTEXT('USERENV','SESSIONID');
USED_UBLK USED_UREC
---------- ----------
302 6238
SQL>
We can see that the operation produced 302 undo blocks, which is why the stats explicitly produced 2.9M redo, to protect these undo blocks.
The following example creates a session, enables temporary undo, loads some data into the temporary table, and then checks redo and undo usage changes, that is, through the V$TEMPUNDOSTAT view to check the generated undo.
CONN test/test@pdb1
-- open temporary undo
ALTER SESSION SETTEMP_UNDO_ENABLED = TRUE;
SET AUTOTRACE ON STATISTICS;
-- Download Data
INSERT INTO g_t_tab
WITH data AS (
SELECT 1 AS c1
FROM dual
CONNECT BY level < 10000
)
SELECT rownum,TO_CHAR(rownum)
FROM data a, data b
WHERE rownum <= 1000000;
1000000 rows created.
Statistics
----------------------------------------------------------
25 recursive calls
15369 db block gets
2348 consistent gets
16 physical reads
1004 redo size
853 bytes sent via SQL*Net to client
986 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
1000000 rows processed
SQL>
SET AUTOTRACE OFF
-- Check the undo generated by the transaction
SELECT t.used_ublk,
t.used_urec
FROM v$transaction t,
v$session s
WHERE s.saddr = t.ses_addr
AND s.audsid = SYS_CONTEXT('USERENV','SESSIONID');
USED_UBLK USED_UREC
---------- ----------
1 1
SQL>
--Check the generated temporary undo
SET LINESIZE 200
ALTER SESSION SETNLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS';
SELECT *
FROM in $ tempundostat
WHERE end_time >= SYSDATE - INTERVAL '1' MINUTE;
BEGIN_TIME END_TIME UNDOTSN TXNCOUNT MAXCONCURRENCY MAXQUERYLENMAXQUERYID UNDOBLKCNT EXTCNT USCOUNT SSOLDERRCNT NOSPACEERRCNT CON_ID
---------------------------------------- ---------- ---------- -------------- ------------------------ ---------- ---------- ---------- ----------- -----------------------
24-NOV-2014 15:11:0923-NOV-2014 15:17:30 3 2 0 0 321 4 1 0 0 0
SQL>
In this example, we see that only a small amount of regular undo is generated, resulting in 1K redo. The V$TEMPUNDOSTAT view shows that 321 temporary undo blocks were generated.