临时表与redo、undo

临时表不会为其中的blocks生成redo信息,所以对临时表的操作是不可恢复的。用户修改临时表的block时,在redo log file中不会有对该block的修改信息。但是临时表会生成undo信息。因此,实际上,对临时表的操作会因为undo的生成而产生redo信息。

为何会生成undo信息呢?这是为了在transaction中可以实现roll back到SAVEPOINT。例如:用户可能rollback临时表中最新插入的50条记录,而保留最先插入的50条记录。这就需要为插入的100条记录产生undo信息,切必须log,以备rollback。

下面就验证对临时表的操作只会生成少量的redo信息。为了验证这一观点,会创建一个permanent table和temporary table进行对比。

创建函数get_stat_val

    create or replace function get_stat_val(p_name in varchar2) return number

    as

           l_val number;

    begin

      select b.value into l_val from v$statname a,v$mystat b

       where a.statistic# = b.statistic# and a.name = p_name;

       return l_val;

    end;

创建过程do_sql:

    create or replace procedure do_sql( p_sql in varchar2) 

    as 

           l_start_redo number;

           l_redo number;

    begin

            l_start_redo :=get_stat_val('redo size');

            execute immediate p_sql;

            commit;

            l_redo :=get_stat_val('redo size') - l_start_redo;

            dbms_output.put_line(to_char(l_redo,'99,999,999') 

                        ||'bytes of redo generated for "'|| 

                                    substr(replace(p_sql,chr(10),' '),1,25) ||'"...');

    end;

    /

在永久表和临时表中分别执行INSERT、UPDATE、DELETE

    set serveroutput on format wrapped

    begin 

                do_sql('insert into perm select 1,1,1 from all_objects where rownum<=500');

                do_sql('insert into temp select 1,1,1 from all_objects where rownum<=500');

                dbms_output.new_line;

                do_sql('update perm set x=2');

                do_sql('update temp set x=2');

                dbms_output.new_line;

                do_sql('delete from perm');

                do_sql('delete from temp');

    end;

    /

输出:

  3,297,284bytes of redo generated for "insert into perm select 1"...

     68,492bytes of redo generated for "insert into temp select 1"...

  4,681,496bytes of redo generated for "update perm set x=2"...

  2,065,204bytes of redo generated for "update temp set x=2"...

  3,330,524bytes of redo generated for "delete from perm"...

  3,226,032bytes of redo generated for "delete from temp"...


从上面可以看出:

1,对一个永久表进行INSERT操作,会生成大量redo,而对临时表进行同样的操作则几乎不生成redo。

2,对永久表进行的UPDATE操作生成的redo信息是临时表生成的redo信息的2倍。

3,  对永久表进行的DELETE操作和对临时表的操作生成的redo信息基本一样。这说明,不管是permanent table还            是temporary table,DELETE会产生大量undo信息,而redo信息很少。

于是,得出DML语句对临时表操作的以下结论:

1,INSERT只会生成少量的undo/redo信息

2,UPDATE永久表产生的undo/redo信息是UPDATE临时表的2倍。

3,DELETE永久表产生的undo/redo信息和DELETE临时表的基本一样。

以上参考自TOM的《Expert Oracle Database Architecture Oracle Database Programming 9i, 10g, and 11g Techniques and Solutions, Second Edition》

猜你喜欢

转载自zzwssfd.iteye.com/blog/1564722
今日推荐