天天看點

表段、索引段上的LOGGING與NOLOGGING

--====================================

-- 表段、索引段上的LOGGING與NOLOGGING

    在有些情況下,對于表段和索引段可以采用記錄日志的模式,也可以使用不記錄日志的模式。如在對表段、索引段使用資料泵導入時,可以

使用NOLOGGING模式,而使用DATA GUARD或對可用性較高的場景中需要記錄日志,甚至使用強制記錄日志。本文介紹了在表段,索引段使用

LOGGING與NOLOGGING時産生redo的大小以及DIRECT INSERT APPEND 的使用方法。

    NOLOGGING跟資料庫的運作模式有關,i和i的預設安裝都是非歸檔模式,并且自動歸檔預設是禁用。在安裝g、g時,可以選擇是否歸

檔。NOLOGGIING将記錄少量日志資訊到日志檔案。如果資料庫級别或表空間級别使用了FORCE LOGGING強制日志記錄模式,則該選項無效。

一、表段,索引段上使用一般DDL,DML時,LOGGING與NOLOGGING情況   

    1.檢視資料庫的歸檔模式

        有關設定日志歸檔模式的問題,請參考:

        sys@ORCL> select log_mode,force_logging from v$database;

        LOG_MODE     FOR

        ------------ ---

        ARCHIVELOG   NO

        sys@ORCL> archive log list;

        Database log mode              Archive Mode

        Automatic archival             Enabled

        Archive destination            /u01/bk/arch

        Oldest online log sequence     50

        Next log sequence to archive   51

        Current log sequence           51  

        sys@ORCL> select tablespace_name,logging,force_logging from dba_tablespaces;

        TABLESPACE_NAME                LOGGING   FOR

        ------------------------------ --------- ---

        SYSTEM                         LOGGING   NO

        UNDOTBS1                       LOGGING   NO

        SYSAUX                         LOGGING   NO

        TEMP                           NOLOGGING NO

        USERS                          LOGGING   NO

        PERFSTAT                       LOGGING   NO

        scott@ORCL> select * from v$version;

        BANNER

        ----------------------------------------------------------------

        Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

        PL/SQL Release 10.2.0.1.0 - Production

        CORE    10.2.0.1.0      Production

        TNS for Linux: Version 10.2.0.1.0 - Production

        NLSRTL Version 10.2.0.1.0 - Production

    2.建立一個檢視redo size 的視圖redo_size

        CREATE OR REPLACE FORCE VIEW "SYS"."REDO_SIZE"

        AS

          SELECT a.name,b.value

          FROM v$statname a

          JOIN v$mystat b

            ON a.statistic# = b.statistic#

          WHERE a.name = 'redo size';

        sys@ORCL> create public synonym redo_size for redo_size;

        sys@ORCL> grant select on redo_size to scott;

    3.在歸檔模式下比較表段上的NOLOGGING與LOGGING

        scott@ORCL> select * from redo_size;

        NAME                 VALUE

        --------------- ----------

        redo size             1644

        scott@ORCL> CREATE TABLE tb_obj_nolog NOLOGGING AS SELECT * FROM dba_objects;  --nologging模式建立表

        scott@ORCL> select 1644 last,70064 as cur,(70064-1644) diff from dual;--使用nologging模式建表産生的redo size為

              LAST        CUR       DIFF

        ---------- ---------- ----------

              1644      70064      68420

        scott@ORCL> CREATE TABLE tb_obj_log LOGGING AS SELECT * FROM dba_objects;    --使用logging模式來建立表

        sscott@ORCL> select * from redo_size;   --檢視目前的redo size

        --------------- ----------             --檢視logging模式産生的redo size 為-68420=1274048,比nologging日志模

        redo size          1344112               --式多出了19倍多

        scott@ORCL> select table_name,logging from user_tables where table_name like 'TB_OBJ%';--檢視建立表的日志記錄模式

        TABLE_NAME                     LOG

        ------------------------------ ---

        TB_OBJ_LOG                     YES

        TB_OBJ_NOLOG                   NO

    4.基于索引來比較redo size(同樣是在歸檔模式下)

        scott@ORCL> select * from redo_size;    --檢視目前的redo_size

        redo size             1140

        scott@ORCL> create index idx_tb_obj_log on tb_obj_log(object_id);  --基于表tb_obj_log來建立索引

        scott@ORCL> select * from redo_size;      --檢視目前的redo_size

        --------------- ----------                --基于loggiing模式,建立索引産生的redo size 為221600-1140=220460

        redo size           221600

        scott@ORCL> alter index idx_tb_obj_log rebuild;    --重建索引

        scott@ORCL> select 221600 last,448132 cur,448132-221600 diff from dual; 

            221600     448132     226532   --重建索引後産生的redo size 為226532,比直接建立時産生的redo size還要多

        scott@ORCL> alter index idx_tb_obj_log rebuild nologging; --使用nologging重建索引。

                                                --也可以在建立索引的時候直接使用nologging關鍵字

                                                --如:create index idx_tb_obj_nolog tb_obj_nolog(object_id) nologging

        scott@ORCL> select * from redo_size;    --檢視目前的redo size

        --------------- ----------              --基于nologging日志模式重建索引産生的redo size為469160-448132=21028

        redo size           469160

    5.非歸檔模式下的LOGGING與NOLOGGING 

        scott@ORCL> drop table tb_obj_log purge;

        scott@ORCL> drop table tb_obj_nolog purge;

        scott@ORCL> select log_mode,force_logging from v$database;  --切換日志到非歸檔模式後,下面是查詢的結果

        NOARCHIVELOG NO

        redo size             1688

        scott@ORCL> create table tb_obj_log as select * from dba_objects;   --建立表對象,使用logging日志記錄模式

        scott@ORCL> select * from redo_size;   --檢視目前的redo size

        NAME                 VALUE

        --------------- ----------            --使用logging日志記錄模式,建立表對象之後産生的redo size 為-1688 =68548

        redo size            70236

        scott@ORCL> create table tb_obj_nolog nologging as select * from dba_objects; --建立表對象,使用nologging日志記錄模式

        --------------- ----------             --使用nologging日志記錄模式建立表對象之後産生的redo size為135464-70236=65228

        redo size           135464

    6.小結:

        使用logging與nologging來建立對象或執行DML時

            對于非歸檔模式下,其産生的日志資訊(redo size)相差的并不大

            對于歸檔模式下,logging模式産生的日志将遠遠大于使用nologging模式産生的日志量

二、使用DIRECT INSERT APPEND方式的LOGGING與NOLOGGING情況       

    DIRECT INSERT APPEND是Oracle插入資料到資料庫的一種方式之一。使用APPEND方式來導入,其實是将記錄直接存放到高水位線(HWM)之上,

    而不考慮高水位線之下的空閑塊。

    1.資料庫運作在非歸檔模式下

        a.使用logging模式建立表

            scott@ORCL> select log_mode from v$database;

            LOG_MODE

            ------------

            NOARCHIVELOG   

            scott@ORCL> select * from redo_size;

            NAME                 VALUE

            --------------- ----------

            redo size             1764

            scott@ORCL> create table tb_obj_log as select * from dba_objects where 1=0;

            --------------- ----------     --建表産生的redo量23908-1764=22144

            redo size            23908  

            scott@ORCL> insert into tb_obj_log select * from dba_objects;

            11634 rows created.

            Elapsed: 00:00:00.36

            --------------- ----------    --直接使用insert時産生的redo量1281060-23908=1257152

            redo size          1281060  

            scott@ORCL> insert /*+ append */ into tb_obj_log select * from dba_objects;

            Elapsed: 00:00:00.26

            --------------- ----------    --使用append模式時産生的redo量1284740-1281060=3680

            redo size          1284740    --普通insert比使用append insert多産生1257152/3680=341倍redo

        b.使用nologging模式建立表

            scott@ORCL> create table tb_obj_nolog nologging as select * from dba_objects where 1=0;

            --------------- ----------     --使用nologging建立空表tb_obj_nolog時産生的日志量1305812-1284740=21072

            redo size          1305812

            scott@ORCL> insert into tb_obj_nolog select * from dba_objects; 

            11635 rows created.

            Elapsed: 00:00:00.21

            scott@ORCL> select * from redo_size;                          

            --------------- ----------    --使用普通insert插入記錄産生的日志量2562664-1305812=1256852

            redo size          2562664

            scott@ORCL> insert /* +append */ into tb_obj_nolog select * from dba_objects;

            Elapsed: 00:00:00.18

            scott@ORCL> select * from redo_size;                                     

            --------------- ----------       --使用append模式時産生的redo量 3766404-2562664=1203740

            redo size          3766404     

        c.redo的比較

            在具有logging屬性對象中,使用append模式時産生的redo量1284740-1281060=3680,

                普通insert比使用append insert多産生/3680=341倍redo

            在具有nologging屬性對象中,使用append insert模式與普通insert模式産生的redo量相差不太大,

                append insert模式為,而普通的insert模式為

    2.資料庫運作在歸檔模式下

        a.前期處理

            scott@ORCL> drop table tb_obj_log purge;

            scott@ORCL> drop table tb_obj_nolog purge;

            sys@ORCL> select log_mode from v$database;

            ARCHIVELOG

        b.建立表對象并進行比較

            scott@ORCL> create table tb_obj_log as select * from dba_objects where 1=0;    --logging模式建立表對象

            scott@ORCL> create table tb_obj_nolog nologging as select * from dba_objects where 1=0;--nologging模式建立表對象

            scott@ORCL> select * from redo_size;    

            --------------- ----------     --檢視目前的redo size 為46844

            redo size            46844

            scott@ORCL> insert into tb_obj_log select * from dba_objects;    --為表tb_obj_log使用正常insert插入記錄

            11598 rows created.

            Elapsed: 00:00:00.25

            --------------- ----------       --表tb_obj_log使用正常insert插入記錄産生的redo size 為1299120-46844=1252276

            redo size          1299120

            scott@ORCL> insert into tb_obj_nolog select * from dba_objects;   --為表tb_obj_nolog使用正常insert插入記錄

            Elapsed: 00:00:00.28

            --------------- ----------    --表tb_obj_nolog使用正常insert插入記錄産生的redo size 為2552880-1299120=1253760

            redo size          2552880

            scott@ORCL> insert /* +append */ into tb_obj_log select * from dba_objects;--表tb_obj_log使用insert append方式 

            Elapsed: 00:00:00.20

            --------------- ----------    --表tb_obj_log使用insert append插入記錄産生的redo size 為3750852-2552880=1197972

            redo size          3750852

            scott@ORCL> insert /* +append */ into tb_obj_nolog select * from dba_objects;--表tb_obj_nolog使用insert append方式 

            --------------- ----------    --表tb_obj_nolog使用insert append插入記錄産生的redo size 為4948764-3750852=1197912

            redo size          4948764

            歸檔模式下,具有nologging特性的表tb_obj_nolog,使用insert append方式插入的速度最快,且日志量最小,為。而

            logging特性的表tb_obj_log使用insert append方式時的日志量為,相差不是很大。對于使用普通的insert插入,則

            産生的日志量差異比較大。

    3.小結

        對于表對象插入記錄時,使用正常insert 與使用direct insert append方式比較

            在非歸檔模式下,表對象在使用nologging模式時,兩者産生的日志量相差不大,而使用logging模式時,正常insert的日志量遠

                大于direct insert append方式。

            在歸檔模式下,表對象使用logging模式,兩者産生的日志量相差不大。而表對象使用nologging模式時,則使用insert append

                将使得性能有所提高。

        在非歸檔模式下的inesrt append操作将是性能最高的。

    4.direct insert append使用時的注意事項     

        a.當使用insert into ... values語句時,不能夠使用append方式

        b.append方式為批量插入的記錄,是以新插入的記錄被存儲在hwm 之上,對于hwm之下空閑塊将不會被使用。

        c.在append方式插入記錄後,要執行commit,才能對表進行查詢。否則會出現錯誤:

            ORA-12838: cannot read/modify an object after modifying it in parallel

        d.在歸檔模式下,表對象具有nologging屬性,且以append方式批量添加記錄,才會顯著減少redo數量。

        e.在非歸檔模式下,表對象即便具有logging屬性,也可減少redo數量。

        f.對于表上具有索引的表對象,如果新增的記錄數量為整個表的很少一部分,則直接以append方式批量添加記錄,如果原表記錄很少,

            實時性要求不是很高,而新增記錄很多,可以先删除索引,在使用append方式追加記錄,最後再建立索引。

三、日志記錄模式請參考

<a href="http://blog.csdn.net/robinson_0612/archive/2011/01/12/6130866.aspx">日志記錄模式(LOGGING 、FORCE LOGGING 、NOLOGGING)</a>

四、更多參考

有關閃回特性請參考

<a href="http://blog.csdn.net/robinson_0612/archive/2010/12/29/6105327.aspx">Oracle 閃回特性(FLASHBACK DROP &amp; RECYCLEBIN)</a>

<a href="http://blog.csdn.net/robinson_0612/archive/2011/01/02/6112607.aspx">Oracle 閃回特性(Flashback Query、Flashback Table)</a>

<a href="http://blog.csdn.net/robinson_0612/archive/2011/01/02/6112981.aspx">Oracle 閃回特性(Flashback Version、Flashback Transaction)</a>

有關基于使用者管理的備份和備份恢複的概念請參考:

    有關RMAN的恢複與管理請參考:

    有關Oracle體系結構請參考:

<a href="http://blog.csdn.net/robinson_0612/archive/2010/04/29/5542983.aspx">Oracle 資料庫執行個體啟動關閉過程</a>