數據庫在運行過程當中,不可避免地要遇到各類可以致使數據庫損壞的狀況。好比忽然斷電、Oracle或者操做系統的程序bug致使數據庫內部邏輯結構損壞、磁盤介質損壞等,都有可能形成數據庫崩潰,從而致使數據丟失的現象發生。數據庫
爲了不,或者說爲了修復這些情況所致使的數據丟失現象,Oracle引入了日誌緩衝區和日誌文件的概念。所謂日誌,就是將數據庫中全部改變數據塊的操做,都原本來本地記錄下來。這些改變數據塊的操做不只包括對數據表的DML命令或者引發數據字典內容變化的DDL命令,還包括對索引的改變、對回滾段數據塊的改變等。只有將數據庫中全部的變化都記錄下來,當發生數據庫損壞時,纔可以經過從新應用這些變化,從而達到恢復數據庫的目的。安全
既然是要記錄,那就必然引出一個問題,就是如何記錄這些變化?比較容易想到的有兩種方式。oracle
第一種是使用邏輯的記錄方式,也就是用描述性的語句來記錄整個變化過程。好比對於某個update更新操做來講來講,能夠記錄爲兩條語句:delete 舊值以及insert 新值。這種方式的優勢是很是節省空間,由於對每一個操做,只須要記錄幾條邏輯上的語句便可。可是缺點也很明顯,就是一旦須要進行恢復,就會很是消耗資源。設想一下,某個update操做更新了很是多的數據塊,因爲buffer cache內存有限,不少髒數據塊都已經寫入了數據文件。但就在更新快結束時,忽然發生斷電,所作的更新丟失。那麼從新啓動實例時,Oracle須要應用日誌文件裏的記錄,因而從新發出delete舊值以及insert新值的語句。這個過程須要從新查找數據文件中符合條件的數據塊,而後再挑出來進行更新。這個過程將很是消耗時間,並且會佔用大量的buffer cache。ide
第二種方式是使用物理的記錄方式,也就是將每一個數據塊改變前的鏡像和改變後的鏡像都記錄下來。這種方式優勢就是恢復起來速度很是快,直接根據日誌文件裏所記錄的數據塊地址和內容更新數據文件中對應的數據塊。可是缺點也很明顯,就是很是佔用磁盤空間。測試
而Oracle在記錄日誌的方式上,採用了邏輯和物理相結合的方式。也就是說,Oracle針對每一個數據塊,記錄了插入某個值或者刪除某個值的描述語句。假如某個update更新了100個數據塊,則Oracle會針對每一個數據塊記錄一對delete 舊值和insert 新值的語句,共有100對這樣的描述語句。在每一對描述語句中,都記錄了相關數據塊的物理地址。經過這種邏輯與物理相結合的方式,Oracle在記錄變化時可以儘可能節省空間,同時在應用變化時,又能比較快速。操作系統
爲了臨時存放所產生的日誌信息,Oracle在SGA中開闢了一塊內存區域。這塊區域就叫作日誌緩衝區(log buffer),當知足必定條件之後,Oracle會使用名爲LGWR的後臺進程將log buffer中的日誌信息寫入聯機日誌文件裏。日誌
可使用初始化參數log_buffer來設置日誌緩衝區的大小,單位是字節。日誌緩衝區會進一步細分爲多個塊,每一個塊的尺寸與操做系統的一個塊的尺寸相同,基本都是512字節。咱們能夠用以下方式來得到日誌緩衝區的塊尺寸。視頻
SQL> select distinct lebsz as redo_block_size from x$kccle;教程
REDO_BLOCK_SIZE索引
---------------
512
也能夠用下面的方式來計算出日誌緩衝區的塊尺寸。
SQL> select round((a.redosize+b.redowast)/c.redoblks) + 16 as
redo_block_size from
2 (select value redosize from v$sysstat where name='redo
size') a,
3 (select value redowast from v$sysstat where name='redo
wastage') b,
4 (select value redoblks from v$sysstat where name='redo
blocks written') c;
REDO_BLOCK_SIZE
---------------
512
日誌緩衝區只是日誌信息臨時存放的區域,這塊區域是有限的,並且其中的每一個塊都是可以循環使用的。這也就說明,日誌緩衝區中的內容必需要寫入磁盤的文件裏,才能永久保留下來,才能在數據庫崩潰時可以用來進行恢復。這個文件就叫作聯機日誌文件。在每一個日誌緩衝區中的日誌塊被重用以前,其內容必然已經被寫入了磁盤上的聯機日誌文件中。
聯機日誌文件就是日誌緩衝區的徹底副本,組成日誌文件的每一個日誌塊的內容都來自於日誌緩衝區的日誌塊。每一個日誌緩衝區中的日誌塊都對應到日誌文件中的一個日誌塊。日誌緩衝區中的日誌塊按照發生的前後順序,放入聯機日誌文件。
因爲日誌文件在故障恢復中的重要性,建議至少使用兩個日誌文件組成一個日誌文件組。同一個日誌文件組中的日誌文件內容如出一轍,由於日誌緩衝區中的日誌塊同時會寫入日誌文件組中的每一個日誌文件中。每一個數據庫都必須至少擁有兩個日誌文件組。這是因爲只要數據庫一天不中止運行,就會不斷產生日誌信息,就會不斷寫入聯機日誌文件,聯機日誌文件總會有寫滿的時候。咱們不可能讓聯機日誌文件無限大,也不可能放無限多的聯機日誌文件,因此聯機日誌文件必須是循環使用的,在若干個日誌文件中輪流的進行寫入。一個日誌文件寫滿之後轉換到另一個日誌文件繼續寫的過程叫作日誌切換(log switch)。
當一個聯機日誌文件寫滿時,能夠選擇將其歸檔爲脫機日誌文件,一般叫作歸檔日誌文件。歸檔也就是副本,歸檔的過程也就是將寫滿的聯機日誌文件複製到預先指定的目錄的過程。只有當一個聯機日誌文件完成歸檔之後,該聯機日誌文件纔可以被再次循環使用。強烈建議在生產庫中選擇這種歸檔方式,只有在測試環境中能夠選擇不歸檔。
能夠說,日誌緩衝區和日誌文件存在的惟一目的就是爲了保證被修改的數據不會被丟失。反過來講,也就是爲了可以在數據庫崩潰的時候,能夠用來將數據庫恢復到崩潰的那個時間點上。這也就是說,只有將被修改的數據塊的日誌信息寫入了聯機日誌文件之後,該被修改的數據塊才能夠說是安全的。若是日誌信息在沒有被寫入日誌文件時發生實例崩潰,這時對數據的修改仍將丟失。由此咱們能夠看出,將日誌緩衝區中的日誌信息寫入日誌文件是一個很是重要的過程,這個過程是由一個名爲LGWR的後臺進程完成的。LGWR 承擔了維護系統數據完整性的任務,它保證了數據在任何狀況下都不會丟失。
觸發LGWR進程將日誌緩衝區中的日誌信息寫入聯機日誌文件條件包括如下幾種。
前臺進程觸發,包括兩種狀況。最顯而易見的一種狀況就是用戶發出commit或rollback語句進行提交時,須要觸發LGWR將內存裏的日誌信息寫入聯機日誌文件,由於提交的數據必須被保護而不被丟失;另一種狀況就是在日誌緩衝區中找不到足夠的內存來放日誌信息時,也會觸發LGWR進程將一些日誌信息寫入聯機日誌文件之後,從而釋放一些空間。
每隔三秒鐘,LGWR啓動一次。
在DBWn啓動時,若是發現髒數據塊所對應的重作條目尚未寫入聯機日誌文件,則DBWn觸發LGWR進程並等待LRWR寫完之後纔會繼續。
日誌信息的數量達到整個日誌緩衝區的1/3時,觸發LGWR。
日誌信息的數量達到1MB時,觸發LGWR。
oracle視頻教程請關注:http://down.51cto.com/4202939/up