1. 程式人生 > >歸檔日誌的大小比線上日誌的大小小很多(轉)

歸檔日誌的大小比線上日誌的大小小很多(轉)

原文地址:https://blogs.oracle.com/Database4CN/entry/%E5%BD%92%E6%A1%A3%E6%97%A5%E5%BF%97%E7%9A%84%E5%A4%A7%E5%B0%8F%E6%AF%94%E5%9C%A8%E7%BA%BF%E6%97%A5%E5%BF%97%E7%9A%84%E5%A4%A7%E5%B0%8F_%E5%B0%8F%E5%BE%88%E5%A4%9A

有些使用者會對於歸檔日誌的大小比線上日誌小感到疑惑,對於這種情況:

首先請檢查您的歸檔日誌檔案是否壓縮:
SELECT to_char(first_time,'yyyy-mm-dd hh24:mi:ss'),blocks*block_size/1024/1024,compressed from v$archived_log;

如果未壓縮,那麼這個問題可能和您的CPU個數有關。
請檢視您的CPU個數:
show parameter CPU_COUNT

歸檔日誌的大小是真實的線上日誌檔案的使用量,也就是線上日誌檔案切換前其中寫入的內容的大小。
但是為了更好的並行減少衝突,oracle會按每16個CPU分一股(strand),每一股獨立從redo buffer以及redo log中分配一塊空間,當這一塊redo buffer用完,會寫入redo log並且繼續從redo log中分配相同大小的空間,如果無法分配空閒空間就會進行日誌切換,而不管其他strand是否寫完。
下面舉例子來說明這個演算法:
比如CPU的個數是64個,則會有64/16=4個strand
例1)當log buffer的大小和redo log file的大小都是256M的時候,則每個strand都是256M/4=64M。
每一個redo log file被啟用時,會預先將redo log file中的大小分配出4個64M與log buffer對應,如圖:


因為log buffer的大小和redo log file的大小都是256M,則redo log file沒有剩餘的未分配的空間了。

每個程序產生的redo會分配到log buffer上的1,2,3,4其中的某一個strand上,單個程序只能對應一個strand,
這樣當資料庫中只有某些程序(比如極端的情況,只有某一個程序)產生的redo很多的時候,其中一個strand會快速寫滿,比如圖中的strand 1:

寫滿之後LGWR會將log buffer中strand 1的內容寫入到redo log file中,並且試圖從redo log file中分配一個新的64M空間,發現沒有了,則將所有strand中的內容寫入日誌,並作日誌切換。

這樣,可能會導致redo log file只寫入了一個strand的內容,其他部分幾乎是空的,則產生的archive log會只接近64M,而不是256M。
當CPU_COUNT很大時,這個差值會更大。

例2)當log buffer的大小是256M,而redo log file的大小是1G的時候,每個strand還是256M/4=64M。
每一個redo log file被啟用時,會預先將redo log file中的大小分配出4個64M與log buffer對應,如圖:

這時,redo log file中還有1G-256M=768M剩餘的未分配的空間。


如果strand 1寫滿之後,LGWR會將log buffer中strand 1的內容寫入到redo log file中,並且試圖從redo log file中分配一個新的64M空間,然後不斷往下寫。


直到redo log file中再沒有可分配空間了,則將所有strand中的內容寫入日誌,並作日誌切換。



例3)當log buffer的大小是256M,而redo log file的大小是100M的時候,每個strand還是256M/4=64M。
但是redo log file中的空間會按strand的個數平均分配,也就是每塊100M/4=25M。

這樣,當每個strand中的內容寫到25M的時候,就會日誌切換,而不是64M。相當於log buffer中的一部分空間被浪費了。

請參考以下文件:
1.Archive Logs Are Created With Smaller, Uneven Size Than The Original Redo Logs. Why? (Doc ID 388627.1)
With a high CPU_COUNT, a low load and a redo log file size smaller than the redolog buffer, you may small archived log files because of log switches at about 1/8 of the size of the define log file size.
This is because CPU_COUNT defines the number of redo strands (ncpus/16). With a low load only a single strand may be used. With redo log file size smaller than the redolog buffer, the log file space is divided over the available strands. When for instance only a single active strand is used, a log switch can already occur when that strand is filled.

<==高 CPU_COUNT和低workload(實際上資料庫不一定不繁忙,只是在產生redo的程序很少的情況下)會導致 Archive Log比redo log小很多,而且日誌頻繁切換。

2.Archived redolog is (significant) smaller than the redologfile. (Doc ID 1356604.1)
The logfile space reservation algorithm
If the logfile is smaller than the log buffer, then the whole logfile space is divided/mapped/reserved equally among all the strands, and there is no unreserved space (ie no log residue).
When any process fills a strand such that all the reserved underlying logfile space for that strand is used, AND there is no log residue, then a log switch is scheduled.

<==log strand 和 log switch的演算法在這個note中講的更明白。