Thursday, September 15, 2022

datapatch throws Error: prereq checks failed! patch 32218454: Error reading descriptor from registry: Couldn't open encmap cp866.enc: No such file or directory

I caught this error when I was running $ORACLE_HOME/OPatch/datapatch -verbose command to apply all the patches of 19.14 RU to 19.13 CDB and its PDBs. The error looked like this :

$ $ORACLE_HOME/OPatch/datapatch -verbose
SQL Patching tool version 19.14.0.0.0 Production on Wed Sep 14 20:31:36 2022
Copyright (c) 2012, 2021, Oracle.  All rights reserved.

Log file for this invocation: /u01/app/oracle/cfgtoollogs/sqlpatch/sqlpatch_29306_2022_09_14_20_31_36/sqlpatch_invocation.log

Connecting to database...OK
Gathering database info...done

Note:  Datapatch will only apply or rollback SQL fixes for PDBs
      that are in an open state, no patches will be applied to closed PDBs.
      Please refer to Note: Datapatch: Database 12c Post Patch SQL Automation
      (Doc ID 1585822.1)

Bootstrapping registry and package to current versions...done
Determining current state...done

...


 PDB PDB2:
   Applied 19.13.0.0.0 Release_Update 211010063823 successfully on 16-NOV-21 07.25.29.732858 PM

Error: prereq checks failed!
 patch 32218454: Error reading descriptor from registry: Couldn't open encmap cp866.enc:
No such file or directory
at /u01/app/oracle/product/19/db_1914/perl/lib/site_perl/5.28.1/sun4-solaris-thread-multi-64/XML/Parser.pm line 187.
XML::Simple called at /u01/app/oracle/product/19/db_1914/sqlpatch/sqlpatch.pm line 8123.

Prereq check failed, exiting without installing any patches.

Please refer to MOS Note 1609718.1 and/or the invocation log
/u01/app/oracle/cfgtoollogs/sqlpatch/sqlpatch_29306_2022_09_14_20_31_36/sqlpatch_invocation.log
for information on how to resolve the above errors.

SQL Patching tool complete on Wed Sep 14 20:32:23 2022

I can only guess why this error happened. Recently I plugged PDB with codepage RU8PC866 over the network and deleted it after a while. So some information had left inside registry$sqlpatch, and I can assume, it has xml part presented in ru8pc866 codepage. The datapatch invokes perl. The information is parsed by xml-parser perl module (from ORACLE_HOME). It seemed that possible solution was rebuilding registry$sqlpatch (required downtime, sounacceptable) or trying to find missed file (I chose the second). 

So, perl module xml-parser has got the following supported (from the box) codepages :

$ l $ORACLE_HOME/perl/lib/site_perl/5.28.1/sun4-solaris-thread-multi-64/XML/Parser/Encodings/
total 554
drwxr-xr-x   2 oracle   oinstall      26 Sep 14 23:01 .
drwxr-xr-x   4 oracle   oinstall       6 Mar 10  2022 ..
-rwxr-x---   1 oracle   oinstall   40706 Mar 26  2019 big5.enc
-rwxr-x---   1 oracle   oinstall   45802 Mar 26  2019 euc-kr.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 ibm866.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 iso-8859-2.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 iso-8859-3.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 iso-8859-4.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 iso-8859-5.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 iso-8859-7.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 iso-8859-8.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 iso-8859-9.enc
-rwxr-x---   1 oracle   oinstall    4821 Mar 26  2019 Japanese_Encodings.msg
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 koi8-r.enc
-rwxr-x---   1 oracle   oinstall    1950 Mar 26  2019 README
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 windows-1250.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 windows-1251.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 windows-1252.enc
-rwxr-x---   1 oracle   oinstall    1072 Mar 26  2019 windows-1255.enc
-rwxr-x---   1 oracle   oinstall   37890 Mar 26  2019 x-euc-jp-jisx0221.enc
-rwxr-x---   1 oracle   oinstall   37890 Mar 26  2019 x-euc-jp-unicode.enc
-rwxr-x---   1 oracle   oinstall   20368 Mar 26  2019 x-sjis-cp932.enc
-rwxr-x---   1 oracle   oinstall   18202 Mar 26  2019 x-sjis-jdk117.enc
-rwxr-x---   1 oracle   oinstall   18202 Mar 26  2019 x-sjis-jisx0221.enc
-rwxr-x---   1 oracle   oinstall   18202 Mar 26  2019 x-sjis-unicode.enc

I needed to find cp866.enc file somewhere. The README file says :

This directory contains binary encoding maps for some selected encodings.
If they are placed in a directory listed in @XML::Parser::Expat::Encoding_Path,
then they are automatically loaded by the XML::Parser::Expat::load_encoding
function as needed. Otherwise you may load what you need directly by
explicitly calling this function.

These maps were generated by a perl script that comes with the module
XML::Encoding, compile_encoding, from XML formatted encoding maps that
are distributed with that module. These XML encoding maps were generated
in turn with a different script, domap, from mapping information contained
on the Unicode version 2.0 CD-ROM. This CD-ROM comes with the Unicode
Standard reference manual and can be ordered from the Unicode Consortium
at http://www.unicode.org. The identical information is available on the
internet at ftp://ftp.unicode.org/Public/MAPPINGS.

So the task is to find both the scripts and get the source of 866 codepage (found CP866.TXT on ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC)

Both compile_encoding and domap (actually, make_encmap) scripts I found in libxml-encoding-perl_2.09-1_all.deb (untar data.tar.xz from downloaded file). So, do these steps :

tar xf ./data.tar.xz 

cd usr/bin

./make_encmap cp866 /temp/service_request/perl/CP866.TXT > cp866_make.out

Edit cp866_make.out (it's actually an xml description of codepage 866) to add expat='yes' at the first line and compile :

<encmap name='cp866' expat='yes'>

./compile_encoding -o cp866.enc cp866_make.out

Put the cp866.enc file into perl module's xml-parser encodings directory, for me it was /u01/app/oracle/product/19/db_1914/perl/lib/site_perl/5.28.1/sun4-solaris-thread-multi-64/XML/Parser/Encodings

and rerun datapatch. In my particular case I cought another error not related to this topic :

Unsupported named object type for bind parameter at /u01/app/oracle/product/19/db_1914/sqlpatch/sqlpatch.pm line 5783.

The cause of it was an absense of tempfile inside one of PDB's temporary tablespace. After adding I ended up with whole CDB patched.

The conclusion : do not use stale and deprecated codepages to keep your data in 😀 ! Oracle recommends all its customers to migrate to AL32UTF8 (but it requres much efforst in many cases and it depends, actually...)

PS. I still don't understand how the patch numbered 32218454 (database 19.10 RU) has turned out to be a cause of this issue. Only one assumption : it had been used with one of PDBs ORACLE_HOME before being plugged in into CDB.



No comments:

Post a Comment