Skip to main content
NetApp database solutions

Create the Oracle standby database with Google Cloud NetApp Volumes storage-layer seeding

Contributors netapp-jsnyder

Create the Oracle physical standby database using Google Cloud NetApp Volumes storage-layer replication, snapshots, or clones to accelerate standby initialization compared to traditional RMAN methods. This procedure covers configuring the listener, creating the standby pfile, seeding standby volumes with GCNV replication, finalizing the Oracle instance, and registering the standby with Oracle Restart. All HA tiers complete these steps. For Prod HA (Data Guard + FSFO) tier, continue with Data Guard finalization before configuring Data Guard Broker, Fast-Start Failover, and the Observer.

Step 1: Configure listener and Data Guard parameters

Configure the listener on both database hosts to support Data Guard connections, including the _DGMGRL service required for the broker. Set up the password file and configure archive log parameters on the primary database.

  1. Configure the primary listener and verify the environment on oracdb1:

    sudo su - oracle
    . ~/.bash_profile        # ORACLE_SID=orcl, ORACLE_HOME set
  2. Configure the standby listener on oracdb2 to include the orcls and orcls_DGMGRL services:

    GRID_HOME=/u01/app/26ai/grid
    sudo -u grid tee "$GRID_HOME/network/admin/listener.ora" >/dev/null <<'EOF'
    LISTENER =
      (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = oracdb2.example.internal)(PORT = 1521)))
    
    SID_LIST_LISTENER =
      (SID_LIST =
        (SID_DESC = (GLOBAL_DBNAME = orcls)        (ORACLE_HOME = /u01/app/oracle/product/26ai/db_1) (SID_NAME = orcls))
        (SID_DESC = (GLOBAL_DBNAME = orcls_DGMGRL) (ORACLE_HOME = /u01/app/oracle/product/26ai/db_1) (SID_NAME = orcls)))
    EOF
  3. Restart the listener through Oracle Restart on both hosts and verify the _DGMGRL service is registered:

    sudo -u grid bash -c '
    export GRID_HOME=/u01/app/26ai/grid
    export ORACLE_HOME=$GRID_HOME
    $GRID_HOME/bin/srvctl stop listener
    $GRID_HOME/bin/srvctl start listener
    $GRID_HOME/bin/lsnrctl status
    '

    lsnrctl status must list <SID> and <SID>_DGMGRL.

Step 2: Prepare standby pfile and NOMOUNT

Prepare the standby database instance by copying the password file from the primary, creating a minimal init.ora pfile with Data Guard parameters, and starting the instance in NOMOUNT mode.

  1. Copy the primary password file to the standby host using IAP and gcloud compute scp:

    PRIMARY_ZONE=us-west1-a       # zone of oracdb1
    STANDBY_ZONE=us-west1-b       # zone of oracdb2
    
    gcloud compute scp \
      oracdb1:/u01/app/oracle/product/26ai/db_1/dbs/orapworcl ./orapworcl \
      --zone=$PRIMARY_ZONE --tunnel-through-iap
    
    gcloud compute scp \
      ./orapworcl oracdb2:/u01/app/oracle/product/26ai/db_1/dbs/orapworcls \
      --zone=$STANDBY_ZONE --tunnel-through-iap
  2. Query the compatible parameter value from the primary database:

    # On oracdb1
    sudo -u oracle sqlplus -s / as sysdba \
      <<<"SELECT value FROM v\$parameter WHERE name='compatible';"
  3. Create the standby pfile on oracdb2, set ownership on the password file, and start the instance in NOMOUNT mode. Substitute the compatible value from the previous step for <COPY_FROM_PRIMARY>:

    sudo -u oracle mkdir -p /u01/app/oracle/admin/orcls/adump
    sudo chown oracle:oinstall /u01/app/oracle/product/26ai/db_1/dbs/orapworcls
    sudo chmod 0600 /u01/app/oracle/product/26ai/db_1/dbs/orapworcls
    
    sudo -u oracle tee /u01/app/oracle/product/26ai/db_1/dbs/initorcls.ora >/dev/null <<'EOF'
    *.db_name='orcl'
    *.db_unique_name='orcls'
    *.audit_file_dest='/u01/app/oracle/admin/orcls/adump'
    *.diagnostic_dest='/u01/app/oracle'
    *.compatible='<COPY_FROM_PRIMARY>'
    *.sga_target=3072m
    *.pga_aggregate_target=1024m
    *.processes=320
    *.remote_login_passwordfile='EXCLUSIVE'
    *.standby_file_management='AUTO'
    *.fal_server='orcl'
    *.log_archive_config='DG_CONFIG=(orcl,orcls)'
    *.log_archive_dest_1='LOCATION=+RECO VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=orcls'
    *.log_archive_dest_2='SERVICE=orcl AFFIRM SYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl'
    *.log_archive_dest_state_2='DEFER'
    *.log_archive_format='%t_%s_%r.arc'
    *.dg_broker_start=TRUE
    *.undo_tablespace='UNDOTBS1'
    *.open_cursors=300
    *.db_create_file_dest='+DATA'
    *.db_create_online_log_dest_1='+DATA'
    *.db_recovery_file_dest='+FRA'
    *.db_recovery_file_dest_size=25000m
    EOF
    
    echo "orcls:/u01/app/oracle/product/26ai/db_1:N" | sudo tee -a /etc/oratab
    
    sudo -u oracle bash -c '
    export ORACLE_HOME=/u01/app/oracle/product/26ai/db_1
    export ORACLE_SID=orcls
    sqlplus / as sysdba <<SQL
    STARTUP NOMOUNT PFILE=/u01/app/oracle/product/26ai/db_1/dbs/initorcls.ora;
    EXIT
    SQL
    '

    The standby instance is now in NOMOUNT mode with no datafiles until Step 3: Initialize standby storage with GCNV.

Step 3: Initialize standby storage with GCNV

Seed the standby volumes in oracle-pool-b, attach them to oracdb2, mount ASM disk groups, and finalize the standby instance at MOUNT state.

Use GCNV replication for production seeding, and use snapshot seeding for one-time lab workflows.

Choose the seeding path

Choose the standby seeding method based on your environment and recovery requirements.

Check prerequisites

Confirm the following prerequisites before you seed standby volumes.

  • gcloud netapp with volume replication support.

  • Two Default-mode pools in different locations (oracle-pool-a, oracle-pool-b).

  • Source volumes on primary pool attached to oracdb1-hg; destination volumes created by replication.

  • Run replication from Cloud Shell or workstation — not from DB VMs.

  • On oracdb2, complete iSCSI and ASM host setup from Step 4, Step 5, and Step 6.

    export PROJECT=<your-gcp-project>
    export LOC_A=us-west1-a
    export LOC_B=us-west1-b
    export DEST_POOL="projects/${PROJECT}/locations/${LOC_B}/storagePools/oracle-pool-b"
  • Create a standby pool if needed:

    gcloud netapp storage-pools create oracle-pool-b \
      --project="${PROJECT}" --location="${LOC_B}" \
      --service-level=flex --type=unified --mode=default \
      --capacity=1024 --network=name=<your-vpc>

Create and sync replications

Create replication relationships from primary volumes to standby volumes, then wait for initial synchronization to finish.

gcloud netapp volumes replications create repl-oracdb2-data \
  --project="${PROJECT}" --location="${LOC_A}" --volume=oracdb1_data \
  --replication-schedule=EVERY_10_MINUTES \
  --destination-volume-parameters="storage_pool=${DEST_POOL},volume_id=oracdb2_data,share_name=oracdb2_data"

gcloud netapp volumes replications create repl-oracdb2-reco \
  --project="${PROJECT}" --location="${LOC_A}" --volume=oracdb1_reco \
  --replication-schedule=EVERY_10_MINUTES \
  --destination-volume-parameters="storage_pool=${DEST_POOL},volume_id=oracdb2_reco,share_name=oracdb2_reco"

+

Wait until mirrorState is MIRRORED and initial sync is complete for each replication.

Cut over and attach standby volumes

Quiesce the primary, stop replication after the final sync, and attach destination volumes to the standby host group.

On the primary, quiesce writes and capture recovery metadata:

ALTER DATABASE BEGIN BACKUP;
SELECT CURRENT_SCN FROM V$DATABASE;
ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/tmp/orcls_stby.ctl';

Allow one final replication cycle, then stop replications:

gcloud netapp volumes replications stop repl-oracdb2-data \
  --project="${PROJECT}" --location="${LOC_A}" --volume=oracdb1_data --force

gcloud netapp volumes replications stop repl-oracdb2-reco \
  --project="${PROJECT}" --location="${LOC_A}" --volume=oracdb1_reco --force

Attach destination volumes to oracdb2-hg (replicated LUNs may keep source names):

HG=$(gcloud netapp host-groups describe oracdb2-hg --project="${PROJECT}" \
  --location=us-west1 --format='value(name)')

gcloud netapp volumes update oracdb2_data --project="${PROJECT}" --location="${LOC_B}" \
  --block-devices="name=oracdb1_data_lun,host-groups=${HG},os-type=LINUX"

Copy the standby controlfile to oracdb2, then end backup mode on the primary:

ALTER DATABASE END BACKUP;

Seed from snapshot

Use this path for one-time lab seeding when continuous replication is not required.

For a one-time lab seed, create a source snapshot and create standby volumes from that snapshot in oracle-pool-b (Cloud Console or API). Attach created volumes to oracdb2-hg, then continue with Mount standby ASM disk groups.

Mount standby ASM disk groups

On the standby host, discover the attached storage paths and mount the ASM disk groups before database recovery.

On oracdb2, log in to standby-pool iSCSI portals and rescan multipath devices. If ASM disk headers match primary naming in a lab workflow, use primary-style aliases (for example ora_oracdb1_data_01, ora_oracdb1_arch_01), set asm_diskstring='/dev/mapper/ora_oracdb1_*p*', and confirm partition ownership is grid:asmadmin, then mount disk groups:

ALTER DISKGROUP DATA MOUNT FORCE;
ALTER DISKGROUP RECO MOUNT FORCE;
ALTER DISKGROUP FRA MOUNT FORCE;

Finalize the standby instance

Restore the standby controlfile, recover to the captured SCN, convert to physical standby, and start managed recovery.

STARTUP NOMOUNT;
RESTORE STANDBY CONTROLFILE FROM '/tmp/orcls_stby.ctl';
ALTER DATABASE MOUNT;
RECOVER DATABASE UNTIL SCN <quiesce_scn>;
ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

At this point, the standby should be PHYSICAL STANDBY and MOUNTED with managed recovery started.

Tier-specific next steps:

Step 4: Register standby with Oracle Restart

Register the standby database with Oracle Restart so that reboots automatically recover ASM disk groups, mount the standby database, and restart managed recovery. Also add the application service to both database resources.

  1. Capture the spfile location from the standby database and register it with Oracle Restart on oracdb2. Substitute <STANDBY_SPFILE_PATH> from the query (often under +DATA):

    sudo -u oracle bash -c '
    export ORACLE_SID=orcls
    sqlplus -s / as sysdba <<< "SHOW PARAMETER spfile;"
    '
    
    sudo -u oracle bash -c '
    export GRID_HOME=/u01/app/26ai/grid
    export ORACLE_HOME=/u01/app/oracle/product/26ai/db_1
    export PATH=$ORACLE_HOME/bin:$GRID_HOME/bin:$PATH
    
    srvctl add database \
      -db orcls \
      -dbname orcl \
      -oraclehome /u01/app/oracle/product/26ai/db_1 \
      -spfile <STANDBY_SPFILE_PATH> \
      -pwfile /u01/app/oracle/product/26ai/db_1/dbs/orapworcls \
      -role PHYSICAL_STANDBY \
      -startoption MOUNT \
      -stopoption IMMEDIATE \
      -diskgroup DATA,RECO,FRA
    
    srvctl config database -db orcls
    srvctl status database -db orcls
    '
  2. Verify and update the primary database resource on oracdb1 to include all ASM disk group dependencies:

    sudo -u oracle bash -c '
    export GRID_HOME=/u01/app/26ai/grid
    export ORACLE_HOME=/u01/app/oracle/product/26ai/db_1
    export PATH=$ORACLE_HOME/bin:$GRID_HOME/bin:$PATH
    srvctl config database -db orcl
    srvctl modify database -db orcl -diskgroup DATA,RECO,FRA
    srvctl config database -db orcl
    '
  3. Add the application service to the standby database resource (orcls on oracdb2). Use role PRIMARY on both sides so orclapp is available after switchover:

    sudo -u oracle bash -c '
    export GRID_HOME=/u01/app/26ai/grid
    export ORACLE_HOME=/u01/app/oracle/product/26ai/db_1
    export PATH=$ORACLE_HOME/bin:$GRID_HOME/bin:$PATH
    
    srvctl add service \
      -db orcls \
      -service orclapp \
      -pdb orclpdb \
      -role PRIMARY \
      -policy AUTOMATIC
    
    srvctl config service -db orcls -service orclapp
    '
  4. Verify the standby database resource on oracdb2:

    sudo -u oracle bash -c '
    export GRID_HOME=/u01/app/26ai/grid
    export ORACLE_HOME=/u01/app/oracle/product/26ai/db_1
    export PATH=$ORACLE_HOME/bin:$GRID_HOME/bin:$PATH
    srvctl status database -db orcls
    '

What's next?

Tier-specific:

  • Prod HA (no Data Guard): To maintain a storage-replication-based recovery target, standby initialization is complete and the standby database is registered with Oracle Restart as a backup instance.

  • Prod HA (Data Guard + FSFO): To enable broker-managed switchover and fast-start failover, continue with Finalize the standby database for Data Guard.