本次场景来源:

通知某个会话:执行execute addupp(1,'five');类似的存储过程,会话等待:(会话等待两种情况:一种确实执行,但是未完成;另一种就是执行的操作无法获取资源,等待资源释放,即锁等待),本次测试锁:行锁等待测试:

本次场景测试:如何快速定位持有锁的会话,kill 释放资源

本次场景操作:

存储过程:执行Update操作,行锁等待,多个会话执行造成:行锁争用,会话被堵塞

模拟环境:行锁如何模拟:争用并发及锁,Lock 有序列,排队

#场景模拟在线: 用户scott,测试表ceshi 
#模拟会话一:调用存储A,插入3条测试数据
#模拟会话一:调用存储B,更新一条数据 SYS
#模拟会话二:调用储存B,更新(会话一)上条已经更新未提交的数据行,造成阻塞Yang
#模拟会话三:直接Update更新相同的数据行 cc用户
#模拟会话五、业务操作:更新数据发现阻塞:scott用户

测试表结构、insert存储过程A、update存储过程B如下所示:

SQL> desc ceshi Name
Null? Type
----------------------------------
ID NUMBER()
NAME VARCHAR2() #SYS用户创建存储过程: #存储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;
/ #存储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;
/

#创建完成查询:

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

#测试场景权限、数据处理:

SYS用户调用存储A:Insert 3条数据
SQL> execute addnew(,'yang');
SQL> execute addnew(,'cheng');
SQL> execute addnew(,'hehe'); #授予测试yang / cc 两个用户对测试表的对象权限:
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; 存储过程授权:
grant execute on addupp to yang;
grant execute on addupp to cc;

#会话一:sys用户调用存储B,更新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

#会话二:yang用户调用存储B,更新id=1,name='two'

SQL> show user USER is "YANG"
SQL> execute addupp(1,'two'); --等待

#会话三:cc用户调用存储B,更新id=1,name='three'

SQL> show user USER is "CC"
SQL> update scott.ceshi set name='three' where id=1;

#会话四:Scott用户调用存储B,更新id=1,name='five'

SQL> show user USER is "SCOTT"
SQL> execute addupp(1,'five');

##################以上是场景模拟,在线还原#################################
 #######################################以下是解决问题#####################

#我们很可能收到的通知是:执行操作发生等待,无法执行后,上报给我们xxx无法执行,上锁了

####SQL> execute addupp(1,'five'); @无法执行

处理思路:=>等待、无法执行原因:锁

=>什么对象

=>哪些会话在等待,持有这些资源

=>查询会话ID,SERIAL,Kill杀死会话,释放资源,让业务能快速恢复

=>查询对象类型:

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

=>查询:被锁定的对象及锁定次数

视图V$DB_OBJECT_CACHE: 找到被锁定的对象

#通过此视图:可以找出某个用户下:被锁定的对象,及锁定次数
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 #根据应用反馈的命令 or 用户对象,本次关注点:是ADDUPP 调用程序,无法执行

#通过被锁定的对象:找到被锁定的SID

 视图:V$ACCESS  #显示当前施加在库高速缓存对象上的锁定信息:
SID 访问对象的会话编号
OWNER 对象拥有者
OBJECT 对象名称
TYPE 对象类型 #通过此视图:找到那些用户对此对象进行了锁定 select * from v$access;
select * from v$access where type='PROCEDURE' and object='ADDUPP';
SID OWNER OBJECT TYPE
---------- ----------------------------------------------------------------
40 SCOTT ADDUPP PROCEDURE
42 YANG ADDUPP PROCEDURE

#####注意:RAC环境下:需要注意Inst_id 实例序号:

#通过SID找到会话serial#

 #v$session 视图:

 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 会话标识符
#SERIAL# 会话标识符,可重复使用,为了避免重复:会话序列号标识: sid+ serial#= 唯一会话信息
#USERNAME 会话登录用户名
#TIME_SINCE_LAST_WAIT_MICRO 会话最后一次执行操作--距离现在多少秒,会话空闲时间
#BLOCKING_SESSION_STATS 会话是否被阻塞:被阻塞则状态为valid

#此时可以使用如下命令:立即杀死被锁定的会话:

# alter system kill session 'sid,serial#' immediate;

#但是对于本次实验测试来说,锁还是存在的,SYS用户是源头,还未查询得到信息:

#继续查询分析:如何找到锁的源头:

#当:BLOCKING_SESSION_STATUS的状态为vaild代表会话被阻塞:
#找到阻塞的源头会话:
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 (,);
----------------- ---------------- ----------- -----------------------
SID 会话ID
SERIAL# 会话序列号
USERNAME SCOTT YANG 会话用户名
blocking_session_status VALID VALID 会话是否被阻塞:VALID有阻塞 no holder没有阻塞
BLOCKING_INSTANCE 阻塞会话的实例号
BLOCKING_SESSION 阻塞会话ID
FINAL_BLOCKING_SESSION_STATUS VALID VALID 有一个阻塞源头会话: no holder没有会话阻塞
FINAL_BLOCKING_INSTANCE 阻塞源头会话实例ID
FINAL_BLOCKING_SESSION 阻塞源头ID #yang用户在等待会话ID 51释放行锁:
#51用户的信息:
SQL> select sid,serial#,username from v$session where sid=; SID SERIAL# USERNAME
---------- ---------- ------------------------------
SYS

#本次实验有个遗憾:

三个update都是使用存储过程调用执行,

其中两个会话通过V$ACCESS堵塞对象进行查询,

另一个会话通过v$session阻塞源头会话查询得到

但是? 还有一个会话cc 使用的是update直接操作执行,本次未分析得到:

##########如何快速,链路分析锁等待#######

使用工具: oradebug

有锁,使用Oradebug 工具生成trace文件进行分析:

#操作
SQL> oradebug hanganalyze 3
Hang Analysis in /picclife/app/oracle/diag/rdbms/aa/dingding/trace/dingding_ora_6118.trc

分析trace文件:

# 处理 攻击:命令:挂起分析级别3
Processing Oradebug command 'hanganalyze 3' *** 2018-04-08 12:03:34.037
===============================================================================
HANG ANALYSIS: 挂起分析:
instances (db_name.oracle_sid): aa.dingding 数据库.实例名称
oradebug_node_dump_level: 3
analysis initiated by oradebug 分析:每秒采样一次
 #最有可能引起的  Hang链路
Chains most likely to have caused the hang:
# 来自客户端sql*net消息,行锁
[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

三条链路:行锁:

第一条链路:

Chain 1:   链路1
session id: 40 会话ID
session serial #: 275 会话序列号 #######通过如上信息查询:为SCOTT用户,等待用户#########
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 ###等待时间 50分钟 58秒
要执行的SQL: update
current sql: UPDATE CESHI SET NAME='u_name' WHERE ID=:B1
and is blocked by   阻塞用户(罪魁祸首):
session id: 51 阻塞用户ID
session serial #: 3135 阻塞用户序列号 :如下等待客户端返回信息
 ####链1签名:“来自客户机的SQL*Net消息”=“Enq:TX-行锁定争用”#####
Chain 1 Signature: 'SQL*Net message from client'<='enq: TX - row lock contention'

第二条链路:

Chain 2:
session id: 35 会话35:
session serial #: 583 SERIAL# 583
######经过查询:此等待用户是CC用户
SQL> select username from v$session where sid=35 and serial#=583; USERNAME
------------------------------
CC
###也是Udate信息 :是直接执行,不是调用程序
current sql: update scott.ceshi set name='three' where id=1 # 本会话是链路一的成员
 # 被实例一,会话ID 51,SESSION阻塞,
and is blocked by 'instance: 1, os id: 5854, session id: 51',
which is a member of 'Chain 1'.

第三条链路:

Chain :
session id:
session serial #: #######是用户yang,等待会话ID51释放锁
SQL> select username from v$session where sid= and serial#=; USERNAME
------------------------------
YANG current sql: UPDATE SCOTT.CESHI SET NAME='u_name' WHERE ID=:B1 #同样被会话id 51堵塞,是链路一的成员
and is blocked by 'instance: 1, os id: 5854, session id: 51',
which is a member of 'Chain 1'. Chain Signature: 'SQL*Net message from client'<='enq: TX - row lock contention'

小结:

链路一、scott用户:调用存储过程更新SCOTT.CESHI:被会话51堵塞,链路一

链路二、CC用户:update操作SCOTT.CESHI:被会话51堵塞,链路一成员

链路三、YANG用户:调用存储过程更新SCOTT.CESHI:被会话51堵塞,链路一

#SID 51用户的信息:
SQL> select sid,serial#,username from v$session where sid=51; SID SERIAL# USERNAME
---------- ---------- ------------------------------
51 3135 SYS

#找到链路上堵塞源头:+堵塞会话,剩下就是考虑杀谁,放谁了

会话执行存储过程,等待被阻塞,Kill session场景模拟的更多相关文章

  1. SQL Server 2008 R2执行存储过程sp_MailItemResultSets引起大量PREEMPTIVE_OS_WAITFORSINGLEOBJEC等待

      从监控工具DPA中发现一个数据库(SQL Server 2008 R2)的等待事件突然彪增,下钻分析发现数据库执行存储过程sp_MailItemResultSets时,引起了非常严重的等待(Hig ...

  2. 找出 alter system kill session ‘sid,serial#’ kill 掉的数据库会话对应进程

    当我们使用alter system kill session ‘sid,serial#’ 在数据库中kill掉某个会话的时候,如果你观察仔细会发现v$session.paddr发生了改变,从而是的不能 ...

  3. orakill和ALTER SYSTEM KILL SESSION详解

    --orakill和ALTER SYSTEM KILL SESSION详解[转]-----------------------------------------2013/11/05 一个用户进程偶尔 ...

  4. oracle kill session

    kill session 是DBA经常碰到的事情之一.如果kill 掉了不该kill 的session,则具有破坏性,因此尽可能的避免这样的错误发生.同时也应当注意,如果kill 的session属于 ...

  5. Oracle中Kill session的研究(转 出自eagle)

    itpub link: http://www.itpub.net/235873.html 我们知道,在Oracle数据库中,可以通过kill session的方式来终止一个进程,其基本语法结构为: a ...

  6. ORACLE 中KILL session

    我们知道,在Oracle数据库中,可以通过kill session的方式来终止一个进程,其基本语法结构为: alter system kill session 'sid,serial#' ; 被kil ...

  7. mysql 原理 ~ kill session解析

    一 简介:kill session为什么需要很久 二 kill语句分为三类  1 DML语句   2 select语句   3 DDL语句 三  kill都要做什么操作   1 kill对sessio ...

  8. 授权其他数据库用户kill session

    授权其他数据库用户kill session kill session权限 CREATE OR REPLACE PROCEDURE P_KILL_SESSION(P_USER IN VARCHAR2, ...

  9. 据库都有哪些锁 然后 Kill session

    当某个数据库用户在数据库中插入.更新.删除一个表的数据,或者增加一个表的主键时或者表的索引时,常常会出现ora-00054:resource busy and acquire with nowait ...

随机推荐

  1. 改写了禁用或启用oracle数据库的约束的存储过程

    改写了网上某位大侠(最开始的源头是哪位没记住)写的禁用或启用oracle数据库所有约束的存储过程,增加了异常控制,以使发生异常时也可以执行下去. –调用过程: 执行前先 set serveroutpu ...

  2. html中传递信息

    <div class="card" data-username="ArgenBarbie"> </div> JS: var userna ...

  3. 整合Spring Security(二十七)

    在这一节,我们将对/hello页面进行权限控制,必须是授权用户才能访问.当没有权限的用户访问后,跳转到登录页面. 添加依赖 在pom.xml中添加如下配置,引入对Spring Security的依赖. ...

  4. 快速搭建springboot框架以及整合ssm+shiro+安装Rabbitmq和Erlang、Mysql下载与配置

    1.快速搭建springboot框架(在idea中): file–>new project–>Spring Initializr–>next–>然后一直下一步. 然后复制一下代 ...

  5. angular 常用插件集合

    md5加密    https://www.npmjs.com/package/md5-typescript angular echarts  https://github.com/xieziyu/ng ...

  6. python 关闭垃圾回收

    import gc gc.disable() http://blog.csdn.net/aixiaohei/article/details/6446869

  7. nyoj-0613-免费馅饼(dp)

    nyoj-0613-免费馅饼 G. 免费馅饼 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在 ...

  8. 请问微信小程序let和var以及const有什么区别

    在JavaScript中有三种声明变量的方式:var.let.const. var:声明全局变量,换句话理解就是,声明在for循环中的变量,跳出for循环同样可以使用. [JavaScript] 纯文 ...

  9. Win10系列:UWP界面布局进阶5

    提示框 在Windows应用商店应用程序中可以使用提示框来向用户显示提示信息,例如可以通过对话框来询问用户当前需要执行的操作,还可以通过弹出窗口来显示需要注意的信息.本节将向读者介绍如何在Window ...

  10. LTP(LinuxTest Project)测试工具

    LTP(LinuxTest Project)是SGI.IBM.OSDL和Bull合作的项目,目的是为开源社区提供一个测试套件,用来验证Linux系统可靠性.健壮性和稳定性.LTP测试套件是测试Linu ...