Source of this scene:
Notify a session: execute execute addupp(1,'five'); similar stored procedure, session waits: (session waits for two situations: one is indeed executed, but not completed; the other is that the executed operation cannot obtain resources , waiting for the resource to be released, i.e. lock waiting), this test lock: row lock waiting test:
This scenario test: how to quickly locate the session holding the lock and kill to release resources
This scene operation:
Stored procedure: execute Update operation, wait for row lock, multiple session execution causes: row lock contention, session is blocked
Simulation environment: How row locks are simulated: contention for concurrency and locks, Lock ordering, queuing
#Scenario simulation online: user scott, test table ceshi #Simulation
session 1: call storage A, insert 3 pieces of test data
#Simulation session 1: call storage B and update a piece of data SYS
#Simulation session 2: call storage B, update (session 1) the data row that has been updated and uncommitted, causing blocking Yang
#Simulation session 3: Direct Update to update the same data row cc user
#Simulation session 5. Business operation: update data discovery blocking: scott user
The test table structure, insert stored procedure A, and update stored procedure B are as follows:
SQL> desc ceshi Name Null? Type ---------------------------------- ID NUMBER(38) NAME VARCHAR2(10) #SYS user creates a stored procedure: # store A create or replace procedure
addnew
(n_id NUMBER, n_name VARCHAR2 )
as begin insert
into scott.ceshi(id,name) values(n_id,n_name); commit;
end addnew; / # store B create or replace procedure addupp
(u_id NUMBER, u_name VARCHAR2 )
as begin update
scott.ceshi set name='u_name' where id=u_id; end addupp;
/
#Create a complete query:
SQL> select OBJECT_NAME,OBJECT_TYPE,STATUS from user_objects where object_type='PROCEDURE' and OBJECT_NAME like 'ADD%';
OBJECT_NAME OBJECT_TYPE STATUS
------------------------------------
ADDNEW PROCEDURE VALID
ADDUPP PROCEDURE VALID
#Test scene permissions, data processing:
SYS user calls to store A: Insert 3 pieces of data SQL> execute addnew(1,'yang'); SQL> execute addnew(2,'cheng'); SQL> execute addnew(3,'hehe'); #Grant test yang / cc two users object permissions on the test table: SQL> grant select on scott.ceshi to yang; SQL> grant update on ceshi to yang; SQL> grant select on scott.ceshi to cc; SQL> grant update on scott.ceshi to cc; Stored procedure authorization: grant execute on addupp to yang; grant execute on addupp to cc;
#Session 1: sys user calls storage B, updates id=1, name='one'
SQL> show user USER is "SYS" SQL> execute addupp(1,'one'); SQL> select * from scott.ceshi; ID NAME ---------- 1 one 2 cheng 3 hehe
#Session two: yang user calls storage B, updates id=1, name='two'
SQL> show user USER is "YANG" SQL> execute addupp(1,'two'); --wait
#Session three: cc user calls storage B, updates id=1, name='three'
SQL> show user USER is "CC" SQL> update scott.ceshi set name='three' where id=1;
#Session 4: Scott user calls storage B, updates id=1, name='five'
SQL> show user USER is "SCOTT" SQL> execute addupp(1,'five');
##################The above is the scene simulation, online restoration########################## ########
####################################### The following is the solution question#####################
#The notification we are likely to receive is: The execution operation is waiting, and after it cannot be executed, it is reported to us that xxx cannot be executed, and it is locked
####SQL> execute addupp(1,'five'); @Cannot execute
Processing idea: => waiting, unable to execute Reason: lock
=> what object
=> which sessions are waiting, holding those resources
=> Query session ID, SERIAL, Kill to kill the session, release resources, and allow the business to recover quickly
=> Query Object Type:
SQL> select OWNER,OBJECT_NAME,OBJECT_TYPE from dba_objects where owner='SCOTT' and object_name='ADDUPP'; OWNER OBJECT_NAME OBJECT_TYPE -------------------------------------------------------------------------------- SCOTT ADDUPP PROCEDURE
=> Query: locked objects and lock times
View V$DB_OBJECT_CACHE: Found locked object
#Through this view: you can find out under a user: locked objects, and the number of locks col name for a10 col type for a20 col locks for 999 col locked_total 9999 select name,type,locks,locked_total from v$db_object_cache where owner='SCOTT' and locks is not null; NAME TYPE LOCKS LOCKED_TOTAL ---------- -------------------- ----- ------------ CESHI TABLE 0 60 DBMS_OUTPUT CURSOR 0 17 ADDUPP PROCEDURE 1 2 SCOTT PUB SUB INTERNAL INF 1 3
#According to the application feedback command or user object, the focus of this time: it is the ADDUPP calling program, which cannot be executed
#By locked object: find the locked SID
View: V$ACCESS #Display lock information currently imposed on library cache objects: The session number of the SID access object OWNER object owner OBJECT object name TYPE object type #Through this view: find those users who have locked this object select * from v$access; select * from v$access where type='PROCEDURE' and object='ADDUPP'; SID OWNER OBJECT TYPE ---------- ---------------------------------------------------------------- 40 SCOTT ADDUPP PROCEDURE 42 THE ADDUPP PROCEDURE
#####Note: In RAC environment: you need to pay attention to the Inst_id instance number:
#Find the session serial by SID#
#v$session view: select sid,serial#,username,TIME_SINCE_LAST_WAIT_MICRO,BLOCKING_SESSION_STATUS from v$session where sid in (40,42); SID SERIAL# USERNAME TIME_SINCE_LAST_WAIT_MICRO BLOCKING_SE ---------- ---------- ------------------------------ ---------------- 40 275 SCOTT 0 VALID 42 897 YANG 0 VALID
#SID session identifier
#SERIAL# session identifier, reusable, in order to avoid repetition: session serial number identification: sid+ serial#= unique session information
#USERNAME session login username
#TIME_SINCE_LAST_WAIT_MICRO session last performed operation --How many seconds from now, session idle time
#BLOCKING_SESSION_STATS Whether the session is blocked: if blocked, the status is valid
#At this point, you can use the following command: Kill the locked session immediately:
# alter system kill session 'sid,serial#' immediate;
#But for this experimental test, the lock still exists, the SYS user is the source, and the information has not been queried yet:
#Continue query analysis: how to find the source of the lock:
#When: the status of BLOCKING_SESSION_STATUS is vaild on behalf of the session is blocked: #Find the blocked origin session: SQL> select sid,serial#,username,blocking_session_status,BLOCKING_INSTANCE, BLOCKING_SESSION,FINAL_BLOCKING_SESSION_STATUS,FINAL_BLOCKING_INSTANCE, FINAL_BLOCKING_SESSION from v$session where sid in (40,42); ----------------- ---------------- ----------- ----------------------- SID 40 42 会话ID SERIAL# 275 897 Session serial number USERNAME SCOTT YANG session username blocking_session_status VALID VALID session is blocked: VALID is blocked no holder is not blocked BLOCKING_INSTANCE 1 1 Instance number of the blocking session BLOCKING_SESSION 51 51 Blocking session ID FINAL_BLOCKING_SESSION_STATUS VALID VALID There is a blocking source session: no holder has no session blocking FINAL_BLOCKING_INSTANCE 1 1 Blocking source session instance ID FINAL_BLOCKING_SESSION 51 51 Blocking source ID 51 #yang user is waiting for session ID 51 to release row lock: Information for user #51: SQL> select sid,serial#,username from v$session where sid=51; SID SERIAL# USERNAME ---------- ---------- ------------------------------ 51 3135 SYS
#This experiment has a regret:
The three updates are performed using stored procedure calls,
Two of the sessions are queried through the V$ACCESS blocking object,
Another session is obtained through v$session blocking source session query
but? There is also a session cc that uses the update direct operation execution, which was not analyzed this time:
##########How fast, link analysis lock waiting########
Use tool: oradebug
If there is a lock, use the Oradebug tool to generate a trace file for analysis:
#operate SQL> oradebug hanganalyze 3 Hang Analysis in /picclife/app/oracle/diag/rdbms/aa/dingding/trace/dingding_ora_6118.trc
Analyze the trace file:
# handle attack: command: pending analysis level 3 Processing Oradebug command 'hanganalyze 3' *** 2018-04-08 12:03:34.037 =============================================================================== HANG ANALYSIS: pending analysis: instances (db_name.oracle_sid): aa.dingding database.instance name oradebug_node_dump_level: 3 analysis initiated by oradebug analysis: sample every second
#The most likely hang link Chains most likely to have caused the hang: # From client sql*net message, row lock [a] Chain 1 Signature: 'SQL*Net message from client'<='enq: TX - row lock contention' Chain 1 Signature Hash: 0x38c48850 [b] Chain 2 Signature: 'SQL*Net message from client'<='enq: TX - row lock contention' Chain 2 Signature Hash: 0x38c48850 [c] Chain 3 Signature: 'SQL*Net message from client'<='enq: TX - row lock contention' Chain 3 Signature Hash: 0x38c48850
Three links: row lock:
First link:
Chain 1: Chain 1 session id: 40 session id session serial #: 275 Session serial number #######Query through the above information: for SCOTT users, waiting for users ######### SQL> select username from v$session where sid=40 and serial#=275; USERNAME ------------------------------ SCOTT is waiting for 'enq: TX - row lock contention' with wait info:
time in wait: 50 min 58 sec ###waiting time 50 minutes 58 seconds SQL
to execute: update current sql: UPDATE CESHI SET NAME='u_name' WHERE ID=:B1
and is blocked by blocking user (the culprit):
session id: 51 blocking user id session serial #: 3135 Blocking user serial number: wait for the client to return information as follows
####Chain 1 Signature: "SQL*Net Message from Client" = "Enq: TX - Row Lock Contention" ##### Chain 1 Signature: 'SQL*Net message from client'<='enq: TX - row lock contention'
Second link:
Chain 2:
session id: 35 Session 35: session serial #: 583 SERIAL# 583
######After query: this waiting user is a CC user SQL> select username from v$session where sid=35 and serial#=583; USERNAME ------------------------------ CC
### is also Udate information: it is executed directly, not the calling program current sql: update scott.ceshi set name='three' where id=1
# This session is a member of link one
# Blocked by instance one, session ID 51, SESSION, and is blocked by 'instance: 1, os id: 5854, session id: 51', which is a member of 'Chain 1'.
Third link:
Chain 3: session id: 42 session serial #: 897 ####### is user yang, waiting for session ID51 to release the lock SQL> select username from v$session where sid=42 and serial#=897; USERNAME ------------------------------ WHICH current sql: UPDATE SCOTT.CESHI SET NAME='u_name' WHERE ID=:B1 #Also blocked by session id 51, is a member of link one and is blocked by 'instance: 1, os id: 5854, session id: 51', which is a member of 'Chain 1'. Chain 3 Signature: 'SQL*Net message from client'<='enq: TX - row lock contention'
summary:
Link one, scott user: call stored procedure to update SCOTT.CESHI: blocked by session 51, link one
Link two, CC user: update operation SCOTT.CESHI: blocked by session 51, link one member
Link three, YANG user: call stored procedure to update SCOTT.CESHI: blocked by session 51, link one
Information for #SID 51 users: SQL> select sid,serial#,username from v$session where sid=51; SID SERIAL# USERNAME ---------- ---------- ------------------------------ 51 3135 SYS
#Find the source of the blockage on the link: + block the session, the rest is to consider who to kill and who to let go