Data Guard 環境下打 CPU/PSU 補丁比單實例複雜得多:必須 Primary/Standby 雙端同步打補丁,且涉及 Redo 傳輸暫停/恢復、密碼檔同步、補丁腳本自動同步驗證等關鍵步驟。一步錯誤可能導致備庫無法跟上、主備不一致甚至主庫掛起。本文提供經過生產驗證的標準化操作流程、關鍵風險點規避與驗證腳本。
SYS@PRIMARY> SELECT database_role FROM v$database; -- 確認 PRIMARY
SYS@PRIMARY> SHOW PARAMETER log_archive_dest_3; -- 確認目標 Standby DEST_ID
SYS@PRIMARY> ALTER SYSTEM SET log_archive_dest_state_3=DEFER SCOPE=BOTH;
System altered.
關鍵點:使用 SCOPE=BOTH 確保內存與 SPFILE 同步生效,避免重啟後恢復傳輸。
# 2.1 關閉實例、監聽、ASM (若獨立)
srvctl stop database -d stdby_db
srvctl stop listener -l listener_stdby
# 若 ASM 獨立: srvctl stop asm
# 2.2 檢查/升級 OPatch 版本 (建議最新)
$ORACLE_HOME/OPatch/opatch version
# 2.3 執行軟件補丁 (以 11.2.0.4 PSU 為例)
cd /patch/11.2.0.4/PSU/XXXXXXXX
$ORACLE_HOME/OPatch/opatch apply
# 2.4 啟動 Standby 至 MOUNT,啟動監聽
srvctl start database -d stdby_db -o mount
srvctl start listener -l listener_stdby
> ⚠️ 鐵律:Standby 絕不執行 @catbundle.sql psu apply!數據庫層面補丁由 Primary 端 Redo 同步自動應用。
# 3.1 關閉 Primary 實例、監聽、ASM
srvctl stop database -d prim_db
srvctl stop listener -l listener_prim
# ASM 同前
# 3.2 檢查/升級 OPatch
$ORACLE_HOME/OPatch/opatch version
# 3.3 打軟件補丁
cd /patch/11.2.0.4/PSU/XXXXXXXX
$ORACLE_HOME/OPatch/opatch apply
# 3.4 打數據庫補丁 (核心步驟)
cd $ORACLE_HOME/rdbms/admin
sqlplus /nolog
SQL> CONNECT / AS SYSDBA
SQL> STARTUP
SQL> @catbundle.sql psu apply
SQL> QUIT
catbundle.sql 關鍵作用:更新數據庫字典視圖、PL/SQL 包、Java 類、權限等元數據,產生 Redo 記錄,後續將同步至 Standby。
# 4.1 啟動 Primary 監聽、實例
srvctl start listener -l listener_prim
srvctl start database -d prim_db
# 4.2 強制註冊服務到監聽 (解決動態註冊延遲)
SYS@PRIMARY> ALTER SYSTEM REGISTER;
# 4.3 重新啟用 Redo 傳輸
SYS@PRIMARY> ALTER SYSTEM SET log_archive_dest_state_3=ENABLE SCOPE=BOTH;
Alert Log 錯誤:
Check that the primary and standby are using a password file
and remote_login_passwordfile is set to SHARED or EXCLUSIVE,
and that the SYS password is same in the password files.
returning error ORA-16191
根因:@catbundle.sql 可能重置 SYS 密碼,導致主備密碼檔不一致。
解決:
# Primary 端備份密碼檔並複製至 Standby
scp $ORACLE_HOME/dbs/orapwPRIM_DB oracle@standby_host:$ORACLE_HOME/dbs/orapwSTDBY_DB
# Standby 端重啟實例使生效 (若在 MOUNT 狀態)
srvctl stop database -d stdby_db
srvctl start database -d stdby_db -o mount
# 6.1 啟動 Redo Apply (非 Real-time Apply)
SYS@STDBY> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
Database altered.
# 6.2 驗證歸檔同步
SYS@PRIMARY> SELECT MAX(sequence#) FROM v$archived_log; -- 159
SYS@STDBY> SELECT sequence#, applied FROM v$archived_log WHERE sequence# >= 157;
Alert Log 關鍵標誌**:
Media Recovery Log /data/oradata/epay/archivelog/1_157_814716635.dbf
Media Recovery Log /data/oradata/epay/archivelog/1_158_814716635.dbf
Media Recovery Log /data/oradata/epay/archivelog/1_159_814716635.dbf
Media Recovery Waiting for thread 1 sequence 160 (in transit)
出現 Waiting for thread 1 sequence 160 (in transit) 表示同步完成,Standby 已應用 Primary 打補丁產生的 Redo (通常 3-5 個歸檔)。
# 7.1 軟件層面驗證
$ORACLE_HOME/OPatch/opatch lsinventory | grep -i "patch\|psu"
# 7.2 數據庫層面驗證
SYS@PRIMARY> SELECT * FROM dba_registry_history WHERE bundle_series = 'PSU' ORDER BY action_time DESC;
SYS@STDBY> SELECT * FROM dba_registry_history WHERE bundle_series = 'PSU' ORDER BY action_time DESC;
# 7.3 關鍵視圖版本一致性
SYS@PRIMARY> SELECT version FROM v$instance;
SYS@STDBY> SELECT version FROM v$instance;
OPatch 支援 RAC rolling$ORACLE_HOME/OPatch/datapatch -verbose 替代 catbundle.sql# 軟件補丁回滾
$ORACLE_HOME/OPatch/opatch rollback -id XXXXXXXX
# 數據庫補丁回滾 (極其罕見,需 Oracle 支援配合)
-- 通常通過恢復 RMAN 備份實現時間點恢復
-- 或重建 Standby 從 Primary 同步
| 關鍵點 | 風險等級 | 驗證方式 |
|---|---|---|
| Standby 僅打軟件補丁,不打 catbundle.sql | 🔴 致命 | 檢查 Alert Log 無數據庫補丁記錄 |
| Primary 打完 catbundle.sql 後才啟用傳輸 | 🔴 致命 | 確認 dba_registry_history 有新記錄 |
| 密碼檔主備同步 (ORA-16191 預防) | 🟠 高危 | scp 密碼檔 + 重啟 Standby |
| Standby Apply 追上 Primary 產生的補丁 Redo | 🟠 高危 | Alert Log 出現 "Waiting for thread N sequence M (in transit)" |
| 雙端 opatch lsinventory + dba_registry_history 一致 | 🟢 必做 | 腳本自動化對比 |
Data Guard 補丁安裝的核心邏輯是:Standby 先備好環境,Primary 產生變更 Redo,Standby Apply 重放變更。嚴守「軟件先行、數據庫後行、傳輸中斷、同步驗證」八字原則,配合標準化腳本與檢查清單,即可實現零事故補丁部署。