Most of the time end user complaining that the database is slow as high performance is common expectation for end user. The database itself is never slow or fast in most of the case session connected to the database slow down when they receive unexpected hit. To resolve session performance issue you need to identify unexpected hit and remove it. As we know an oracle database is always one of the 3 states:
Idle: Waiting for the task.
Processing: Doing some useful task.
Waiting: Waiting for something, a block to come from disk or lock to be released.
Sometimes the situation is session is waiting for resource and another session trying to update that record and many other such scenarios. Our goal is to find and eliminate that type of session.
Update pay_employee_personal_info
Set amount = 4000
Where employee_number = 5205;
Do not issue a commit after this update operation. That means you are forcing the session to get and hold a lock on the first row of the ‘pay_employee_personal_info’ table.
Now if you try the below update statement on the second session. The statement will hang! The question why?
Update pay_employee_personal_info
Set amount = 5000
Where employee_number = 5205;
This is due to the first session holds a lock on the row, which cause the second session to hang and the user to complain that the session is slow.
To know exactly what the second session is doing join your query with v$session_wait.
--Displays information on particular user session waits.
SELECT NVL(s.username, '(oracle)') AS username,
s.sid, s.serial#, sw.event, sw.wait_time, sw.seconds_in_wait, sw.state
FROM v$session_wait sw, v$session s
WHERE s.sid = sw.sid and s.username = 'HRMS'
ORDER BY sw.seconds_in_wait DESC;
USERN SID SERIAL#EVENT WAIT_TIME SECONDS STATE
------ --- ------ ------------------------ -------- ------- ----------
HRMS 53 6,581 SQL*Net message from client 0 870 WAITED KNOWN TIME
HRMS 22 47,542 SQL*Net message from client 0 633 WAITED KNOWN TIME
HRMS 18 21,757 SQL*Net message from client 0 24 WAITED KNOWN TIME
HRMS 36 18,360 enq:TX - row lock contention0 12 WAITING
HRMS 34 18,633 SQL*Net message from client 0 9 WAITING
If you don’t know exactly which user or Terminal causing issues you can run your query to ask whole database session waits information then gradually move for particular user or Terminal session wait information. From the output you can see the users are connected with different application such as Payroll software (HRMS), Oracle Financial software (ORAFIN), EDSS, ITGFIN.
--Displays information on all database session waits.
SELECT NVL(s.username, '(oracle)') AS username,
s.sid, s.serial#, sw.event, sw.wait_time, sw.seconds_in_wait, sw.state
FROM v$session_wait sw, v$session s
WHERE s.sid = sw.sid
ORDER BY sw.seconds_in_wait DESC;
Select SID, osuser, machine, terminal,
logon_time, last_call_et
from v$session
where username = 'HRMS' AND TERMINAL = 'HR-RAFEQ';
If you study the output carefully for SID (53, 22, and 18) which shows that it waited for some known amount of time earlier but now it is working properly where as SID (36, 34) indicates that it is waiting for something therefore it is not working. Why it is waiting for, you can check the reason in EVENT column of the output. The EVENT column not only shows the current waiting situation, also shows an EVENT session waited for earlier.
From the SID 36 output shows that session is waiting right now for transaction level lock on row and session is still waiting to lock one or more rows, but another session has already placed locks on the rows. Unless that other session commits or rolls back its transaction, SID 36 will not release the lock. You can also view the time since the session is waiting. A very long wait usually indicates some sorts of performance bottleneck.
From the above output you can also see the session 34 is idle but any complain regarding this session is not related to the session performance. Check the other aspects of performance troubleshooting why it is going through an infinite loop or high CPU consumption on the application server.
From the below query you can get the information of system identification as well as user information along with logon_time. It is important for you to know which user or system is creating this issue.
--Displays system and user details with logon_time for database sessions
SELECT NVL(s.username, '(oracle)') AS username,
s.osuser, s.sid, s.serial#, p.spid, s.lockwait,s.status,
s.module,s.machine, TO_CHAR(s.logon_Time,'DD-MON-YYYY HH24:MI:SS') AS logon_time
FROM v$session s, v$process p
WHERE s.paddr = p.addr
ORDER BY s.username, s.osuser;
Once you find the issue ‘a session is waiting for row lock’ it is important for you to find which session holds that lock.
To identify the locked row:
Select row_wait_obj#, row_wait_file#, row_wait_block#, row_wait_row#
from v$session where sid=36;
To identify the lock object:
Select owner, object_type, object_name, data_object_id
from dba_objects
where object_id = 145425;
To find Lock session Text:
select s.sid, q.sql_text from v$sqltext q, v$session s
where q.address = s.sql_address
and s.sid = &sid
order by piece;
Follow the link to find query on database locks or who is blocking the session or blocker session details: Find Locks : Blockers
Once you find which session blocking the lock or which session holds the lock, you need to find the SQL statements which cause issue.
--To find Lock session Text
select address, s.sid, q.sql_text from v$sqltext q, v$session s
where q.address = s.sql_address
and s.sid = &sid
order by piece;
Select sql_text from v$sql
where address = '4AC67EE4';
Locking is not only the cause to effects the performance. Another major case of contention is disk I/O. When a session retrieves data from the database datafiles on disk to the buffer cache, it has to wait until the disk sends the data. The wait event shows up for the session as “db file sequential read” (for index scan) or “db file scattered read” (for full table scan). You can find more related query on event details and I/O details by clicking on the link: DB Locks
When you see the event, you know that the session is waiting for I/O from the disk to complete. To improve session performance, you have to reduce that waiting period. There are several ways to reduce the wait. The exact step depends on specific situation, but the first technique “reducing the number of blocks retrieved by a SQL statement” almost always works.
– Reduce the number of blocks retrieved by the SQL statement. Examine the SQL statement to see if it is doing a full-table scan when it should be using an index, if it is using a wrong index, or if it can be rewritten to reduce the amount of data it retrieves.
– Place the tables used in the SQL statement on a faster part of the disk.
– Consider increasing the buffer cache to see if the expanded size will accommodate the additional blocks, therefore reducing the I/O and the wait.
– Tune the I/O subsystem to return data faster.
Idle: Waiting for the task.
Processing: Doing some useful task.
Waiting: Waiting for something, a block to come from disk or lock to be released.
Sometimes the situation is session is waiting for resource and another session trying to update that record and many other such scenarios. Our goal is to find and eliminate that type of session.
Update pay_employee_personal_info
Set amount = 4000
Where employee_number = 5205;
Do not issue a commit after this update operation. That means you are forcing the session to get and hold a lock on the first row of the ‘pay_employee_personal_info’ table.
Now if you try the below update statement on the second session. The statement will hang! The question why?
Update pay_employee_personal_info
Set amount = 5000
Where employee_number = 5205;
This is due to the first session holds a lock on the row, which cause the second session to hang and the user to complain that the session is slow.
To know exactly what the second session is doing join your query with v$session_wait.
--Displays information on particular user session waits.
SELECT NVL(s.username, '(oracle)') AS username,
s.sid, s.serial#, sw.event, sw.wait_time, sw.seconds_in_wait, sw.state
FROM v$session_wait sw, v$session s
WHERE s.sid = sw.sid and s.username = 'HRMS'
ORDER BY sw.seconds_in_wait DESC;
USERN SID SERIAL#EVENT WAIT_TIME SECONDS STATE
------ --- ------ ------------------------ -------- ------- ----------
HRMS 53 6,581 SQL*Net message from client 0 870 WAITED KNOWN TIME
HRMS 22 47,542 SQL*Net message from client 0 633 WAITED KNOWN TIME
HRMS 18 21,757 SQL*Net message from client 0 24 WAITED KNOWN TIME
HRMS 36 18,360 enq:TX - row lock contention0 12 WAITING
HRMS 34 18,633 SQL*Net message from client 0 9 WAITING
If you don’t know exactly which user or Terminal causing issues you can run your query to ask whole database session waits information then gradually move for particular user or Terminal session wait information. From the output you can see the users are connected with different application such as Payroll software (HRMS), Oracle Financial software (ORAFIN), EDSS, ITGFIN.
--Displays information on all database session waits.
SELECT NVL(s.username, '(oracle)') AS username,
s.sid, s.serial#, sw.event, sw.wait_time, sw.seconds_in_wait, sw.state
FROM v$session_wait sw, v$session s
WHERE s.sid = sw.sid
ORDER BY sw.seconds_in_wait DESC;
Select SID, osuser, machine, terminal,
logon_time, last_call_et
from v$session
where username = 'HRMS' AND TERMINAL = 'HR-RAFEQ';
If you study the output carefully for SID (53, 22, and 18) which shows that it waited for some known amount of time earlier but now it is working properly where as SID (36, 34) indicates that it is waiting for something therefore it is not working. Why it is waiting for, you can check the reason in EVENT column of the output. The EVENT column not only shows the current waiting situation, also shows an EVENT session waited for earlier.
From the SID 36 output shows that session is waiting right now for transaction level lock on row and session is still waiting to lock one or more rows, but another session has already placed locks on the rows. Unless that other session commits or rolls back its transaction, SID 36 will not release the lock. You can also view the time since the session is waiting. A very long wait usually indicates some sorts of performance bottleneck.
From the above output you can also see the session 34 is idle but any complain regarding this session is not related to the session performance. Check the other aspects of performance troubleshooting why it is going through an infinite loop or high CPU consumption on the application server.
From the below query you can get the information of system identification as well as user information along with logon_time. It is important for you to know which user or system is creating this issue.
--Displays system and user details with logon_time for database sessions
SELECT NVL(s.username, '(oracle)') AS username,
s.osuser, s.sid, s.serial#, p.spid, s.lockwait,s.status,
s.module,s.machine, TO_CHAR(s.logon_Time,'DD-MON-YYYY HH24:MI:SS') AS logon_time
FROM v$session s, v$process p
WHERE s.paddr = p.addr
ORDER BY s.username, s.osuser;
Once you find the issue ‘a session is waiting for row lock’ it is important for you to find which session holds that lock.
To identify the locked row:
Select row_wait_obj#, row_wait_file#, row_wait_block#, row_wait_row#
from v$session where sid=36;
To identify the lock object:
Select owner, object_type, object_name, data_object_id
from dba_objects
where object_id = 145425;
To find Lock session Text:
select s.sid, q.sql_text from v$sqltext q, v$session s
where q.address = s.sql_address
and s.sid = &sid
order by piece;
Follow the link to find query on database locks or who is blocking the session or blocker session details: Find Locks : Blockers
Once you find which session blocking the lock or which session holds the lock, you need to find the SQL statements which cause issue.
--To find Lock session Text
select address, s.sid, q.sql_text from v$sqltext q, v$session s
where q.address = s.sql_address
and s.sid = &sid
order by piece;
Select sql_text from v$sql
where address = '4AC67EE4';
Locking is not only the cause to effects the performance. Another major case of contention is disk I/O. When a session retrieves data from the database datafiles on disk to the buffer cache, it has to wait until the disk sends the data. The wait event shows up for the session as “db file sequential read” (for index scan) or “db file scattered read” (for full table scan). You can find more related query on event details and I/O details by clicking on the link: DB Locks
When you see the event, you know that the session is waiting for I/O from the disk to complete. To improve session performance, you have to reduce that waiting period. There are several ways to reduce the wait. The exact step depends on specific situation, but the first technique “reducing the number of blocks retrieved by a SQL statement” almost always works.
– Reduce the number of blocks retrieved by the SQL statement. Examine the SQL statement to see if it is doing a full-table scan when it should be using an index, if it is using a wrong index, or if it can be rewritten to reduce the amount of data it retrieves.
– Place the tables used in the SQL statement on a faster part of the disk.
– Consider increasing the buffer cache to see if the expanded size will accommodate the additional blocks, therefore reducing the I/O and the wait.
– Tune the I/O subsystem to return data faster.
No comments:
Post a Comment