??? 很多人看電影或者電視劇時(shí)往往都以為,影響劇情發(fā)展的關(guān)鍵是主角的命運(yùn),那么,我不得不又說,你只看到了問題的表面,真正影響劇情發(fā)展的...............是導(dǎo)演。對(duì)于data guard 的數(shù)據(jù)應(yīng)用而言,幕后的導(dǎo)演是LOG_ARCHIVE_DEST_n。本章節(jié)我們要學(xué)習(xí)的內(nèi)容會(huì)很多,這一次,希望你能理清要學(xué)習(xí)的重點(diǎn)。
??? 在primary 數(shù)據(jù)庫,DataGuard 可以使用歸檔進(jìn)程(ARCn)或者日志寫進(jìn)程(LGWR)收集redo 數(shù)據(jù)并傳輸?shù)絪tandby,不過不管你選擇歸檔進(jìn)程也好,日志寫進(jìn)程也好,都由一個(gè)核心參數(shù)來控制,它就是:LOG_ARCHIVE_DEST_n,所以,我們先來:
??? 提示:
??? 對(duì)于每一個(gè)LOG_ARCHIVE_DEST_n 參數(shù),還有一個(gè)對(duì)應(yīng)的LOG_ARCHIVE_DEST_STATE_n 參數(shù)。LOG_ARCHIVE_DEST_STATE_n 參數(shù)用來指定對(duì)應(yīng)的LOG_ARCHIVE_DEST_n 參數(shù)是否生效,擁有4 個(gè)屬性值:
??? ● ENABLE:默認(rèn)值,表示允許傳輸服務(wù)。
??? ● DEFER:該屬性指定對(duì)應(yīng)的log_archive_dest_n 參數(shù)有效,但暫不使用。
??? ● ALTERNATE:禁止傳輸,但是如果其它相關(guān)的目的地的連接通通失敗,則它將變成enable。
??? ● RESET:功能與DEFER 屬性類似,不過如果傳輸目的地之前有過錯(cuò)誤,它會(huì)清除其所有錯(cuò)誤信息。
??? LOG_ARCHIVE_DEST_1='LOCATION=/arch1/chicago/'
??? LOG_ARCHIVE_DEST_STATE_1=ENABLE
??? LOG_ARCHIVE_DEST_2='SERVICE=jsspdg'
??? LOG_ARCHIVE_DEST_STATE_2=ENABLE
??? SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=jsspdgVALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)';
??? 默認(rèn)情況下,redo 傳輸服務(wù)使用ARCn 進(jìn)程歸檔redo 日志。不過ARCn 歸檔進(jìn)程只支持最高性能的保護(hù)模式。如果standby 數(shù)據(jù)庫處于其它類型的保護(hù)模式,那你必須使用LGWR 傳輸redo 數(shù)據(jù)(為什么會(huì)這樣呢,三思再來白話幾句,我們知道對(duì)于最大保護(hù)和最高可用性兩種模式而言,其實(shí)強(qiáng)調(diào)的都是一點(diǎn),redo數(shù)據(jù)必須實(shí)時(shí)應(yīng)用于standby 數(shù)據(jù)庫,我們再看來歸檔,歸檔是做什么呢?是備份已完成切換的redolog,完成切換的redolog 代表著什么呢?說明該redo 中所有數(shù)據(jù)均已提交至數(shù)據(jù)文件,那好我們再回過頭來看,數(shù)據(jù)已完成提交的redo 并且完成了切換還被復(fù)制了一份做為歸檔,這個(gè)時(shí)候才準(zhǔn)備開始傳輸?shù)絪tandby 數(shù)據(jù)庫,這與最大保護(hù)和最高可用所要求的實(shí)時(shí)應(yīng)用差的簡直不是一點(diǎn)半點(diǎn),現(xiàn)在,你是不是明白了為什么ARCn 歸檔進(jìn)程只能支持最高性能的保護(hù)模式)。
??? LOG_ARCHIVE_DEST_n 及LOG_ARCHIVE_MAX_PROCESSES。
??? ALTER SYSTEM SET LOG_ARCHIVE_MAX_PROCESSES = n;
??? 注:n>0 and n<=30??? ● 在standby 數(shù)據(jù)庫,RFS 進(jìn)程輪流將redo 數(shù)據(jù)寫入standby redo log,再由standby 數(shù)據(jù)庫中的ARCn 進(jìn)程將其寫入歸檔,然后通過REDO 應(yīng)用或SQL 應(yīng)用將數(shù)據(jù)應(yīng)用到standby 數(shù)據(jù)庫。
??? 另外,因?yàn)楸镜氐臍w檔進(jìn)程與遠(yuǎn)程歸檔進(jìn)程間并無聯(lián)系,注意如果本地存在刪除完成備份的歸檔的策略,需要在刪除之前首先確認(rèn)這些歸檔已經(jīng)被傳輸?shù)絪tandby 數(shù)據(jù)庫。
??? 使用LGWR 進(jìn)程與使用ARCn 進(jìn)程有明顯不同,LGWR 無須等待日志切換及完成歸檔。
??? Standby 數(shù)據(jù)庫的LGWR 進(jìn)程會(huì)先選擇一個(gè)standby redo log 文件映射primary 數(shù)據(jù)庫當(dāng)前redolog 的sequence(以及文件大小),一旦primary 數(shù)據(jù)庫有redo 數(shù)據(jù)產(chǎn)生,視LOG_ARCHIVE_DEST_n 初始化參數(shù)中sync 或async 屬性設(shè)置,以同步或非同步方式傳輸?shù)絪tandby 數(shù)據(jù)庫。
??? 要繼續(xù)下面的內(nèi)容,我們必須先了解與LGWR 歸檔進(jìn)程密切相關(guān)的幾個(gè)LOG_ARCHIVE_DEST_n 參數(shù)的屬性,如果選擇LGWR 歸檔redo 數(shù)據(jù),那么在LOG_ARCHIVE_DEST_n中必須指定SERVICE 和LGWR屬性以允許日志傳輸服務(wù)使用LGWR 進(jìn)程來傳送redo 數(shù)據(jù)到遠(yuǎn)程歸檔目的地。我們還需要指定SYNC(同步)還是ASYNC(異步)的傳輸方式,如果指定SYNC 屬性(如果不明確指定的話,默認(rèn)是SYNC),則primary數(shù)據(jù)庫任何會(huì)產(chǎn)生redo 操作都會(huì)同步觸發(fā)網(wǎng)絡(luò)I/O,并且等到網(wǎng)絡(luò)I/O 全部完成才會(huì)繼續(xù)下面的提交,而如果指定了ASYNC 屬性,則會(huì)primary 數(shù)據(jù)庫的操作會(huì)先記錄online redologs,然后再傳輸?shù)絪tandby。下面詳細(xì)看看其流程:
??? 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
??? 如果設(shè)置LOG_ARCHIVE_DEST_n 初始化參數(shù)SYNC 屬性,建議同時(shí)設(shè)置NET_TIMEOUT 屬性,該屬性控制網(wǎng)絡(luò)連接的超時(shí)時(shí)間,如果超時(shí)仍無響應(yīng),則會(huì)返回錯(cuò)誤信息。
??? 如圖:

??? 展示了primary 數(shù)據(jù)庫LGWR 寫online redologs 的同時(shí),同步傳輸redo 數(shù)據(jù)到standby 數(shù)據(jù)庫的過程。
??? ● standby 數(shù)據(jù)庫的RFS(Remote File Server)將接收到的redo 數(shù)據(jù)寫入standby redolog。特別注意, 在此期間, primary 數(shù)據(jù)庫的事務(wù)會(huì)一直保持, 直到所有所有含LGWR SYNC 屬性的LOG_ARCHIVE_DEST_n 指定路徑均已完成接收。
??? 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 了,因?yàn)長GWR 與LNSn 之間已無關(guān)聯(lián),所以指定不指定NET_TIMEOUT 就都沒任何影響了,因此對(duì)于異步傳輸而言,即使網(wǎng)絡(luò)出現(xiàn)故障造成primary 與standby 之間通信中斷,也并不會(huì)影響到primary 數(shù)據(jù)庫的提交。
??? database_role 可設(shè)置為:PRIMARY_ROLE,STANDBY_ROLE,ALL_ROLES
??? 注意valid_for 參數(shù)是有默認(rèn)值的,如果不設(shè)置的話,其默認(rèn)值等同于:valid_for=(ALL_LOGFILES,ALL_ROLES)
??? ● SEND 允許數(shù)據(jù)庫發(fā)送數(shù)據(jù)到遠(yuǎn)端
??? ● RECEIVE 則允許standby 接收來自其它數(shù)據(jù)庫的數(shù)據(jù)
??? ● NOSEND,NORECEIVE 自然就是禁止嘍。
??? LOG_ARCHIVE_CONFIG='NORECEIVE,DG_CONFIG=(jssweb,jsspdg)'
??? 對(duì)于歸檔失敗的處理,LOG_ARCHIVE_DEST_n 參數(shù)有幾個(gè)屬性可以用來控制一旦向歸檔過程中出現(xiàn)故障時(shí)應(yīng)該采取什么措施,它們是:
??? 使用REOPEN=seconds(默認(rèn)=300)屬性,在指定時(shí)間重復(fù)嘗試向歸檔目的地進(jìn)行歸檔操作,如果該參數(shù)值設(shè)置為0,則一旦失敗就不會(huì)再嘗試重新連接并發(fā)送,直到下次redo 數(shù)據(jù)再被歸檔時(shí)會(huì)重新嘗試,不過并不會(huì)歸檔到已經(jīng)失敗的歸檔目的地,而是向替補(bǔ)的歸檔目的地發(fā)送。
??? alternate 屬性定義一個(gè)替補(bǔ)的歸檔目的地,所謂替補(bǔ)就是一旦主歸檔目的地因各種原因無法使用,則臨時(shí)向alternate 屬性中指定的路徑寫。
??? 需要注意一點(diǎn),reopen 的屬性會(huì)比alternate屬性優(yōu)先級(jí)要高,如果你指定reopen 屬性的值>0,則lgwr/arch會(huì)首先嘗試向主歸檔目的地寫入,直到達(dá)到最大重試次數(shù),如果仍然寫入失敗,才會(huì)向alternate 屬性指定的路徑寫。
??? LOG_ARCHIVE_DEST_1='LOCATION=E:\ora10g\oradata\jsspdg\ REOPEN=60 MAX_FAILURE=3'
??? 如果primary 數(shù)據(jù)庫中的歸檔日志沒能成功發(fā)送至standby 數(shù)據(jù)庫,就會(huì)出現(xiàn)歸檔中斷。當(dāng)然通常情況下你不需要擔(dān)心這一點(diǎn),因?yàn)閐g 會(huì)自動(dòng)檢測并嘗試復(fù)制丟失的歸檔以解決中斷問題,通過什么解決呢? FAL(FetchArchive Log)。
??? ● 當(dāng)創(chuàng)建物理或邏輯的standby 數(shù)據(jù)庫,F(xiàn)AL 機(jī)制會(huì)自動(dòng)獲取primary 數(shù)據(jù)庫熱備時(shí)產(chǎn)生的歸檔文件。
??? ● 當(dāng)接收的歸檔文件出現(xiàn)下列的問題時(shí),F(xiàn)AL 機(jī)會(huì)會(huì)自動(dòng)獲取歸檔文件解決:
??????? ※ 當(dāng)接收到的歸檔在應(yīng)用之后被刪除時(shí);
??????? ※ 當(dāng)接收到的歸檔所在磁盤損壞時(shí);
??? ● 當(dāng)存在多個(gè)物理standby 時(shí),F(xiàn)AL 機(jī)制會(huì)自動(dòng)嘗試從其它standby 服務(wù)器獲取丟失的歸檔文件。
??? SQL> select *from v$archive_gap;
?
??? SQL> SELECT NAME FROM V$ARCHIVED_LOG WHERE THREAD#=1 AND DEST_ID=1 ANDSEQUENCE# BETWEEN 7 AND 10;
??? 然后通過alter database register logfile 命令將這些文件重新注冊一下,例如:
??? SQL> ALTER DATABASE REGISTER LOGFILE 'e:\ora10g\jsspdg\xxxx.arc';
??? 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#;