首先我們來看下什麼是archive log file,oracle 11g 的concept中是這樣定義的:When you enable archiving of the online redo logs, Oracle Database copies the online redo log files to another location before they are overwritten. These copied files are referred to as archived redo log files. 那麼根據這個定義,archive log file就是redo log file的拷貝,既然是拷貝,在排除壓縮的情況下,兩種文件的大小應該是一致的。但是我們在真實環境中看到的archive log file就是redo log file卻不是一樣大,真實情況是archive log file比redo log file小,極端情況下,甚至會小非常多。
引起archive log file就是redo log file大小不一致的原因大致有如下幾種:
一、人爲操作類型
1、SQL>alter system switch logfile;
2、SQL>alter system archive log current;
3、RMAN>backup archive log all;
4、RMAN>backup database plus archivelog;
二、參數設置類型
archive_lag_target:日誌切換的強制時間間隔,即只要到達該參數設置的時間間隔,無論redo 文件是否寫滿,都會進行日誌切換。
三、oracle bug類型
BUG 9272059、BUG 10354739、BUG 12317474、BUG 5450861、BUG 7016254
下面對archive log file就是redo log file大小不一致的原因進行分析,首先,如果redo log file中是以空白結尾,那麼,archive log file中會將末尾的空白去除,這就樣就會出現archive log比redo log file小,具體小多少,就根據歸檔時redo log file末尾的空白大小決定。這種情形常見於前面提到的認爲操作類型和參數設置類型。因爲在進行強制切換日誌的時候,redo log file是沒有被寫滿的,文件的末尾必然存在空白。
另外,日誌切換並不是發生redo log file 100%滿的時候,這是由於oracle的內部算法決定的,這樣做的主要目的是處於性能的考慮。所以redo log file始終不會被100%的寫滿,在進行歸檔的時候,末尾的空白會被丟棄,所以就導致了archive log file小於redo log file。影響redo log切換時間的因素有:LOG_BUFFER_SIZE參數設置、系統負載、log file size、logfile 空間分配算法。
CUP_COUNT值會影響logfile空間分配算法,所以,如果出現日誌頻繁切換且歸檔日誌遠小於redo log file的情況,請檢查CUP_COUNT是否符合系統的實際情況。
再次,如果是RAC環境,如果各節點的負載不一致,爲了保證數據庫的可恢復性,空閒節點會進行一些的日誌切換,主要是爲了增進redo 日誌的FIRST_CHANGE#,空閒節點產生的歸檔日誌大小會與redo file大小有較大差距。下面進行驗證:
--查看redo file大小
SQL> select thread#,group#,bytes/1024/1024 "size" from v$log order by 1,2;
THREAD# GROUP# size
---------- ---------- ----------
1 1 50
1 2 50
2 3 50
2 4 50
--在節點1上建立測試表
SQL> create table darren(id number,item varchar2(2));
--查看當前的歸檔情況和redo log的FRIST_CHANGE#
SQL> select thread#,name,blocks*block_size/1024/1024 "size" from v$archived_log order by 1,2;
THREAD# NAME size
---------- ---------------------------------------------------------------------- ----------
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_10.268.861729569 1.4453125
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_11.270.861730475 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_12.271.861730509 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_13.272.861730545 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_14.274.861730573 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_15.275.861730601 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_16.276.861788401 35.8242188
2 +DATADG01/gyl/archivelog/2014_10_23/thread_2_seq_2.269.861729571 2.37207031
2 +DATADG01/gyl/archivelog/2014_10_23/thread_2_seq_3.273.861730551 .008300781
2 +DATADG01/gyl/archivelog/2014_10_24/thread_2_seq_4.277.861788403 .567871094
SQL> select GROUP#,THREAD#,SEQUENCE#,STATUS,FIRST_CHANGE# from v$log order by 2;
GROUP# THREAD# SEQUENCE# STATUS FIRST_CHANGE#
---------- ---------- ---------- ---------------- -------------
1 1 17 CURRENT 794878
2 1 16 INACTIVE 700672
3 2 5 CURRENT 794876
4 2 4 INACTIVE 517670
--在節點1上進行事務,由於是測試環境,節點2上完全沒事務,是空閒實例
begin
for i in 1..500000 loop
insert into darren values(1,'aa');
commit;
end loop;
end;
--查看歸檔情況和redo log 的FRIST_CHANGE#
SQL> select thread#,name,blocks*block_size/1024/1024 "size" from v$archived_log order by 1,2;
THREAD# NAME size
---------- ---------------------------------------------------------------------- ----------
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_10.268.861729569 1.4453125
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_11.270.861730475 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_12.271.861730509 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_13.272.861730545 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_14.274.861730573 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_15.275.861730601 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_16.276.861788401 35.8242188
1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_17.278.861791005 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_18.279.861791039 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_19.281.861791071 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_20.282.861791091 49.9980469
1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_21.283.861791119 49.9980469
2 +DATADG01/gyl/archivelog/2014_10_23/thread_2_seq_2.269.861729571 2.37207031
2 +DATADG01/gyl/archivelog/2014_10_23/thread_2_seq_3.273.861730551 .008300781
2 +DATADG01/gyl/archivelog/2014_10_24/thread_2_seq_4.277.861788403 .567871094
2 +DATADG01/gyl/archivelog/2014_10_24/thread_2_seq_5.280.861791047 .791503906
2 +DATADG01/gyl/archivelog/2014_10_24/thread_2_seq_6.284.861791125 .000976563
(thread_1_seq_17至thread_1_seq_21爲insert過程中節點1產生的歸檔,大小都接近redo file大小,thread_2_seq_5和thread_2_seq_6爲節點2產生的歸檔,遠小於redo file大小)
SQL> select GROUP#,THREAD#,SEQUENCE#,STATUS,FIRST_CHANGE# from v$log order by 2;
GROUP# THREAD# SEQUENCE# STATUS FIRST_CHANGE#
---------- ---------- ---------- ---------------- -------------
1 1 21 ACTIVE 1206256
2 1 22 CURRENT 1308608
3 2 7 CURRENT 1338258
4 2 6 INACTIVE 1014874
(可以看到,節點2的FIRST_CHANGE#也跟進了,這裏還超過了節點1的)
--關閉節點2
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
--繼續在節點1插入數據
begin
for i in 1..500000 loop
insert into darren values(1,'aa');
commit;
end loop;
end;
--查看歸檔情況和redo log 的FRIST_CHANGE#
SQL> select thread#,ARCHIVAL_THREAD#,name,blocks*block_size/1024/1024 "size" from v$archived_log order by 1,2;
THREAD# ARCHIVAL_THREAD# NAME size
---------- ---------------- ---------------------------------------------------------------------- ----------
1 1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_10.268.861729569 1.4453125
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_18.279.861791039 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_27.291.861795885 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_26.290.861795861 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_25.289.861795837 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_24.287.861795815 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_23.286.861795789 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_22.285.861795765 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_11.270.861730475 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_12.271.861730509 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_13.272.861730545 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_14.274.861730573 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_23/thread_1_seq_15.275.861730601 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_16.276.861788401 35.8242188
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_17.278.861791005 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_19.281.861791071 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_20.282.861791091 49.9980469
1 1 +DATADG01/gyl/archivelog/2014_10_24/thread_1_seq_21.283.861791119 49.9980469
2 1 +DATADG01/gyl/archivelog/2014_10_24/thread_2_seq_8.292.861795895 .000488281
2 1 +DATADG01/gyl/archivelog/2014_10_24/thread_2_seq_7.288.861795827 .921386719
2 1 +DATADG01/gyl/archivelog/2014_10_24/thread_2_seq_4.277.861788403 .567871094
2 2 +DATADG01/gyl/archivelog/2014_10_24/thread_2_seq_5.280.861791047 .791503906
2 2 +DATADG01/gyl/archivelog/2014_10_23/thread_2_seq_3.273.861730551 .008300781
2 2 +DATADG01/gyl/archivelog/2014_10_24/thread_2_seq_6.284.861791125 .000976563
2 2 +DATADG01/gyl/archivelog/2014_10_23/thread_2_seq_2.269.861729571 2.37207031
(注意thread_2_seq_7和thread_2_seq_8,他們的歸檔是由thread 1 執行的,參看THREAD# 和ARCHIVAL_THREAD# 列,這兩個歸檔正是在實例2關閉的時候生成的)
SQL> select GROUP#,THREAD#,SEQUENCE#,STATUS,FIRST_CHANGE# from v$log order by 2;
GROUP# THREAD# SEQUENCE# STATUS FIRST_CHANGE#
---------- ---------- ---------- ---------------- -------------
1 1 27 ACTIVE 1831962
2 1 28 CURRENT 1935906
3 2 9 CURRENT 1955175
4 2 8 INACTIVE 1690602
由於redo wastage的存在,redo log file中間也會存在空白,那這部分空白會不會被丟棄呢?首先看下什麼是redo wastage,簡單的說就是LGWR進程在寫redo log file的時候是按操作系統的標準塊爲單位進行寫入的,具體塊的大小,可以使用下述語句進行查詢:
select max(l.lebsz) log_block_size_kccle
from sys.x$kccle l
where l.inst_id = userenv('Instance');
下面通過實驗觀察redo wastage造成的空白會不會在歸檔的時候被丟棄:
--查看redo file大小
SQL> select group#,bytes/1024/1024 \"size(M)\" from v$log;
GROUP# size(M)
---------- ----------
1 50
2 50
3 50
--建立測試表
SQL> create table darren(id number,item varchar2(2));
Table created.
--查看當前歸檔的情況
SQL> select SEQUENCE#,ARCHIVED,status,COMPRESSED from v$archived_log;
SEQUENCE# ARC S COM
---------- --- - ---
81 YES A NO
82 YES A NO
83 YES A NO
84 YES A NO
85 YES A NO
86 YES A NO
87 YES A NO
88 YES A NO
89 YES A NO
90 YES A NO--查看當前的redo size和redo wastage
SQL> select name,value from v$sysstat where name in('redo size','redo wastage');
NAME VALUE
--------------------- ------------------------------------------ ----------
redo size 258664912
redo wastage 86181420
--向測試表插入數據,產生redo記錄
begin
for i in 1..500000 loop
insert into darren values(1,'aa');
commit;
end loop;
end;
--切換一起日誌,將insert過程中產生的redo文件全部歸檔
SQL> alter system archive log current;
System altered.
--查看現在的redo size和redo wastage
SQL> select name,value from v$sysstat where name in('redo size','redo wastage');
NAME VALUE
---------- ------------
redo size 512888704
redo wastage 202172176
--計算insert過程中產生的redo size和redo wastage
SQL> select 512888704-258664912 redo from dual;
REDO
----------
254223792
SQL> select 202172176-86181420 wastage from dual;
WASTAGE
----------
115990756
--計算redo wastage的比例
SQL> select 115990756/254223792 from dual;
115990756/254223792
-------------------
.456254527
--查看insert 過程中產生的archive log file
SQL> select SEQUENCE#,ARCHIVED,status,COMPRESSED from v$archived_log;
SEQUENCE# ARC S COM
---------- --- - ---
81 YES A NO
82 YES A NO
83 YES A NO
84 YES A NO
85 YES A NO
86 YES A NO
87 YES A NO
88 YES A NO
89 YES A NO
90 YES A NO
91 YES A NO
92 YES A NO
93 YES A NO
94 YES A NO
95 YES A NO
96 YES A NO
97 YES A NO
98 YES A NO
99 YES A NO
從91號歸檔開始爲本次insert操作產生的歸檔
--查看歸檔文件大小
[oracle@oracle11g archive]$ ls -trl
-rw-r----- 1 oracle oinstall 49917440 Oct 23 13:49 orcl_1_91_851966182.arc
-rw-r----- 1 oracle oinstall 49257472 Oct 23 13:49 orcl_1_92_851966182.arc
-rw-r----- 1 oracle oinstall 49896448 Oct 23 13:50 orcl_1_93_851966182.arc
-rw-r----- 1 oracle oinstall 44149760 Oct 23 13:50 orcl_1_94_851966182.arc
-rw-r----- 1 oracle oinstall 49917440 Oct 23 13:50 orcl_1_95_851966182.arc
-rw-r----- 1 oracle oinstall 44199936 Oct 23 13:50 orcl_1_96_851966182.arc
-rw-r----- 1 oracle oinstall 46582784 Oct 23 13:51 orcl_1_97_851966182.arc
-rw-r----- 1 oracle oinstall 48513536 Oct 23 13:51 orcl_1_98_851966182.arc
-rw-r----- 1 oracle oinstall 13312 Oct 23 13:51 orcl_1_99_851966182.arc
結論:歸檔時不會丟棄由於redo wastage產生的redo log file中間的空白。
另外再說明一點,由於某些BUG的存在,會出現redo log切換非常頻繁,產生的歸檔都遠小於redo log file的大小,所以,在觀察到redo log切換頻繁的時候,要關注下歸檔日誌的大小,如歸歸檔日誌遠小於redo log file大小,這時造成redo log頻繁切換的原因可能不是大量的事務,這時要綜合考慮,不要貿然加大redo log file大小。