[20180104]oracle臨時表.txt

lfree發表於2018-01-04

[20180104]oracle臨時表.txt

--//簡單探究oracle臨時表,oracle對於臨時表日誌記錄相對普通表DML操作日誌量要少,因為臨時表dml操作不需要記錄後映像,僅僅為了rollback操作,
--//僅僅在日誌檔案中記錄undo產生的日誌以及少量遞迴事務.這樣日誌相對普通表事務要小一些,但是對於delete操作,因為日誌記錄整條記錄,產生
--//日誌相對較大.

透過Dump UNDO Block觀察到DML操作記錄在UNDO中的資訊,主要為以下內容:
1、對於Insert操作,需要在UNDO中記錄插入行的ROWID.
2、對於Update操作,需要在UNDO中記錄被更新列的前映象的值,同時也會記錄被更新行的ROWID。
3、對於Delete操作,需要在UNDO中記錄被刪除行所有列的值(前映象)及ROWID。

--//本文透過測試例子簡單說明這些問題.

1.環境:
SCOTT@book> @ &r/ver1
PORT_STRING         VERSION    BANNER
------------------- ---------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

create global temporary table t(id number,test varchar2(20),pad varchar2(20)) on commit preserve rows;

SYS@book> alter system archive log current ;
System altered.

SCOTT@book> @ &r/logfile ;
GROUP# STATUS TYPE    MEMBER                          IS_ GROUP# THREAD# SEQUENCE#       BYTES BLOCKSIZE MEMBERS ARC STATUS   FIRST_CHANGE# FIRST_TIME          NEXT_CHANGE# NEXT_TIME
------ ------ ------- ------------------------------- --- ------ ------- --------- ----------- --------- ------- --- -------- ------------- ------------------- ------------ -------------------
     1        ONLINE  /mnt/ramdisk/book/redo01.log    NO       1       1       746    52428800       512       1 NO  CURRENT    13277158952 2018-01-04 15:45:35 2.814750E+14
     2        ONLINE  /mnt/ramdisk/book/redo02.log    NO       2       1       744    52428800       512       1 YES INACTIVE   13277158937 2018-01-04 15:45:30  13277158943 2018-01-04 15:45:31
     3        ONLINE  /mnt/ramdisk/book/redo03.log    NO       3       1       745    52428800       512       1 YES ACTIVE     13277158943 2018-01-04 15:45:31  13277158952 2018-01-04 15:45:35
     4        STANDBY /mnt/ramdisk/book/redostb01.log NO
     5        STANDBY /mnt/ramdisk/book/redostb02.log NO
     6        STANDBY /mnt/ramdisk/book/redostb03.log NO
     7        STANDBY /mnt/ramdisk/book/redostb04.log NO
7 rows selected.
--//當前日誌是/mnt/ramdisk/book/redo01.log.

2.測試1:
--//插入記錄:
insert into t values (1,'a1b2c3d4','aaaaaaa');
commit ;
alter system checkpoint;
alter system checkpoint;

$ strings /mnt/ramdisk/book/redo01.log |egrep  "a1b2c3d4|aaaaaaa"

--//無法查詢到插入字串a1b2c3d4,aaaaaa.因為產生的redo僅僅記錄undo段產生的日誌(對於臨時表),這樣對應插入操作,僅僅需要知道rowid就足夠rollback.
--//所以在日誌檔案看不到插入的字串資訊.

3.測試2:
--//修改記錄:
SCOTT@book> select * from t;
          ID TEST                 PAD
------------ -------------------- --------------------
           1 a1b2c3d4             aaaaaaa

update t set test=upper(test) where id=1 and rownum=1;
commit ;
alter system checkpoint;

$ strings -t x /mnt/ramdisk/book/redo01.log |egrep -i "a1b2c3d4|aaaaaaa"
  18559 a1b2c3d4

--//僅僅看到小寫的字串a1b2c3d4,說明產生日誌部分僅僅記錄undo產生的前映像,為了rollback的需要,而後映像沒有記錄.而且oracle日誌記錄的是改變向量,
--//這樣日誌裡面看到字串a1b2c3d4.
--//對於update操作臨時表僅僅記錄undo段產生的日誌,這樣看到的資訊僅僅是修改前的前映像記錄向量.

4.測試3:
SCOTT@book> select * from t;
          ID TEST                 PAD
------------ -------------------- --------------------
           1 A1B2C3D4             aaaaaaa

delete from t where id=1 and rownum=1;
commit ;
alter system checkpoint;

$ strings -t x /mnt/ramdisk/book/redo01.log |egrep -i "a1b2c3d4|aaaaaaa"
  18559 a1b2c3d4
  4056e YMA1B2C3D4aaaaaaa*4

--//可以發現記錄的整條記錄.對於臨時delete操作產生的日誌最大,這樣在實際應用中需要這個細節.

5.測試4.做一個對比說明:
SCOTT@book> alter system archive log current ;
System altered.

SCOTT@book> @ &r/logfile
GROUP# STATUS     TYPE       MEMBER                           IS_ GROUP# THREAD# SEQUENCE#       BYTES BLOCKSIZE MEMBERS ARC STATUS     FIRST_CHANGE# FIRST_TIME          NEXT_CHANGE# NEXT_TIME
------ ---------- ---------- -------------------------------- --- ------ ------- --------- ----------- --------- ------- --- ---------- ------------- ------------------- ------------ -------------------
     1            ONLINE     /mnt/ramdisk/book/redo01.log     NO       1       1       746    52428800       512       1 YES ACTIVE       13277158952 2018-01-04 15:45:35  13277160333 2018-01-04 16:03:34
     2            ONLINE     /mnt/ramdisk/book/redo02.log     NO       2       1       747    52428800       512       1 NO  CURRENT      13277160333 2018-01-04 16:03:34 2.814750E+14
     3            ONLINE     /mnt/ramdisk/book/redo03.log     NO       3       1       745    52428800       512       1 YES INACTIVE     13277158943 2018-01-04 15:45:31  13277158952 2018-01-04 15:45:35
     4            STANDBY    /mnt/ramdisk/book/redostb01.log  NO
     5            STANDBY    /mnt/ramdisk/book/redostb02.log  NO
     6            STANDBY    /mnt/ramdisk/book/redostb03.log  NO
     7            STANDBY    /mnt/ramdisk/book/redostb04.log  NO
7 rows selected.
--//當前日誌是/mnt/ramdisk/book/redo02.log.

create table tx(id number,test varchar2(20),pad varchar2(20)) ;
insert into tx values (1,'AAAA1234','BBBBBB');
commit ;

$ strings -t x /mnt/ramdisk/book/redo02.log |egrep  "AAAA1234|BBBBBB"
   ca64 AAAA1234BBBBBB
--//可以發現對於普通表的插入操作,記錄後映像,可以看到插入的資訊AAAA1234,BBBBBB.

--//12C提供特性臨時表執行dml時生成的undo儲存在臨時表空間,這個特性叫Temporary Undo,由資料庫引數temp_undo_enabled控制.這樣以上問題不再存在.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2149703/,如需轉載,請註明出處,否則將追究法律責任。

相關文章