Pages

Monday, December 18, 2023

Change resource of a profile

Change resource of a profile by Example.

Example: Change IDLE_TIME from 480 minutes to UNLIMITED

SELECT profile, resource_name, limit 
  FROM DBA_PROFILES 
 WHERE limit NOT IN ('UNLIMITED','DEFAULT');

PROFILE              RESOURCE_NAME                    LIMIT
-------------------- -------------------------------- ---------------
APP_PROF             IDLE_TIME                        480
APP_PROF             PASSWORD_VERIFY_FUNCTION        
 ORA12C_STIG_VERIFY_FUNCTION
GSM_PROF             FAILED_LOGIN_ATTEMPTS            10000000
DEFAULT              PASSWORD_VERIFY_FUNCTION         NULL
DEFAULT              PASSWORD_LOCK_TIME               1
ORA_STIG_PROFILE     IDLE_TIME                        15
ORA_STIG_PROFILE     FAILED_LOGIN_ATTEMPTS            3
ORA_STIG_PROFILE     PASSWORD_LIFE_TIME               60
ORA_STIG_PROFILE     PASSWORD_REUSE_TIME              365
ORA_STIG_PROFILE     PASSWORD_REUSE_MAX               10
ORA_STIG_PROFILE     PASSWORD_VERIFY_FUNCTION         ORA12C_STIG_VERIFY_FUNCTION
ORA_STIG_PROFILE     PASSWORD_GRACE_TIME              5
ORA_STIG_PROFILE     INACTIVE_ACCOUNT_TIME            35


ALTER PROFILE APP_PROF LIMIT IDLE_TIME UNLIMITED;

SELECT profile, resource_name, limit 
  FROM DBA_PROFILES 
 WHERE resource_name ='IDLE_TIME';


PROFILE              RESOURCE_NAME                    LIMIT
-------------------- -------------------------------- ---------------
DEFAULT              IDLE_TIME                        UNLIMITED
GSM_PROF             IDLE_TIME                        DEFAULT
ORA_STIG_PROFILE     IDLE_TIME                        15
APP_PROF             IDLE_TIME                        UNLIMITED
 
Note: This will effect only new sessions. 

Thursday, December 14, 2023

AWR "enq: TX - row lock contention" Wait Event

=============================
General
=============================
Checking AWR, Oracle is spending a lot of time in "enq: TX - row lock contention" waits.
How to troubleshoot?

                                                   Avg        %Total
                                   %Tim Total Wait wait Waits Call
Event                        Waits  out   Time (s) (ms) /txn  Time
---------------------------- ----- ---- ---------- ---- ----- ------
enq: TX - row lock contentio    21    0         85 4049   0.0     .2
1. Get the sessions that are in waiting state.
2. Get the blocking session of these sessions.
3. See what the blocking session is running

=============================
To get the history SQLs in waiting state:
=============================
Get summary for last intervals
SELECT LOCKS_SUMMARY.locks, 
       LOCKS_SUMMARY.snap_id, 
       LOCKS_SUMMARY.sample_time, 
       LOCKS_SUMMARY.sql_id, 
       SQLAREA.sql_fulltext
  FROM V$SQLAREA SQLAREA, 
(SELECT COUNT(*) as locks, 
       snap_id, TO_CHAR(sample_time,'YYYYMMDD hh24') sample_time, 
       sql_id
  FROM dba_hist_active_sess_history hist
 WHERE wait_class != 'Idle' 
   AND event = 'enq: TX - row lock contention'
GROUP BY snap_id, TO_CHAR(sample_time,'YYYYMMDD hh24'),sql_id
 ORDER BY snap_id DESC,  COUNT(*) DESC
  ) LOCKS_SUMMARY
WHERE SQLAREA.sql_id = LOCKS_SUMMARY.sql_id
ORDER BY 2 desc, 1 desc, 3;


Get details for last intervals
SELECT snap_id, sample_time, session_id,  
       SQLAREA.sql_id, 
       SQLAREA.sql_text
  FROM dba_hist_active_sess_history hist, 
       v$sqlarea SQLAREA
 WHERE wait_class != 'Idle' 
   AND event = 'enq: TX - row lock contention'
   AND SQLAREA.sql_id = hist.sql_id
 ORDER BY snap_id DESC, sample_time DESC;
 
Get details for last interval
SELECT snap_id, session_type, sql_id, event, program , machine, port
  FROM dba_hist_active_sess_history
 WHERE snap_id = (SELECT MAX(snap_id) FROM DBA_HIST_SNAPSHOT)
   AND event = 'enq: TX - row lock contention';

=============================
To get the current SQLs in waiting state:
============================= 
set linesize 140
set pagesize 1000

SELECT SESSIONS.sid, 
       SESSIONS.sql_id, 
       SUBSTR(SQLS.sql_text ,1,30) as sql_text,
       SESSIONS.program, 
       SESSIONS.schemaname, 
       SESSIONS.machine, 
       SESSIONS.port
  FROM V$SESSION SESSIONS,
       V$SQL SQLS 
 WHERE SESSIONS.sid IN 
       (SELECT sid  
          FROM V$SESSION 
         WHERE state in ('WAITING') 
           AND wait_class != 'Idle' 
           AND event='enq: TX - row lock contention'
   AND schemaname IS NOT NULL
        )
   AND  SQLS.sql_id = SESSIONS.sql_id;

============================= 
To get the Blocking session:
============================= 

SELECT blocking_session, 
       sid, 
       serial#, 
       wait_class, 
       seconds_in_wait 
  FROM V$SESSION 
 WHERE blocking_session is not NULL 
ORDER BY blocking_session;

Output is missing, but blocking session was 401.

============================= 
See what blocking session is running:
============================= 
SELECT USERNAME, SQL_ID FROM V$SESSION WHERE blocking_session=401;

USERNAME                       SQL_ID
------------------------------ -------------
MY_USER                        d94vtj1qqdvct


SELECT SQL_TEXT FROM V$SQLAREA
 WHERE sql_id = 'd94vtj1qqdvct';

SQL_TEXT
-------------------------------------------------------------------------------------
MERGE into SGA_W_SUBSCRIBER o using (select :1  MSISDN from dual) o1 on (o.MSISDN = o1.MSISDN) when matched then updateset o.IMSI= :2 ,o.DYNAMIC_COMMUNITIES =:3 ,o.CURRENT_COUNTRY= :4 ,o.CURRENT_NETWORK_ID = :5  , o.CURRENT_VLR = :6  ,o.CURRENT_MSC = :7  , o.TS_FIRST_REGISTRATION = :8  ,o.TS_E_LAST_LU = :9  , o.IS_ROAMING = :10 , o.TS_LAST_ROAMER_EVENT = :11 , o.CURRENT_SGSN = :12   ,o.NON_PURGEABLE_COUNT = :13 , o.PREVIOUS_VLR=:14 ,o.PREVIOUS_SGSN=:15 , o.TS_E_LAST_CANCEL=:16 , o.TS_E_LAST_PURGE=:17 , o.TS_E_LAST_SRI4SM_REQ=:18 , o.TS_VISIT_START=:19 , o.TS_VISIT_END=:20 , o.TS_LAST_MODIFIED=:21 , o.MAP_CATEGORY=:22 , o.MAP_CAMEL_PHASE=:23 , o.MAP_CAMEL_SERVICE_KEY=:24 , o.MAP_BARRING_INDICATION=:25 , o.MAP_BARRING_INDICATION_TS=:26 , o.MAP_FTN_BUSY=:27 , o.MAP_FTN_BUSY_TS=:28 , o.MAP_FTN_BUSY_TEL_SERVICE=:29 , o.MAP_FTN_BUSY_STATUS=:30 , o.MAP_FTN_NOREPLY=:31 , o.MAP_FTN_NOREPLY_TS=:32 , o.MAP_FTN_NOREPLY_TEL_SERVICE=:33 , o.MAP_FTN_NOREPLY_STATUS=:34 , o.MAP_FTN_NOREPLY_TIMEOUT=:






============================= 
See locks by sql_id:
============================= 
1st
SELECT sample_id,
       TO_CHAR(sample_time,'YYYYMMDD hh24:mi') as sample_min,
       LOCKS_HIST.session_id as locked_sid,
       LOCKS_HIST.session_serial# as locked_serial,
       LOCKS_HIST.sql_id,
       LOCKS_HIST.sql_exec_start,
       LOCKS_HIST.event,
       LOCKS_HIST.session_state,
       LOCKS_HIST.blocking_session,
       LOCKS_HIST.program,
       LOCKS_HIST.module, 
       LOCKS_HIST.machine,
       LOCKS_HIST.port,
       LOCKS_HIST.session_state,
       LOCKS_HIST.blocking_session,
       LOCKS_HIST.blocking_session_serial#
  FROM DBA_HIST_ACTIVE_SESS_HISTORY LOCKS_HIST
 WHERE sql_id = '2xkrv2tcm98sn'
   AND sample_time > TRUNC(SYSDATE);

2nd.
Take blocking_sessions from 1st SQL

SELECT LOCKS_HIST.program,
       LOCKS_HIST.module, 
       LOCKS_HIST.machine,
       LOCKS_HIST.port
  FROM DBA_HIST_ACTIVE_SESS_HISTORY LOCKS_HIST 
 WHERE session_id IN (2331, 1152, 969, 2331);

3rd
SELECT CURRENT_SESSIONS.program,
       CURRENT_SESSIONS.module, 
       CURRENT_SESSIONS.machine,
       CURRENT_SESSIONS.port
  FROM V$SESSION CURRENT_SESSIONS 
WHERE sid IN (2331, 1152, 969, 2331);

Golden gate - crontab to log golden gate processes stats

 59 * * * * /software/oracle/oracle/scripts/gg_stats_monitor/get_gg_stats.sh

get_gg_stats.sh
#!/bin/bash
. /etc/sh/orash/oracle_login.sh igt
GG_HOME=/software/ogg/191
ORACLE_SID=igt
ORACLE_HOME=/software/oracle/122

HOME_DIR=/software/oracle/oracle/scripts/gg_stats_monitor
DAY_LOG_FILE="${HOME_DIR}/logs/gg_stats_daily.log"
HOUR_LOG_FILE="${HOME_DIR}/logs/gg_stats_hourly.log"
TEMP_HR_LOG=/tmp/gg_stats_hr.log
TEMP_DAY_LOG=/tmp/gg_stats_day.log

SCHEMA_NAME=XXX_YYYYY_ZZZZZ

RUN_HOUR=$(date +"%H")
RUN_DATE=`date +"%Y%m%d"_"%H%M%S"`

rm -f $TEMP_HR_LOG 2>/dev/null
rm -f $TEMP_DAY_LOG 2>/dev/null

$GG_HOME/ggsci > $TEMP_HR_LOG << EOD
STATS EXTRACT EXT_I_01, HOURLY
STATS EXTRACT EXT_P_01, HOURLY
STATS EXTRACT EXT_S_01, HOURLY
STATS REPLICAT REP_I_01, HOURLY
STATS REPLICAT REP_P_01, HOURLY
STATS REPLICAT REP_S_01, HOURLY
exit
EOD

if [[ $RUN_HOUR == "09" ]]; then
 $GG_HOME/ggsci > $TEMP_DAY_LOG << EOD
STATS EXTRACT EXT_I_01, DAILY
STATS EXTRACT EXT_P_01, DAILY
STATS EXTRACT EXT_S_01, DAILY
STATS REPLICAT REP_I_01, DAILY
STATS REPLICAT REP_P_01, DAILY
STATS REPLICAT REP_S_01, DAILY
exit
EOD
fi

echo "=======================" >> $HOUR_LOG_FILE
echo $RUN_DATE >> $HOUR_LOG_FILE
echo "=======================" >> $HOUR_LOG_FILE
less ${TEMP_HR_LOG} | grep -v "Command Interpreter for Oracle" | grep -v OGGCORE | grep -v "Operating system" | grep -v Copyright | grep -v "character set" | grep -v "Linux, x64" | grep -v GGSCI >> $HOUR_LOG_FILE

if [[ -f $TEMP_DAY_LOG ]]; then
 echo "=======================" >> $DAY_LOG_FILE
 echo $RUN_DATE >> $DAY_LOG_FILE
 echo "=======================" >> $DAY_LOG_FILE
 less ${TEMP_DAY_LOG} | grep -v "Command Interpreter for Oracle" | grep -v OGGCORE | grep -v "Operating system" | grep -v Copyright | grep -v "character set" | grep -v "Linux, x64" | grep -v GGSCI >> $DAY_LOG_FILE
fi

#=======================
# Keeps Logs for 1 Week
#=======================
if [[ $RUN_HOUR == "01" ]]; then
 mv ${HOUR_LOG_FILE}_06 ${HOUR_LOG_FILE}_07 2>/dev/null
 mv ${HOUR_LOG_FILE}_05 ${HOUR_LOG_FILE}_06 2>/dev/null
 mv ${HOUR_LOG_FILE}_04 ${HOUR_LOG_FILE}_05 2>/dev/null
 mv ${HOUR_LOG_FILE}_03 ${HOUR_LOG_FILE}_04 2>/dev/null
 mv ${HOUR_LOG_FILE}_02 ${HOUR_LOG_FILE}_03 2>/dev/null
 mv ${HOUR_LOG_FILE}_01 ${HOUR_LOG_FILE}_02 2>/dev/null
 mv ${HOUR_LOG_FILE} ${HOUR_LOG_FILE}_01 2>/dev/null

 mv ${DAY_LOG_FILE}_06 ${DAY_LOG_FILE}_07 2>/dev/null
 mv ${DAY_LOG_FILE}_05 ${DAY_LOG_FILE}_06 2>/dev/null
 mv ${DAY_LOG_FILE}_04 ${DAY_LOG_FILE}_05 2>/dev/null
 mv ${DAY_LOG_FILE}_03 ${DAY_LOG_FILE}_04 2>/dev/null
 mv ${DAY_LOG_FILE}_02 ${DAY_LOG_FILE}_03 2>/dev/null
 mv ${DAY_LOG_FILE}_01 ${DAY_LOG_FILE}_02 2>/dev/null
 mv ${DAY_LOG_FILE} ${DAY_LOG_FILE}_01 2>/dev/null
fi

Golden Gate - Crontab to log INFO ALL

crontab
*/10 * * * * /software/oracle/oracle/scripts/gg_stats_monitor/get_gg_info.sh

get_gg_info.sh
#!/bin/bash
. /etc/sh/orash/oracle_login.sh igt
GG_HOME=/software/ogg/191
ORACLE_SID=igt
ORACLE_HOME=/software/oracle/122

SCHEMA_NAME=XXX_YYYYY_ZZZZZ

HOME_DIR=/software/oracle/oracle/scripts/gg_stats_monitor
INFO_LOG_FILE="${HOME_DIR}/logs/gg_info.log"
TEMP_INFO_LOG=/tmp/gg_info_all.log

RUN_HOUR=$(date +"%H")
RUN_MIN=$(date +"%M")
RUN_DATE=`date +"%Y%m%d"_"%H%M%S"`

#main()
rm -f $TEMP_INFO_LOG 2>/dev/null

$GG_HOME/ggsci > $TEMP_INFO_LOG << EOD
INFO ALL
exit
EOD

echo "=======================" >> $INFO_LOG_FILE
echo $RUN_DATE >> $INFO_LOG_FILE
echo "=======================" >> $INFO_LOG_FILE
less ${TEMP_INFO_LOG} | grep -v "Command Interpreter for Oracle" | grep -v OGGCORE | grep -v "Operating system" | grep -v Copyright | grep -v "character set" | grep -v "Linux, x64" | grep -v GGSCI | grep -v "SYSLOG"  | grep -v ^$ >> $INFO_LOG_FILE


#=======================
# Keeps Logs for 1 Week
#=======================
if [[ $RUN_HOUR == "01" && $RUN_MIN == "00" ]]; then
 mv ${TEMP_INFO_LOG}_06 ${TEMP_INFO_LOG}_07 2>/dev/null
 mv ${TEMP_INFO_LOG}_05 ${TEMP_INFO_LOG}_06 2>/dev/null
 mv ${TEMP_INFO_LOG}_04 ${TEMP_INFO_LOG}_05 2>/dev/null
 mv ${TEMP_INFO_LOG}_03 ${TEMP_INFO_LOG}_04 2>/dev/null
 mv ${TEMP_INFO_LOG}_02 ${TEMP_INFO_LOG}_03 2>/dev/null
 mv ${TEMP_INFO_LOG}_01 ${TEMP_INFO_LOG}_02 2>/dev/null
 mv ${TEMP_INFO_LOG} ${TEMP_INFO_LOG}_01 2>/dev/null
fi

Generated File
=======================
20231214_082001
=======================
Program     Status      Group       Lag at Chkpt  Time Since Chkpt
MANAGER     RUNNING
EXTRACT     RUNNING     DPM_I_01    00:00:00      00:00:01
EXTRACT     RUNNING     DPM_P_01    00:00:00      00:00:08
EXTRACT     RUNNING     DPM_S_01    00:00:03      00:00:05
EXTRACT     RUNNING     EXT_I_01    00:00:02      00:00:05
EXTRACT     RUNNING     EXT_P_01    00:00:02      00:00:02
EXTRACT     RUNNING     EXT_S_01    00:00:02      00:00:02
REPLICAT    RUNNING     REP_I_01    00:00:00      00:00:04
REPLICAT    RUNNING     REP_P_01    00:00:00      00:00:08
REPLICAT    RUNNING     REP_S_01    00:00:03      00:00:00

Wednesday, December 6, 2023

ORA-32001: write to SPFILE requested but no SPFILE is in use

==========================
Error Details
==========================
ALTER SYSTEM SET MEMORY_MAX_TARGET=24576M scope=spfile;

ERROR at line 1:
ORA-32001: write to SPFILE requested but no SPFILE is in use


==========================
Solution
==========================

SQL> show parameter pfile

NAME            VALUE
--------------- --------------------
spfile          


Notice! - the value for spfile is not defined.

SQL> CREATE SPFILE FROM MEMORY;

spfile<inst>.ora is created under default location:
${ORACLE_HOME}/dbs/

/software/oracle/1910/dbs/spfileigt.ora

SQL> CREATE PFILE='/software/oracle/1910/dbs/pfileigt.ora' FROM SPFILE='/software/oracle/1910/dbs/spfileigt.ora'
PFILE is created:
/software/oracle/1910/dbs/pfileigt.ora


SQL> ALTER SYSTEM SET MEMORY_MAX_TARGET=24576M scope=spfile;
ALTER SYSTEM SET MEMORY_MAX_TARGET=24576M scope=spfile
*
ERROR at line 1:
ORA-32001: write to SPFILE requested but no SPFILE is in use

SQL> show parameter spfile

NAME              VALUE
----------------- ---------------------------------------
spfile

spfile is still not defined.
Need to restart oracle.


SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;

SQL> show parameter spfile

NAME              VALUE
----------------- ---------------------------------------
spfile            /software/oracle/1910/dbs/spfileigt.ora


SQL> ALTER SYSTEM SET MEMORY_MAX_TARGET=24576M scope=spfile;

System altered.

SQL> ALTER SYSTEM SET MEMORY_TARGET=24576M scope=spfile;

System altered.

NAME                  VALUE
--------------------- -----------
memory_max_target     24G
memory_target         24G




Tuesday, December 5, 2023

Archive logs is pointing to non exiting location

===============================
The Problem:
===============================
Archive destination is not available.
Oracle is running in ARCHIVE mode.
This is giving errors during startup

SQL> shutdown immediate
ORA-01034: ORACLE not available
ORA-27101: shared memory realm does not exist
Linux-x86_64 Error: 2: No such file or directory
Or
SQL> shutdown immediate;
ORA-24324: service handle not initialized
ORA-01041: internal error. hostdef extension doesn't exist

SQL> startup mount;
ORA-16032: parameter LOG_ARCHIVE_DEST_1 destination string cannot be translated
ORA-07286: sksagdi: cannot obtain device information.
Linux-x86_64 Error: 2: No such file or directory


The problem is this parameter (LOG_ARCHIVE_DEST_1) is pointing to non existent locatoin.
To change the value of LOG_ARCHIVE_DEST_1:


===============================
Steps to resolve Problem:
===============================

A. locate spfileigt.ora
/software/oracle/admin/igt/pfile/spfileigt.ora


STARTUP NOMOUNT;

B. Create a pfileigt.ora

SQL> create pfile='/software/oracle/admin/igt/pfile/orig_pfile.ora' 

from spfile='/software/oracle/admin/igt/pfile/spfileigt.ora';


File created.


C. Edit the new pfile.ora. change location for log_archive_dest_1

cp orig_pfile.ora pfile.ora

vi pfile.ora

Change from:*.log_archive_dest_1='location=/path/does/not/exist'
To:log_archive_dest_1='location=/path/does/exist'

For example:
diff orig_pfile.ora pfile.ora 
27c27
< *.log_archive_dest_1='location=/oracle_db/db2/db_igt/arch'
---
> *.log_archive_dest_1='location=/oracle_db/db1/db_igt/arch'

D. Replace between files and start instance from new spfile

cp spfileigt.ora orig_spfileigt.ora

CREATE SPFILE='/software/oracle/admin/igt/pfile/spfileigt.ora' 
FROM PFILE='/software/oracle/admin/igt/pfile/pfile.ora';
ERROR at line 1:
ORA-32002: cannot create SPFILE already being used by the instance

CREATE SPFILE='/software/oracle/admin/igt/pfile/spfileigt.ora_new' 
FROM PFILE='/software/oracle/admin/igt/pfile/pfile.ora';

SHUTDOWN IMMEDIATE;
ORA-01507: database not mounted
ORACLE instance shut down.

mv spfileigt.ora_new spfileigt.ora

cd /software/oracle/admin/igt/pfile
/software/oracle/admin/igt/pfile>% ls -l
-rw-r--r-- 1 oracle dba 1296 Dec  5 07:52 orig_pfile.ora
-rw-r----- 1 oracle dba 3584 Dec  5 07:52 orig_spfileigt.ora
-rw-r--r-- 1 oracle dba 1296 Dec  5 07:54 pfile.ora
-rw-r----- 1 oracle dba 3584 Dec  5 08:08 spfileigt.ora


E. Restart the database
SQL> STARTUP NOMOUNT;
ORACLE instance started.

Total System Global Area 8589930592 bytes
Fixed Size                 12456032 bytes
Variable Size            4328521728 bytes
Database Buffers         4227858432 bytes
Redo Buffers               21094400 bytes
SQL> ALTER DATABASE MOUNT;

Database altered.

F. Optionally - change database to be in NOARCHIVELOG mode
SQL> ALTER DATABASE NOARCHIVELOG;

Database altered.

SQL> ALTER DATABASE OPEN;

Database altered.

SQL> SHUTDOWN IMMEDIATE;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> STARTUP;
ORACLE instance started.

Total System Global Area 8589930592 bytes
Fixed Size                 12456032 bytes
Variable Size            4328521728 bytes
Database Buffers         4227858432 bytes
Redo Buffers               21094400 bytes
Database mounted.
Database opened.
SQL> exit

G. Take backup with expdp

===================
In Short:
===================
Open two sessions
sqlplus 
STARTUP NOMOUNT;
CREATE PFILE='/software/oracle/admin/igt/pfile/orig_pfile.ora' 
FROM SPFILE='/software/oracle/admin/igt/pfile/spfileigt.ora';

Linux
cp orig_pfile.ora pfile.ora
vi pfile.ora
log_archive_dest_1='location=/oracle_db/db1/db_igt/arch

sqlplus 
CREATE SPFILE='/software/oracle/admin/igt/pfile/noarch_spfile.ora' 
FROM PFILE='/software/oracle/admin/igt/pfile/pfile.ora';

SHUTDOWN IMMEDIATE;

Linux 
cd /software/oracle/admin/igt/pfile
cp spfileigt.ora orig_spfileigt.ora
cp noarch_spfile.ora spfileigt.ora

sqlplus 
STARTUP NOMOUNT;
ALTER DATABASE MOUNT;
ALTER DATABASE NOARCHIVELOG;
ALTER DATABASE OPEN;
SHUTDOWN IMMEDIATE;
STARTUP;

Sunday, November 26, 2023

crontab to delete old dmp files

crontab
11 11 * * * /software/oracle/oracle/scripts/del_old_dmp_files/del_old_dmp.sh

del_old_dmp.sh
#!/bin/bash

WORK_DIR=/software/oracle/oracle/scripts/del_old_dmp_files
EXP_DIR=/backup/ora_exp
LOG_FILE=${WORK_DIR}/del_old_dmp.log
RUN_DATE=`date +"%Y%m%d"_"%H%M%S"`

cd ${WORK_DIR}
echo "=========================" >> ${LOG_FILE}
echo "Start Delete old dmp files at ${RUN_DATE}" >> ${LOG_FILE}

for f in `ls -1 ${EXP_DIR}  | grep export | grep dmp | grep igt`
do
 echo "Deleting File $f" >> ${LOG_FILE}
 echo "rm -f ${EXP_DIR}/$f" >> ${LOG_FILE}
 rm -f ${EXP_DIR}/$f
done
echo "=========================" >> ${LOG_FILE}

Wednesday, November 22, 2023

ORA-04036: PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT

=====================
Error in oracle startup
=====================
SQL> Connected to an idle instance.
SQL> ORA-01078: failure in processing system parameters
ORA-00093: pga_aggregate_limit must be between 16384M and 100000G
SQL> Disconnected

=====================
What to check
=====================
COL name for A30
COL VALUE for A30
SELECT name, value 
  FROM V$PARAMETER 
 WHERE name = 'pga_aggregate_limit';

NAME                           VALUE
------------------------------ ------------------------------
pga_aggregate_limit            3145728000

3145728000=3000M


=====================
Solution
=====================
SQL> ALTER SYSTEM SET pga_aggregate_limit=0 SCOPE=BOTH;
System altered.

Issue resolved

=====================
Theory
=====================
As per Oracle documentation
In Oracle Database 12c, a new parameter called PGA_AGGREGATE_LIMIT sets a hard limit on the amount of PGA taken up by an instance. 
When the overall PGA occupied by all the sessions in that instance exceed the limit, Oracle kills the session holding the most untunable PGA memory, releasing all PGA memory held by that session.

If you are hitting this error message you have 2 options
Option 1:
Set the value of pga_aggregate_limit to 0 and the parameter will not have any impact.
It behave like pre12c database.
ALTER SYSTEM SET PGA_AGGREGATE_LIMIT=0 SCOPE=BOTH;

Option 2:
Set this value to a higher value if you have enough physical memory on your system by using below command the server
ALTER SYSTEM SET PGA_AGGREGATE_LIMIT=6000M SCOPE=BOTH;

No need restart the database, as this is a dynamic parameter.


==========================================
How to now if pga_aggregate_limit is set ot not?
==========================================
CREATE PFILE='/software/oracle/122/dbs/pfileigt.ora_20231121' FROM SPFILE='/software/oracle/122/dbs/spfileigt.ora';

oracle@qanfv-2-dbs-01:~>% less /software/oracle/122/dbs/pfileigt.ora_20231121 | grep -i pga

igt.__pga_aggregate_target=18790481920
*._pga_max_size=5368709120
*.pga_aggregate_target=15728640000


SQL> SHOW PARAMETER PGA_AGGREGATE

NAME                         VALUE
---------------------------- --------------
pga_aggregate_limit          56G
pga_aggregate_target         15000M

SQL> SHOW PARAMETER MEMORY
NAME                         VALUE
---------------------------- --------------
memory_max_target            56G
memory_target                50G


PGA_AGGREGATE_LIMIT Theory
PGA_AGGREGATE_LIMIT specifies a limit on the aggregate PGA memory consumed by the instance.

Default value
If MEMORY_TARGET is set, then PGA_AGGREGATE_LIMIT defaults to the MEMORY_MAX_TARGET value.

If MEMORY_TARGET is not set, then PGA_AGGREGATE_LIMIT defaults to 200% of PGA_AGGREGATE_TARGET.

If MEMORY_TARGET is not set, and PGA_AGGREGATE_TARGET is explicitly set to 0, then the value of PGA_AGGREGATE_LIMIT is set to 90% of the physical memory size minus the total SGA size.

In all cases, the default PGA_AGGREGATE_LIMIT is at least 2GB and at least 3MB times the PROCESSES parameter (and at least 5MB times the PROCESSES parameter for an Oracle RAC instance).

Range of values
Do not attempt to set PGA_AGGREGATE_LIMIT below its default value, even in a parameter file (pfile), or instance startup will fail. 
However, PGA_AGGREGATE_LIMIT can be set to 0 either in a parameter file or dynamically after startup. 
If a value of 0 is specified, it means there is no limit to the aggregate PGA memory consumed by the instance.

Tuesday, November 14, 2023

Gather stats from crontab - once a month

crontab (run at 22:05 on second of each month)
5 22 2 * * bash -l /software/oracle/oracle/scripts/shared_pool_latch/gather_stats.sh

gather_stats.sh
#!/bin/bash
ORA_VER=1120
ORACLE_SID=igt
ORACLE_BASE=/software/oracle
ORA_NLS33=/software/oracle/112/ocommon/nls/admin/data
ORACLE_HOME=/software/oracle/112
WORK_DIR=/software/oracle/oracle/scripts/shared_pool_latch
LOG_FILE=${WORK_DIR}/gather_stats.log
RUN_DATE=`date "+%Y%m%d"_"%H%M"`
cd $WORK_DIR
echo "===============================" >> ${LOG_FILE}
echo "Start Gather Stats at ${RUN_DATE}" >> ${LOG_FILE}
sqlplus / as sysdba @gather_stats.sql
RUN_DATE=`date "+%Y%m%d"_"%H%M"`
echo "Finished Gather Stats at ${RUN_DATE}" >> ${LOG_FILE}
echo "===============================" >> ${LOG_FILE}

gather_stats.sql
spool gather_stats.log append
PROMPT DBMS_STATS.GATHER_SCHEMA_STATS ('SYS')
BEGIN
 DBMS_STATS.GATHER_SCHEMA_STATS ('SYS');
END;
/
PROMPT DBMS_STATS.GATHER_DICTIONARY_STATS
BEGIN
 DBMS_STATS.GATHER_DICTIONARY_STATS;
END;
/
PROMPT DBMS_STATS.GATHER_FIXED_OBJECTS_STATS
BEGIN
 DBMS_STATS.GATHER_FIXED_OBJECTS_STATS;
END;
/
PROMPT DBMS_STATS.gather_schema_stats('XXX_YYYYY_AAAAA')
BEGIN
 DBMS_STATS.gather_schema_stats('XXX_YYYYY_AAAAA');
END;
/
PROMPT DBMS_STATS.gather_schema_stats('XXX_YYYYY_BBBBB')
BEGIN
 DBMS_STATS.gather_schema_stats('XXX_YYYYY_BBBBB');
END;
/
PROMPT DBMS_STATS.gather_schema_stats('XXX_YYYYY_CCCCC')
BEGIN
 DBMS_STATS.gather_schema_stats('XXX_YYYYY_CCCCC');
END;
/
EXIT;

Sunday, October 29, 2023

DBMS_STATS Starhome Stuff

BEGIN
 DBMS_STATS.GATHER_SCHEMA_STATS ('SYS');
END;
/

BEGIN
 DBMS_STATS.GATHER_DICTIONARY_STATS;
END;
/

BEGIN
 DBMS_STATS.GATHER_FIXED_OBJECTS_STATS;
END;
/


BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GSM_IMSI_PREFIXES', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GSM_COUNTRIES', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GSM_NETWORKS_T', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GSM_MERGE_NETWORKS', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GSM_MERGE_NW_MAPPING', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GSM_NETWORKS_SEG_T', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GA_LANGUAGES', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GSM_SERVICE_MERGED_NETWORKS', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GSM_NETWORKS_EXCEPTIONS', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

BEGIN
  DBMS_STATS.gather_table_stats
  (ownname=>'XXX', 
   tabname=>'GA_ACCOUNTS', 
   estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
   cascade => DBMS_STATS.AUTO_CASCADE );
END;
/

=========================
See execution plan of an SQL
=========================
ALTER SYSTEM FLUSH SHARED_POOL;

SELECT sql_id, child_number 
  FROM V$SQL 
WHERE sql_id = 'fw4tmpkt79r4r';

SELECT sql_id, child_number 
  FROM V$SQL 
WHERE sql_text LIKE 'MERGE into SGA_W_IPN_SUBSCRIBER o using%';


SET LINESIZE 120
SET PAGESIZE 0
SELECT * FROM TABLE(DBMS_XPLAN.display_cursor('fw4tmpkt79r4r',3,'OUTLINE'));

Thursday, October 26, 2023

SHUTDOWN ABORT, IMMEDIATE, NORMAL, TRANSACTIONAL

SHUTDOWN ABORT;
Fastest.
Uncommitted transactions are not rolled back.
All users currently connected to the database are implicitly disconnected.
The next database startup will require instance recovery.

SHUTDOWN IMMEDIATE;
Does not wait for current calls to complete or users to disconnect from the database.
Further connects are prohibited. 
The database is closed and dismounted. 
The instance is shutdown and no instance recovery is required on the next database startup.

SHUTDOWN NORMAL;
NORMAL is the default option which waits for users to disconnect from the database.
Further connects are prohibited. 
The database is closed and dismounted. 
The instance is shutdown and no instance recovery is required on the next database startup.

SHUTDOWN TRANSACTIONAL;
Performs a planned shutdown of an instance while allowing active transactions to complete first. 
It prevents clients from losing work without requiring all users to log off.
No client can start a new transaction on this instance.
After completion of all transactions, any client still connected to the instance is disconnected.
Now the instance shuts down just as it would if a SHUTDOWN IMMEDIATE
The next startup of the database will not require any instance recovery procedures.
$ lsnrctl start 

You must be connected to a database as SYSDBA, SYSOPER, SYSBACKUP, or SYSDG.


SYSDBA - database management commands
SYSOPER - Limited to database shutdown, startup, open, recover, create spfile.
SYSBACKUP - similar to SYSDBA. with few limitations.
SYSDG - Data Guards Related