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;