Thursday, January 19, 2023

How to setup a custom env variable in R12.2

In R12.2, custom env variables can be defined in file $INST_TOP/appl/admin/custom$CONTEXT_NAME.env (after it is created), which is called by $APPL_TOP/APPS$CONTEXT_NAME.env (and so, by the main env file EBSapps.env).  For example, use two lines in custom$CONTEXT_NAME.env to define a custom variable:
$ cd $INST_TOP/appl/admin
$ more custom$CONTEXT_NAME.env
FORMS_RECORD_GROUP_MAX=30000
export FORMS_RECORD_GROUP_MAX
$ echo $FORMS_RECORD_GROUP_MAX
30000

Another way is to use the "custom" folder under $AD_TOP/admin/template. Oracle Doc ID 745711.1 gives steps on defining a Forms env variable:

a) Go to the autoconfig Template folder:
$ cd $AD_TOP/admin/template
b) Create new directory named (custom)
$ mkdir custom
c) Make sure that new directory has same file permissions as ($AD_TOP/admin/template)
d) Copy the following autoconfig template to the new custom directory:
$ cp $AD_TOP/admin/template/APPLSYS_ux.env $AD_TOP/admin/template/custom/APPLSYS_ux.env
e) Edit the file copied file under custom directory and add the following 2 lines at the end of section:

####################################
# Oracle Forms environment variables
####################################
FORMS_RECORD_GROUP_MAX=30000
export FORMS_RECORD_GROUP_MAX

f) Save and exit from the file.
g) Next time autoconfig run, it will read the custom directory and check for any customizations there.

After AutoConfig, above two lines will be copied to file $APPL_TOP/$CONTEXT_NAME.env (and other AD files?).

Notes: "FORMS_RECORD_GROUP_MAX=30000" can be equivalently added to Forms file $INST_TOP/ora/10.1.2/forms/server/default.env. But that file will be overwritten by AutoConfig. See Oracle Doc ID 745711.1.

Sunday, January 15, 2023

EBS session status in the database & on OS

When an OS process uses high CPU or other OS resources which may lead to failure in launching EBS Forms or login page, use below line to find its start time:
$  ps -eo pid,lstart,cmd | grep 21846
74063 Tue Dec 19 12:29:31 2022 grep --color=auto 21486
21486 Tue Dec 19 07:39:01 2022 frmweb server webfile=HTTP-0,0,1,default

If a forms process (frmweb) exists on OS level but does not have a responding session in the database, it is a run-away and it can be terminated.  

Below SQL statement will tell and monitor what an EBS session is doing in the database after its process ID is identified (e.g. 21846) on OS level of EBS apps server. 

SQL> SELECT to_char(S.logon_time, 'DD-MON-RRRR HH24:MI:SS') "logon_time", to_char(S.PREV_EXEC_START, 'DD-MON-RRRR HH24:MI:SS') "last op started", 
    client_identifier, module, action, status, machine, round(last_call_et/60,1) "Minutes in current status",
    sql_id, blocking_session, process, sid, serial#, state,
    ROUND((S.WAIT_TIME_MICRO/1000000)/60/60,1) "total wait hrs",
    DECODE(S.TIME_REMAINING_MICRO,'-1', 'indefinite', '0','Wait timed out',NULL,'session not waiting') "remaining wait time", 
    DECODE(S.TIME_SINCE_LAST_WAIT_MICRO, '0','Still waiting') "current wait status",
    S.time_since_last_wait_micro
   FROM v$session s
WHERE process = '21846' 
-- order by client_identifier
;
  BLOCKING_SESSION - Tell if it is blocked by another session.
  STATE - The state of the wait event.
  WAIT_TIME_MICRO - The wait time of the wait event in microseconds.
  TIME_REMAINING_MICRO - The time remaining in microseconds before the wait event times out.
  TIME_SINCE_LAST_WAIT_MICRO - The amount of time in microseconds elapsed from the last wait to the current wait.

Normally, a session for a running concurrent request will show the SQL_ID.

An oacore process may have many sessions in the database. To find which process ID is for oacore, try "$ ps -ef | grep oacore " on OS level of apps server, or run below line in the database (if XX is part of a CUSTOM top name).

SQL> select distinct process, machine from v$session 
where action like '%XX%' order by machine;

When an OACORE process taking high CPU, you can take some actions:
(1) Log onto WebLogic console to see which oacore is not in Running status, and you may recycle it from the console. By that, some users' session will be terminated.

(2) If WebLogic console is not accessible, you may recycle WebLogic Admin services by adadminsrvctl.sh from primary node (which will not affect users' sessions). Then, you may have to recycle that frozen oacore by command such as "admanagedsrvctl.sh stop oacore_server2".

(3) Run following commands (But it may not help):

1) ps -eLo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm | grep PID
==> which thread is taking CPU.  Most of them should show 0.0 (which is the CPU column).

I did see an OACORE process (e.g. 13030) supports 125 JVM threads in one of my instances. So, it is NOT good to simply kill an oacore OS process.
$ ps -eLo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm | grep 13030 | wc -l
125

2) jmap -histo <jvm_process_id> > /tmp/ <jvm_process_id>.histo
==> will dump heap usage details.  

3) jmap -dump:format=b,file= <jvm_process_id>.jmap <jvm_process_id>
==> will generate an actual heap dump, binary format

4) kill -3 <jvm_process_id>
==> output goes to 12.2 oacore_server1.out. It will generate stack trace, run twice a minute apart.
kill -3 <jvm_process_id>

5) lsof -p <jvm_process_id> > <jvm_process_id>.log
==> List of open ports/files

6) SELECT audsid, module, last_call_et, action from gv$session where process = '&jvm_process_id';
==> corresponding DB sessions

7) log / incident files from that oacore :
$EBS_DOMAIN_HOME/servers/oa*/logs/*
$EBS_DOMAIN_HOME/servers/oa*/adr/diag/ofm/EBS_domain*/oacore*/incident/incdir*/*

Tuesday, January 10, 2023

SQL statement to find blocking session

Use SQL to identify and monitor the database session that blocks other session:

SQL> SELECT DECODE(request,0,'Holder: ','Waiter: ') status, sid sess_ID, id1, id2, lmode, request, type
FROM    V$LOCK
WHERE (id1, id2, type) IN
(SELECT id1, id2, type FROM V$LOCK WHERE request > 0)
ORDER BY id1, request;

Use below to confirm the blocking status in the database:

SQL> SELECT blocking_session block_holder,
  sid, serial#, process, machine, client_identifier, wait_class, seconds_in_wait
FROM v$session
WHERE blocking_session IS NOT NULL
ORDER BY blocking_session; 

Wednesday, January 4, 2023

Purge R12.2 log files in Linux OS

Folder structure in R12.2 file system is more complicated than in R12.1, because RUN and PATCH may switch their location. After an adop cutover, the path to log files will be changed to a different one. Below are folders that have a growing number of log files. "ls" can be used to list the log files but "cd" do not work to reach the folder, while the path uses "*" in it.

$IAS_ORACLE_HOME/instances/*/diagnostics/logs/OHS/*/*.log*
$EBS_DOMAIN_HOME/servers/oacore*/logs/*.log*
$EBS_DOMAIN_HOME/servers/form*/logs/*.log*
$EBS_DOMAIN_HOME/servers/AdminServer/logs/*.log*

Fortunately, "find" works with path having "*" in it. Below lines work in cron to purge/delete old log files (on web/forms node).

$ crontab -l
05 05 * * * . /u07/app/.profile; /usr/bin/find $IAS_ORACLE_HOME/instances/*/diagnostics/logs/OHS/*/*log* -type f -mtime +30 -exec rm -f {} \;
05 15 * * * . /u07/app/.profile; /usr/bin/find $EBS_DOMAIN_HOME/servers/oacore*/logs/*log* -type f -mtime +30 -exec rm -f {} \;

Other logs or their locations:

$ADOP_LOG_HOME/*                   <== each ADOP session ID has a sub-folder
$INST_TOP/admin/log/MMDDHHMM/adconfig.log
$LOG_HOME/appl/admin/log/*      <== adstrtal.sh & adstpall.sh 
$LOG_HOME/appl/rgf/javacache.log 
$IAS_ORACLE_HOME/instances/*/diagnostics/logs/OPMN/opmn/* 
$EBS_DOMAIN_HOME/sysman/log/* 
$EBS_DOMAIN_HOME/servers/oac*/adr/diag/ofm/EBS_domain*/oac*/incident/* 
$EBS_DOMAIN_HOME/servers/forms_s*/adr/diag/ofm/EBS_domain*/forms_s*/incident/*
$INST_TOP/logs/ora/10.1.2/reports/cache/*.*

Locations or files for configuration and setups:

$IAS_ORACLE_HOME/instances/EBS_web*/config/OHS/EBS_web* 
$FMW_HOME/webtier/instances/EBS_web*/config/OPMN/opmn/* 
$CONTEXT_FILE
$INST_TOP/appl/admin/*.properties
$INST_TOP/ora/10.1.2/forms/server/default.env    (AutoConfig overwrites it)
$FND_TOP/fndenv.env
$EBS_DOMAIN_HOME/config/config.xml
$EBS_APPS_DEPLOYMENT_DIR/*/APP-INF/node_info.txt

.profile file (for account runs the crontab jobs on RHEL)
$ more .profile
PATH=/bin:/usr/bin:/usr/local/bin
export PATH

MANPATH=/usr/share/man:/usr/local/share/man:/usr/X11R6/man
export MANPATH

EDITOR=/bin/vi
export EDITOR

. /u07/app/EBSDEV/EBSapps.env RUN

isMaster="no"
if [ ! -z $APPS_VERSION ] && [ ${APPS_VERSION:0:4} == "12.2" ]
then
s_status=`cat $CONTEXT_FILE | grep -i s_adminserverstatus`
isMaster="${s_status:60:7}"
fi

if [ $isMaster == "enabled" ]
then

if [ `echo -n ${HOSTNAME%%.*} | tail -c -1` != "p" ]
then
PS1=$'
\e[0;31m$USER@${HOSTNAME%%.*}[$TWO_TASK]\e[m$PWD
-->$ '
else
PS1=$'
\e[0;31m$USER@${HOSTNAME%%.*}[$TWO_TASK]\e[m\E[32m$PWD \E[0m
-->$ '
fi

else

if [ `echo -n ${HOSTNAME%%.*} | tail -c -1` != "p" ]
then
PS1='
$USER@${HOSTNAME%%.*}[$TWO_TASK]$PWD
-->$ '
else
PS1=$'
$USER@${HOSTNAME%%.*}[$TWO_TASK]\E[32m$PWD \E[0m
-->$ '
fi

fi

alias rm='rm -i'
stty erase ^?

Thursday, December 22, 2022

EBS steps when database is upgraded to 19c using Export/Import

In some special situations, database can not be upgraded to 19c by Database Upgrade procedure. For example, run hcheck as sysdba (Doc ID 136697.1). If get below error, you have to fix the problem before moving forward with database upgrade.

Problem Summary
---------------------------------------------------
HCKW-0027: System Tablespace does not have relative file number of 1  (Doc ID 2364065.1)

Problem Description
---------------------------------------------------
Running hcheck.sql
Returned warning:
 - SystemNotRfile1 ... 1201000200 > 902000000 03/04 16:03:08 WARN

Confirm file names caused the mess-up:
SQL> select RELATIVE_FNO fno, file_id, substr(file_name,1,50) fileName 
from dba_data_files where file_name like '%sys%';

FNO  File_ID  FILENAME
  16              1   /oradata/u10/EBSDEV/system01.dbf
    8              8   /oradata/u10/EBSDEV/system06.dbf
  87            87   /oradata/u10/EBSDEV/system07.dbf
etc … … 

SQL> select RELATIVE_FNO, file_id, substr(file_name,1,50) fileName 
from dba_data_files where file_id =16;

FNO  File_ID  FILENAME
  16           16   /oradata/u11/EBSDEV/APPS_TS_TX_IDX36.dbf

Steps on EBS apps side when database export & import are used to upgrade the database:

1. Make sure all pre-requisite patches were applied to apps side 
A list of EBS patches are needed before 19c database upgrade. See Doc ID 2552181.1 (Interoperability Notes: Oracle E-Business Suite Release 12.2 with Oracle  Database 19c).

2. Run through patch cycle to complete adop cleanup

On the current run file system:

Run fs_clone first (if no pending ADOP session exists). It will screen out problems and help to fix potential issues (for example, fs_clone was not executed right after ssl cert renewal):
$ adop phase=fs_clone
If troubleshooting was performed, make sure nothing is running on PATCH (say, fs2) file system and log onto EBS site to do a sanity check.
$ ps -ef | grep fs2

Starting a new OS session on primary node:
$ adop phase=prepare
$ adop phase=actualize_all
$ adop phase=finalize finalize_mode=full

$ adop -status
... ...
===============================================================
Node Name  Node Type      Phase           Status          Started              Finished             Elapsed
--------------- ---------- --------------- --------------- -------------------- -------------------- ------------
node1    master    PREPARE       COMPLETED       2022/X/14 20:32:32  2022/X/14 20:38:05  0:05:33
                            APPLY             ACTIVE
                            FINALIZE       COMPLETED       2022/X/14 21:27:31  2022/X/14 21:34:38  0:07:07
                            CUTOVER      NOT STARTED
                            CLEANUP       NOT STARTED

node2    slave      PREPARE       COMPLETED       2022/X/14 20:32:31  2022/X/14 20:38:07  0:05:36
                            APPLY            NOT STARTED
                            FINALIZE      COMPLETED       2022/X/14 21:27:31  2022/X/14 21:34:38  0:07:07
                            CUTOVER     NOT STARTED
                            CLEANUP     NOT STARTED

node3    slave      PREPARE      COMPLETED       2022/X/14 20:32:31  2022/X/14 20:39:39  0:07:08
                           APPLY             NOT STARTED
                           FINALIZE      COMPLETED       2022/X/14 21:27:31  2022/X/14 21:34:38  0:07:07
                           CUTOVER      NOT STARTED
                           CLEANUP      NOT STARTED

May see concurrent job "Online Patching In Progress"

$ adop phase=cutover
On the new run file system:
$ adop phase=cleanup cleanup_mode=full 

Also run SQL scripts by apps:
@$AD_TOP/sql/ADZDSHOWOBJS.sql - to check which objects still need to be tidied up.
@$AD_TOP/sql/ADZDSHOWLOG.sql  - to make sure that it ran through properly
@$AD_TOP/sql/ADZDSHOWED.sql     - to get the list of Editions

Shutdown apps services

3. DBA upgrades database to 19c by using Export and Import

4. Modify apps files after DBA provides new TNS entry. 
Below is an example of the new TNS entry. 
EBSDEV=
        (DESCRIPTION=
                (ADDRESS=(PROTOCOL=tcp)(HOST=ebs_db1d.domain.com)(PORT=1560))
            (CONNECT_DATA=
                (SERVICE_NAME=ebs_EBSDEV)
                (INSTANCE_NAME=CEBSDEV)
            )
        )

To modify the TNS entries, edit the $TNS_ADMIN/tnsnames.ora files to specify the CDB instance name. 
$ cd $TNS_ADMIN
$ vi tnsnames.ora
replace every INSTANCE_NAME to CDBEDEV
replace every SERVICE_NAME to ebs_EBSDEV (if it is different from 12c)

$ sqlplus apps/appsPWD
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
SQL> 

$ tnsping ebsdev
... ...
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION= (ADDRESS=(PROTOCOL=tcp)(HOST=ebsDB1d.domain.com)(PORT=1560)) (CONNECT_DATA= (SERVICE_NAME=ebs_EBSDEV) (INSTANCE_NAME=CDBEDEV)))
OK (0 msec)

5. Edit $CONTEXT_FILE on both RUN and PATCH file systems

Update the following values in the context file.
Variable Name                         Value
s_dbhost                                          New database hostname (if changed)
s_dbport                                         New database port (if changed)
s_dbGlnam                                      CDBEDEV    (Seems autoconfig does not keep it)
s_apps_jdbc_connect_descriptor NULL (<jdbc_url oa_var="s_apps_jdbc_connect_descriptor"/>)
s_dbport                                         New database port
s_applptmp                                 Defined in UTL_FILE_DIR (e.g. /path/to/EBSDEV/utl_dir)

6. Run AutoConfig on RUN and PATCH file systems in all nodes
SQL> select * from FND_OAM_CONTEXT_FILES;     
SQL> select * from fnd_nodes;         <== only one row for db node

$ ./adautocfg.sh
Notes: 
a). AutoConfig will fail on jtfictx.sh because jtfictx.sql requires AD_CTX_DDL, which is created in a later step. AutoConfig will be run again after AD_CTX_DDL has been created. 
b). After AutoConfig, s_apps_jdbc_connect_descriptor will get new value.
c). AutoConfig will overwrite variable s_dbGlnam ?

Table FND_OAM_CONTEXT_FILES might be cleaned during database upgrade. If CONTEXT FILE records for PATCH system are missing, run AutoConfig on PATCH file system as well to avoid ADOP session failure in the future.

To run AutoConfig on PATCH file system, disable a trigger first (and afterwards enable it).
SQL> conn system/systemPWD
Connected.
SQL> alter trigger ebs_logon disable;
Trigger altered.

SQL> select * from FND_OAM_CONTEXT_FILES;     <== entries for both RUN and PATCH

7. Create the CTX objects
Certain Oracle Text objects are not preserved by the import process. The consolidated export/import utility patch that were applied to the administration server node in Section 4 of Doc ID 2552181.1 contains a perl script, dpost_imp.pl, that will generate an AutoPatch driver file. Use this driver file to call the scripts that create these objects.

$ cd $AU_TOP/patch/115/bin
$ mkdir 6924477
$ perl dpost_imp.pl u6924477.drv 12      <== it creates file u6924477.drv
$ mv u6924477.drv 6924477                   <== repeat above steps on other node(s)
$ adop phase=apply hotpatch=yes patchtop=$AU_TOP/patch/115/bin patches=6924477 options=forceapply

8. DBAs run some reports, compile invalid objects and make necessary grants.

9. Run AutoConfig in 2nd time on all apps nodes and start all EBS services.
All shall work by now.

OPTIONAL actions

1. If WF agent does not start, the issue is with table AQ$_WF_CONTROL_P. Build WF queue on fly.

$ sqlplus applsys/PWD
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
SQL> set pages 10000
SQL> select instance_name from v$instance;
SQL> select count(*) from all_objects;
  COUNT(*)
----------
     62483

SQL> exec dbms_aqadm.drop_queue_table(queue_table=>'WF_CONTROL',force => TRUE);
PL/SQL procedure successfully completed.

SQL> select count(*) from all_objects;
  COUNT(*)
----------
     62446

SQL> select * from all_objects where object_name like'AQ$WF_CONTROL%';
no rows selected

SQL> select * from all_objects where object_name like'AQ$_WF_CONTROL%';
no rows selected

$ sqlplus apps/appsPWD
SQL> @/path/to/EBSPGRND/utl_dir/wfctqrec_new.sql APPLSYS appsPWD
Connected.                                               (see below Notes)
PL/SQL procedure successfully completed.
Commit complete.

$ sqlplus applsys/PWD
SQL> select count(*) from all_objects;
  COUNT(*)
----------
     62474

SQL> column object_name format a25
SQL> column object_type format a10
SQL> select object_name, object_type from all_objects 
where object_name like 'AQ$_WF_CONTROL%';

OBJECT_NAME                      OBJECT_TYP
------------------------------------- ----------
AQ$_WF_CONTROL_E          QUEUE
AQ$_WF_CONTROL_F           VIEW
AQ$_WF_CONTROL_G          TABLE
AQ$_WF_CONTROL_H          TABLE
AQ$_WF_CONTROL_I           TABLE
AQ$_WF_CONTROL_L          TABLE
AQ$_WF_CONTROL_N          SEQUENCE
AQ$_WF_CONTROL_S          TABLE
AQ$_WF_CONTROL_T          TABLE
AQ$_WF_CONTROL_V          EVALUATION
                                                       CONTEXT
10 rows selected.

SQL> select object_name, object_type from all_objects 
where object_name like 'AQ$WF_CONTROL%';

OBJECT_NAME               OBJECT_TYP
------------------------- ----------
AQ$WF_CONTROL               VIEW
AQ$WF_CONTROL_R          VIEW
AQ$WF_CONTROL_S           VIEW

Some database objects are created on "fly" after EBS services are started:

$ cd $ADMIN_SCRIPTS_HOME
$ ./adstrtal.sh apps/appsPWD

SQL> select object_name, object_type from all_objects 
where object_name like 'AQ$_WF_CONTROL%';

OBJECT_NAME               OBJECT_TYP
------------------------- ----------
AQ$_WF_CONTROL_D          TABLE
AQ$_WF_CONTROL_E          QUEUE
AQ$_WF_CONTROL_F           VIEW
AQ$_WF_CONTROL_G          TABLE
AQ$_WF_CONTROL_H          TABLE
AQ$_WF_CONTROL_I           TABLE
AQ$_WF_CONTROL_L          TABLE
AQ$_WF_CONTROL_N          SEQUENCE
AQ$_WF_CONTROL_P          TABLE
AQ$_WF_CONTROL_S          TABLE
AQ$_WF_CONTROL_T          TABLE
AQ$_WF_CONTROL_V          EVALUATION
                                                       CONTEXT
12 rows selected.

SQL> select object_name, object_type from all_objects 
where object_name like 'AQ$WF_CONTROL%';

OBJECT_NAME                     OBJECT_TYP
------------------------------------ ----------
AQ$WF_CONTROL               VIEW
AQ$WF_CONTROL_R          VIEW
AQ$WF_CONTROL_S           VIEW

SQL> select count(*) from all_objects;
  COUNT(*)
----------
     62487

Three Concurrent Managers shall be started and in running:
   . Workflow Mailer Service
   . Workflow Agent Listener Service
   . Workflow Document Web Services Service

But "Workflow Notification Mailer" may still show Down status due to a wrong SMTP server.

Notes: If running wfctqrec.sql gets error, delete some rows and save it as wfctqrec_new.sql for execution.
$ ls -altr wfctqrec*.sql
-rwxr-xr-x 1 user group 3734 Apr 12  2021 wfctqrec.sql
-rwxr-xr-x 1 user group 2865 Jul 14 17:16 wfctqrec_new.sql

$ diff wfctqrec.sql wfctqrec_new.sql

<   BEGIN
<     dbms_aqadm.stop_queue( queue_name => 'WF_CONTROL', wait => FALSE);
<   EXCEPTION
<     WHEN no_queue THEN
<       null;
<     WHEN others THEN
<       RAISE_APPLICATION_ERROR(-20000, 'Oracle Error = '
<                                     ||to_char(sqlcode)||' - '||sqlerrm);
<   END;
<
<   BEGIN
<     dbms_aqadm.drop_queue(queue_name=> 'WF_CONTROL');
<   EXCEPTION
<     WHEN no_queue THEN
<       null;
<     WHEN others THEN
<       RAISE_APPLICATION_ERROR(-20000, 'Oracle Error = '
<                                     ||to_char(sqlcode)||' - '||sqlerrm);
<   END;
<
<   BEGIN
<     dbms_aqadm.drop_queue_table( queue_table => 'WF_CONTROL', force => TRUE);
<   EXCEPTION
<     WHEN queue_table_not_exists THEN
<       null;
<     WHEN others THEN
<       RAISE_APPLICATION_ERROR(-20000, 'Oracle Error = '
<                                     ||to_char(sqlcode)||' - '||sqlerrm);
<   END;
<

2. After 19c upgrade, three AZ tables for EBS iSetup becomes missing in 19c database.  Follow 
Oracle Doc ID 832459.1 (How To Cleanup Invalid Oracle iSetup (AZ) Tables And Recreate) to re-create them

3. In R12.2, when below line was used to hold concurrent jobs for a period of time for database upgrade completion and then from GUI forms to cancel the HOLD, some concurrent jobs got "No Manager" status.

SQL> update  apps.fnd_concurrent_requests  set hold_flag = 'Y' 
where status_code in ('Q','I') and hold_flag = 'N';

The problem may be column EDITION_NAME of table fnd_concurrent_requests was populated with invalid data. The fix is to find the current edition and run an update to the column.  

SQL> select edition_name from all_editions;
EDITION_NAME
-----------------------
ORA$BASE

SQL> update fnd_concurrent_requests
set edition_name='ORA$BASE'
where request_id in (228633x, 228633x, 228632x, 228632x, 228624x, 228624x)
;