Thursday, March 2, 2023

Rolling upgrade of Oracle database from 12c to 19c - short outline

1. check unsupported objects on primary database :

SQL> select * from dba_rolling_unsupported ;

if find any - export them (if possible, or treat them in other way) and remove them from the database, then import after upgrade if needed

SQL> select 'drop table '||owner||'.'||table_name||' ;' from dba_rolling_unsupported ;

2. check unsupported objects again

2.2 create tracking table on the primary

SQL> create table c##ddi.tracking_table (phase number, text varchar2(4000)) ;
SQL> insert into c##ddi.tracking_table values (1, 'Start') ;

3. although using DG broker is supported during rolling upgrade (starting from version 12.2), i would recommend to disable data guard broker on primary and all standby databases (i caught some bugs on it) :

% dgmgrl sys/aaa
DGMGRL> disable configuration ;

SQL> alter system set dg_broker_start = false ;

3.1 configure archivelog destination for future primary database (in case dataguard broker is disabled) :

SQL> alter system set log_archive_dest_2 = 'service="dg-bbb-test1-loc1" ASYNC NOAFFIRM delay=0 optional compression=disable max_failure=0 max_connections=1 reopen=60 db_unique_name="bbb_tes
t1_loc1" net_timeout=30 valid_for=(online_logfile,all_roles)'

4. initialize rolling upgrade plan   

SQL> begin dbms_rolling.init_plan (future_primary => 'bbb_test1_loc2') ; end ;

5. query rolling plan  

SQL> select scope, name, curval from dba_rolling_parameters order by scope, name;

6. build the plan

SQL> begin dbms_rolling.build_plan ; end ;

6.1 verify the plan

SQL> select batchid,source,target,description,phase,status from dba_rolling_plan ;

7. start the plan

SQL> begin dbms_rolling.start_plan ; end ;

7.1 look through the events history :

SQL> select event_time,type,message from dba_rolling_events ;

8. insert data into tracking table on the primary (may be created earlier)

SQL> insert into c##ddi.tracking_table values (2, 'plan started, bbb_test1_loc2 is now TLS') ;

8.1 query this table on the TLS. you must see the data there as well

9. UPGRADE TLS to 19c

9.1 prepare cfg file upg1.cfg like this :

global.autoupg_log_dir=/u01/app/oracle/cfgtoollogs/autoupgrade

#
# Database number 1 - Full DB/CDB upgrade
#
upg1.log_dir=/u01/app/oracle/cfgtoollogs/autoupgrade/bbb_test1_loc2
upg1.sid=bbb_test1_loc2
upg1.source_home=/u01/app/oracle/product/12.2/db_202201  # Path of the source ORACLE_HOME
upg1.target_home=/u01/app/oracle/product/19/db_1917  # Path of the target ORACLE_HOME
upg1.start_time=NOW                                       # Optional. [NOW | +XhYm (X hours, Y minutes after launch) | dd/mm/yyyy hh:mm:ss]
upg1.run_utlrp=yes                                  # Optional. Whether or not to run utlrp after upgrade
upg1.timezone_upg=yes                               # Optional. Whether or not to run the timezone upgrade
upg1.target_version=19                      # Oracle version of the target ORACLE_HOME.  Only required when the target Oracle database version is 12.2
upg1.remove_underscore_parameter=yes
upg1.restoration=no

do other required staff (configure wallet to be opened automatically and so on)
 

9.2 run autoupgrade in analyze mode :

$ /u01/app/oracle/product/19/db_1917/jdk/bin/java -jar /mnt/tst/install/oracle/autoupgrade/autoupgrade.jar -restore_on_fail -config /export/home/oracle/migration/bbb_test1_loc2_to_19c/upg1.cfg -mode analyze

check logfiles carefully

9.3 run autoupgrade in deploy mode :

$ /u01/app/oracle/product/19/db_1917/jdk/bin/java -jar /mnt/tst/install/oracle/autoupgrade/autoupgrade.jar -restore_on_fail -config /export/home/oracle/migration/bbb_test1_loc2_to_19c/upg1.cfg -mode deploy

9.4 you might be encountered into error like :

Error: UPG-1524

Cause: PDBs have been found that are either MOUNTED or RESTRICTED. The following PDBs need attention: [PDB1, PDB2]
For further details, see the log file located at /u01/app/oracle/cfgtoollogs/autoupgrade/bbb_test1_loc2/bbb_test1_loc2/101/autoupgrade_20230223_user.log]

the main cause is configured "read only" open mode in GI :

% srvctl config database
Database unique name: bbb_test1_loc2
Database name: bbbtest1
Oracle home: /u01/app/oracle/product/19/db_1917
Oracle user: oracle
Spfile: +DATAC7/BBB_TEST1_M8F/PARAMETERFILE/spfile.299.1129575269
Password file: +datac7/pw_files/orapwbbb_test1_loc2
Domain:
Start options: read only
Stop options: immediate
Database role: PHYSICAL_STANDBY
Management policy: AUTOMATIC
Server pools:
Disk Groups: RECOC7,DATAC7
Mount point paths:
Services: service1_prim,service2_prim
Type: SINGLE
OSDBA group: dba
OSOPER group: dba
Database instance: bbb_test1_loc2
Configured nodes: loc2-p0l2-bbb-adm
CSS critical: no
CPU count: 0
Memory target: 0
Maximum memory: 0
Default network number for database services:
Database is administrator managed

fix :

% srvctl modify database -d $ORACLE_SID -startoption "open"

!!! BE AWARE OF SERVICES WHICH MIGHT BE RUN AFTER REOPENING BEING UPGRADED DATABASE !!! you'd better remove services beforehand, and then recreate them after all works will have been completed :

% srvctl remove service ...
% srvctl add service ...

9.5 after successful upgrade procedure on TLS restart SQL APPLY on TLS manually (transient logical standby database)

SQL> alter database start logical standby apply immediate ;

9.6 make sure you've created log_archive_dest_n parameter(s) back to original primary database and all standby databases as well. it will be used after switchover

9.7 insert into protocol table values (on primary) :

SQL> insert into c##ddi.tracking_table values (3, 'TLS upgraded, bbb_test1_loc1 is still PRIMARY') ;
SQL> commit ;

check on TSL weather new data has appeared :

SQL> select * from c##ddi.tracking_table ;

10. SWITCHOVER

10.1 from primary database (12c) execute :

SQL> begin dbms_rolling.switchover; end
/

10.2 check on the former primary which now must be logical standby (and transient logical standby should already have been primary):

SQL> select * from v$dataguard_config ;

Now you can check the application and restart it if needed.


10.3 restart former primary database under new OH (19)
                                                        
% srvctl stop database -d $ORACLE_SID
% srvctl remove database -d $ORACLE_SID

switch to new ORACLE_HOME and add database using srvctl :

% srvctl add database -d bbb_test1_loc1 -o /u01/app/oracle/product/19/db_1917 -pwfile +datac7/pw_files/orapwbbb_test1_loc1 -spfile +datac7/sp_files/spfilebbb_test1_loc1.ora -role logical_st
andby -startoption mount -stopoption immediate -instance bbb_test1_loc1 -dbtype single -dbname bbbtest1 -policy automatic -node $(hostname)

% srvctl start database -d bbb_test1_loc1

10.4 you may encounter the error :

PRCR-1079 : Failed to start resource ora.bbb_test1_loc1.db
CRS-5017: The resource action "ora.bbb_test1_loc1.db start" encountered the following error:
ORA-01078: failure in processing system parameters
LRM-00101: unknown parameter name '_gc_cpu_time'

in this case you'd better to recreate spfile and remove all underscore parameters, which have left from oracle 12 :

SQL> create pfile='/export/home/oracle/pfile' from spfile='+datac7/sp_files/spfilebbb_test1_loc1.ora' ;
go to host end edit pfile (rem all underscore parameters)
SQL> create spfile='+datac7/sp_files/spfilebbb_test1_loc1.ora' from pfile='/export/home/oracle/pfile' ;

$ srvctl start database -d bbb_test1_loc1

former primary database must be started in mount state

10.5 if needed, copy files from old ORACLE HOME to new (*.ora files etc.)

10.6 on the new primary, consult upgrade plan and event log once again

SQL> select event_time,type,message from dba_rolling_events ;
SQL> select batchid,source,target,description,phase,status from dba_rolling_plan ;


11 FINISH phase

11.1 before running finish_plan, set log_archive_dest_state_n=enable for all standbys of new primary database

11.2 run from new primary database :
SQL> begin dbms_rolling.finish_plan ; end ;

/

SQL> select event_time,type,message from dba_rolling_events ;
SQL> select * from v$dataguard_config ;

11.3 insert into protocol table values :

SQL> insert into c##ddi.tracking_table values (4, 'FINISH') ;
SQL> commit ;

12 POSTUPGRADE tasks

12.1 modify clusterware configuration according to new roles (if not already done). you may need add custom services as it were for former primary :

for new primary :
$ srvctl modify database -d $ORACLE_SID -startoption open -role primary

for former primary :
$ srvctl modify database -d $ORACLE_SID -role physical_standby
$ srvctl add service -d $ORACLE_SID -s service1_prim -pdb pdb1 -role primary -policy automatic -failovertype session -failovermethod basic -failoverretry 10 -failoverdelay 10
$ srvctl add service -d $ORACLE_SID -s service2_prim -pdb pdb2 -role primary -policy automatic -failovertype session -failovermethod basic -failoverretry 10 -failoverdelay 10

12.2 restore Data Guard Broker configuration on both databases :

SQL> alter system set dg_broker_start = true ;

% dgmgrl sys/aaa
DGMGRL> enable configuration ;

after enabling configuration, the new membership roles should be synchronized, but the error can occur :

Error: ORA-16700: The standby database has diverged from the primary database.

in this case, recreate dataguard configuration :

DGMGRL> remove configuration ;
Removed configuration
DGMGRL> show configuration ;
ORA-16532: Oracle Data Guard broker configuration does not exist
DGMGRL> create configuration bbbtest1_dg as primary database is bbb_test1_loc2 connect identifier is "dg-bbb-test1-loc2" ;

                                                  
DGMGRL> add database bbb_test1_loc1 as connect identifier is "dg-bbb-test1-loc1" ;

in case of Error: ORA-16698: member has a LOG_ARCHIVE_DEST_n parameter with SERVICE attribute set
remove log_archive_dest_n parameter from being added database :

SQL> alter system set log_archive_dest_2='' scope=memory ;
SQL> alter system reset log_archive_dest_2 ;

DGMGRL> show configuration ;
DGMGRL> enable configuration ;

12.3 if needed, do switchover back to the former primary database

connect to dg broker (primary database) using tns :

$ dgmgrl sys@dg-bbb-test1-loc2 as sysdba
DGMGRL> switchover to bbb_test1_loc1 ;

12.4 it has noticed that new spfile (with default name, as autoupgrade.jar utility does) was created for upgraded database (transient logical standby). it has default name and contains lots of underscore parameters. after switchover one needs to fix this:

SQL> create pfile='/export/home/oracle/pfile' from spfile ;

edit pfile if needed (remove unnecessary underscore parameters) and recreate spfile with required custom name (if needed):

SQL> create spfile='+datac7/sp_files/spfilebbb_test1_loc2.ora' from pfile='/export/home/oracle/pfile' ; -- do it on the running instance in order to update clusterware registry

$ srvctl stop database -d $ORACLE_SID
$ srvctl start database -d $ORACLE_SID -o nomount

SQL> alter database mount ;
SQL> alter database open read only ; -- opened read only required on standby to enable optimizer fixes

enable optimizer fixes on the standby and primary databases :

SQL> begin dbms_optim_bundle.enable_optim_fixes ('ON','BOTH') ; END ;
/

restart physical standby :
$ srvctl stop database -d $ORACLE_SID
$ srvctl start database -d $ORACLE_SID

12.5 RUN BACKUP OF LEVEL 0 of the new PRIMARY
                                                      
12.6 set some parameters (recommended by Oracle Migration Team)

alter system set deferred_segment_creation=false ;
alter system set "_cursor_obsolete_threshold"=1024 scope=spfile ;
alter system set "_enable_ptime_update_for_sys"=true ;
alter system set optimizer_adaptive_plans=true ;

12.7 check database directory objects and do all the staff related to postupgrade tasks (gather dictionary stats after 10 days of work, increase compatible etc.)

12.8 check that database parameters are in sync between primary and standby databases

12.9 reconfigure databases in Oracle Enterprise Manager to new Oracle Home if needed

Friday, January 27, 2023

PostgreSQL : pg_archivecleanup doesn't delete any archived wal file

I've bumped into situation the other days related to removing archived log files not needed for recovery from the backup. After making backup by pg_basebackup, the pg_archivecleanup command was used like of :

$ pg_archivecleanup -d -n -x .gz /arch/archive 000000010000005C000000ED.00000028.backup

The response was :

$ pg_archivecleanup: keeping WAL file "/arch/archive/000000010000005C000000ED" and later

And nothing happened more. The directory /arch/archive contained 24k files, but pg_archivecleanup haven't considered them at all.

The culprit of such behavior - a prefix in archive wal filenames. Their names included 'archive' prefix, and pg_archivecleanup expects they didn't :

archive000000010000005E000000D6.gz
archive000000010000005E000000D5.gz
archive000000010000005E000000D4.gz
archive000000010000005E000000D3.gz
archive000000010000005E000000D2.gz
archive000000010000005E000000D1.gz
archive000000010000005E000000D0.gz
archive000000010000005E000000CF.gz
archive000000010000005E000000CE.gz

To make cleanup you'd better to rename them :

% cd ${archive_dir} && find -type f -name "archive*" -exec rename archive "" '{}' \;

After that the cleanup worked as expected :

$ pg_archivecleanup -d -n -x .gz /arch/archive 000000010000005C000000ED.00000028.backup

dry run cleanup execution :
pg_archivecleanup: keeping WAL file "/arch/archive/000000010000005C000000ED" and later
/arch/archive/000000010000001000000080.gz
pg_archivecleanup: file "/arch/archive/000000010000001000000080.gz" would be removed
/arch/archive/000000010000000100000029.gz
pg_archivecleanup: file "/arch/archive/000000010000000100000029.gz" would be removed
/arch/archive/00000001000000500000003D.gz
...

P.S. When -x switch is used, then compressed (and uncompressed as well) wal archived files are considered for removing.

That's it ! Good Luck !


Tuesday, December 13, 2022

ORA-32010: cannot find entry to delete in SPFILE

1. SQL> alter system reset "_time_based_rcv_ckpt_target" scope = spfile sid='aaa'

 *
ERROR at line 1:
ORA-32010: cannot find entry to delete in SPFILE

2.
SQL> alter system reset "_bct_public_dba_buffer_size" sid='aaa' scope=spfile ;

System altered.

3. 😶

Thursday, December 1, 2022

DBMS_WORKLOAD_CAPTURE: cannot import STS for capture with ID... in the alert.log

This error encountered in the alert log file of  replay system. The replay was being using to assess the consequences of Oracle database upgrade from 12.2 to 19.16 version.

Actually I found this error trying to figure out the absence of SQL tuning set, generated during capture system, on the replay system. It was signaled in the alert.log during executing DBMS_WORKLOAD_CAPTURE.IMPORT_AWR procedure. This led to inability of generating 'compare sqlsets report' after replaying the captured load.

Moving on to searching the cause, I found out the dump wcr_ca_sts.dmp
 
file of STS in the <replay_directory>/cap directory. Inspecting it with help if impdp (using parameters SQLFILE and MASTER_ONLY=true), it turned out that dump file contained the only table "SYSTEM"."WRRSTSTAB", which was a stage table for STS from the capture side. And this table existed in the replay database already (created after executing IMPORT_AWR procedure).

Next I tried to unpack stage table and assign STS to different owner :

SQL> begin dbms_sqltune.unpack_stgtab_sqlset (sqlset_name => '%', sqlset_owner => 'NEW_OWNER', replace => false, staging_table_name => 'WRRSTSTAB', staging_schema_owner => 'SYSTEM') ; end ;
/

It generated the error 

ORA-19377: no "SQL Tuning Set" with name like "%" exists for owner like "NEW_OWNER"
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 95
ORA-06512: at "SYS.DBMS_SQLTUNE", line 10526
ORA-06512: at line 1
19377. 00000 -  "no \"SQL Tuning Set\" with name like \"%s\" exists for owner like \"%s\""
*Cause:    The user specified a filter to a pack/unpack function for the SQL
           Tuning Set that targets no STS in the SYS schema or the staging
           table, respectively
*Action:   Provide a different filter after checking the state of the system

I didn't try to change sqlset_name, I changed sqlset_owner instead to owner from the source database (SYS). After that execution of unpack_stgtab_sqlset procedure was succeeded.

At that point the last step was :

SQL> update wrr$_captures
    set sqlset_owner = 'SYS', sqlset_name = 'sqlset_name' where id = <capture_id> ;

I queried dba_workload_replays view to confirm changes from previous update. Then I was able to generate the report comparing performance using SQL tuning sets from capture and replay processes :

set pages 100 lines 30000 serveroutput on long 2000000000 longchunksize 99999 trim on trimspool on termout off head off

var sql_r clob  

spool replay_compare_sqlset_report.html

--alter session set events '19119 trace name context forever, level 0x400000';

declare
r clob ;
a varchar2 (20) ;
begin
 r := 'test string' ;
 a := dbms_workload_replay.compare_sqlset_report (replay_id1 => &1, replay_id2 => null, format => 'HTML', result => :sql_r) ;
--  dbms_output.put_line (r) ;
--  :sql_r := r ;
end ;
/

print :sql_r

spool off

exit

Good Luck !

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.



Sunday, September 4, 2022

When crontab schedule is not enough

As far as you know, cron provides the schedule on the following time attributes: minute, hour, day of the week, month, day of month. What if you need to set the specific schedule, for example, you need (not) to fire the event only on last working day of the current month and on the next day after it (2 days in a row) ? 

The application is restarting every day. Let's assume that working days between Monday and Friday, the current month (September) has 30 days, and last working day is Friday, 28th. So, we need (not) to fire the event on 28th and 29th. How to do this using only crontab file ? Have a look :

#
# If END_OF_MONTH=true, the app server is not stopped and not restarted automatically.
# END_OF_MONTH is set to true when current day is last working day of month, and next day after it (2 days in row).
# a and b - intermediate variables to keep END_OF_MONTH intermediate value.
# Exception when 30.04 is Monday (as in 2018 and 2029; then end of month must be moved to Saturday, 28.04, because 01.05 (day off) is Tuesday),
# or 29.04 is Radonica (in 2025 and 2036, so 30.04 is moved to 03.05, end of month in this case 28.04).
#
cy='date +%Y'
cm='LANG=en date +%b'
nm1wd='$(test $(eval $cm) = "Dec") && eval $(echo "LANG=en date +%u -d \"$(LANG=en date +%b -d "next month") 1 +1year\"") || eval $(echo "LANG=en date +%u -d \"$(LANG=en date +%b -d "next m
onth") 1\"")'
lcmd='LANG=en date +%d -d "$(LANG=en date +%b -d "next month") 1 -1day"'
cday='date +%-d'
cwday='date +%u'
fr1="cal -m | tail -n +3 | awk '{print $5}' | sed -n '4p'"
fr2="cal -m | tail -n +3 | awk '{print $5}' | sed -n '5p'"
last_fr='test -z "$(eval $fr2)" && echo $(eval $fr1) || echo $(eval $fr2)'
sa1="cal -m | tail -n +3 | awk '{print $6}' | sed -n '4p'"
sa2="cal -m | tail -n +3 | awk '{print $6}' | sed -n '5p'"
last_sa='test -z "$(eval $sa2)" && echo $(eval $sa1) || echo $(eval $sa2)'
_END_OF_MONTH='$(test $(eval $nm1wd) -ge 3 -a $(eval $nm1wd) -le 5 -a $(eval $cday) -eq $(eval $lcmd) || (test $(eval $nm1wd) -eq 6 -a $(eval $cday) -eq $(eval $last_fr)) || (test $(eval $n
m1wd) -eq 7 -o $(eval $nm1wd) -eq 1 && test $(eval $cday) -eq $(eval $last_fr) -o $(eval $cday) -eq $(eval $last_sa)) || test $(eval $nm1wd) -eq 2 -a $(eval $cday) -eq $(eval $last_sa) || t
est $(eval $cday) -eq 1 -a $(eval $cwday) -ge 2 -a $(eval $cwday) -le 6) && echo true'
apr_d='LANG=en date +%d%b%a'
apr_eom='$(test $(eval $apr_d) = "28AprSat" -o $(eval $apr_d) = "29AprSun" -o $(eval $apr_d) = "28AprMon" -o $(eval $apr_d) = "29AprTue") && echo true || echo false'
apr_no_eom='$(test $(eval $apr_d) = "30AprMon" -o $(eval $apr_d) = "01MayTue" -o $(eval $apr_d) = "30AprWed" -o $(eval $apr_d) = "01MayThu") && echo true || echo false'
END_OF_MONTH='$(test $(eval $apr_eom) = "true" -a $(eval $cy) != "2031" ) && echo true || echo $(eval $_END_OF_MONTH)'
END_OF_MONTH='$(test $(eval $apr_no_eom) = "true" -a $(eval $cy) != "2031" ) && echo false || echo $(eval $_END_OF_MONTH)'
END_OF_MONTH='$(test \( $(eval $apr_d) = "27AprSat" -o $(eval $apr_d) = "28AprSun" \) -a $(eval $cy) = "2041") && echo true || echo $(eval $_END_OF_MONTH)'
END_OF_MONTH='$(test \( $(eval $apr_d) = "30AprTue" -o $(eval $apr_d) = "01MayWed" \) -a $(eval $cy) = "2041") && echo false || echo $(eval $_END_OF_MONTH)'
 

00    02    *   *     *           [ "$(echo $(eval $END_OF_MONTH))" != "true" ] && su - app_user -c "/home/app_user/app stop"

00    03    *   *     1-7         [ "$(echo $(eval $END_OF_MONTH))" != "true" ] && su - app_user -c "/home/app_user/app restart"

The logic is build around using bash eval and test buildin commands. If END_OF_MONTH is set to true, then nothing happens, app stop and restart tasks aren't run. There are couple of exceptions regarding to my country : 1st of May and Cristian Orthodox holiday named Radonica are always day off; because of this the movements of day off and working days are possible. I tried to count these exceptions in crontab too.

Good Luck !


Wednesday, August 31, 2022

dnf (yum) throws "The SSL certificate failed verification" error

All of a sudden an application named dnf (a successor of yum, used as package manager on Oracle Linux OS) stopped functioning, but throwing the message from the title, even when it's being called with help option(s). The main cause was local machine time, it wasn't synchronized with real clock time. The solution was to sync it, as well as modify the chrony.conf (add string like 'server vm_host iburst' in order to sync time quickly after save_vm->restore_vm operation) and run the dnf with required options :

# systemctl stop chronyd

# chronyd -q 'pool pool.ntp.org iburst'

# systemctl start chronyd

# dnf help

Good Luck !