聊聊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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- undo log和redo log
- alter table nologging /*+APPEND PARALLEL(n)*/APPParallel
- MySQL Undo Log和Redo Log介紹MySql
- MySQL中的redo log和undo logMySql
- MySQL中的redo log和checkpointMySql
- nologging、force logging、supplemental log的理解
- 深入理解MySQL系列之redo log、undo log和binlogMySql
- mysql之 redo logMySql
- MySQL的Redo log 以及Bin logMySql
- MySQL學習之change buffer 和 redo logMySql
- 基於Redo Log和Undo Log的MySQL崩潰恢復流程MySql
- redo log 和 binlog 的一些總結
- 【Mysql】三大日誌 redo log、bin log、undo logMySql
- redo log file 最佳化
- MySQL redo log最佳化MySql
- MySQL重做日誌(redo log)MySql
- 必須瞭解的mysql三大日誌-binlog、redo log和undo logMySql
- Oracle redo解析之-1、oracle redo log結構計算Oracle Redo
- InnoDB文件筆記(二)—— Redo Log筆記
- How to Dump Redo Log File Information --metalinkORM
- 3000幀動畫圖解MySQL為什麼需要binlog、redo log和undo log動畫圖解MySql
- mysql日誌:redo log、binlog、undo log 區別與作用MySql
- MySQL中redo log、undo log、binlog關係以及區別MySql
- 硬核乾貨!一文掌握 binlog 、redo log、undo log
- MYSQL 是如何保證binlog 和redo log同時提交的?MySql
- MySQL 日誌系統 redo log、binlogMySql
- MySQL如何計算統計redo log大小MySql
- 調整innodb redo log files數目和大小的具體方法和步驟
- MySQL Redo log頁內邏輯怎麼理解MySql
- Oracle RAC+DG 調整redo/standby log fileOracle
- jQuery的append和appendTojQueryAPP
- 更改online redo log file 提示 ORA-01511 ORA-01141
- MySQL中Redo Log相關的重要引數總結MySql
- duplicate遇到RMAN-05535: warning: All redo log files were not defined
- 2 萬字 + 30 張圖 | 細聊 MySQL undo log、redo log、binlog 有什麼用?MySql
- Sqlserver沒有單獨的undo檔案,使用tempdb和redo log來存放undo資料SQLServer
- 一生摯友redo log、binlog《死磕MySQL系列 二》MySql
- MySQL更新資料時,日誌(redo log、binlog)執行流程MySql
- oracle的redo和undoOracle