共计 3577 个字符,预计需要花费 9 分钟才能阅读完成。
临时表最有意思的特点之一是 undo 段也存储在常规 undo 表空间中,而它们的 undo 反过来被 redo 保护,这会导致一些问题。
1) 写 undo 表空间需要数据库以读写模式打开,因此,只读数据库和物理备库中不能用临时表。
2) 临时表中存储的是临时数据,恢复数据库时不需要恢复它们,因此,浪费 redo 来保护它们没必要。
3) 临时表的 undo 占用满足 undo 保留时间的表空间。
Oracle12c 中,允许将临时表的 undo 数据存储在临时表空间中,这使得临时表可以用于物理备库和只读库中,因为临时表没必要产生 redo。
1. 启用 / 禁用临时 undo
Oracle12c 中,临时表的 undo 段默认还是通过常规 undo 表空间管理。临时 undo 通过 TEMP_UNDO_ENABLED 参数在会话或系统级别启用或禁用。
— 会话级别
ALTER SESSION SETTEMP_UNDO_ENABLED = TRUE;
ALTER SESSION SETTEMP_UNDO_ENABLED = FALSE;
— 系统级别
CONN sys@pdb1 AS SYSDBA
ALTER SYSTEM SETTEMP_UNDO_ENABLED = TRUE;
ALTER SYSTEM SETTEMP_UNDO_ENABLED = FALSE;
以下为临时 undo 的注意事项。
1) 临时 undo 功能仅在 COMPATIBLE 参数设置为 12.0.0 或更高时才可用。
2) 一旦会话创建了一些临时 undo,无论用常规还是临时 undo,怎么设置 TEMP_UNDO_ENABLED 参数也是无济于事的,除非退出会话,期间,也不会有什么报错。
3) 临时 undo 在备库上是默认的设置,因此,无论在备库上怎么设置 TEMP_UNDO_ENABLED 参数,都没什么作用。
2. 监控临时 undo
常规 undo 活动通过 V$UNDOSTAT 视图监控。Oracle12c 中,增加了 V$TEMPUNDOSTAT 视图来监控临时 undo 活动。下面通过创建一个临时表来测试。
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;
确信用户可以访问 V$TEMPUNDOSTAT 视图。
CONN sys@pdb1 AS SYSDBA
GRANT SELECT ONv_$tempundostat TO test;
下面的测试创建一个会话,往临时表里加载一些数据,然后,检查 redo 和 undo 的使用变化。下例中没有用到临时 undo。
CONN test/test@pdb1
SET AUTOTRACE ON STATISTICS;
– 加载数据
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
— 检查该事务产生的 undo
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>
我们可以看到该操作产生了 302 个 undo 块,这就是统计信息显式产生了 2.9M redo 的原因,是为了保护这些 undo 块。
下例创建一个会话,开启临时 undo,往临时表中加载一些数据,再检查 redo 和 undo 使用变化,即通过 V$TEMPUNDOSTAT 视图来检查产生的 undo。
CONN test/test@pdb1
— 打开临时 undo
ALTER SESSION SETTEMP_UNDO_ENABLED = TRUE;
SET AUTOTRACE ON STATISTICS;
— 加载数据
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
— 检查该事务产生的 undo
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>
– 检查产生的临时 undo
SET LINESIZE 200
ALTER SESSION SETNLS_DATE_FORMAT=’DD-MON-YYYY HH24:MI:SS’;
SELECT *
FROM v$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>
该例中,看到仅产生了少量的常规 undo,导致产生了 1K 的 redo。V$TEMPUNDOSTAT 视图显示产生了 321 个临时 undo 块。
更多 Oracle 相关信息见 Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-01/140020.htm