How to migrate to OracleDB for Azure using ZDM Physical Online Migration

Introduction

OracleDB for Azure (or, Oracle Database Service for Azure) simplifies multicloud deployments by providing an Oracle-managed interconnect between your Azure and OCI accounts. Customers running their workloads on Azure can now keep the application on Azure and move the Database to Oracle Cloud to benefit from Cloud Automation, Exadata Service, Oracle RAC, and more.

In previous blog posts, we created an Oracle Database in Oracle Cloud via OracleDB for Azure Portal and connected to it from Azure. This blog post describes how to migrate an Oracle Database to a Base Database running on Oracle Cloud created via the OracleDB for Azure service. All data traffic between Azure and Oracle Cloud will use the Oracle-managed multicloud network link.

The Database will be migrated using Oracle Zero Downtime Migration (ZDM) Physical Online migration method, which creates a physical standby database on Oracle Cloud, keeps it in sync, and finally switches over to Oracle Cloud providing zero to minimal downtime for your database and application.

The Environment

  • ZDM Host: Azure IaaS VM using Oracle Linux 7.9 operating system with private IP 10.1.1.6 and hostname zdmhost.
  • Source Database: Oracle Database version 19.17 running on Azure IaaS VM using Oracle Linux 7.7 operating system with private IP 10.1.1.5 and hostname azurehost.
    • Database name is ORCL and database unique name orcl.
  • Target Database: Oracle Base Database version 19.17 running on Oracle Cloud using Oracle Linux 7.9 operating system with private IP 10.13.0.238 and hostname ocihost.
    • Database name is ORCL and database unique name ORCL_ams1hs.
    • This is the “placeholder” database that will be used by ZDM as a target.

The Target Database must be created via the OracleDB for Azure Portal, so the multicloud network link gets created between Azure and Oracle Cloud.

The source Oracle Database can also be running on-premises instead of on Azure IaaS:

Prerequisites

For ZDM physical online migrations:

  • The target database name must be the same as the source database name, here ORCL.
  • The SYS password must be the same on the source and target database.
  • The COMPATIBLE parameter must be the same on the source and target database.

Preparation

Step 1: Prepare the source database host on Azure

Copy the SSH public key for zdmuser from the ZDM host to the .ssh/authorized_keys file on the source database host for the user you want to use for login, in this case azureuser:

#on ZDM host as zdmuser
[zdmuser@zdmhost ~]$ cat .ssh/id_rsa.pub
#on the source database host as user azureuser
[azureuser@azurehost ~]$ vi .ssh/authorized_keys
#insert the public key and save the changes

Add the target database server hostname and IP information into the /etc/hosts file. As root user:

[root@azurehost ~]# vi /etc/hosts
#add the following entries
10.13.0.238 ocihost.odsp922684.cvcn.oraclevcn.com ocihost
10.13.0.238 ocihost-scan.odsp922684.cvcn.oraclevcn.com ocihost-scan

Step 2: Prepare the source database on Azure

As SYS user:

-- To protect against unlogged direct writes in the primary database that cannot be propagated to the standby database, turn on FORCE LOGGING at the primary database:
SQL> select force_logging from v$database;
FORCE_LOGGING
---------------------------------------
NO
SQL> alter database force logging;
SQL> select force_logging from v$database;
FORCE_LOGGING
---------------------------------------
YES
 
-- Enable ARCHIVELOG mode for the database:
SQL> select log_mode from v$database;
LOG_MODE
------------
ARCHIVELOG
 
-- For Oracle Database 12c Release 2 and later, it is mandatory to configure TDE before migration begins
-- follow the steps in: https://database-heartbeat.com/2020/12/31/enable-tde-auto-login-wallet-and-secure-external-password-store-seps/ 
SQL> select wrl_type, status from v$encryption_wallet;
WRL_TYPE             STATUS
-------------------- ------------------------------
FILE                 OPEN
 
-- Set RMAN CONFIGURE CONTROLFILE AUTOBACKUP to ON
RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;

Step 3: Prepare the target database host on Oracle Cloud

Copy the SSH public key for zdmuser from the ZDM host to the .ssh/authorized_keys file on the target database host for the user you want to use for login, in this case opc:

#on ZDM host as zdmuser
[zdmuser@zdmhost ~]$ cat .ssh/id_rsa.pub
#on the target database host as user opc
[opc@ocihost ~]$ vi .ssh/authorized_keys
#insert the public key and save the changes

Add the source database server hostname and IP information into the /etc/hosts file. As root user:

[root@ocihost ~]# vi /etc/hosts
#add the following entries
10.1.1.5 azurehost

Step 4: Prepare the ZDM host on Azure

Add the source and target servers’ hostname and IP information into the /etc/hosts file. As root user:

[root@zdmhost ~]# vi /etc/hosts
#add the following entries
10.1.1.5 azurehost
10.13.0.238 ocihost.odsp922684.cvcn.oraclevcn.com ocihost
10.13.0.238 ocihost-scan.odsp922684.cvcn.oraclevcn.com ocihost-scan

Test the SSH connectivity to the source and target database servers:

[zdmuser@zdmhost ~]$ ssh -i /home/zdmuser/.ssh/id_rsa azureuser@azurehost
Last login: Tue Feb 14 11:11:15 2023 from zdmhost.internal.cloudapp.net
[azureuser@azurehost ~]$

[zdmuser@zdmhost ~]$ ssh -i /home/zdmuser/.ssh/id_rsa opc@ocihost
Last login: Tue Feb 14 11:11:41 2023 from 10.1.1.6
[opc@ocihost ~]$

Verify that TTY is disabled for the SSH-privileged user. If TTY is disabled, the following command returns the date from the remote host without any errors:

[zdmuser@zdmhost ~]$ ssh -i /home/zdmuser/.ssh/id_rsa azureuser@azurehost "/usr/bin/sudo /bin/sh -c date"
Tue Feb 14 11:15:22 UTC 2023
 
[zdmuser@zdmhost ~]$ ssh -i /home/zdmuser/.ssh/id_rsa opc@ocihost "/usr/bin/sudo /bin/sh -c date"
Tue Feb 14 11:15:33 UTC 2023

Step 5: Set SQL*Net connectivity between source and target database servers

Check the network connectivity from source to target and vice versa:

#from source host on Azure
[oracle@azurehost ~]$ tnsping ocihost:1521
Used HOSTNAME adapter to resolve the alias
Attempting to contact (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=))(ADDRESS=(PROTOCOL=tcp)(HOST=10.13.0.238)(PORT=1521)))
OK (10 msec)

#from target host on Oracle Cloud
[oracle@ocihost ~]$ tnsping azurehost:1521
Used HOSTNAME adapter to resolve the alias
Attempting to contact (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=))(ADDRESS=(PROTOCOL=tcp)(HOST=10.1.1.5)(PORT=1521)))
OK (10 msec)

Migration

Step 6: Create the Physical Migration Response File

Starting from ZDM 21.2, ZDM provides the DIRECT option to directly transfer the data between the source and target without an intermediate storage location by using RMAN active database duplication or restoring from service.

ZDM_RMAN_DIRECT_METHOD specifies the RMAN method (restore from service or active duplicate) to use when DIRECT data transfer method is specified. Oracle MAA best practices recommend using active duplication for Oracle Database 11.2 and using restore from service for Oracle Database 12.1 and later.

[zdmuser@zdmhost ~]$ vi /home/zdmuser/physical_online/physical_online.rsp
MIGRATION_METHOD=ONLINE_PHYSICAL
DATA_TRANSFER_MEDIUM=DIRECT
ZDM_RMAN_DIRECT_METHOD=RESTORE_FROM_SERVICE
ZDM_SRC_DB_RESTORE_SERVICE_NAME=orcl
TGT_DB_UNIQUE_NAME=ORCL_ams1hs
PLATFORM_TYPE=VMDB

Step 7: Evaluate the configuration

On the ZDM host as zdmuser:

$ZDMHOME/bin/zdmcli migrate database \
-rsp /home/zdmuser/physical_online/physical_online.rsp \
-sourcesid orcl \
-sourcenode azurehost \
-srcauth zdmauth \
-srcarg1 user:azureuser \
-srcarg2 identity_file:/home/zdmuser/.ssh/id_rsa \
-srcarg3 sudo_location:/usr/bin/sudo \
-targetnode ocihost \
-tgtauth zdmauth \
-tgtarg1 user:opc \
-tgtarg2 identity_file:/home/zdmuser/.ssh/id_rsa \
-tgtarg3 sudo_location:/usr/bin/sudo \
-targethome /u01/app/oracle/product/19.0.0.0/dbhome_1 \
-eval

If the source database is using ASM for storage management, then use -sourcedb <db_unique_name> instead of -sourcesid <SID> in the zdmcli command.

Check the job status. On the ZDM host as zdmuser:

[zdmuser@zdmhost ~]$ while :; do $ZDMHOME/bin/zdmcli query job -jobid 15; sleep 10; done

Job ID: 15
User: zdmuser
Client: zdmhost
Job Type: "EVAL"
...
Current status: SUCCEEDED
Result file path: "/datadrive/zdm/zdmbase//chkbase/scheduled/job-15-2023-02-14-12:08:02.log"
Metrics file path: "/datadrive/zdm/zdmbase//chkbase/scheduled/job-15-2023-02-14-12:08:02.json"
Job execution start time: 2023-02-14 12:08:03
Job execution end time: 2023-02-14 12:15:33
Job execution elapsed time: 7 minutes 29 seconds
ZDM_GET_SRC_INFO ........... PRECHECK_PASSED
ZDM_GET_TGT_INFO ........... PRECHECK_PASSED
ZDM_PRECHECKS_SRC .......... PRECHECK_PASSED
ZDM_PRECHECKS_TGT .......... PRECHECK_PASSED
ZDM_SETUP_SRC .............. PRECHECK_PASSED
ZDM_SETUP_TGT .............. PRECHECK_PASSED
ZDM_PREUSERACTIONS ......... PRECHECK_PASSED
ZDM_PREUSERACTIONS_TGT ..... PRECHECK_PASSED
ZDM_VALIDATE_SRC ........... PRECHECK_PASSED
ZDM_VALIDATE_TGT ........... PRECHECK_PASSED
ZDM_POSTUSERACTIONS ........ PRECHECK_PASSED
ZDM_POSTUSERACTIONS_TGT .... PRECHECK_PASSED
ZDM_CLEANUP_SRC ............ PRECHECK_PASSED
ZDM_CLEANUP_TGT ............ PRECHECK_PASSED

Step 8: Initiate the migration

Execute the same command for evaluation, but this time without the -eval parameter.

Oracle ZDM allows to pause of the migration process at any given stage, and hence, the migration process can be paused before the role swap and switchover phase. Upon executing the zdm migrate database command, the -pauseafter flag must be entered with the desired stage for pausing, in this case, ZDM_CONFIGURE_DG_SRC.

On the ZDM host as zdmuser:

$ZDMHOME/bin/zdmcli migrate database \
-rsp /home/zdmuser/physical_online/physical_online.rsp \
-sourcesid orcl \
-sourcenode azurehost \
-srcauth zdmauth \
-srcarg1 user:azureuser \
-srcarg2 identity_file:/home/zdmuser/.ssh/id_rsa \
-srcarg3 sudo_location:/usr/bin/sudo \
-targetnode ocihost \
-tgtauth zdmauth \
-tgtarg1 user:opc \
-tgtarg2 identity_file:/home/zdmuser/.ssh/id_rsa \
-tgtarg3 sudo_location:/usr/bin/sudo \
-targethome /u01/app/oracle/product/19.0.0.0/dbhome_1 \
-pauseafter ZDM_CONFIGURE_DG_SRC

Check the job status. On the ZDM host as zdmuser:

[zdmuser@zdmhost ~]$ while :; do $ZDMHOME/bin/zdmcli query job -jobid 16; sleep 10; done

Job ID: 16
User: zdmuser
Client: zdmhost
Job Type: "MIGRATE"
...
Current status: PAUSED
...
ZDM_GET_SRC_INFO .............. COMPLETED
ZDM_GET_TGT_INFO .............. COMPLETED
ZDM_PRECHECKS_SRC ............. COMPLETED
ZDM_PRECHECKS_TGT ............. COMPLETED
ZDM_SETUP_SRC ................. COMPLETED
ZDM_SETUP_TGT ................. COMPLETED
ZDM_PREUSERACTIONS ............ COMPLETED
ZDM_PREUSERACTIONS_TGT ........ COMPLETED
ZDM_VALIDATE_SRC .............. COMPLETED
ZDM_VALIDATE_TGT .............. COMPLETED
ZDM_DISCOVER_SRC .............. COMPLETED
ZDM_COPYFILES ................. COMPLETED
ZDM_PREPARE_TGT ............... COMPLETED
ZDM_SETUP_TDE_TGT ............. COMPLETED
ZDM_RESTORE_TGT ............... COMPLETED
ZDM_RECOVER_TGT ............... COMPLETED
ZDM_FINALIZE_TGT .............. COMPLETED
ZDM_CONFIGURE_DG_SRC .......... COMPLETED
ZDM_SWITCHOVER_SRC ............ PENDING
ZDM_SWITCHOVER_TGT ............ PENDING
ZDM_POST_DATABASE_OPEN_TGT .... PENDING
ZDM_DATAPATCH_TGT ............. PENDING
ZDM_POST_MIGRATE_TGT .......... PENDING
ZDM_POSTUSERACTIONS ........... PENDING
ZDM_POSTUSERACTIONS_TGT ....... PENDING
ZDM_CLEANUP_SRC ............... PENDING
ZDM_CLEANUP_TGT ............... PENDING

Pay attention to the current job status. It is in PAUSED status now. Also, the progress stopped after phase ZDM_CONFIGURE_DG_SRC was COMPLETED.

Check the database roles. The source is primary now, and the target is standby:

[oracle@azurehost ~]$ sqlplus / as sysdba
SQL> select database_role from v$database;
DATABASE_ROLE
----------------
PRIMARY
 
[oracle@ocihost ~]$ sqlplus / as sysdba
SQL> select database_role from v$database;
DATABASE_ROLE
----------------
PHYSICAL STANDBY

At this stage, every change in the source database is immediately synchronized with the target database. Resume the job when your application is ready for migration.

Step 9: Complete the migration

Resume the job from the previous step. On the ZDM host as zdmuser:

[zdmuser@zdmhost ~]$ $ZDMHOME/bin/zdmcli resume job -jobid 16

Query the status again and wait until all phases are completed.

Check the database roles again. The source is the standby now, and the target is primary:

[oracle@azurehost ~]$ sqlplus / as sysdba
SQL> select database_role from v$database;
DATABASE_ROLE
----------------
PHYSICAL STANDBY
 
[oracle@ocihost ~]$ sqlplus / as sysdba
SQL> select database_role from v$database;
DATABASE_ROLE
----------------
PRIMARY

Use Transparent Application Continuity to hide the switchover operation for your application. The end user will not encounter any error or interruption, but instead only a slight delay in execution.

Post-Tasks

Step 10: Clean Up

Now, your application on Azure accesses the primary Base Database on OCI. You can deinstall the standby database (the source database) and the ZDM host as the migration is completed.

Conclusion

OracleDB for Azure provides an Oracle-managed network interconnect between your Azure subscription and OCI tenancy. You can use this network to migrate your Oracle Databases running on-premises or on Azure IaaS VMs to Base Databases on Oracle Cloud using the ZDM Physical Online Migration method with the DIRECT option to directly transfer the data between the source and target without an intermediate storage location by using RMAN restore from service.

ZDM offers a wide range of options that you might need for more flexibility and control. Have a look at the documentation for the complete list of available parameters.

Further Reading

Would you like to get notified when the next post is published?