Monthly Archives: February 2022


The OPatch, .patch_storage and its space issues: the solutions!

[a new solution is available as of 2023. Read here about the new OPatch util DeleteInactivePatches option.]

I love database patching and apart of the tiring coordination work or the applications that keep to not automatically reconnect to the database, all is usually perfect and issue free. Well, almost. The most common error are space issues.

You can try to follow the Oracle guidelines and have a 100 GB partition for the $ORACLE_HOME(s). Initially it only uses 7 or 8 GB per home, but after few years you are fighting against the space pressure.

There are several strategies to prevent or act against this space problem when patching:

Solution 1 – Recreate separate Oracle Home from scratch

It is a clean solution, when you make really from scratch, meaning no home cloning, no opatchauto apply -outofplace, and then apply only the latest patch there. This solution is quite easy to do for DB home. However when you have Grid Home this is a bit more hassle.

Solution 2 – Use the opatch hidden “archive” feature

This feature allows to move out from .patch_storage folder some patches in a zip format. It was “documented” by Mike Dietrich in his blog. Unfortunately to have a common archive between different Oracle Homes you need to do some hand work: archive on one Oracle Home, delete the patches from remaining homes and copy the $ORACLE_HOME/OPatch/.patch_storage/.patch_archive_mapping.xml file to the other homes. Of course this works when all Homes have exactly the same features installed and patches. Keep in mind that before rollback you need to use the “unarchive” option and that the rollback procedure will restore the files that were changed, and this can vary depending on the state of the oracle home at the moment of patch. Use opatch util archive -help for more info.

Here we are not saving any space, just moving the problem away. The other partition can be a remote slower location, but the patching will also then be slower, as it will need to copy files there. Use: TARGET=<partition>/patch_storage ; mv $ORACLE_HOME/.patch_storage $TARGET ; ln -s $TARGET $ORACLE_HOME/.patch_storage

Solution 4 – Remove unneeded patches from .patch_storage

In $ORACLE_HOME/.patch_storage the whole history of patches you applied is kept. You can rollback one after the other and bring the Oracle Home several steps behind. However, the most of the cases you are ok to just be able to move one step backward. The older history of the home is past. If that is you case, then there is this nice Python script clean_patch_storage.py which is based on the premise of Oracle Doc ID 550522.1 which states you can “remove all the sub-directories from $ORACLE_HOME/.patch_storage that are not present in the list of installed patches”. The list directories you can delete is exactly what the script do.


Maybe you have other solutions or tricks, please share in the comments.


Solution for ODA 19.13 list-availablepatches error

After patching an ODA to 19.13, often we have the error

[root@oda-01 DB1]# odacli list-availablepatches
DCS-10001:Internal error encountered: For input string: "".

The workaround provided by Oracle on the 19.13 “Known Issues” is incomplete and might not solve the problem in many cases.

The complete solution is to change all patchmetadata.xml files where this “targetVersion” is missing. Here is the sed command that creates a backup (extension .bck) and adds the missing bit:

sed -i.bck -E 's/name="DB" repotag="(1[0-9]\.[0-9]{1,2}\.[0-9]\.[0-9]\.[0-9]{6})"><\/component>/name="DB" repotag="\1" targetVersion="\1"><\/component>/g' /opt/oracle/oak/pkgrepos/System/*/patchmetadata.xml

Now, odacli list-availablepatches is back to normal:

[root@oda-01 DB1]# odacli list-availablepatches
-------------------- ------------------------- -------------------------
ODA Release Version  Supported DB Versions     Available DB Versions
-------------------- ------------------------- -------------------------

19.6.0.0.0           19.6.0.0.200114           Clone not available
                     18.9.0.0.200114           Clone not available
                     12.2.0.1.200114           Clone not available
                     12.1.0.2.200114           Clone not available
                     11.2.0.4.200114           Clone not available

19.13.0.0.0          21.4.0.0.211019           Clone not available
                     19.13.0.0.211019          19.13.0.0.211019
                     12.2.0.1.211019           Clone not available
                     12.1.0.2.211019           Clone not available

19.10.0.0.0          19.10.0.0.210119          Clone not available
                     18.13.0.0.210119          Clone not available
                     12.2.0.1.210119           Clone not available
                     12.1.0.2.210119           Clone not available
                     11.2.0.4.210119           Clone not available

18.8.0.0.0           18.8.0.0.191015           Clone not available
                     18.8.0.0.191015           Clone not available
                     12.2.0.1.191015           Clone not available
                     12.1.0.2.191015           Clone not available
                     11.2.0.4.191015           Clone not available

18.5.0.0.0           11.2.0.4.190115           Clone not available
                     12.1.0.2.190115           Clone not available
                     12.2.0.1.190115           12.2.0.1.190115
                     18.5.0.0.190115           Clone not available

18.4.0.0.0           11.2.0.4.181016           Clone not available
                     12.1.0.2.181016           Clone not available
                     12.2.0.1.181016           Clone not available
                     18.4.0.0.181016           Clone not available

18.2.1.0.0           11.2.0.4.180417           Clone not available
                     12.1.0.2.180417           Clone not available
                     12.2.0.1.180417           Clone not available

12.2.1.4.0           11.2.0.4.180417           Clone not available
                     12.1.0.2.180417           Clone not available
                     12.2.0.1.180417           Clone not available

Useful aliases for ODA Patching

Patching an Oracle Database Appliance can be tiring. The ODA patching commands are quite long and there is always a jobid to check… So I just created a set of alias that make these tasks a bit easier:

# List jobs run today - $ jt
alias jt="odacli list-jobs -o $(date +%Y-%m-%d)"

# Describe one job - $ j <id>
alias j="odacli describe-job -i $1"

# Describe last job created - $ lj
alias lj='odacli describe-job -i $(odacli list-jobs -tl 1 | sed -n 4p | cut -d" " -f1)'

# Describe last prepatch report - $ lpr
alias lpr='odacli describe-prepatchreport -i $(odacli list-jobs -tl 1 | sed -n 4p | cut -d" " -f1)'

# Show free space of / /u01 and /opt - $ dff
alias dff="df -h / /u01 /opt"

# Describe components - $ comp
alias comp="odacli describe-component"

# Tail -f DCS Agent log - $ tal
alias tal="tail -f /opt/oracle/dcs/log/dcs-agent.log"

Maybe you have other suggestions?