1. Home
  2. Knowledge Base
  3. Zero Downtime Migration
  4. Oracle database 12c to 21c online migration using ZDM (Zero Downtime Migration) – Part 1

Oracle database 12c to 21c online migration using ZDM (Zero Downtime Migration) – Part 1

Oracle Zero Downtime Migration (ZDM) is the free-to-use Oracle Maximum Availability Architecture (MAA)-recommended solution to migrate Oracle Databases to the Oracle Cloud Infrastructure.

ZDM provides a number of migration options – Physical offline,Physical online, Logical offline, Logical online.

In a Logical Online migration, users are still connected to a live database while ZDM is executing in the background. Internally ZDM uses Oracle GoldenGate technology to enable the ‘zero-downtime’ migration as well as Oracle Data Pump.

Oracle Zero Downtime Migration (ZDM) is the free-to-use Oracle Maximum Availability Architecture (MAA)-recommended solution to migrate Oracle Databases to the Oracle Cloud Infrastructure.

ZDM provides a number of migration options – Physical offline,Physical online, Logical offline, Logical online.

In a Logical Online migration, users are still connected to a live database while ZDM is executing in the background. Internally ZDM uses Oracle GoldenGate technology to enable the ‘zero-downtime’ migration as well as Oracle Data Pump.

These series of posts provide a step-by-step procedure of how to do an Online Logical Migration of an Oracle Database 12c to Oracle Database 21c.

In this example both the source 12c and target 21c databases are hosted in OCI – but the same procedure can easily be adopted to migrate (and upgrade) an on-premises Oracle database to OCI.

In the first part of this series we will look at how to configure and set up the ZDM hub.

Download the Oracle ZDM software from edelivery.oracle.com – the Oracle Software Delivery Cloud.

https://www.oracle.com/database/technologies/rac/zdm-downloads.html#

Note – the ZDM version in this series is 21.3. A newer version 21.4 is now also available for download. We will discuss the new 21.4 features in a separate post.

Oracle Zero Downtime Migration (ZDM) is the free-to-use Oracle Maximum Availability Architecture (MAA)-recommended solution to migrate Oracle Databases to the Oracle Cloud Infrastructure.

ZDM provides a number of migration options – Physical offline,Physical online, Logical offline, Logical online.

In a Logical Online migration, users are still connected to a live database while ZDM is executing in the background. Internally ZDM uses Oracle GoldenGate technology to enable the ‘zero-downtime’ migration as well as Oracle Data Pump.

These series of posts provide a step-by-step procedure of how to do an Online Logical Migration of an Oracle Database 12c to Oracle Database 21c.

In this example both the source 12c and target 21c databases are hosted in OCI – but the same procedure can easily be adopted to migrate (and upgrade) an on-premises Oracle database to OCI.

Oracle Zero Downtime Migration (ZDM) is the free-to-use Oracle Maximum Availability Architecture (MAA)-recommended solution to migrate Oracle Databases to the Oracle Cloud Infrastructure.

ZDM provides a number of migration options – Physical offline,Physical online, Logical offline, Logical online.

In a Logical Online migration, users are still connected to a live database while ZDM is executing in the background. Internally ZDM uses Oracle GoldenGate technology to enable the ‘zero-downtime’ migration as well as Oracle Data Pump.

These series of posts provide a step-by-step procedure of how to do an Online Logical Migration of an Oracle Database 12c to Oracle Database 21c.

In this example both the source 12c and target 21c databases are hosted in OCI – but the same procedure can easily be adopted to migrate (and upgrade) an on-premises Oracle database to OCI.

Provision a Linux OS compute instance for the ZDM hub in OCI. Ensure the boot volume size is at least 220 GB in size.

After the compute instance has been provisioned, extend the logical volume.

[opc@zdm-hub ~]$  sudo su -
[root@zdm-hub ~]# /usr/libexec/oci-growfs -y

Install the following RPM’s via yum – glibc-devel, expect, unzip, libaio, oraclelinux-developer-release-el7.

[root@zdm-hub ~]# yum install glibc-devel expect unzip libaio oraclelinux-developer-release-el7 -y

Create the ZDM user account (zdmuser) and ZDM group (zdm).

[root@zdm-hub ~]# groupadd zdm
[root@zdm-hub ~]#  useradd -g zdm zdmuser

Create the directrory structure for the ZDM installation.

[root@zdm-hub ~]# cd /
[root@zdm-hub /]# mkdir u02
[root@zdm-hub /]# cd /u02
[root@zdm-hub u02]# mkdir zdmuser/zdminstall
[root@zdm-hub u02]# cd zdmuser
[root@zdm-hub zdmuser]# mkdir zdmhome
[root@zdm-hub zdmuser]# mkdir zdmbase

Copy the download ZDM software to the ZDM compute node. Set the ZDMBASE and ZDMHOME environment variables.

[root@zdm-hub u02]# cp /home/opc/V1019875-01.zip /u02/zdmuser/zdminstall/
[root@zdm-hub zdmuser]#  cd /u02
[root@zdm-hub u02]# chown -R zdmuser:zdm /u02
[root@zdm-hub u02]# su – zdmuser
[zdmuser@zdm-hub ~]$ vi .bash_profile
ZDMHOME=/u02/zdmuser/zdmhome
export ZDMHOME
ZDMBASE=/u02/zdmuser/zdmbase
export ZDMBASE
[zdmuser@zdm-hub ~]$ . ./.bash_profile

Unzip the ZDM 21.3 software in the appropriate directory and execute the zdminstall.sh script.

[zdmuser@zdm-hub ~]$  cd  /u02/zdmuser/zdminstall
[zdmuser@zdm-hub zdminstall]$ unzip V1019875-01.zip
Archive:  V1019875-01.zip
   creating: zdm21.3/
  inflating: zdm21.3/README
  inflating: zdm21.3/zdminstall.sh
  inflating: zdm21.3/CredentialsDriver.class
 extracting: zdm21.3/zdm_home.zip
   creating: zdm21.3/rhp/
 extracting: zdm21.3/rhp/zdm.build
  inflating: zdm21.3/schema_operations.sh
[zdmuser@zdm-hub ~]$ cd /u02/zdmuser/zdminstall/zdm21.3
[zdmuser@zdm-hub zdm21.3]$  ./zdminstall.sh setup oraclehome=$ZDMHOME oraclebase=$ZDMBASE ziploc=/u02/zdmuser/zdminstall/zdm21.3/zdm_home.zip -zdm
ZDM kit home: /u02/zdmuser/zdminstall/zdm21.3
/u02/zdmuser/zdminstall/zdm21.3
---------------------------------------
Unzipping shiphome to ZDM home...
---------------------------------------
Unzipping shiphome...
Shiphome unzipped successfully..
---------------------------------------
##### Performing GridHome Software Only Installation #####
---------------------------------------
Installation log location: /u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/logs/runInstaller_1675660051.out
making dir /u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/conf
---------------------------------------
Generating Preference file
---------------------------------------
/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/conf/rhp.pref
Using port 8897 for MySQL
---------------------------------------
Generating Root Certificate
---------------------------------------
Cluster root certificate generated successfully.
---------------------------------------
Generating CA CERTS file
---------------------------------------
spawn /u02/zdmuser/zdmhome/bin/crskeytoolctl -copycacerts -filestore /u02/zdmuser/zdmbase/crsdata/zdm-hub/security
Enter JRE cacerts truststore password:
JRE cacerts copied to file [/u02/zdmuser/zdmbase/crsdata/zdm-hub/security/cacerts].
---------------------------------------
Generating nogi.enabled file
---------------------------------------
nogi.enabled file generated sucessfully
---------------------------------------
Generating standalone_config.properties file
---------------------------------------
Setting base folder permissions
---------------------------------------
Copying service script to bin folder in Oracle Home
RHP_PT.ZDM21_LINUX.X64_220214.7
rhpctl working
label_date is: 220214.7
---------------------------------------
Storing to wallet
---------------------------------------
cacerts  crskeytoolctl.log  cwallet.sso  cwallet.sso.lck
---------------------------------------
Generating random password
---------------------------------------
-rw-------. 1 zdmuser zdm 4325 Feb  6 05:07 /u02/zdmuser/zdmbase/crsdata/zdm-hub/security/cwallet.sso
-rw-------. 1 zdmuser zdm 4325 Feb  6 05:07 /u02/zdmuser/zdmbase/crsdata/zdm-hub/security/cwallet.sso
---------------------------------------
Setting up MySQL...
---------------------------------------
spawn /u02/zdmuser/zdmhome/mysql/server/bin/mysqladmin --defaults-file=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/conf/my.cnf -u root -p ping
---------------------------------------
Storing to wallet
---------------------------------------
cacerts  crskeytoolctl.log  cwallet.sso  cwallet.sso.lck
---------------------------------------
Generating random password
---------------------------------------
-rw-------. 1 zdmuser zdm 4445 Feb  6 05:08 /u02/zdmuser/zdmbase/crsdata/zdm-hub/security/cwallet.sso
-rw-------. 1 zdmuser zdm 4445 Feb  6 05:08 /u02/zdmuser/zdmbase/crsdata/zdm-hub/security/cwallet.sso
spawn /u02/zdmuser/zdmhome/mysql/server/bin/mysql --socket=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/mysql/metadata/mysql.sock -u root
---------------------------------------
Creating MySQL DB and user...
---------------------------------------
spawn /u02/zdmuser/zdmhome/mysql/server/bin/mysql --socket=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/mysql/metadata/mysql.sock -u root -p -e CREATE DATABASE IF NOT EXISTS GHSUSER21;
spawn /u02/zdmuser/zdmhome/mysql/server/bin/mysql --socket=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/mysql/metadata/mysql.sock -u root -p
spawn /u02/zdmuser/zdmhome/mysql/server/bin/mysql --socket=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/mysql/metadata/mysql.sock -u root -p -e GRANT ALTER, CREATE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, INDEX, INSERT, LOCK TABLES, REFERENCES, SELECT, SHOW VIEW, UPDATE ON GHSUSER21.* TO 'GHSUSER21'@'localhost';
current node is active node
spawn /u02/zdmuser/zdmhome/mysql/server/bin/mysqladmin --defaults-file=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/conf/my.cnf -u root -p shutdown
---------------------------------------
Adding Certs to ZDM
---------------------------------------
ZDM service setup finished successfully...

[zdmuser@zdm-hub zdm21.3]$

Execute the zdmservice start command to start the ZDM service.

[zdmuser@zdm-hub zdm21.3]$  $ZDMHOME/bin/zdmservice start
Use of uninitialized value in concatenation (.) or string at /u02/zdmuser/zdmhome/lib/jwcctl_lib.pm line 571.
 CRS_ERROR:WARNING: Invalid data ALWAYS_ON= in _USR_ORA_ENV
No instance detected, starting zdmservice
spawn /u02/zdmuser/zdmhome/mysql/server/bin/mysqladmin --defaults-file=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/conf/my.cnf -u root -p ping

 WARNING: oracle.jwc.jmx does not exist in the configuration file. It will be TRUE by default.
Use of uninitialized value in concatenation (.) or string at /u02/zdmuser/zdmhome/lib/jwcctl_lib.pm line 571.
 WARNING: oracle.jwc.env.user.always_on does not exist in the configuration file. It will be FALSE by default.
 CRS_ERROR:WARNING: Invalid data ALWAYS_ON= in _USR_ORA_ENV
[jwcctl debug] Environment ready to start JWC
[jwcctl debug] Return code of initialization: [0]

[jwcctl debug] ... BEGIN_DEBUG [Action= start] ...
Start JWC
[jwcctl debug] Loading configuration file: /u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/conf/jwc.properties
[jwcctl debug]     oracle.jmx.login.credstore = CRSCRED
[jwcctl debug]     oracle.jmx.login.args = DOMAIN=rhp CACHE_ENABLED=true CACHE_EXPIRATION=180
[jwcctl debug]     oracle.rmi.url = service:jmx:rmi://{0}:{1,number,#}/jndi/rmi://{0}:{1,number,#}/jmxrmi
[jwcctl debug]     oracle.http.url = http://{0}:{1,number,#}/rhp/gridhome
[jwcctl debug]     oracle.jwc.tls.clientauth = false
[jwcctl debug]     oracle.jwc.tls.rmi.clientfactory = RELOADABLE
[jwcctl debug]     oracle.jwc.lifecycle.start.log.fileName = JWCStartEvent.log
[jwcctl debug]     oracle.jwc.http.connector.ssl.protocols = TLSv1.2,TLSv1.3
[jwcctl debug] Get JWC PIDs
[jwcctl debug] Done Getting JWC PIDs
[jwcctl debug] ... JWC containers not found ...
[jwcctl debug]     Start command:-server -Xms2048M -Xmx4096M -Djava.awt.headless=true -Ddisable.checkForUpdate=true -Djava.util.logging.config.file=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -DTRACING.ENABLED=true -DTRACING.LEVEL=2 -Doracle.wlm.dbwlmlogger.logging.level=FINEST -Duse_scan_IP=true -Djava.rmi.server.hostname=localhost -Doracle.http.port=8896 -Doracle.jmx.port=8895 -Doracle.tls.enabled=false -Doracle.jwc.tls.http.enabled=false -Doracle.rhp.storagebase=/u02/zdmuser/zdmbase -Djava.security.manager -Djava.security.policy=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/conf/catalina.policy -Djava.security.egd=file:/dev/urandom -Doracle.jwc.wallet.path=/u02/zdmuser/zdmbase/crsdata/zdm-hub/security -Doracle.jmx.login.credstore=WALLET -Doracle.rest.enabled=false -Doracle.jmx.enabled=true -Dcatalina.home=/u02/zdmuser/zdmhome/tomcat -Dcatalina.base=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp -Djava.io.tmpdir=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/temp -Doracle.home=/u02/zdmuser/zdmhome -Doracle.jwc.mode=STANDALONE -classpath /u02/zdmuser/zdmhome/jlib/cryptoj.jar:/u02/zdmuser/zdmhome/jlib/oraclepki.jar:/u02/zdmuser/zdmhome/jlib/osdt_core.jar:/u02/zdmuser/zdmhome/jlib/osdt_cert.jar:/u02/zdmuser/zdmhome/tomcat/lib/tomcat-juli.jar:/u02/zdmuser/zdmhome/tomcat/lib/bootstrap.jar:/u02/zdmuser/zdmhome/jlib/jwc-logging.jar org.apache.catalina.startup.Bootstrap start
[jwcctl debug] Get JWC PIDs
[jwcctl debug] Done Getting JWC PIDs
[jwcctl debug] ... JWC Container (pid=31664) ...
[jwcctl debug] ... JWC Container running (pid=31664) ...
[jwcctl debug]     Check command:-Djava.net.preferIPv6Addresses=true -Dcatalina.base=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp -Doracle.wlm.dbwlmlogger.logging.level=FINEST -Doracle.jwc.client.logger.file.name=/u02/zdmuser/zdmbase/crsdata/zdm-hub/rhp/logs/jwc_checker_stdout_err_%g.log -Doracle.jwc.client.logger.file.number=10 -Doracle.jwc.client.logger.file.size=1048576 -Doracle.jwc.wallet.path=/u02/zdmuser/zdmbase/crsdata/zdm-hub/security -Doracle.jmx.login.credstore=WALLET -Doracle.tls.enabled=false -Doracle.jwc.tls.http.enabled=false -classpath /u02/zdmuser/zdmhome/jlib/jwc-logging.jar:/u02/zdmuser/zdmhome/jlib/jwc-security.jar:/u02/zdmuser/zdmhome/jlib/jwc-client.jar:/u02/zdmuser/zdmhome/jlib/jwc-cred.jar:/u02/zdmuser/zdmhome/jlib/srvm.jar:/u02/zdmuser/zdmhome/jlib/srvmhas.jar:/u02/zdmuser/zdmhome/jlib/cryptoj.jar:/u02/zdmuser/zdmhome/jlib/oraclepki.jar:/u02/zdmuser/zdmhome/jlib/osdt_core.jar:/u02/zdmuser/zdmhome/jlib/osdt_cert.jar:/u02/zdmuser/zdmhome/tomcat/lib/tomcat-juli.jar oracle.cluster.jwc.tomcat.client.JWCChecker localhost 8896 -1

[jwcctl debug] ... JWC Container is ready ...
[jwcctl debug] ... START - Return code = 0 ...
[jwcctl debug]  ... END_DEBUG [Action=start] ...
[jwcctl debug] Return code of AGENT: [0]

Return code is 0
Server started successfully.

Execute the zdmservice status command to verify the status of the ZDM service.

[zdmuser@zdm-hub zdm21.3]$  $ZDMHOME/bin/zdmservice status
Use of uninitialized value in concatenation (.) or string at /u02/zdmuser/zdmhome/lib/jwcctl_lib.pm line 571.
 CRS_ERROR:WARNING: Invalid data ALWAYS_ON= in _USR_ORA_ENV

---------------------------------------
        Service Status
---------------------------------------

 Running:       true
 Tranferport:
 Conn String:   jdbc:mysql://localhost:8897/
 RMI port:      8895
 HTTP port:     8896
 Wallet path:   /u02/zdmuser/zdmbase/crsdata/zdm-hub/security

To check the version of the ZDM environment, we can issue the zdmcli -build command.

[zdmuser@zdm rhp]$  $ZDM_HOME/bin/zdmcli -build
version: 21.0.0.0.0
full version: 21.3.0.0.0
label date: 220214.7
ZDM kit build date: Mar 03 2022 19:35:40 PST
CPAT build version: 22.5.2
Updated on May 10, 2023

Was this article helpful?

Related Articles

Leave a Comment