博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[20150225]Temporary Tables and RedoUndo
阅读量:5815 次
发布时间:2019-06-18

本文共 4996 字,大约阅读时间需要 16 分钟。

[20150225]Temporary Tables and RedoUndo.txt

摘要:

Apress.Oracle.Database.Transactions.and.Locking.Revealed.1484207610.pdf

Temporary tables generate no redo for their blocks. Therefore, an operation on a temporary table is not recoverable.

When you modify a block in a temporary table, no record of this change will be made in the redo log files. However,
temporary tables do generate undo, and the undo is logged. Hence, temporary tables will generate some redo. At first
glance, this doesn't seem to make total sense: Why would they need to generate undo? This is because you can roll
back to a SAVEPOINT within a transaction. You might erase the last 50 INSERTs into a temporary table, leaving the first 50.
Temporary tables can have constraints and everything else a normal table can have. They might fail a statement on
the five-hundredth row of a 500-row INSERT, necessitating a rollback of that statement. Since temporary tables behave
in general just like normal tables, temporary tables must generate undo. Since undo data must be logged, temporary
tables will generate some redo log for the undo they generate.

This is not nearly as ominous as it seems. The primary SQL statements used against temporary tables are INSERTs

and SELECTs. Fortunately, INSERTs generate very little undo (you need to restore the block to "nothing," and it doesn't
take very much room to store "nothing"), and SELECTs generate no undo. Hence, if you use temporary tables for
INSERTs and SELECTs exclusively, this section means nothing to you. It is only if you UPDATE or DELETE that you might
be concerned about this.

I set up a small test to demonstrate the amount of redo generated while working with temporary tables, an

indication therefore of the amount of undo generated for temporary tables, since only the undo is logged for them. To
demonstrate, I'll take identically configured permanent and temporary tables, and then perform the same operations
on each, measuring the amount of redo generated each time. The tables I'll use are as follows:

1.建立测试环境:

SCOTT@test> @ver1

PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.3.0     Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

create table perm( x char(2000) ,  y char(2000) ,  z char(2000)  );

create global temporary table temp ( x char(2000) , y char(2000) , z char(2000)  ) on commit preserve rows;

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;

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;
/

2.开始测试:

set serveroutput on format wrapped
begin
    do_sql( 'insert into perm
             select 1,1,1
               from all_objects
              where rownum

    do_sql( 'insert into temp

             select 1,1,1
               from all_objects
              where rownum     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,300,328 bytes of redo generated for "insert into perm         "...

     78,768 bytes of redo generated for "insert into temp         "...

  2,165,168 bytes of redo generated for "update perm set x = 2"...

  1,096,796 bytes of redo generated for "update temp set x = 2"...

  3,232,460 bytes of redo generated for "delete from perm"...

  3,229,900 bytes of redo generated for "delete from temp"...

PL/SQL procedure successfully completed.

--可以发现insert最少,update居中,delete最多。

--主要是因为对于undo讲:
insert  undo记录信息最少,反相操作是delete,仅仅知道rowid就ok了。
update  undo记录的信息是修改前映像,这种情况取决于前映像的大小,如果开始插入的是NULL,这样undo生成不会太大。
delete  undo记录的信息是完整的一条记录,反相操作是insert。这种情况undo记录的信息最大。

3.如果字段开始插入是NULL的情况:

set serveroutput on format wrapped

begin
    do_sql( 'insert into perm
             select null,1,1
               from all_objects
              where rownum

    do_sql( 'insert into temp

             select null,1,1
               from all_objects
              where rownum     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;
/

  2,244,640 bytes of redo generated for "insert into perm         "...

     90,748 bytes of redo generated for "insert into temp         "...

  1,163,996 bytes of redo generated for "update perm set x = 2"...

     98,808 bytes of redo generated for "update temp set x = 2"...

  3,235,736 bytes of redo generated for "delete from perm"...

  3,225,808 bytes of redo generated for "delete from temp"...

PL/SQL procedure successfully completed.

--对比上面update的情况可以发现,第2次update生成的redo很少,几乎与insert接近。

--主要是开始插入x都是NULL,这样undo记录的信息很少,生成的redo也很少。

转载地址:http://lfxbx.baihongyu.com/

你可能感兴趣的文章
子类构造函数是否会默认调用父类的无参构造函数
查看>>
centos7安装mysql5.6(rpm包安装)
查看>>
二叉树的路径和
查看>>
Visual Studio 2013无法打开IIS Express Web的解决办法
查看>>
剑指offer-面试题8.旋转数组的最小数字
查看>>
微软邮件系统Exchange 2013系列(三)安装客户端访问角色
查看>>
WinForm事件中的Object sender和EventArgs e参数
查看>>
老王学linux-centos6.7heartbeat-2.1.4-12.el6.x86_64
查看>>
通过JavaService 将java jar包注册成Windows 服务
查看>>
在java编程语言中模拟抽象工厂模式
查看>>
vsphere高可用性
查看>>
python备份脚本
查看>>
ssh登陆慢的问题
查看>>
ubuntu开启ssh
查看>>
如何限制用户在指定机器登陆
查看>>
JSON(一):基本概念
查看>>
Elasticsearch FAQ
查看>>
配置 <mvc:resources location="/js/" mapping="/js/**.js"/> @Controller
查看>>
netstat
查看>>
一颗马蹄钉亡了一个帝国
查看>>