?
?
第四部分Standby之REDO傳輸服務? 2007.12.18
??? 很多人看電影或者電視劇時往往都以為,影響劇情發展的關鍵是主角的命運,那么,我不得不又說,你只看到了問題的表面,真正影響劇情發展的...............是導演。對于data guard 的數據應用而言,幕后的導演是LOG_ARCHIVE_DEST_n。本章節我們要學習的內容會很多,這一次,希望你能理清要學習的重點。
??? 關于redo 傳輸服務(Redo Transport Services),它不僅控制著傳輸redo 數據到其它數據庫,同時還管理著解決由于網絡中斷造成的歸檔文件未接收的過程。
?
?
一、如何發送數據
??? 在primary 數據庫,DataGuard 可以使用歸檔進程(ARCn)或者日志寫進程(LGWR)收集redo 數據并傳輸到standby,不過不管你選擇歸檔進程也好,日志寫進程也好,都由一個核心參數來控制,它就是:LOG_ARCHIVE_DEST_n,所以,我們先來:
?
1、認識LOG_ARCHIVE_DEST_n參數
?
??? LOG_ARCHIVE_DEST_n(n 從1 到10)定義redo 文件路徑。該參數定義必須通過location 或service 指明歸檔文件路徑。location 表示本地路徑,service 通常是net service name,即接收redo 數據的standby 數據庫。
??? 提示:
??? 對于每一個LOG_ARCHIVE_DEST_n 參數,還有一個對應的LOG_ARCHIVE_DEST_STATE_n 參數。LOG_ARCHIVE_DEST_STATE_n 參數用來指定對應的LOG_ARCHIVE_DEST_n 參數是否生效,擁有4 個屬性值:
??? ● ENABLE:默認值,表示允許傳輸服務。
??? ● DEFER:該屬性指定對應的log_archive_dest_n 參數有效,但暫不使用。
??? ● ALTERNATE:禁止傳輸,但是如果其它相關的目的地的連接通通失敗,則它將變成enable。
??? ● RESET:功能與DEFER 屬性類似,不過如果傳輸目的地之前有過錯誤,它會清除其所有錯誤信息。
?
??? 例如:指定本地歸檔路徑
??? LOG_ARCHIVE_DEST_1='LOCATION=/arch1/chicago/'
??? LOG_ARCHIVE_DEST_STATE_1=ENABLE
?
??? 又比如,指定redo 傳輸服務
??? LOG_ARCHIVE_DEST_2='SERVICE=jsspdg'
??? LOG_ARCHIVE_DEST_STATE_2=ENABLE
?
??? 當然,LOG_ARCHIVE_DEST_n 參數的屬性遠不止這些。
?
??? 這些參數都可以通過alter system set 語句直接聯機修改,修改會在primary 下次日志切換時生效,當然你直接shutdown 再重啟數據庫的話也會即時生效:)比如:
??? SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=jsspdgVALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)';
?
??? 除show parameter log_archive_dest 外,還可以通過查詢V$ARCHIVE_DEST 視圖的方式查看參數配置,并且V$ARCHIVE_DEST 視圖還可以看到更詳細的同步信息。
?
2、使用ARCARCn歸檔redo數據
??? 默認情況下,redo 傳輸服務使用ARCn 進程歸檔redo 日志。不過ARCn 歸檔進程只支持最高性能的保護模式。如果standby 數據庫處于其它類型的保護模式,那你必須使用LGWR 傳輸redo 數據(為什么會這樣呢,三思再來白話幾句,我們知道對于最大保護和最高可用性兩種模式而言,其實強調的都是一點,redo數據必須實時應用于standby 數據庫,我們再看來歸檔,歸檔是做什么呢?是備份已完成切換的redolog,完成切換的redolog 代表著什么呢?說明該redo 中所有數據均已提交至數據文件,那好我們再回過頭來看,數據已完成提交的redo 并且完成了切換還被復制了一份做為歸檔,這個時候才準備開始傳輸到standby 數據庫,這與最大保護和最高可用所要求的實時應用差的簡直不是一點半點,現在,你是不是明白了為什么ARCn 歸檔進程只能支持最高性能的保護模式)。
?
??
1).初始化參數控制ARCn 歸檔行為
?
??? 影響ARCn 進程的初始化參數有:
??? LOG_ARCHIVE_DEST_n 及LOG_ARCHIVE_MAX_PROCESSES。
?
??? 關于LOG_ARCHIVE_DEST_n 參數的配置前面介紹了一些,我們知道該參數的部分屬性與ARCn進程相關,而LOG_ARCHIVE_MAX_PROCESSES 初始化參數則可看做是專為ARCn 進程量身打造,該參數用來指定最大可被調用的ARCn 進程的數量,注意我們指定的是最大值,也就是說數據庫在運行過程中是會根據歸檔的任務繁重程度自動調節歸檔進程數量的。當然如果說你覺著你的系統歸檔任務比較繁重,可以通過設置較多的歸檔進程數量提高歸檔并發度,但是這個數字也不是越高越好,過高的歸檔進程數量有可能反而影響系統性能(所謂物極必反就是這個意思,所以這中間是需要你來把握平衡的,當然這方面更多涉及到調優了,非本章所要講解之重點,就不多說了)。調整該參數可以通過下列語句:
??? ALTER SYSTEM SET LOG_ARCHIVE_MAX_PROCESSES = n;
??? 注:n>0 and n<=30
?
???
2).ARCn 的歸檔過程
?
??? primary 數據庫日志發生切換時就會啟動歸檔:
??? ● 在primary 數據庫(假設有2 個歸檔進程),一旦ARC0 進程完成redolog 的歸檔,ARC1 進程即開始傳輸該歸檔到standby 數據庫的指定路徑。
??? ● 在standby 數據庫,RFS 進程輪流將redo 數據寫入standby redo log,再由standby 數據庫中的ARCn 進程將其寫入歸檔,然后通過REDO 應用或SQL 應用將數據應用到standby 數據庫。
?
??? 如圖:
???
??? 另外,因為本地的歸檔進程與遠程歸檔進程間并無聯系,注意如果本地存在刪除完成備份的歸檔的策略,需要在刪除之前首先確認這些歸檔已經被傳輸到standby 數據庫。
?
3、使用LGWR歸檔redo數據
??? 使用LGWR 進程與使用ARCn 進程有明顯不同,LGWR 無須等待日志切換及完成歸檔。
??? Standby 數據庫的LGWR 進程會先選擇一個standby redo log 文件映射primary 數據庫當前redolog 的sequence(以及文件大小),一旦primary 數據庫有redo 數據產生,視LOG_ARCHIVE_DEST_n 初始化參數中sync 或async 屬性設置,以同步或非同步方式傳輸到standby 數據庫。
??? 要繼續下面的內容,我們必須先了解與LGWR 歸檔進程密切相關的幾個LOG_ARCHIVE_DEST_n 參數的屬性,如果選擇LGWR 歸檔redo 數據,那么在LOG_ARCHIVE_DEST_n中必須指定SERVICE 和LGWR屬性以允許日志傳輸服務使用LGWR 進程來傳送redo 數據到遠程歸檔目的地。我們還需要指定SYNC(同步)還是ASYNC(異步)的傳輸方式,如果指定SYNC 屬性(如果不明確指定的話,默認是SYNC),則primary數據庫任何會產生redo 操作都會同步觸發網絡I/O,并且等到網絡I/O 全部完成才會繼續下面的提交,而如果指定了ASYNC 屬性,則會primary 數據庫的操作會先記錄online redologs,然后再傳輸到standby。下面詳細看看其流程:
?
??? 1).LGWR 同步歸檔的流程
?
??? 例如初始化參數中有如下設置:
??? LOG_ARCHIVE_DEST_1='LOCATION=E:\ora10g\oradata\jssweb\'
??? LOG_ARCHIVE_DEST_2='SERVICE=jsspdg LGWR SYNC NET_TIMEOUT=30'
??? LOG_ARCHIVE_DEST_STATE_1=ENABLE
??? LOG_ARCHIVE_DEST_STATE_2=ENABLE
??? 如果設置LOG_ARCHIVE_DEST_n 初始化參數SYNC 屬性,建議同時設置NET_TIMEOUT 屬性,該屬性控制網絡連接的超時時間,如果超時仍無響應,則會返回錯誤信息。
??? 如圖:
???
??? 展示了primary 數據庫LGWR 寫online redologs 的同時,同步傳輸redo 數據到standby 數據庫的過程。
?
??? 我們仍然分兩部分來解讀:
??? ● 在primary 數據庫,LGWR 提交redo 數據到LNSn(LGWR Network Server process)進程(n>0),LNSn 啟動網絡傳輸。
??? ● standby 數據庫的RFS(Remote File Server)將接收到的redo 數據寫入standby redolog。特別注意, 在此期間, primary 數據庫的事務會一直保持, 直到所有所有含LGWR SYNC 屬性的LOG_ARCHIVE_DEST_n 指定路徑均已完成接收。
??? 一旦primary 數據庫執行日志切換,就會級聯觸發standby 的ARCn 將standby redo 寫入歸檔,然后通過redo 應用(MRP 進程)或sql 應用(LSP 進程)讀取歸檔文件將數據應用至standby 數據庫。(如果啟用了實時應用的話,MRP/LSP 會直接讀取standby redolog 并應用到standby 數據庫,無須再等待歸檔)。
?
???
2).LGWR 不同步歸檔的流程
?
??? 例如初始化參數中有如下設置:
??? LOG_ARCHIVE_DEST_1='LOCATION=E:\ora10g\oradata\jssweb\ '
??? LOG_ARCHIVE_DEST_2='SERVICE=jsspdg LGWR ASYNC'
??? LOG_ARCHIVE_DEST_STATE_1=ENABLE
??? LOG_ARCHIVE_DEST_STATE_2=ENABLE
??? ASYNC 方式歸檔就不需要再指定NET_TIMEOUT 了,因為LGWR 與LNSn 之間已無關聯,所以指定不指定NET_TIMEOUT 就都沒任何影響了,因此對于異步傳輸而言,即使網絡出現故障造成primary 與standby 之間通信中斷,也并不會影響到primary 數據庫的提交。
?
??? 如圖:
???
??? 展示了LNSn 進程異步傳輸redo 數據到standby 數據庫RFS 進程的過程。
?
??? 大致步驟與同步傳輸相同,差別只在LNSn 進程這里,LGWR 寫數據到online redolog,LNSn 進程訪問online redolog 并傳輸數據到遠程standby 的RFS 而不再與本地LGWR 之間有聯系。standby 數據庫方面的處理邏輯仍然不變。
?
?
二、什么時候發送
?
??? 這小節包含兩個內容,發送什么,以及發送給誰:
?
1、通過VALID_FOR 屬性指定傳輸及接收對象
?
??? valid_for,字面理解就是基于xx 有效,再配合其redo_log_type,database_role 屬性,我們基本上可以將其理解為:為指定角色設置日志文件的歸檔路徑,主要目的是為了輔助一旦發生角色切換操作后數據庫的正常運轉。
?
??? redo_log_type 可設置為:ONLINE_LOGFILE,STANDBY_LOGFILE,ALL_LOGFILES
??? database_role 可設置為:PRIMARY_ROLE,STANDBY_ROLE,ALL_ROLES
??? 注意valid_for 參數是有默認值的,如果不設置的話,其默認值等同于:valid_for=(ALL_LOGFILES,ALL_ROLES)
?
??? 推薦主動設置該參數而不要使用默認值,某些情況下默認的參數值不一定合適,比如邏輯standby 就不像物理standby ,邏輯standby 處于open 模式, 不僅有redo 數據而且還包含多種日志文件(onlineredologs,archived redologs 以及standby redologs)。多數情況下,邏輯standby 生成的online redologs 與standbyredologs 生成在相同的目錄內。因此,推薦你對每個*dest 設置合適的valid_for 屬性。
?
2、通過DB_UNIQUE_NAME 屬性指定數據庫
?
??? DB_UNIQUE_NAME 屬性主要是為某個數據庫指定唯一的數據庫名稱,這就使得動態添加standby 到包含RAC 結構的primary 數據庫的dg 配置成為可能,并且對于log_archive_dest_n 中的service 屬性,其屬
性值對應的也必然是db_unique_name,也正因有了db_unique_name,redo 數據在傳輸過程中才能確認傳輸到你希望被傳輸到的數據庫上。當然要保障傳輸redo 數據到指定服務器, 除了db_unique_name,log_archive_dest_n 之外,還有一個初始化參數:log_archive_config。
?
??? 關于log_archive_config 呢,我們前面有過一些接觸,在第二部分第1 節中也有一些簡單的介紹,log_archive_config 初始化參數還包括幾個屬性, 可以用過控制數據庫的傳輸和接收,SEND,NOSEND,RECEIVE,NORECEIVE:
??? ● SEND 允許數據庫發送數據到遠端
??? ● RECEIVE 則允許standby 接收來自其它數據庫的數據
??? ● NOSEND,NORECEIVE 自然就是禁止嘍。
?
??? 例如,設置primary 數據庫不接收任何歸檔數據,可以做如下的設置:
??? LOG_ARCHIVE_CONFIG='NORECEIVE,DG_CONFIG=(jssweb,jsspdg)'
?
??? 當然,你同樣也需要注意,一旦做了如上的設置,那么假設該服務器發生了角色切換,那它仍然也沒有接收redo 數據的能力喲。
?
?
三、出錯了咋整
??? 對于歸檔失敗的處理,LOG_ARCHIVE_DEST_n 參數有幾個屬性可以用來控制一旦向歸檔過程中出現故障時應該采取什么措施,它們是:
?
1、REOPEN 指定時間后再次嘗試歸檔
??? 使用REOPEN=seconds(默認=300)屬性,在指定時間重復嘗試向歸檔目的地進行歸檔操作,如果該參數值設置為0,則一旦失敗就不會再嘗試重新連接并發送,直到下次redo 數據再被歸檔時會重新嘗試,不過并不會歸檔到已經失敗的歸檔目的地,而是向替補的歸檔目的地發送。
?
2、ALTERNATE 指定替補的歸檔目的地
??? alternate 屬性定義一個替補的歸檔目的地,所謂替補就是一旦主歸檔目的地因各種原因無法使用,則臨時向alternate 屬性中指定的路徑寫。
??? 需要注意一點,reopen 的屬性會比alternate屬性優先級要高,如果你指定reopen 屬性的值>0,則lgwr/arch會首先嘗試向主歸檔目的地寫入,直到達到最大重試次數,如果仍然寫入失敗,才會向alternate 屬性指定的路徑寫。
?
3、MAX_FAILURE 控制失敗嘗試次數
?
??? max_failure 屬性指定一個最大失敗嘗試次數,大家應該能夠聯想到reopen,沒錯兩者通常是應該配合使用,reopen 指定失敗后重新嘗試的時間周期,max_failure 則控制失敗嘗試的次數,如例:
??? LOG_ARCHIVE_DEST_1='LOCATION=E:\ora10g\oradata\jsspdg\ REOPEN=60 MAX_FAILURE=3'
?
?
四、管理歸檔中斷
??? 如果primary 數據庫中的歸檔日志沒能成功發送至standby 數據庫,就會出現歸檔中斷。當然通常情況下你不需要擔心這一點,因為dg 會自動檢測并嘗試復制丟失的歸檔以解決中斷問題,通過什么解決呢?
FAL(FetchArchive Log)。
?
??? FAL 分server 和client,前面創建步驟中講初始化參數時想必大家也注意到了。FAL client 自動主動要求傳
輸歸檔文件,FAL server 則響應FAL client 發送的請求。多好的兩口子啊。
?
??? FAL 機制會自動處理下列類似的歸檔中斷問題:
??? ● 當創建物理或邏輯的standby 數據庫,FAL 機制會自動獲取primary 數據庫熱備時產生的歸檔文件。
??? ● 當接收的歸檔文件出現下列的問題時,FAL 機會會自動獲取歸檔文件解決:
??????? ※ 當接收到的歸檔在應用之后被刪除時;
??????? ※ 當接收到的歸檔所在磁盤損壞時;
??? ● 當存在多個物理standby 時,FAL 機制會自動嘗試從其它standby 服務器獲取丟失的歸檔文件。
?
??? 讓大家了解這個東西不是為了讓你做什么,而是希望你放心,oracle 會管理好這些,如果它沒有管理好,你明白這個原理,你也能分析一下它為什么沒能管理好,通過什么方式能夠促使它恢復有效管理的能力,當然你一定要自己動手,也可以,下面通過示例來說明手工處理歸檔中斷(注意,俺只描述步驟,演示俺就不做了。因為三思現在用地最大保護模式,不會丟失歸檔地說,哇哈哈哈:))
?
1、首先你要確認一下standby 是否存在歸檔中斷
?
??? 可以通過查詢v$archive_gap 視圖來確定,如果有記錄就表示有中斷。
??? SQL> select *from v$archive_gap;
?
??? 這一步的目的是為了取出對應的LOW_SEQUENCE#和HIGH_SEQUENCE#,如果有RAC 的話,還需要注意一下THREAD#。
?
2、查找sequence 對應的歸檔文件
?
??? SQL> SELECT NAME FROM V$ARCHIVED_LOG WHERE THREAD#=1 AND DEST_ID=1 ANDSEQUENCE# BETWEEN 7 AND 10;
?
?
3、復制對應的歸檔文件到standby
?
??? 注意,如果是RAC 的話,要找對機器喲:)
??? 然后通過alter database register logfile 命令將這些文件重新注冊一下,例如:
??? SQL> ALTER DATABASE REGISTER LOGFILE 'e:\ora10g\jsspdg\xxxx.arc';
?
??? 然后重啟redo 應用即可。
??? 對于邏輯standby 的丟失歸檔處理稍微復雜一點點,因為邏輯standby 沒有提供類型v$archive_gap;之類的視圖,因此我們需要自己想辦法來識別是否存在丟失的情況,具體可以通過下列的語句:
??? SQL> select thread#,sequence#,file_name from dba_logstdby_log l
?????? 2 where next_change# not in (
?????? 3 select first_change# from dba_logstdby_log where l.thread# = thread#)
?????? 4 order by thread#,sequence#;
?
??? 找出丟失的歸檔文件后,接著的處理方式與物理standby 相同。
?
?