Oracle DBA - Data Guard / Disaster Recovery
Physical-standby Data Guard for Oracle 19c and 23ai, Enterprise Edition,
single-instance and Data Guard, on-prem. In-DB SQL runs through the SQLcl MCP
server on the saved connection dba_ai_conn (wallet). Host tools
(dgmgrl, rman, srvctl, sqlplus) cannot go through the SQLcl MCP server
(it is in-DB only) - they run from a shell via a script or a runbook, and would
later front a guarded oracle-dba-ops MCP.
Scope & risk map
Every task in this domain (both authoring halves), with its self-execute tier
and the exact mechanism. T1 = read-only/observe (self-executes freely);
T2 = reversible (self-executes only with --dry-run default + explicit
--execute); T3 = destructive / role-change / structural (runbook-only +
require_approval_token, NEVER self-executes).
| Task |
Level |
Tier |
Mechanism (path) |
Idempotent? |
| Data Guard status / health snapshot |
L1 |
T1 |
script:scripts/dg_status.sh / scripts/dg_status.ps1 (db|broker|all) + sqlcl-mcp:sql/dg_status.sql |
yes (read-only) |
| Apply + transport lag report |
L1 |
T1 |
sqlcl-mcp:sql/dg_lag_monitor.sql; tighter pre-role-change: sql/dg_apply_lag.sql |
yes (read-only) |
| Standby Redo Apply (MRP) status |
L1 |
T1 |
sqlcl-mcp:sql/standby_apply_status.sql |
yes (read-only) |
| DG readiness PASS/FAIL inventory |
L1 |
T1 |
sqlcl-mcp:sql/dg_config_check.sql |
yes (read-only) |
| Archive / redo gap detection |
L1 |
T1 |
sqlcl-mcp:sql/archive_gap_detect.sql; wrapper: scripts/archive_gap_resolution.{sh,ps1} detect |
yes (read-only) |
| Archive / redo gap nudge (restart apply -> FAL refetch) |
L2 |
T2 |
script:scripts/archive_gap_resolution.{sh,ps1} nudge |
yes (no gap -> noop) |
| Standby redo log (SRL) assessment |
L1 |
T1 |
sqlcl-mcp:sql/standby_redo_assess.sql; wrapper: scripts/standby_redo_management.{sh,ps1} assess |
yes (read-only) |
| Add a standby redo log group |
L2 |
T2 |
script:scripts/standby_redo_management.{sh,ps1} add; in-DB DDL: sql/standby_redo_add.sql |
yes (group exists -> noop) |
| DG broker - show configuration |
L1 |
T1 |
script:scripts/dg_broker_config.{sh,ps1} show |
yes (read-only) |
| DG broker - set (safe) property / enable config |
L2 |
T2 |
script:scripts/dg_broker_config.{sh,ps1} set|enable (refuses FSFO/protection props -> runbook) |
yes (already-set -> noop) |
| FSFO observer - status |
L1 |
T1 |
script:scripts/dg_observer.{sh,ps1} status |
yes (read-only) |
| FSFO observer - start / stop |
L2 |
T2 |
script:scripts/dg_observer.{sh,ps1} start|stop |
yes (already running/stopped -> noop) |
| Active Data Guard - open-mode toggle |
L2 |
T2 |
script:scripts/active_data_guard.{sh,ps1} enable|disable; in-DB: sql/active_dg_enable.sql / sql/active_dg_disable.sql |
yes (already-in-state -> noop) |
| Data Guard setup / configuration |
L3 |
T3 |
runbook:references/runbooks.md#dg-setup (T1 assess via sql/dg_config_check.sql, sql/dg_status.sql) |
n/a (human-gated; setup is additive/reversible) |
| Failover operation (+ switchover branch) |
L3 |
T3 |
runbook:references/runbooks.md#failover (pre-loss assess: sql/dg_apply_lag.sql) |
n/a (one-way role change) |
| Reinstate failed primary |
L3 |
T3 |
runbook:references/runbooks.md#reinstate (verify: sql/dg_status.sql) |
n/a (recovery op) |
| Standby database build / rebuild |
L3 |
T3 |
runbook:references/runbooks.md#standby-build (prereq: sql/dg_config_check.sql) |
n/a (structural; overwrites on rebuild) |
| Active Data Guard - architecture (Far Sync, cascade, DML redirect, licensing) |
L3 |
T3 |
runbook:references/runbooks.md#active-dg (toggle handled by the T2 script above) |
n/a (architecture/licensing) |
| Fast-Start Failover (FSFO) configuration |
L3 |
T3 |
runbook:references/runbooks.md#fsfo (observer start/stop is the T2 dg_observer script) |
n/a (HA automation config) |
| Snapshot standby conversion |
L3 |
T3 |
runbook:references/runbooks.md#snapshot-standby |
n/a (conversion is its own reverse) |
| Cascaded standby setup |
L3 |
T3 |
runbook:references/runbooks.md#cascaded-standby |
n/a (multi-tier topology) |
Routing note for the T2 helper scripts. archive_gap_resolution,
dg_broker_config, and dg_observer deliberately STOP and route to a runbook
when a request crosses into T3. Manual RMAN restore/catalog of missing archived
logs or an incremental-SCN roll-forward escalates to #standby-build /
#reinstate. A broker property that alters failover/protection posture
(FastStartFailover*, *Protection*) or ENABLE FAST_START FAILOVER
escalates to #fsfo. Switchover/failover escalate to #failover. These
scripts refuse those operations rather than self-executing them.
Preconditions
- SQLcl MCP connection
dba_ai_conn reachable and wallet-backed. It is NOT
SYS/SYSTEM; the in-DB DDL paths (standby_redo_add.sql, the Active DG toggle,
the gap nudge) require the dba_ai_conn user to hold ALTER DATABASE, granted
out of band per site policy. SYSDBA is used ONLY inside a T3 runbook, supplied
interactively by the operator - never the default, never auto.
- Secrets resolve from the Oracle Wallet / external password store only. No
plaintext in argv, env, or files.
dgmgrl/rman connect with / (OS auth) or
a wallet-backed alias; every host script refuses a user/pass@db or
password= connect identifier (EX_SECRET=8). The redo-transport (SYS)
password is propagated by copying the password file, never by typing it.
- Helpers sourced from
_common/scripts/lib.sh / lib.ps1
(connect_db/Connect-Db, log_event, emit_metric, require_dry_run,
require_approval_token, precheck/postcheck, print_banner). Scripts do
not reinvent them.
- Canonical logs: Linux
/var/log/oracle-dba/data-guard/data-guard.log;
Windows C:/ProgramData/oracle-dba/logs/data-guard/data-guard.log.
- Run the read-only assessment first. Before ANY T2/T3 action, capture role,
open_mode, protection mode, apply/transport lag, and gaps with
scripts/dg_status.{sh,ps1} all + sql/dg_config_check.sql. Recovering or
transitioning the wrong database is the classic Data Guard catastrophe.
- Version: works on 19c and 23ai (23ai is CDB-only; DG operates at the CDB
level, PDBs follow the CDB role). Deltas in
references/version-notes.md.
Procedures
Each procedure: Trigger -> Precheck -> Action -> Postcheck -> Rollback.
Read-only assessment (dg_status, the lag/apply/gap/SRL/config-check SQL) has no
precheck/rollback beyond "it changes nothing" and is run freely; the entries
below cover the acting (T2) and gated (T3) tasks.
T1 - observe (self-execute freely, read-only)
- DG status / lag / apply / gaps / SRL / readiness. Trigger: any "how is DR /
the standby doing" question, or as the mandatory first step before a change.
Action:
scripts/dg_status.{sh,ps1} [db|broker|all], and via dba_ai_conn
sql/dg_status.sql, sql/dg_lag_monitor.sql, sql/dg_apply_lag.sql,
sql/standby_apply_status.sql, sql/archive_gap_detect.sql,
sql/standby_redo_assess.sql, sql/dg_config_check.sql. Postcheck: n/a (these
ARE the check). Rollback: none (no changes made).
T2 - reversible (dry-run default; --execute to act; idempotent)
- Archive/redo gap nudge. Trigger:
archive_gap_detect shows a gap on a
standby and you want to prod automatic FAL re-fetch without destructive
recovery. Precheck: must be a PHYSICAL STANDBY; gap_count>0 (else noop).
Action: scripts/archive_gap_resolution.{sh,ps1} nudge --execute (cancels then
restarts Redo Apply with real-time apply). Postcheck: MRP running again.
Rollback: apply simply continues; nothing destroyed. If the gap persists,
escalate to references/runbooks.md#standby-build (manual restore/roll-forward).
- Add a standby redo log group. Trigger:
standby_redo_assess /
dg_config_check flags too few or wrong-sized SRLs. Precheck: group not already
present (else noop). Action: scripts/standby_redo_management.{sh,ps1} add --group N --thread T --bytes B --member PATH --execute (in-DB DDL in
sql/standby_redo_add.sql). Postcheck: group present and sized. Rollback: a
quiescent SRL can be dropped (ALTER DATABASE DROP STANDBY LOGFILE GROUP N).
- DG broker set / enable. Trigger: adjust a safe broker property
(e.g.
LogXptMode, DelayMins) or ENABLE the configuration/a member.
Precheck: property already at desired value / config already SUCCESS -> noop;
FSFO/protection properties are refused (-> #fsfo). Action:
scripts/dg_broker_config.{sh,ps1} set --property .. --value .. --member .. --execute
or ... enable [--member ..] --execute. Postcheck: property reads back /
status SUCCESS. Rollback: re-EDIT ... SET PROPERTY to the prior value;
DISABLE the member/config.
- FSFO observer start / stop. Trigger: bring up / take down the observer
process (NOT enabling FSFO). Precheck: observer already running for this config
/ already stopped -> noop; refuses to enable FSFO. Action:
scripts/dg_observer.{sh,ps1} start --config-file PATH [--name N] --execute /
... stop [--name N] --execute. Postcheck: SHOW OBSERVER state matches.
Rollback: stop reverses start (observer changes nothing in the databases).
- Active Data Guard open-mode toggle. Trigger: open a healthy physical standby
READ ONLY WITH APPLY (real-time query) or revert it to MOUNTED + managed
recovery. Precheck: role = PHYSICAL STANDBY; already in target open_mode -> noop.
Action:
scripts/active_data_guard.{sh,ps1} enable --execute /
... disable --execute (in-DB: sql/active_dg_enable.sql /
sql/active_dg_disable.sql). Postcheck: open_mode is the intended state.
Rollback: disable reverses enable and vice-versa (fully reversible).
Licensing/Far Sync/cascade/DML-redirect architecture is T3 -> #active-dg.
T3 - destructive / role-change / structural (runbook-only; never self-executes)
For each: Trigger -> Precheck (read-only readiness report) -> Action (PRINT the
runbook, obtain approval token, operator runs the commands by hand) -> Postcheck
(verify in the runbook) -> Rollback (in the runbook). Precheck for ALL of these is
scripts/dg_status.{sh,ps1} all + sql/dg_config_check.sql on both sites.
- Data Guard setup ->
references/runbooks.md#dg-setup. Rollback: additive;
DISABLE/REMOVE CONFIGURATION + revert log_archive_* params.
- Failover (and switchover decision branch) ->
references/runbooks.md#failover.
Rollback: no in-place undo after FAILOVER - reinstate or rebuild the old primary;
before issuing FAILOVER, prefer a reversible switchover if the primary is alive.
- Reinstate failed primary ->
references/runbooks.md#reinstate. Rollback: if
flashback can't reach standby_became_primary_scn, abandon and rebuild.
- Standby build / rebuild ->
references/runbooks.md#standby-build. Rollback:
new build doesn't touch the primary; rebuild intentionally overwrites the target.
- Active Data Guard architecture ->
references/runbooks.md#active-dg.
Rollback: the open-mode part is the reversible T2 script above; remove Far Sync /
reset RedoRoutes.
- Fast-Start Failover (FSFO) ->
references/runbooks.md#fsfo. Rollback:
DISABLE FAST_START FAILOVER + STOP OBSERVER; revert protection mode.
- Snapshot standby conversion ->
references/runbooks.md#snapshot-standby.
Rollback: the convert-back IS the reverse (discards interim RW changes via the
auto guaranteed restore point - do not drop it).
- Cascaded standby ->
references/runbooks.md#cascaded-standby. Rollback:
DEFER/clear the forwarding dest (or remove cascade RedoRoutes); narrow
DG_CONFIG; drop tier-2 files.
Tier-3 runbooks
See references/runbooks.md. Every section there is TIER 3: it PRINTS exact
commands for a human operator (both broker dgmgrl and manual ALTER DATABASE
paths, for 19c and 23ai) and NEVER self-executes. Each is gated by
require_approval_token (a real change ticket; placeholders rejected,
EX_APPROVAL=6) and carries a pre-flight checklist, diagnostics, explicit
verification, and a rollback/abort path. An automated agent's only sanctioned
action there is to print the relevant section and stop until a human supplies a
valid token. When in doubt, runbook.
1---2name: oracle-dba-data-guard-disaster-recovery3description: USE THIS SKILL for ANY Oracle Data Guard / standby / disaster-recovery / HA request - EVEN IF the user does not name the task. Triggers: physical/standby database, redo transport & apply, apply/transport LAG, archive/redo GAP, switchover, FAILOVER, reinstate failed primary, standby build/rebuild (RMAN active duplicate), Active Data Guard / real-time query / DML redirect, Fast-Start Failover (FSFO) + observer, snapshot standby, cascaded standby, Data Guard broker (dgmgrl), protection modes (Max Protection/Availability/ Performance), Far Sync, role-based services. Symptoms: "standby is behind", "apply stopped", "MRP not running", "redo not shipping", "lost the primary", "DR site", "promote standby". Error codes: ORA-16xxx broker/DG family (ORA-16700/16766/16778/16789/16809/16810/16664/16661 reinstate, ORA-16143/16131), ORA-01153, ORA-19909 (standby_became_primary), ORA-00752, RMAN-05xxx during DUPLICATE ... FOR STANDBY, CRS-xxxx when srvctl relocates DG services. Follows oracle-dba-common contracts: in-DB work 4---5# Oracle DBA - Data Guard / Disaster Recovery67Physical-standby Data Guard for Oracle **19c and 23ai**, Enterprise Edition,8single-instance and Data Guard, on-prem. In-DB SQL runs through the SQLcl MCP9server on the saved connection **`dba_ai_conn`** (wallet). Host tools10(`dgmgrl`, `rman`, `srvctl`, `sqlplus`) cannot go through the SQLcl MCP server11(it is in-DB only) - they run from a shell via a script or a runbook, and would12later front a guarded `oracle-dba-ops` MCP.1314## Scope & risk map1516Every task in this domain (both authoring halves), with its self-execute tier17and the exact mechanism. T1 = read-only/observe (self-executes freely);18T2 = reversible (self-executes only with `--dry-run` default + explicit19`--execute`); T3 = destructive / role-change / structural (runbook-only +20`require_approval_token`, NEVER self-executes).2122| Task | Level | Tier | Mechanism (path) | Idempotent? |23|------|-------|------|------------------|-------------|24| Data Guard status / health snapshot | L1 | T1 | script:`scripts/dg_status.sh` / `scripts/dg_status.ps1` (db\|broker\|all) + sqlcl-mcp:`sql/dg_status.sql` | yes (read-only) |25| Apply + transport lag report | L1 | T1 | sqlcl-mcp:`sql/dg_lag_monitor.sql`; tighter pre-role-change: `sql/dg_apply_lag.sql` | yes (read-only) |26| Standby Redo Apply (MRP) status | L1 | T1 | sqlcl-mcp:`sql/standby_apply_status.sql` | yes (read-only) |27| DG readiness PASS/FAIL inventory | L1 | T1 | sqlcl-mcp:`sql/dg_config_check.sql` | yes (read-only) |28| Archive / redo gap detection | L1 | T1 | sqlcl-mcp:`sql/archive_gap_detect.sql`; wrapper: `scripts/archive_gap_resolution.{sh,ps1} detect` | yes (read-only) |29| Archive / redo gap nudge (restart apply -> FAL refetch) | L2 | T2 | script:`scripts/archive_gap_resolution.{sh,ps1} nudge` | yes (no gap -> noop) |30| Standby redo log (SRL) assessment | L1 | T1 | sqlcl-mcp:`sql/standby_redo_assess.sql`; wrapper: `scripts/standby_redo_management.{sh,ps1} assess` | yes (read-only) |31| Add a standby redo log group | L2 | T2 | script:`scripts/standby_redo_management.{sh,ps1} add`; in-DB DDL: `sql/standby_redo_add.sql` | yes (group exists -> noop) |32| DG broker - show configuration | L1 | T1 | script:`scripts/dg_broker_config.{sh,ps1} show` | yes (read-only) |33| DG broker - set (safe) property / enable config | L2 | T2 | script:`scripts/dg_broker_config.{sh,ps1} set\|enable` (refuses FSFO/protection props -> runbook) | yes (already-set -> noop) |34| FSFO observer - status | L1 | T1 | script:`scripts/dg_observer.{sh,ps1} status` | yes (read-only) |35| FSFO observer - start / stop | L2 | T2 | script:`scripts/dg_observer.{sh,ps1} start\|stop` | yes (already running/stopped -> noop) |36| Active Data Guard - open-mode toggle | L2 | T2 | script:`scripts/active_data_guard.{sh,ps1} enable\|disable`; in-DB: `sql/active_dg_enable.sql` / `sql/active_dg_disable.sql` | yes (already-in-state -> noop) |37| Data Guard setup / configuration | L3 | T3 | runbook:`references/runbooks.md#dg-setup` (T1 assess via `sql/dg_config_check.sql`, `sql/dg_status.sql`) | n/a (human-gated; setup is additive/reversible) |38| Failover operation (+ switchover branch) | L3 | T3 | runbook:`references/runbooks.md#failover` (pre-loss assess: `sql/dg_apply_lag.sql`) | n/a (one-way role change) |39| Reinstate failed primary | L3 | T3 | runbook:`references/runbooks.md#reinstate` (verify: `sql/dg_status.sql`) | n/a (recovery op) |40| Standby database build / rebuild | L3 | T3 | runbook:`references/runbooks.md#standby-build` (prereq: `sql/dg_config_check.sql`) | n/a (structural; overwrites on rebuild) |41| Active Data Guard - architecture (Far Sync, cascade, DML redirect, licensing) | L3 | T3 | runbook:`references/runbooks.md#active-dg` (toggle handled by the T2 script above) | n/a (architecture/licensing) |42| Fast-Start Failover (FSFO) configuration | L3 | T3 | runbook:`references/runbooks.md#fsfo` (observer start/stop is the T2 `dg_observer` script) | n/a (HA automation config) |43| Snapshot standby conversion | L3 | T3 | runbook:`references/runbooks.md#snapshot-standby` | n/a (conversion is its own reverse) |44| Cascaded standby setup | L3 | T3 | runbook:`references/runbooks.md#cascaded-standby` | n/a (multi-tier topology) |4546> **Routing note for the T2 helper scripts.** `archive_gap_resolution`,47> `dg_broker_config`, and `dg_observer` deliberately STOP and route to a runbook48> when a request crosses into T3. Manual RMAN restore/catalog of missing archived49> logs or an incremental-SCN roll-forward escalates to `#standby-build` /50> `#reinstate`. A broker property that alters failover/protection posture51> (`FastStartFailover*`, `*Protection*`) or `ENABLE FAST_START FAILOVER`52> escalates to `#fsfo`. Switchover/failover escalate to `#failover`. These53> scripts refuse those operations rather than self-executing them.5455## Preconditions56- **SQLcl MCP connection `dba_ai_conn`** reachable and wallet-backed. It is NOT57 SYS/SYSTEM; the in-DB DDL paths (`standby_redo_add.sql`, the Active DG toggle,58 the gap nudge) require the `dba_ai_conn` user to hold `ALTER DATABASE`, granted59 out of band per site policy. SYSDBA is used ONLY inside a T3 runbook, supplied60 interactively by the operator - never the default, never auto.61- **Secrets resolve from the Oracle Wallet / external password store** only. No62 plaintext in argv, env, or files. `dgmgrl`/`rman` connect with `/` (OS auth) or63 a wallet-backed alias; every host script refuses a `user/pass@db` or64 `password=` connect identifier (`EX_SECRET`=8). The redo-transport (SYS)65 password is propagated by copying the password file, never by typing it.66- **Helpers** sourced from `_common/scripts/lib.sh` / `lib.ps1`67 (`connect_db`/`Connect-Db`, `log_event`, `emit_metric`, `require_dry_run`,68 `require_approval_token`, `precheck`/`postcheck`, `print_banner`). Scripts do69 not reinvent them.70- **Canonical logs**: Linux `/var/log/oracle-dba/data-guard/data-guard.log`;71 Windows `C:/ProgramData/oracle-dba/logs/data-guard/data-guard.log`.72- **Run the read-only assessment first.** Before ANY T2/T3 action, capture role,73 open_mode, protection mode, apply/transport lag, and gaps with74 `scripts/dg_status.{sh,ps1} all` + `sql/dg_config_check.sql`. Recovering or75 transitioning the wrong database is the classic Data Guard catastrophe.76- **Version**: works on 19c and 23ai (23ai is CDB-only; DG operates at the CDB77 level, PDBs follow the CDB role). Deltas in `references/version-notes.md`.7879## Procedures8081Each procedure: **Trigger -> Precheck -> Action -> Postcheck -> Rollback.**82Read-only assessment (`dg_status`, the lag/apply/gap/SRL/config-check SQL) has no83precheck/rollback beyond "it changes nothing" and is run freely; the entries84below cover the acting (T2) and gated (T3) tasks.8586### T1 - observe (self-execute freely, read-only)87- **DG status / lag / apply / gaps / SRL / readiness.** Trigger: any "how is DR /88 the standby doing" question, or as the mandatory first step before a change.89 Action: `scripts/dg_status.{sh,ps1} [db|broker|all]`, and via `dba_ai_conn`90 `sql/dg_status.sql`, `sql/dg_lag_monitor.sql`, `sql/dg_apply_lag.sql`,91 `sql/standby_apply_status.sql`, `sql/archive_gap_detect.sql`,92 `sql/standby_redo_assess.sql`, `sql/dg_config_check.sql`. Postcheck: n/a (these93 ARE the check). Rollback: none (no changes made).9495### T2 - reversible (dry-run default; `--execute` to act; idempotent)96- **Archive/redo gap nudge.** Trigger: `archive_gap_detect` shows a gap on a97 standby and you want to prod automatic FAL re-fetch without destructive98 recovery. Precheck: must be a PHYSICAL STANDBY; `gap_count>0` (else noop).99 Action: `scripts/archive_gap_resolution.{sh,ps1} nudge --execute` (cancels then100 restarts Redo Apply with real-time apply). Postcheck: MRP running again.101 Rollback: apply simply continues; nothing destroyed. If the gap persists,102 escalate to `references/runbooks.md#standby-build` (manual restore/roll-forward).103- **Add a standby redo log group.** Trigger: `standby_redo_assess` /104 `dg_config_check` flags too few or wrong-sized SRLs. Precheck: group not already105 present (else noop). Action: `scripts/standby_redo_management.{sh,ps1} add106 --group N --thread T --bytes B --member PATH --execute` (in-DB DDL in107 `sql/standby_redo_add.sql`). Postcheck: group present and sized. Rollback: a108 quiescent SRL can be dropped (`ALTER DATABASE DROP STANDBY LOGFILE GROUP N`).109- **DG broker set / enable.** Trigger: adjust a safe broker property110 (e.g. `LogXptMode`, `DelayMins`) or `ENABLE` the configuration/a member.111 Precheck: property already at desired value / config already SUCCESS -> noop;112 FSFO/protection properties are refused (-> `#fsfo`). Action:113 `scripts/dg_broker_config.{sh,ps1} set --property .. --value .. --member .. --execute`114 or `... enable [--member ..] --execute`. Postcheck: property reads back /115 status SUCCESS. Rollback: re-`EDIT ... SET PROPERTY` to the prior value;116 `DISABLE` the member/config.117- **FSFO observer start / stop.** Trigger: bring up / take down the observer118 process (NOT enabling FSFO). Precheck: observer already running for this config119 / already stopped -> noop; refuses to enable FSFO. Action:120 `scripts/dg_observer.{sh,ps1} start --config-file PATH [--name N] --execute` /121 `... stop [--name N] --execute`. Postcheck: `SHOW OBSERVER` state matches.122 Rollback: `stop` reverses `start` (observer changes nothing in the databases).123- **Active Data Guard open-mode toggle.** Trigger: open a healthy physical standby124 READ ONLY WITH APPLY (real-time query) or revert it to MOUNTED + managed125 recovery. Precheck: role = PHYSICAL STANDBY; already in target open_mode -> noop.126 Action: `scripts/active_data_guard.{sh,ps1} enable --execute` /127 `... disable --execute` (in-DB: `sql/active_dg_enable.sql` /128 `sql/active_dg_disable.sql`). Postcheck: `open_mode` is the intended state.129 Rollback: `disable` reverses `enable` and vice-versa (fully reversible).130 Licensing/Far Sync/cascade/DML-redirect architecture is T3 -> `#active-dg`.131132### T3 - destructive / role-change / structural (runbook-only; never self-executes)133For each: Trigger -> Precheck (read-only readiness report) -> Action (PRINT the134runbook, obtain approval token, operator runs the commands by hand) -> Postcheck135(verify in the runbook) -> Rollback (in the runbook). Precheck for ALL of these is136`scripts/dg_status.{sh,ps1} all` + `sql/dg_config_check.sql` on both sites.137138- **Data Guard setup** -> `references/runbooks.md#dg-setup`. Rollback: additive;139 `DISABLE`/`REMOVE CONFIGURATION` + revert `log_archive_*` params.140- **Failover (and switchover decision branch)** -> `references/runbooks.md#failover`.141 Rollback: no in-place undo after FAILOVER - reinstate or rebuild the old primary;142 before issuing FAILOVER, prefer a reversible switchover if the primary is alive.143- **Reinstate failed primary** -> `references/runbooks.md#reinstate`. Rollback: if144 flashback can't reach `standby_became_primary_scn`, abandon and rebuild.145- **Standby build / rebuild** -> `references/runbooks.md#standby-build`. Rollback:146 new build doesn't touch the primary; rebuild intentionally overwrites the target.147- **Active Data Guard architecture** -> `references/runbooks.md#active-dg`.148 Rollback: the open-mode part is the reversible T2 script above; remove Far Sync /149 reset RedoRoutes.150- **Fast-Start Failover (FSFO)** -> `references/runbooks.md#fsfo`. Rollback:151 `DISABLE FAST_START FAILOVER` + `STOP OBSERVER`; revert protection mode.152- **Snapshot standby conversion** -> `references/runbooks.md#snapshot-standby`.153 Rollback: the convert-back IS the reverse (discards interim RW changes via the154 auto guaranteed restore point - do not drop it).155- **Cascaded standby** -> `references/runbooks.md#cascaded-standby`. Rollback:156 `DEFER`/clear the forwarding dest (or remove cascade RedoRoutes); narrow157 `DG_CONFIG`; drop tier-2 files.158159## Tier-3 runbooks160See **`references/runbooks.md`**. Every section there is TIER 3: it PRINTS exact161commands for a human operator (both broker `dgmgrl` and manual `ALTER DATABASE`162paths, for 19c and 23ai) and **NEVER self-executes**. Each is gated by163`require_approval_token` (a real change ticket; placeholders rejected,164`EX_APPROVAL`=6) and carries a pre-flight checklist, diagnostics, explicit165verification, and a rollback/abort path. An automated agent's only sanctioned166action there is to print the relevant section and stop until a human supplies a167valid token. When in doubt, runbook.