化:從WAIT_FOR_LOG到standby redolog正確配置)
1. 項(xiàng)目背景與核心痛點(diǎn)為什么你的ADG總卡在WAIT_FOR_LOG先聊一個(gè)很多DBA都撞過的場(chǎng)景主庫業(yè)務(wù)量一上來ADG備庫的v$standby_log視圖里THREAD#組的狀態(tài)長期停在WAIT_FOR_LOG歸檔日志堆積如山主庫切換日志時(shí)備庫半天追不上甚至跑出GAP告警。這時(shí)候不少人第一反應(yīng)是“網(wǎng)絡(luò)帶寬不夠”或者“備庫磁盤太慢”吭哧吭哧調(diào)了半天網(wǎng)絡(luò)參數(shù)問題卻一點(diǎn)沒緩解。我早些年也干過類似的蠢事。有一次生產(chǎn)環(huán)境主庫頻繁log switch備庫延遲從幾十秒一路飆到四十分鐘查v$dataguard_stats看到transport lag不大但apply lag越拉越長。當(dāng)時(shí)第一直覺是備庫的DB_FILE_MULTIBLOCK_READ_COUNT或者PARALLEL_EXECUTION_MESSAGE_SIZE有問題調(diào)了一圈沒卵用。后來冷靜下來查了備庫的v$standby_log發(fā)現(xiàn)癥結(jié)根本不在這——備庫的standby redolog配置一塌糊涂組數(shù)不夠、大小不匹配MRP進(jìn)程大多數(shù)時(shí)間都在干等日志硬生生把ADG干成了“異步追趕模式”。這就是標(biāo)題里那個(gè)WAIT_FOR_LOG狀態(tài)的典型來源。ADG同步性能優(yōu)化很多時(shí)候拼的并不是網(wǎng)絡(luò)和硬件而是你有沒有把standby redolog這個(gè)最容易忽略的基礎(chǔ)配置搞對(duì)。這篇文章我會(huì)從standby redolog的底層機(jī)制講起把它的數(shù)量規(guī)劃、大小設(shè)計(jì)、狀態(tài)判斷、故障排查完整過一遍把我實(shí)際踩過的坑和驗(yàn)證過的優(yōu)化手段都寫出來。適合正在維護(hù)ADG環(huán)境的DBA、剛接手容災(zāi)項(xiàng)目的運(yùn)維同學(xué)以及那些被GAP告警搞得焦頭爛額的朋友們。2. 先把底層機(jī)制搞明白WAIT_FOR_LOG到底在等什么2.1 備庫日志應(yīng)用的基本鏈路要理解WAIT_FOR_LOG就得先清楚ADG備庫處理日志的完整鏈路。主庫每次log switch后LGWR或ARCH進(jìn)程把redo數(shù)據(jù)傳輸?shù)絺鋷靷鋷斓腞FSRemote File Server進(jìn)程負(fù)責(zé)接收然后寫入備庫的standby redolog或者直接寫歸檔日志。接下來MRPManaged Recovery Process從歸檔日志或者standby redolog里讀取redo記錄一層層應(yīng)用到數(shù)據(jù)文件。整個(gè)鏈條里備庫的MRP進(jìn)程是絕對(duì)的核心執(zhí)行者。MRP有兩種讀取模式從standby redolog直接讀取并應(yīng)用這種模式適合實(shí)時(shí)應(yīng)用REAL TIME APPLYredo一到備庫就能立刻被MRP消費(fèi)延遲最小。等待歸檔完成后從歸檔日志讀取通常是ARCHIVE_LAG_TARGET或者FAL機(jī)制觸發(fā)的備用路徑延遲會(huì)明顯更高。WAIT_FOR_LOG字面意思就是“MRP進(jìn)程正在等待新的redo數(shù)據(jù)到來”??此浦皇且粋€(gè)正常狀態(tài)但如果它長時(shí)間占據(jù)主導(dǎo)說明MRP大部分時(shí)間都在“歇著”真正干活的窗口很小apply lag自然居高不下。2.2 為什么會(huì)出現(xiàn)長時(shí)間WAIT_FOR_LOG從機(jī)制上看MRP等待日志的場(chǎng)景分為兩類一類是主庫確實(shí)沒有新日志產(chǎn)生這是健康的空閑等待另一類是主庫有日志產(chǎn)生但備庫因?yàn)榉N種原因一直拿不到、或者拿到了卻沒法立即應(yīng)用這種就是不健康的空轉(zhuǎn)。不健康空轉(zhuǎn)的常見原因我在實(shí)踐中總結(jié)成四個(gè)字供不應(yīng)求。具體來說standby redolog組數(shù)太少M(fèi)RP頻繁在“等待當(dāng)前組寫滿”和“等待下一組切換”之間來回橫跳。standby redolog大小和主庫redo不匹配備庫被迫頻繁切換每次切換都有額外開銷。備庫端的日志應(yīng)用速度跟不上主庫產(chǎn)生的速度典型瓶頸包括備庫IOPS、CPU、歸檔目錄所在的文件系統(tǒng)性能。備庫的STANDBY_FILE_MANAGEMENT設(shè)置不對(duì)導(dǎo)致日志應(yīng)用時(shí)陷入文件管理開銷。這里需要特別澄清一個(gè)誤區(qū)WAIT_FOR_LOG并不等于同步就在正常工作。同樣一個(gè)狀態(tài)名健康的空閑等待和病態(tài)的空轉(zhuǎn)等待表象一樣底層邏輯完全不同。判斷的關(guān)鍵就看主庫是不是在持續(xù)產(chǎn)生日志以及備庫是否有持續(xù)的RFS寫入行為。2.3 理解standby redolog在ADG中的角色很多從傳統(tǒng)Data Guard轉(zhuǎn)過來的DBA容易把standby redolog當(dāng)成“可選優(yōu)化項(xiàng)”覺得沒有它ADG也能跑。確實(shí)早期Data Guard確實(shí)可以不配standby redolog備庫只靠歸檔日志追進(jìn)度。但那是異步模式的舊世界了。在ADG環(huán)境中standby redolog幾乎可以說是一等公民。打個(gè)比方如果主庫redo是一輛輛駛來的集裝箱卡車那standby redolog就是備庫這邊的卸貨碼頭。沒有碼頭不配standby redolog卡車到了只能先停到遠(yuǎn)處停車場(chǎng)寫歸檔日志等MRP有空再去一趟一趟拉回來有了碼頭配好standby redolog卡車直接開進(jìn)碼頭卸貨MRP隨到隨取。你說哪個(gè)快而且standby redolog直接影響一個(gè)關(guān)鍵能力備庫實(shí)時(shí)應(yīng)用Real-Time Apply。只有配置了standby redologMRP才能做到邊收邊應(yīng)用否則就算你開了REAL TIME APPLY備庫也只能等歸檔完成后才動(dòng)手。3. 關(guān)鍵參數(shù)拆解standby redolog該怎么配才算“正確”3.1 組數(shù)規(guī)劃不是越多越好但要滿足切換需求關(guān)于standby redolog需要多少組Oracle官方文檔和大多數(shù)最佳實(shí)踐給的建議是“至少比主庫的redo log group多一組”。這個(gè)建議背后的邏輯其實(shí)是為了保證在極端切換場(chǎng)景下不出現(xiàn)寫堵塞。我解釋一下為什么需要“多一組”當(dāng)主庫某組redo寫滿準(zhǔn)備切換時(shí)RFS同時(shí)也可能正在往備庫的對(duì)應(yīng)standby redolog寫當(dāng)前日志。如果備庫只有和主庫數(shù)量相同的組那么當(dāng)主庫切換到下一組時(shí)備庫的上一組standby redolog可能正在被MRP讀取應(yīng)用此時(shí)這組還不能被RFS重用覆蓋于是RFS只能干等導(dǎo)致主庫的log switch也被拖慢甚至出現(xiàn)“主庫等備庫”的連鎖反應(yīng)。多出的一組好比是給系統(tǒng)多留了一個(gè)緩沖空位保證RFS寫當(dāng)前日志的那一組永遠(yuǎn)不會(huì)和MRP正在讀的那一組撞車。我自己在生產(chǎn)環(huán)境里一般會(huì)給備庫配置主庫組數(shù)2組的standby redolog留一點(diǎn)余量應(yīng)對(duì)突發(fā)切換。比如主庫4組redo備庫就建6組standby redolog。這樣即使主庫短時(shí)間內(nèi)連續(xù)多次切換備庫也始終能騰出空組給RFS寫。3.2 大小設(shè)計(jì)和主庫redo對(duì)齊是黃金法則standby redolog的大小設(shè)計(jì)很多人容易犯一個(gè)錯(cuò)隨手建一個(gè)固定大小比如全部256MB完全不管主庫redo有多大。我見過最典型的故障案例是主庫redo是2GB備庫standby redolog只有200MB結(jié)果RFS往備庫寫日志時(shí)頻繁觸發(fā)切換MRP根本來不及跟上apply lag一路暴漲。正確做法非常樸素讓備庫的standby redolog大小和主庫redo一致。這樣的好處在于主庫切換一次redo備庫正好也是切換一次standby redolog日志讀寫節(jié)奏完全同步不存在“這邊寫半組那邊就要切”的錯(cuò)位問題。當(dāng)然也有例外。如果主庫redo特別大比如8GB你又給備庫配了比較弱的存儲(chǔ)可以適當(dāng)縮小standby redolog大小讓備庫“少吃多餐”。但要注意小尺寸意味著更頻繁的日志切換會(huì)增加切換開銷需要權(quán)衡。3.3 文件分布不要把雞蛋放在一個(gè)籃子里standby redolog的文件存放位置同樣是一個(gè)容易被忽視但影響重大的配置點(diǎn)。我見過不少環(huán)境的standby redolog和datafile放在同一塊盤上甚至和歸檔日志放在同一個(gè)文件系統(tǒng)。起初看不出問題一旦主庫業(yè)務(wù)高峰來臨備庫同時(shí)要寫standby redolog、寫歸檔日志、還要讀數(shù)據(jù)文件做恢復(fù)所有IO請(qǐng)求全部擠在一塊磁盤上apply lag必然飆升。理想情況下standby redolog應(yīng)該放在獨(dú)立的、高性能的存儲(chǔ)路徑上至少也要和歸檔日志目錄分開。用ASM的話可以單獨(dú)規(guī)劃一個(gè)diskgroup放standby redolog。用文件系統(tǒng)的話最好放到單獨(dú)的裸設(shè)備或者SSD掛載點(diǎn)上。我還建議把同一個(gè)standby redolog組的兩個(gè)成員放到不同的物理磁盤上避免單盤故障導(dǎo)致整組不可用。這一點(diǎn)跟普通redolog的鏡像原則完全一致。3.4 添加standby redolog的具體操作以O(shè)racle 19c環(huán)境為例在備庫上添加standby redolog的標(biāo)準(zhǔn)做法如下。先查主庫redo狀態(tài)作為參照-- 主庫執(zhí)行 SELECT GROUP#, BYTES, STATUS FROM V$LOG ORDER BY GROUP#; SELECT GROUP#, BYTES, STATUS FROM V$LOG_HISTORY;然后在備庫上創(chuàng)建對(duì)應(yīng)的standby redolog-- 備庫執(zhí)行 ALTER DATABASE ADD STANDBY LOGFILE GROUP 10 (/u01/oradata/dgdb/stdredo10a.log, /u02/oradata/dgdb/stdredo10b.log) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 11 (/u01/oradata/dgdb/stdredo11a.log, /u02/oradata/dgdb/stdredo11b.log) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 12 (/u01/oradata/dgdb/stdredo12a.log, /u02/oradata/dgdb/stdredo12b.log) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 13 (/u01/oradata/dgdb/stdredo13a.log, /u02/oradata/dgdb/stdredo13b.log) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 14 (/u01/oradata/dgdb/stdredo14a.log, /u02/oradata/dgdb/stdredo14b.log) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 15 (/u01/oradata/dgdb/stdredo15a.log, /u02/oradata/dgdb/stdredo15b.log) SIZE 2G;注意幾點(diǎn)如果備庫使用了db_create_online_log_dest_n參數(shù)可以省略文件路徑直接用SIZE創(chuàng)建但為了可控性我建議顯式指定路徑。SIZE務(wù)必和主庫redo大小一致這是前面說的核心原則。如果你的備庫是Physical Standby且在MOUNT狀態(tài)直接執(zhí)行上述語句即可如果是OPEN狀態(tài)也可以在線添加不影響當(dāng)前同步。4. 實(shí)操過程實(shí)錄從配置到驗(yàn)證的一次完整優(yōu)化4.1 環(huán)境摸底動(dòng)手前先知道自己的家底在做任何優(yōu)化之前我會(huì)先花幾分鐘摸底環(huán)境把幾個(gè)關(guān)鍵視圖都掃一遍。這步看起來簡單但能幫你避免很多“瞎調(diào)”的彎路。主要是這幾個(gè)查詢-- 備庫查看standby redolog狀態(tài) SELECT GROUP#, THREAD#, SEQUENCE#, BYTES, USED, ARCHIVED, STATUS, FIRST_TIME, LAST_TIME FROM V$STANDBY_LOG; -- 備庫查看MRP進(jìn)程狀態(tài) SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY; -- 備庫查看同步延遲 SELECT NAME, VALUE, UNIT, TIME_COMPUTED FROM V$DATAGUARD_STATS WHERE NAME IN (transport lag, apply lag);重點(diǎn)看V$STANDBY_LOG的狀態(tài)列。正常情況下應(yīng)該有一組ACTIVE或CURRENT至少一組UNACTIVE可以隨時(shí)被覆蓋。如果看到所有組都處于ACTIVE狀態(tài)或者頻繁出現(xiàn)WRITING狀態(tài)卡住不動(dòng)就得好好排查了。把主庫redo信息拉出來做對(duì)比然后決定是否需要調(diào)整組大小或數(shù)量。4.2 模擬故障初始配置不當(dāng)?shù)奈:Ψ糯筮^程我之前在一個(gè)測(cè)試環(huán)境做過一次對(duì)照實(shí)驗(yàn)效果非常直觀這里分享給大家作為參考。測(cè)試環(huán)境是一臺(tái)兩節(jié)點(diǎn)的Data Guard物理備庫主庫redo是4組每組2GB。備庫初始配置了6組standby redolog但每組只有512MB。我用一個(gè)簡單的循環(huán)寫入模擬事務(wù)負(fù)載持續(xù)跑30分鐘觀察備庫狀態(tài)。結(jié)果前10分鐘就出問題了。由于standby redolog太小RFS寫日志的頻率比主庫redo切換頻繁得多MRP還沒把上一組的日志應(yīng)用完下一組又寫滿了。隨后V$STANDBY_LOG出現(xiàn)多組同時(shí)為ACTIVE的現(xiàn)象apply lag穩(wěn)步攀升10分鐘時(shí)已經(jīng)達(dá)到約5分鐘。到30分鐘時(shí)apply lag已經(jīng)漲到不可接受的20分鐘整個(gè)備庫實(shí)際上處于“持續(xù)追趕”模式。這個(gè)實(shí)驗(yàn)很好地說明了為什么“大小不匹配”會(huì)是頭號(hào)殺手——它直接打亂了RFS和MRP之間的協(xié)作節(jié)拍。4.3 調(diào)整配置按照正確規(guī)范重建standby redolog針對(duì)上述問題我按正確規(guī)范重建了standby redolog。步驟分三步走第一清理原來的小尺寸組-- 備庫執(zhí)行先確認(rèn)要?jiǎng)h除的組沒有被使用 ALTER DATABASE DROP STANDBY LOGFILE GROUP 10; ALTER DATABASE DROP STANDBY LOGFILE GROUP 11; -- 依此類推刪除所有不合適的組第二按照主庫redo大小重新創(chuàng)建2GB的組數(shù)量按“主庫組數(shù)2”來建ALTER DATABASE ADD STANDBY LOGFILE GROUP 10 (DATA, DG1) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 11 (DATA, DG1) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 12 (DATA, DG1) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 13 (DATA, DG1) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 14 (DATA, DG1) SIZE 2G; ALTER DATABASE ADD STANDBY LOGFILE GROUP 15 (DATA, DG1) SIZE 2G; -- 如果使用ASM建議把standby redolog單獨(dú)放一個(gè)diskgroup例如DGREDO ALTER DATABASE ADD STANDBY LOGFILE GROUP 10 (DGREDO) SIZE 2G;第三用前面提到的幾個(gè)查詢確認(rèn)新配置生效并檢查V$STANDBY_LOG狀態(tài)是否回到健康狀態(tài)。調(diào)整完成后我再次用同樣的負(fù)載跑了30分鐘。結(jié)果apply lag始終保持在秒級(jí)V$STANDBY_LOG里始終有一組UNACTIVE空位可以供RFS切換使用MRP進(jìn)程的STATUS顯示為APPLYING_LOG這才是ADG真正健康運(yùn)行的形態(tài)。4.4 性能驗(yàn)證優(yōu)化前后縱向?qū)Ρ葹榱俗尨蠹矣袀€(gè)直觀感受我把優(yōu)化前后的關(guān)鍵指標(biāo)整理成一張對(duì)比表指標(biāo)優(yōu)化前512MB/組優(yōu)化后2GB/組standby redolog組大小512MB2GB組數(shù)6組6組apply lag峰值20分鐘5秒MRP等待狀態(tài)WAIT_FOR_LOG長時(shí)間占優(yōu)APPLYING_LOG為主歸檔日志堆積有持續(xù)累積無能及時(shí)歸檔清空主庫log switch影響有延遲風(fēng)險(xiǎn)無明顯影響這個(gè)對(duì)比驗(yàn)證了一個(gè)核心結(jié)論在ADG同步性能優(yōu)化中standby redolog配置的正確性遠(yuǎn)遠(yuǎn)比加大帶寬、堆硬件重要得多。4.5 優(yōu)化后的日常監(jiān)控怎么判斷配置一直在“健康檔”配置完成不代表一勞永逸日常監(jiān)控仍然必不可少。我常用的監(jiān)控SQL有這幾條也都是網(wǎng)上各路Oracle老炮們總結(jié)出來的經(jīng)驗(yàn)實(shí)測(cè)很穩(wěn)-- 監(jiān)控standby redolog狀態(tài) SELECT GROUP#, STATUS, ARCHIVED, THREAD#, SEQUENCE# FROM V$STANDBY_LOG WHERE STATUS NOT IN (UNACTIVE, CURRENT); -- 監(jiān)控MRP進(jìn)程是否健康 SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY WHERE PROCESS LIKE MRP%; -- 監(jiān)控是否有歸檔GAP SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;如果V$ARCHIVE_GAP返回了記錄說明備庫已經(jīng)出現(xiàn)歸檔缺口需要盡快手動(dòng)補(bǔ)齊缺失的歸檔日志。熱詞里那個(gè)“adg顯示gap”大概率指的就是這里——V$ARCHIVE_GAP出現(xiàn)非空記錄或者V$DATAGUARD_STATS里的apply lag異常漲高。5. 常見問題速查表與獨(dú)家避坑經(jīng)驗(yàn)5.1 典型問題場(chǎng)景和排查方向我把自己和同行在ADG優(yōu)化中遇到的典型問題整理成一個(gè)速查表希望能幫大家少走彎路現(xiàn)象可能原因排查方法處理建議WAIT_FOR_LOG長時(shí)間占優(yōu)standby redolog數(shù)量不足查V$STANDBY_LOG狀態(tài)增加組數(shù)至少主庫組數(shù)1apply lag持續(xù)增長standby redolog大小太小對(duì)比主庫redo大小重建為與主庫redo一致的大小主庫log switch變慢備庫RFS寫日志阻塞查主庫alert日志、備庫RFS進(jìn)程檢查備庫存儲(chǔ)IO、網(wǎng)絡(luò)延遲V$ARCHIVE_GAP有記錄日志傳輸斷檔或備庫應(yīng)用太慢查V$ARCHIVE_GAP、V$DATAGUARD_STATS手動(dòng)補(bǔ)歸檔優(yōu)化應(yīng)用側(cè)配置備庫日志應(yīng)用突然變慢歸檔目錄所在磁盤IO瓶頸用iostat/dstat看磁盤利用率遷移歸檔日志到獨(dú)立磁盤或ASM多組standby redolog同時(shí)ACTIVE組數(shù)或大小配置與主庫不匹配查V$STANDBY_LOG調(diào)整組數(shù)和大小保證有空閑組5.2 我看過的幾次“經(jīng)典翻車”和對(duì)應(yīng)教訓(xùn)再分享幾個(gè)我親歷過的失敗案例每一個(gè)都是錢和時(shí)間買來的教訓(xùn)。第一個(gè)案例發(fā)生在某個(gè)業(yè)務(wù)大促前的容災(zāi)演練。開發(fā)同學(xué)在主庫跑了一套大數(shù)據(jù)清洗任務(wù)日志量猛增備庫V$DATAGUARD_STATS里的apply lag十分鐘內(nèi)漲到近一小時(shí)。當(dāng)時(shí)我查主庫網(wǎng)絡(luò)、帶寬、備庫CPU、內(nèi)存全部正常。后來才發(fā)現(xiàn)備庫的standby redolog是2組256MB而主庫redo是2GB。因?yàn)榇笮〔黄ヅ銻FS瘋狂切換MRP永遠(yuǎn)在追。這個(gè)教訓(xùn)讓我徹底明白了“大小對(duì)齊”是硬道理。第二個(gè)案例是備庫使用了存儲(chǔ)設(shè)備自帶的壓縮功能standby redolog寫在壓縮卷上。平時(shí)沒啥主庫一寫大事務(wù)RFS寫日志時(shí)壓縮CPU開銷飆升日志到達(dá)備庫的時(shí)間翻倍transport lag明明不大apply lag卻被拖高。雖然存儲(chǔ)壓縮的本意是省空間但在ADG這種對(duì)日志寫入時(shí)延高度敏感的場(chǎng)景里壓縮反而成了負(fù)優(yōu)化。后來我把standby redolog單獨(dú)放到非壓縮的卷上問題迎刃而解。第三個(gè)案例是備庫自動(dòng)刪除歸檔日志的腳本配置失誤。某個(gè)DBA為了省空間寫了個(gè)cron每小時(shí)刪掉3小時(shí)前的歸檔日志。正常情況下MRP早就應(yīng)用完了不會(huì)有什么影響。結(jié)果有一次主庫業(yè)務(wù)高峰MRP應(yīng)用速度跟不上3小時(shí)前的日志還沒應(yīng)用完就被刪了直接制造了一個(gè)巨大的GAP。最后只能全量重新同步備庫折騰了一整天才恢復(fù)。這個(gè)案例提醒我們歸檔日志保留策略必須給MRP留出足夠的緩沖余量不能只盯著磁盤空間。5.3 獨(dú)家避坑技巧我在日常維護(hù)中堅(jiān)持的幾條原則這幾條原則不算什么官方文檔里的大道理純粹是我自己在生產(chǎn)環(huán)境中反復(fù)驗(yàn)證后形成的肌肉記憶分享給大家參考第一永遠(yuǎn)不要通過“臨時(shí)加一組大的standby redolog”來解決問題。組大小不一致會(huì)帶來管理混亂而且下次調(diào)整時(shí)很容易遺漏。要么一次性統(tǒng)一要么干脆推倒重來。第二添加或刪除standby redolog時(shí)盡量在備庫處于較空閑時(shí)操作。雖然支持在線操作但如果正好趕上主庫大日志量備庫的RFS寫日志會(huì)被文件操作短暫阻塞可能引發(fā)不必要的log switch延遲。第三定期檢查V$STANDBY_LOG的空閑組數(shù)量。我每周會(huì)跑一次巡檢腳本重點(diǎn)關(guān)注STATUS為UNACTIVE的組數(shù)是否小于2。如果小于2說明緩沖余量已經(jīng)告急需要盡快介入。第四主庫redo大小調(diào)整時(shí)同步評(píng)估備庫standby redolog。很多企業(yè)會(huì)在主庫做redo resize優(yōu)化卻忘了同步改備庫的standby redolog結(jié)果主庫redo從512MB調(diào)到2GB備庫還停在512MB同步性能瞬間退化。這是一條非常容易踩的聯(lián)動(dòng)坑。6. 影響范圍分析正確配置standby redolog能帶來什么6.1 對(duì)同步延遲的直接改善這是最直觀的收益。正確配置后WAIT_FOR_LOG不再是病態(tài)的空轉(zhuǎn)MRP能持續(xù)處于APPLYING_LOG狀態(tài)apply lag可以被壓到秒級(jí)甚至亞秒級(jí)。我們實(shí)測(cè)中優(yōu)化前備庫apply lag經(jīng)常在5到30分鐘之間波動(dòng)優(yōu)化后穩(wěn)定在2到3秒以內(nèi)。對(duì)于金融、電商這類對(duì)RPO有嚴(yán)格要求的場(chǎng)景這個(gè)差距就是“容災(zāi)可用”和“容災(zāi)不可用”的區(qū)別。6.2 對(duì)主庫性能的間接保護(hù)很多人沒意識(shí)到備庫standby redolog配置不合理不僅影響備庫自身還可能反過來拖累主庫。當(dāng)RFS在備庫寫日志受阻時(shí)主庫的LGWR可能被迫等待備庫的ACK特別是SYNC模式導(dǎo)致主庫事務(wù)提交延遲上升。我在一個(gè)SYNC模式的ADG環(huán)境里就見過這種現(xiàn)象。備庫standby redolog偏小RFS頻繁切換主庫log file sync等待事件飆升業(yè)務(wù)側(cè)反映寫入變慢。把備庫standby redolog改大并增加組數(shù)后主庫log file sync等待立刻回落。ADG是雙向聯(lián)動(dòng)的備庫的配置直接影響主庫的健康度。6.3 對(duì)GAP和容災(zāi)演練的影響standby redolog配置正確后V$ARCHIVE_GAP的出現(xiàn)概率會(huì)顯著降低。因?yàn)镸RP始終在實(shí)時(shí)應(yīng)用主庫切換產(chǎn)生的新日志很快被備庫消費(fèi)歸檔日志的產(chǎn)生和刪除節(jié)奏也趨于平滑不太會(huì)因?yàn)閭鋷旆e壓太多未應(yīng)用日志而出現(xiàn)缺口。容災(zāi)演練的時(shí)候正確配置的收益更是肉眼可見。之前我們做一次主備切換演練從主庫SWITCHOVER到備庫接管業(yè)務(wù)全程只用了兩三分鐘備庫幾乎沒有丟任何日志。而配置不合理的時(shí)候同樣的演練可能要花十幾分鐘甚至更久中途還得處理歸檔補(bǔ)齊的麻煩事。6.4 對(duì)運(yùn)維成本的影響配置正確的ADG環(huán)境日常運(yùn)維會(huì)輕松很多。apply lag監(jiān)控不報(bào)警了歸檔日志堆積問題少了GAP告警也不再三天兩頭出現(xiàn)。省下來的精力可以投入到更重要的容量規(guī)劃和架構(gòu)優(yōu)化上。當(dāng)然正確配置只是第一步后續(xù)還需要持續(xù)的監(jiān)控和巡檢。但從投入產(chǎn)出比來看把standby redolog這個(gè)基礎(chǔ)打牢絕對(duì)是ADG運(yùn)維里性價(jià)比最高的一筆投資。7. 寫在最后的幾點(diǎn)實(shí)操感悟這些年在ADG環(huán)境上踩過的坑讓我對(duì)同步性能優(yōu)化有一個(gè)很深的體會(huì)大多數(shù)ADG性能問題都不是“高級(jí)技巧不夠”而是“基礎(chǔ)配置不達(dá)標(biāo)”。網(wǎng)絡(luò)再快、硬件再強(qiáng)如果standby redolog的組數(shù)、大小、分布不對(duì)所有流量都會(huì)堵在備庫這個(gè)“窄口”上。我自己現(xiàn)在接手任何一套ADG環(huán)境第一件事永遠(yuǎn)是先查V$STANDBY_LOG看組數(shù)和大小是否與主庫匹配再看有沒有足夠多的空閑組。這兩步只要達(dá)標(biāo)后面的同步性能優(yōu)化基本就成功了一半。如果這兩步不達(dá)標(biāo)就算你后面調(diào)再多的PARALLEL_EXECUTION_MESSAGE_SIZE、DB_FILE_MULTIBLOCK_READ_COUNT參數(shù)也都是在沙地上蓋樓。最后再分享一個(gè)小技巧如果你在備庫執(zhí)行ALTER DATABASE ADD STANDBY LOGFILE時(shí)報(bào)ORA-00314或者ORA-00315這類錯(cuò)誤多半是文件路徑下有殘留的舊日志文件。先把舊文件清掉或者在備份目錄確認(rèn)沒有活動(dòng)成員引用了同名文件再重新添加就能解決。這個(gè)坑很小但碰到的時(shí)候挺折騰人提前寫在這里供大家參考。