Tuesday 30 April 2024

Oracle on Windows: out-of-place Patching with Virtual Account

This guide shows a way, how a Gold Image can be created from an Oracle Home on Windows and how that can be used to patch other Oracle Homes. This worked for me, but is not meant to be the only, best or officially recommended Oracle way.

Prepare the image source home

Say we have an unpatched 19.3 installed in c:\oracle\product\19.0.0\dbhome_1 with a database ORCL (non-PDB), installed with the option to use a Virtual Account, which is the default from the Oracle installer.

So the owner for the Oracle software home and datafiles has been created as ORA_OraDB19Home1_SVCACCTS by the installer.
Next we set up a new Oracle home and patch it, to make it the source of our gold image in c:\oracle\product\19.0.0\dbhome_2.

There is no standard oraenv.sh under Windows. As some tasks have to be done from the old and some from the new home, it helps to create two different oraenv scripts, eg. old-oraenv.cmd and new-oraenv.cmd , like in my environment:

old-oraenv.cmd

set ORACLE_BASE=C:\Oracle
set ORACLE_HOME=%ORACLE_BASE%\Product\19.0.0\dbhome_1
set PATH=%ORACLE_HOME%\bin;%PATH%
set PATH=%ORACLE_HOME%\perl\bin;%PATH%
set PATH=%ORACLE_HOME%\OPatch\;%PATH%
set PATH=%ORACLE_HOME%\jdk\bin\;%PATH%

new-oraenv.cmd

set ORACLE_BASE=C:\Oracle
set OLDORA_HOME=%ORACLE_BASE%\Product\19.0.0\dbhome_1
set ORACLE_HOME=%ORACLE_BASE%\Product\19.21\dbhome_3
set PATH=%ORACLE_HOME%\bin;%PATH%
set PATH=%ORACLE_HOME%\perl\bin;%PATH%
set PATH=%ORACLE_HOME%\OPatch\;%PATH%
set PATH=%ORACLE_HOME%\jdk\bin\;%PATH%

Run your oraenv.cmd, unpack the software (you can use tar xfz under Windows for unzip) and run setup.bat, see the Database Installation Guide 19c for Microsoft Windows

C:\app>oraenv.cmd
C:\app>mkdir %ORACLE_HOME%
C:\app>cd %ORACLE_HOME%
C:\app\oracle\product\19.0.0\dbhome_2>tar xfz z:\Install\Windows\WINDOWS.X64_193000_db_home.zip
C:\app\oracle\product\19.0.0\dbhome_2>setup.bat 

We only need to setup the software only and this is a single instance installation. Under Linux, we would just apply the RU and one-offs from the setup, but the options '-applyRU 'and '-applyOneOffs' are not available under Windows (see the comments on https://mikedietrichde.com/2022/05/17/simple-database-installation-with-applyru-and-applyoneoffs/, search for Windows).

Update opatch by following Doc ID 274526.1 from Oracle Support, in this case using opatch 12.2.0.1.41.

For the Gold Image, we will patch the 19.3 dbhome_2 up to 19.21 plus two one-off patches for the JVM. So download and unpack the patches to a given directory, in this example c:\app\oracle\patches. The patch numbers are 35638318, 35648110 and 35681552, these have to be applied manually by running opatch apply in every patch directory, starting with 35681552 which is the Bundle Patch 19.21.

Now the dbhome_2 is on 19.21 with two additional one-off patches and will serve as source for our Gold Image.

Create the Gold Image

Next, from the patched Oracle Home, we create a Gold Image following the documentation.

setup.exe -createGoldImage -destinationLocation c:\oracle\images 

Wait for the installer to finish, then you should have the newly created image in the directory stated by -destinationLocation. The dbhome_2 can be deleted with Oracle's deinstall program.

Out-of-place patching using the Gold Image

We now have an unpatched Oracle 19.3 home in dbhome_1 with the database ORCL and a gold image with version version 19.21 and two one-off patches.

For out-of-place patching, we need to create a new Oracle Home, where we unpack the Gold Image. 

C:\app>new-oraenv.cmd
C:\app>mkdir %ORACLE_HOME%
C:\app>cd %ORACLE_HOME%
C:\app\oracle\product\19.21\dbhome_3>tar xfz c:\app\oracle\images\db_home_2024-02-21_05-21-14PM.zip
C:\app\oracle\product\19.21\dbhome_3>setup

Run setup, choose software only and accept the default virtual account. If setup.exe crashes with a Java EXCEPTION_ACCESS_VIOLATION, follow MOS note 2772729.1.

rem --- Copy spfile and pwdfile to new ORACLE_HOME
copy %OLDORA_HOME%\database\SPFILEORCL.ORA %ORACLE_HOME%\database
copy %OLDORA_HOME%\database\PWDorcl.ora    %ORACLE_HOME%\database

Shutdown the database first, then copy the spfile and pwdfile to the new dbhome_3
The setup has created a new user ORA_OraDB19Home2_SVCACCTS and granted full control for the oradata directory, so the Oracle software from the new dbhome_2 can take over the files from the old dbhome_1.
On Unix/Linux systems, we would already be done, but on Windows we have services which need to be migrated to the new Oracle Home.
In the registry, we see that some services are linked to a given Oracle Home, so these need to be recreated.

set OLDORA_HOME=%ORACLE_BASE%\product\19.0.0\dbhome_1

rem --- use oradim to delete Oracle services ---
oradim -DELETE -SID orcl

For easier scripting, we point OLDORA_HOME to the Oracle home running the old version.
First delete the instance services with oradim, which will remove OracleServiceORCL, OracleVssWriterORCL and OracleJobSchedulerORCL. 
The Oracle Home specific services will remain. These will be deleted, when deleting the dbhome_1. 

rem --- stop remaining Oracle services ---
sc stop OracleOraDB19Home1MTSRecoveryService
sc config OracleOraDB19Home1MTSRecoveryService start= disabled
sc stop OracleOraDB19Home1TNSListener
sc config OracleOraDB19Home1TNSListener start=disabled

But as one advantage of out-of-place patching is, that you can go back to the old version, you probably want to keep them for some time, so we will just disable them.
The remaining services should now be stopped and disabled.

rem --- create new services for new Oracle home
oradim -NEW -SID orcl -STARTMODE auto -SRVCSTART system -SPFILE -PFILE %ORACLE_HOME%\database\SPFILEORCL.ORA

Then use oradim again to create the instance specific services
It recreates the OracleServiceorcl, OracleVssWriterorcl and OracleJobSchedulerorcl for the new Oracle home.
Double checking from the Registry, that we are now running on the patched dbhome_3
Also from SQLPlus, everything looks fine.

rem --- recreate remaining services
%ORACLE_HOME%\bin\oramtsctl -new
%ORACLE_HOME%\bin\lsnrctl start
sc config "OracleOraDB19Home3TNSListener" start= auto

The formerly disabled services from the old home need to be recreated for the new home. Starting the Listener automatically creates a new Service for the new home. That should be configured to start automatically.

Now we have migrated all services to the new Oracle home.

rem --- start the database and run datapatch
rem --- not needed with service auto start --- @echo startup | sqlplus / as sysdba
rem --- @echo alter pluggable database all open | sqlplus / as sysdba
rem --- @echo show pdbs | sqlplus / as sysdba
@echo @?/rdbms/admin/utlrp.sql | sqlplus / as sysdba
%ORACLE_HOME%\OPatch\datapatch

Before running the datapatch, make sure that all pds are open if already running on Mutlitenant architecture. When the open state has been saved by using ALTER PLUGGABLE DATABASE ... SAVE STATE, that step can be skipped. Here we open all PDB's before running the datapatch 
The database software and data dictionary should now be on the new version.

rem --- apply optimizer fixes for every PDB
@echo @?/rdbms/admin/dbmsoptim.sql | sqlplus / as sysdba
@echo @?/rdbms/admin/prvtoptim.plb | sqlplus / as sysdba
@echo execute dbms_optim_bundle.enable_optim_fixes('ON','BOTH', 'YES'); | sqlplus / as sysdba

Last step is enabling the optimizer fixes for the new version. That's it, we are running on 19.21 after out-of-place patching.
Finally, after some time, you might want to delete the old 19.3 Oracle home dbhome_1. Run %ORACLE_HOME%\deinstall\deinstall.bat to clean up the old installation.
After the deinstallation of the old home, only the patched 19.21 services from dbhome_3 will remain.

The complete scripting can be found on GitLab.