| « | 十月 2008 | » | ||||
|---|---|---|---|---|---|---|
| 一 | 二 | 三 | 四 | 五 | 六 | 日 |
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 | 31 | ||
今天遇到一个bug,对临时表进行insert的时候产生异常多的redo,下面模拟过程:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE 9.2.0.1.0 Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production
--在会话1执行:
SQL> create global temporary table t1(id int) on commit preserve rows;
Table created
SQL> create global temporary table t2(id int) on commit delete rows;
Table created
SQL> create table t3(id int);
Table created
SQL> select * from v$statname where name='redo size';
STATISTIC# NAME CLASS
---------- ---------------------------------------------------------------- ----------
115 redo size 2
--新开一个会话2执行:
SQL> select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
---------- ---------- ----------
10 0 1
SQL> insert into t1 select rownum from dual connect by rownum<500000;
499999 rows inserted
--在会话1查询产生的redo量
SQL> select * from v$sesstat where sid=10 and statistic#=115;
SID STATISTIC# VALUE
---------- ---------- ----------
10 115 62249712
--再会话2往t2插入数据
SQL> insert into t2 select rownum from dual connect by rownum<500000;
499999 rows inserted
--会话1中查询此时的redo情况
SQL> select * from v$sesstat where sid=10 and statistic#=115;
SID STATISTIC# VALUE
---------- ---------- ----------
10 115 124499216
--在会话1往普通表插入数据
SQL> insert into t3 select rownum from dual connect by rownum<500000;
499999 rows inserted
--会话1中查询此时的redo情况
SQL> select * from v$sesstat where sid=10 and statistic#=115;
SID STATISTIC# VALUE
---------- ---------- ----------
10 115 132242444
--产生的redo比较:
会话级临时表:62249712
事务级临时表:62249504
普通表 :7743228
可见,无论对事务级的临时表还是会话级的临时表,都产生远比普通表多的redo,这是极不正常的。
临时表的数据对于恢复是没有任何用处的,所以,它不需要为insert的数据记录redo信息。因此,遇到上面的情况,十有八九是因为bug引起的。
查了一个metalink,确认这是一个bug:
Bug 2874489 Excessive REDO generated for INSERT as SELECT into GLOBAL TEMPORARY TABLES
This note gives a brief overview of bug 2874489.
Using 'insert as select' to insert into a global
temporary table can generate far more redo than
the same insert into a permanent table.
Updates and deletes are not affected, only multirow inserts.
这个 bug在9205后修正。
实际上,这个bug也影响undo的使用,对临时表的操作占用的undo远比普通表多。
学习,lz今天更新很多哦
carcase | 15/01/2008, 14:02