# Setup Oracle Data Guard observer

This is the first time in several years that I've configured a DataGuard observer.
See in the following how to install and configure Oracle Dataguard observer for Oracle database 19c 
(on Exadata @ OCI /ODB@AWS, should work similaron other envs  making a difference just to be transparent here)
Software installation has been done by my favorite tool: autoupgrade :-)

## preps

### install oracle preinstall

download the preinstall from public yum repo

```bash
wget https://yum.oracle.com/repo/OracleLinux/OL8/appstream/x86_64/getPackage/oracle-database-preinstall-19c-1.0-4.el8.x86_64.rpm
```

install with

```bash
sudo dnf localinstall oracle-database-preinstall-19c-1.0-4.el8.x86_64.rpm
```

I've faced an issue with the preinstalled bindutils version on my EC2 instance.
I was not able to tell yum or dnf to omit the package with ```--no-best```
therefore I removed the bindutils manually with 

```
sudo yum remove bind9.16-utils.x86_64
```
and was able to install oracle preinstall 19c package afterwards



### install java & zip


autoupgrade needs an installed java and zip cli.
```bash
yum install zip -y
yum install java -y
```

### autoupgrade etc


as we now have an oracle user we could switch to the oracle user and do our work
with that user

```bash
mkdir autoupgrade
```

download autoupgrade

```bash
wget https://download.oracle.com/otn-pub/otn_software/autoupgrade.jar
```

create a config file for autoupgrade to download the software
I've used autoupgrade composer by Marcus Vinicius to ease the config file creation.

``` bash
touch download-19c.cfg
```

add the following (adapt if needed)
```ìni
# Created by AutoUpgrade Composer
# AutoUpgrade Version: 26.6
# Patch, ExecMode: Download

global.global_log_dir=/home/oracle/autoupgrade/log
global.keystore=/home/oracle/autoupgrade/keystore

patch1.log_dir=/home/oracle/autoupgrade/log/patch1
patch1.download_folder=/home/oracle/autoupgrade/patches
patch1.patch=RU
patch1.target_version=19
patch1.platform=LINUX.X64
```

now we're nearly ready to download the patches
first load the password to the keystore , for details see my other blog around autoupgrade

```bash
java -jar autoupgrade.jar -config download-19c.cfg -patch -load_password
```

let's download the patches:
```bash
java -jar autoupgrade.jar -config download-19c.cfg -patch -mode download
```

```
java -jar autoupgrade.jar -config download-19c.cfg -patch -mode download
AutoUpgrade Patching 26.6.260925 launched with default internal options
Processing config file ...
Loading AutoUpgrade Patching keystore
AutoUpgrade Patching keystore is loaded
AutoUpgrade Patching adds the MRP and OCW options to the PATCH configuration parameter because the generated Gold Image always includes those fixes.

Connected to Oracle Update Advisor service |- Requesting Gold Images 
AutoUpgrade Patching has finished processing the Gold Image requests

-----------------------------------------------------
Downloading files to /home/oracle/autoupgrade/patches
-----------------------------------------------------
DB Gold Image - 19.33.0.0.0
    File: db_goldimage_19_33_20261103131316.zip - VALIDATED
-----------------------------------------------------
```

let's go ahead and install the database home

create a new autoupgrade config

``` 
vi install-19c.cfg
```

add the following

```ini
# Created by AutoUpgrade Composer
# AutoUpgrade Version: 26.6
# Patch, ExecMode: CreateHome

global.global_log_dir=/home/oracle/autoupgrade/log

patch1.log_dir=/home/oracle/autoupgrade/log/DB1
patch1.download_folder=/home/oracle/autoupgrade/patches
patch1.patch=RU
patch1.target_version=19
patch1.target_home=/u00/app/oracle/product/%RELEASE%.%UPDATE%/dbhome_1
patch1.home_settings.edition=ee
patch1.home_settings.oracle_base=/u00/app/oracle
patch1.home_settings.inventory_location=/u00/app/oraInventory
```

```bash
java -jar autoupgrade.jar -config install-19.cfg -patch -mode create_home
```

## the dataguard observer part

### preps
create a small env file to have all the needed env vars set automatically

```bash
cat ora.env 
export ORACLE_HOME=/u00/app/oracle/product/19.33/dbhome_1/
export ORACLE_BASE=/u00/app/oracle/

export PATH=$PATH:$ORACLE_HOME/bin
export TNS_ADMIN=$ORACLE_HOME/network/admin
```
### networking & db connectivity

configure tnsnames for primary and standby database
```ìni
DG_SITE1 =
  (DESCRIPTION =
    (CONNECT_TIMEOUT = 120)
    (RETRY_COUNT = 3)
    (TRANSPORT_CONNECT_TIMEOUT = 90)
    (ADDRESS_LIST =
      (LOAD_BALANCE = yes)
      (ADDRESS = (PROTOCOL = TCP)(HOST = vmc-prd-01-scan.client.wjad0tl.oraclevcn.com)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = demo_site1.client.demo1.oraclevcn.com)
      (UR = A)
      (FAILOVER_MODE = (TYPE = select)(METHOD = basic))
    )
  )

DG_SITE2 =
  (DESCRIPTION =
    (CONNECT_TIMEOUT = 120)
    (RETRY_COUNT = 3)
    (TRANSPORT_CONNECT_TIMEOUT = 90)
    (ADDRESS_LIST =
      (LOAD_BALANCE = yes)
      (ADDRESS = (PROTOCOL = TCP)(HOST = vnc-stby-01-scan.client.demo2.oraclevcn.com(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = demo_site2.client.demo2.oraclevcn.com))
      (UR = A)
      (FAILOVER_MODE = (TYPE = select)(METHOD = basic))
    )
  )

```
tnsping to both sites above should be fine

```bash
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (CONNECT_TIMEOUT = 120) (RETRY_COUNT = 3) (TRANSPORT_CONNECT_TIMEOUT = 90) (ADDRESS_LIST = (LOAD_BALANCE = yes) (ADDRESS = (PROTOCOL = TCP)(HOST = vmc-prd-01-scan.client.wjad0tl.oraclevcn.com))(PORT = 1521))) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = demo_site1.client.demo1.oraclevcn.com (UR = A) (FAILOVER_MODE = (TYPE = select)(METHOD = basic))))
OK (0 msec)
```

#### wallet config
as we're running on 19c observer includes the option to run in background.
to achieve that we need to ensure passwordless authentication to the database is possible.


add the following to our sqlnet.ora

```bash
vi $TNS_ADMIN/sqlnet.ora

WALLET_LOCATION =
   (SOURCE =
      (METHOD = FILE)
      (METHOD_DATA = (DIRECTORY = /u00/app/oracle/admin/wallet))
)
SQLNET.WALLET_OVERRIDE = TRUE
```

create the wallet dir if it does not exist

```bash
mkdir /u00/app/oracle/admin/wallet
```

initialize a wallet (provide a password when prompted)

```bash
mkstore -wrl /u00/app/oracle/admin/wallet -create
```

store the passwords
```bash
mkstore -wrl /u00/app/oracle/admin/wallet -createCredential DG_SITE1 sys
mkstore -wrl /u00/app/oracle/admin/wallet -createCredential DG_SITE2 sys
```

mkstore -wrl /u00/app/oracle/admin/wallet  -listCredential


test the connection
```bash
sqlplus /@DG_SITE1 as sysdba
sqlplus /@DG_SITE2 as sysdba
```
should be successful without a password prompt

### observer config

create a directory to hold the configs

mkdir /u00/app/oracle/admin/fsfo

```bash
dgmgrl
connect /@dg_site1;

show configuration
enable fast_start failover;
Enabled in Potential Data Loss Mode.
```

now start the observer with (also in dgmrl)

```bash
start observer observer1 in background file is '/u00/app/oracle/admin/fsfoobserver1_dg.dat' logfile is '/u00/app/oracle/admin/fsfo/observer1.log' connect identifier is dg_site1;
```

output will look like

```
[...]
Submitted command "START OBSERVER" using connect identifier "DG_SITE1" 
DGMGRL> DGMGRL for Linux: Release 19.0.0.0.0 - Production on Wed Nov 4 10:35:35 2026
Version 19.33.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

[...]
Connected as SYSDBA.
Observer file "/u00/app/oracle/admin/fsfoobserver1_dg.dat" is created.
Succeeded in opening the observer file "/u00/app/oracle/admin/fsfoobserver1_dg.dat".
[W000 2026-11-04T10:35:38.522+00:00] FSFO target standby is DG_SITE2
Observer 'i-xxxx.eu-central-1.compute.internal1' started
The observer log file is '/u00/app/oracle/admin/fsfo/observer_dg1.log'.
```

Check the configuration (with dgmgrl)

```

show configuration

[...]

Fast-Start Failover: Enabled in Potential Data Loss Mode
  Lag Limit:          30 seconds
  Lag Type:           APPLY
  Threshold:          30 seconds
  Active Target:      DG_SITE2
  Potential Targets:  "DG_SITE2"
    DG_SITE2 valid
  Observer:           i-xxx.eu-central-1.compute.internal1
  Shutdown Primary:   TRUE
  Auto-reinstate:     TRUE
  Observer Reconnect: (none)
  Observer Override:  FALSE
  Lag Grace Time:     0 seconds
```


That's it :-)
We've succesfully installed and configured DataGuard observer with the help of autoupgrade.

### summary/lessons learned

- autoupgrade eases and helps here as well by installing the needed oracle home
- make use of autoupgrade composer to get the needed config files created
- create wallets for the db credentials to keep observer running in background

### Links, further reading

DataGuard docs and best practices
* https://docs.oracle.com/en/database/oracle/oracle-database/19/dgbkr/using-data-guard-broker-to-manage-switchovers-failovers.html?source=%3Aso%3Ach%3Aor%3Aawr%3A%3A%3A%3APrivateEndpointsPlaybook&utm_source=chatgpt.com
* https://docs.oracle.com/en/database/oracle/oracle-database/19/sbydb/introduction-to-oracle-data-guard-concepts.html
* https://docs.oracle.com/en/database/oracle/oracle-database/19/haovw/oracle-data-guard.html

Ludovicos blog around DataGuard and Oracle Database
* https://www.ludovicocaldara.net/

Guide to Oracle Data Guard Fast-Start Failover
* https://www.oracle.com/technical-resources/articles/smiley-fsfo.html

autoupgrade composer by Marcus Vinicius
* https://viniciusdba.com.br/autoupgrade-composer/

step by step doc for FSFP by Google Cloud
* https://docs.cloud.google.com/oracle/compute/gcnv-configure-broker-fsfo-observer
