聊聊Append、nologging和Redo Log
剛剛接觸Oracle的時候,Append+Nologging可以減少Redo Size的說法在網路上討論的很廣。各種流言頻出,混淆了很多人的概念體系。之後,一些牛人自此著手,澄清了很多的概念和觀點。
老實說:我們不是Oracle的設計者,也沒有機會研讀原始碼。實驗看看是一種最簡單、也是最直接的驗證手段。本篇就一起將archive log/noarchive log、append、nologging和Redo Log幾個關係重做實驗,權當是自我實踐,仿前人之路。
1、聊聊問題起源
很多偶然發生的歷史事件,造就了今天的我們。
起源自一個問題:我們如何能夠在進行DML(主要是insert)過程中快一點?影響DML的因素很多,其中一條就是Redo Log的生成。Redo Log的生成會引起之後的log buffer使用、LGWR激發、IO寫入、Redo Log Switch和之後的Archive動作。那個時代的很多同行對於Redo Log有很多想法,於是問題變成了:我們怎麼樣可以減少一個insert的Redo Log生成。
那個時代的朋友提出了append和nologging策略。將資料表的logging屬性關閉,在插入的時候使用append hint,可以減少Redo Log生成。一度網路上流言認為還可以不生成Redo Log。
“實踐出真知”,下面我們透過一系列的實驗對比,來重溫一下這個思路過程。
2、實驗環境介紹
我們選擇Oracle 11R2進行實驗。注意:不同的資料庫版本在這個問題上的行為可能存在差異。筆者此處是就事論事,僅討論11gR2。
SQL> select * from v$version;
BANNER
-----------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 – Production
建立兩張資料表T_LOGGING和T_NOLOGGING,結構相同,差異就在資料表的logging屬性上。
SQL> create table t_logging as select * from dba_objects where 1=0;
Table created
SQL> create table t_nologging nologging as select * from dba_objects where 1=0;
Table created
SQL> select table_name, logging from dba_tables where owner='SCOTT' and table_name in ('T_LOGGING','T_NOLOGGING');
TABLE_NAME LOGGING
------------------------------ -------
T_NOLOGGING NO
T_LOGGING YES
我們怎麼樣統計彙總Redo Log生成呢?藉助v$mystat檢視,可以發現其中關於redo log size的統計資訊。執行insert前後分別執行這個語句,透過差值可以估算出Redo Log Size情況。
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
----------------------------- ----------
redo size 42456
redo size for lost write detection 0
redo size for direct writes 0
下面,分別從noarchived模式和archived模式看實際的效果差異。
3、NoArchived情況
我們先看看非歸檔模式下的實驗情況。資料庫此時執行在非歸檔模式下。
SQL> archive log list;
Database log mode No Archive Mode
Automatic archival Disabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 477
Current log sequence 479
開始進行測試,測試是沒有關閉logging屬性的資料表T_LOGGING。
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
------------------------------------------------------- ----------
redo size 85664
redo size for lost write detection 0
redo size for direct writes 0
SQL> insert into T_LOGGING select * from dba_objects;
72767 rows inserted
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
--------------------------------------------------- ----------
redo size 8593336
redo size for lost write detection 0
redo size for direct writes 0
SQL> rollback;
Rollback complete
兩次度量的差額為:8593336-85664=8507672
下面進行NOLOGGING資料表測試。
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
--------------------------------------------- ----------
redo size 9150492
redo size for lost write detection 0
redo size for direct writes 0
SQL> insert into T_NOLOGGING select * from dba_objects;
72767 rows inserted
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
------------------------------------------------------ ----------
redo size 17666980
redo size for lost write detection 0
redo size for direct writes 0
SQL> rollback;
Rollback complete
兩次度量的差額為:17666980-9150492=8516488。
我們發現:作為nologging的T_NOLOGGING,其在非歸檔模式下,生成日誌量比LOGGING模式的資料表還大一些。沒有明顯的優勢。
下面我們將APPEND加入進來,看看NOLOGGING能否有一些變化。
--清理環境
SQL> truncate table t_logging;
Table truncated
SQL> truncate table t_nologging;
Table truncated
--加入append
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
--------------------------------------------------- ----------
redo size 18304400
redo size for lost write detection 0
redo size for direct writes 0
SQL> insert /*+append */into T_NOLOGGING select * from dba_objects;
72767 rows inserted
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
----------------------------------------------------- ----------
redo size 18361040
redo size for lost write detection 0
redo size for direct writes 2236
SQL> rollback;
Rollback complete
兩次度量的差額:18361040-18304400=56640,此外還有2236的direct writes型別的Redo Size。這個度量值要大大小於我們之前的測算。
說明:在非歸檔模式下,使用append和nologging可以減少Redo Size的生成。
下面看看歸檔模式的情況。
4、Archived Log情況
切換到Archived Log模式。
SQL> archive log list;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 478
Next log sequence to archive 480
Current log sequence 480
先進行logging模式的測試。
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
----------------------------------------------------- ----------
redo size 804
redo size for lost write detection 0
redo size for direct writes 0
SQL> insert into T_LOGGING select * from dba_objects;
72767 rows inserted
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
------------------------------------------------ ----------
redo size 8511740
redo size for lost write detection 0
redo size for direct writes 0
SQL> rollback;
Rollback complete
兩次度量差額為:8511740-804=8510936。比之前非歸檔情況下實驗redo log生成量略大一些。
下面是nologging資料表情況。
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
------------------------------------------------ ----------
redo size 9068376
redo size for lost write detection 0
redo size for direct writes 0
SQL> insert into T_NOLOGGING select * from dba_objects;
72767 rows inserted
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
------------------------------------------ ----------
redo size 17579204
redo size for lost write detection 0
redo size for direct writes 0
SQL> rollback;
Rollback complete
兩次度量差額:17579204-9068376=8510828。和Logging比,生成的Redo Log Size是略大一點點。
加入append之後呢?
SQL> truncate table t_logging;
Table truncated
SQL> truncate table t_nologging;
Table truncated
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
---------------------------------------------------- ----------
redo size 18217420
redo size for lost write detection 0
redo size for direct writes 0
SQL> insert /*+append*/into T_NOLOGGING select * from dba_objects;
72767 rows inserted
SQL> select sn.NAME, ms.VALUE
2 from v$statname sn, v$mystat ms
3 where sn.STATISTIC#=ms.STATISTIC#
4 and sn.NAME like '%redo size%';
NAME VALUE
---------------------------------------------------- ----------
redo size 18274060
redo size for lost write detection 0
redo size for direct writes 2236
SQL> rollback;
Rollback complete
兩次度量的差額為:56640,外加2236的direct writes的Redo Log生成量。這個和我們在非歸檔模式下append+nologging的取值是一樣的!
5、結論
下面透過一張表格將實驗資料進行彙總。
歸檔模式 |
Insert語句 |
Redo Size |
非歸檔 |
Logging |
8507672 |
NoLogging |
8516488 |
|
Append+Nologging |
56640+2236 |
|
歸檔 |
Logging |
8510936 |
NoLogging |
8510828 |
|
Append+Nologging |
56640+2236 |
從實驗結果上看,的確使用append+nologging可以減少Redo Log的生成。但是,這樣就可以了嗎?
回到問題的出發點,在Insert故障中,究竟有多少Redo Log Size減少以提升的空間。老實說,從實踐領域看,insert出現效能問題的機率是比較小的。如果使用堆表Heap Table,而且資料表沒有過多的索引物件,我們insert大部分的消耗是在空間擴充上。
Redo Log在insert過程中最大問題點在於Redo Log Group Member過小,引起頻繁的切換動作。這種現象完全可以透過增大Redo Log Size和Group數量來緩解。
從另一個角度看,我們少生成了Redo Log,失去了什麼?Redo Log是Oracle進行資料恢復動作的重要構成。少量Redo Log Size的生成,給我們帶來的是日後恢復過程中難以想象的惡果。這個將在筆者下篇文章進行介紹。
如果是生產環境,強烈建議不要使用nologging+append策略進行插入動作。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30496894/viewspace-1825207/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle nologging和appendOracleAPP
- nologging和insert /*+append*/APP
- append和nologging的案例APP
- Nologging and append testAPP
- nologging與append ztAPP
- Oracle NoLogging Append 方式減少批量insert的redo_sizeOracleAPP
- alter table nologging /*+APPEND PARALLEL(n)*/APPParallel
- 轉eygle_append與nologgingAPP
- 歸檔模式下的 nologging和/*+ append */引數 效能測試模式APP
- 使用append+nologging引起恢復故障實驗APP
- 線上重定義分割槽表和NOLOGGING APPEND分割槽表對比APP
- nologgin和appendAPP
- 關於加快INSERT語句執行速度和 HINT /*+ append*/及nologging的使用APP
- nolog和append的使用APP
- 表的nologging和logging屬性對資料庫redo資料生成的影響資料庫
- MySQL中的redo log和undo logMySql
- MySQL Undo Log和Redo Log介紹MySql
- redo的等待log file sync和log file parallel write和redo size設定Parallel
- NOLOGGING和FORCE LOGGING的理解
- Redo Log之一:理解Oracle redo logOracle Redo
- 11g append 和常規insert在logging FORCE_LOGGING產生redo量差異APP
- Oracle nologgingOracle
- Archive Log模式下Redo Log、Check Point和Switch LogHive模式
- Oracle logging 和nologging 的區別Oracle
- MySQL中的redo log和checkpointMySql
- 使用LOGMNR工具分析Oracle Redo Log和Archive Log教程Oracle RedoHive
- Oracle DML NOLOGGINGOracle
- index與nologgingIndex
- Oracle’s NOLOGGINGOracle
- redo log 和 binlog 的一些總結
- MySQL binlog和redo的組提交MySql
- 深入理解MySQL系列之redo log、undo log和binlogMySql
- oracle啟用nologgingOracle
- Dataguard環境修改主庫和standby庫online redo log&standby redo log大小
- MySQL學習之change buffer 和 redo logMySql
- MySQL:Redo & binlogMySql
- mysql之 redo logMySql
- oracle redo log operationOracle Redo