Welcome 微信登录

首页 / 数据库 / MySQL / Oracle 12c中性能优化&功能增强新特性之临时undo

临时表最有意思的特点之一是undo段也存储在常规undo表空间中,而它们的undo反过来被redo保护,这会导致一些问题。1)  写undo表空间需要数据库以读写模式打开,因此,只读数据库和物理备库中不能用临时表。2)  临时表中存储的是临时数据,恢复数据库时不需要恢复它们,因此,浪费redo来保护它们没必要。3)  临时表的undo占用满足undo保留时间的表空间。Oracle12c中,允许将临时表的undo数据存储在临时表空间中,这使得临时表可以用于物理备库和只读库中,因为临时表没必要产生redo。1. 启用/禁用临时undoOracle12c中,临时表的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@pdb1SET AUTOTRACE ON STATISTICS; --加载数据INSERT INTO g_t_tabWITH data AS (  SELECT 1 AS c1  FROM  dual  CONNECT BY level < 10000)SELECT rownum,TO_CHAR(rownum)FROM data a, data bWHERE  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 -- 检查该事务产生的undoSELECT t.used_ublk,     t.used_urecFROM v$transaction t,     v$session sWHERE  s.saddr = t.ses_addrAND    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 -- 打开临时undoALTER SESSION SETTEMP_UNDO_ENABLED = TRUE; SET AUTOTRACE ON STATISTICS; -- 加载数据INSERT INTO g_t_tabWITH data AS (  SELECT 1 AS c1  FROM dual  CONNECT BY level < 10000)SELECT rownum,TO_CHAR(rownum)FROM data a, data bWHERE  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 -- 检查该事务产生的undoSELECT t.used_ublk,     t.used_urecFROM v$transaction t,     v$session sWHERE  s.saddr = t.ses_addrAND    s.audsid = SYS_CONTEXT("USERENV","SESSIONID");  USED_UBLK USED_UREC---------- ----------       1          1 SQL> --检查产生的临时undoSET LINESIZE 200ALTER SESSION SETNLS_DATE_FORMAT="DD-MON-YYYY HH24:MI:SS"; SELECT *FROM v$tempundostatWHERE  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本文永久更新链接地址