Oracle insert hang引发的行锁等待

问题描述:

客户方前台应用某个操作hang住,无报错也未有操作正常结束提示。

查看锁信息如下:

SQL> with lk as (select blocking_instance||‘.‘||blocking_session blocker, inst_id||‘.‘||sid waiter

2              from gv$session

3              where blocking_instance is not null

4                and blocking_session is not null)

5  select lpad(‘  ‘,2*(level-1))||waiter lock_tree from

6   (select * from lk

7    union all

8    select distinct ‘root‘, blocker from lk

9    where blocker not in (select waiter from lk))

10  connect by prior waiter=blocker start with blocker=‘root‘;

LOCK_TREE

-------------------------------------------------------------------------------

1.71

1.1349

2.136

与客户方负责人确认后,Kill持锁session:

SQL> alter system kill session ‘71,36519‘;

alter system kill session ‘71,36519‘

*

ERROR at line 1:

ORA-00031: session marked for kill

SQL> select spid, osuser, s.program from v$session s, v$process p where s.paddr = p.addr and s.sid =71;

SPID                     OSUSER    PROGRAM

------------------------ ------------------------------

16783

[[email protected] ~]$ kill -9 16783

约3秒后再查:

[[email protected] ~]$ kill -9 16783

-bash: kill: (16783) - No such process

SQL> /

LOCK_TREE

-------------------------------------------------------------------------------

1.1349

2.136

SQL> select sid,serial# from v$session where sid=1349;

SID    SERIAL#

---------- ----------

1349       3539

Kill该session同样报错ORA-00031: session marked for kill。

SQL> select spid, osuser, s.program from v$session s, v$process p where s.paddr = p.addr and s.sid =1349;

SPID                     OSUSER    PROGRAM

------------------------ ------------------------------

8581

[[email protected] ~]$ kill -9 8581

[[email protected] ~]$ ps -ef |grep 8581

oracle   22749 21897  0 10:34 pts/1    00:00:00 grep 8581

SQL> /

LOCK_TREE

-------------------------------------------------------------------------------

1.1349

2.136

SQL> select spid, osuser, s.program from v$session s, v$process p where s.paddr = p.addr and s.sid =1349;

SPID                     OSUSER     PROGRAM

------------------------ ------------------------------

8581

约5秒后再查:

[[email protected] ~]$ kill -9 8581

-bash: kill: (8581) - No such process

SQL> /

LOCK_TREE

-------------------------------------------------------------------------------

1.1349

2.136

SQL> /

no rows selected.

判断是由于kill session后,后台回滚操作还未结束,所以此sid进程结束较慢。

Kill相关持锁进程后,重新执行页面操作,会产生新的行锁等待。

分析:

期间查到1.71进程(每次行锁的持有者进程)正在执行的sql语句为:

SQL> select sid,sql_text from v$session a,v$sql b where sid in(71) and (b.sql_id=a.sql_id or b.sql_id=a.prev_sql_id);

查询结果为一个insert语句。

与客户确认1.71进程(行锁的持有者进程)执行的sql语句正是客户hang住页面正在执行的sql语句。

select owner,object_type from dba_objects where object_name="TEST_TABLE";结果为同义词。

查询确认TEST_TABLE该对象为Oracle端的同义词,与客户方确认该插入操作由oracle直接写入sqlserver数据库;对象TEST_TABLE在sqlserver端为业务表,oracle通过gateway创建dblink连接sqlserver,从oracle端向sqlserver端推送数据。(本次oracle端出现行锁问题,是由于sqlserver端数据库insert hang,导致oracle端insert无法完成。)

找到客户方该系统sqlserver负责人,尝试在sqlserver本地insert同样hang住,由sqlserver负责人继续排查此问题。

sqlserver端insert问题解决(sqlserver工程师重建了表TEST_TABLE)后,oracle端未再次出现行锁。客户方业务可以正常进行。

至于oracle端产生行锁的原因,由业务开发人员依据业务逻辑进一步分析。

举例:由于insert产生行锁的实验:

SQL> create table t(id int primary key);

Table created.

SQL> insert into t values(1); --插入未提交

1 row created.

session 2:

SQL> insert into t values(1); --此时插入有同样主键记录时SQL产生等待

session 3:

SQL> select sid,type,id1,id2,lmode,request,block from v$lock where sid in (834,854) order by 1,2;

SID TY     ID1     ID2   LMODE    REQUEST      BLOCK

---------- --  -------------- ------- ---------- ----------

834 TM   91874       0       3          0          0

834 TX  262174  192335       6          0          0

834 TX  458776  193901       0          4          0

854 TM   91874       0       3          0          0

854 TX  458776  193901       6          0          1

SQL> select sid,event from v$session_wait where sid in (834,854);

SID EVENT

---------- ----------------------------------------------------------------

834 enq: TX - row lock contention

854 SQL*Net message from client

说明:出现行锁等待时,是可以正常查询表数据的。

时间: 2024-12-26 09:01:18

Oracle insert hang引发的行锁等待的相关文章

检查行锁等待问题的脚本(单机和rac都通用)

来源于: How to use historic ASH data to identify lock conflicts (文档 ID 1593227.1) 对于当前正在lock的情况,脚本为(单机和rac通用): with lk as (select blocking_instance||'.'||blocking_session blocker, inst_id||'.'||sid waiter from gv$session where blocking_instance is not n

RR隔离级别下锁情况(探究gap锁和行锁)

!!!我的数据库演示版本为5.5,以后会追加最新数据库的演示版本 间隙锁(GAP Lock)时InnoDB在可重复读下的隔离级别下为了解决幻读问题引入的锁机制.幻读存在的问题是因为在新增或者更新时如果进行查询,会出现不一致的现象,这时单纯的使用行锁无法满足我们的需求,我们需要对一定范围的数据加锁,防止幻读. 可重复读隔离级别就是数据库通过行锁和间隙锁(不要搞混gap lock和next-key lock)共同组成来实现的,在网上抄了一下加锁的规则,然后自己进行一下验证: 1.加锁的基本单位是(n

mysql外键引发的锁等待

有这样两条sql: insert table_a (bId) value(1); -- sql-1  update table_b set b.xx=123 where b.id =1; -- sql-2 其中,table_a的字段bId是个外键:外键关联的正是table_b的id字段. 在mysql上执行这两条数据时,sql-1会锁住sql-2.我们的系统中,为这一个锁,发生了不知道多少的锁等待,更引发了不知道多少的死锁. 特此备忘.

oracle 死锁和锁等待的区别

所谓的锁等待:就是一个事务a对一个数据表进行ddl或是dml操作时,系统就会对该表加上表级的排它锁,此时其他的事务对该表进行操作的时候会等待a提交或是回滚后,才可以继续b的操作 所谓的死锁:当两个或多个用户相互等待锁定的数据时就会发生死锁,这时这些用户被卡在不能继续处理业务,oracle可以自动检测死锁并解决他们,通过回滚一个死锁中的语句,释放锁定的数据,回滚的话会遇到ora-00060 deadlock detected while waiting for resource 模拟锁等待: 两个

MySQL和Oracle行锁比较

有人问,MySQL里Update时条件列没有索引,产生的是表级锁,而Oracle里是行级锁. 下面来对比下MySQL INNODB引擎和Oracle的行锁机制: INNODB INNODB表是索引组织的表,主键是聚集索引,非主键索引都包含主键信息. INNODB默认是行锁. INNODB行锁是通过给索引项加锁来实现的,即只有通过索引条件检索数据,InnoDB才使用行级锁,否则将使用表锁. Oracle 在Oracle的每行数据上,都有一个标志位来表示该行数据是否被锁定.这样就大大减小了行级锁的维

oracle[insert 时报错: 单行子查询返回多行]

-- 错误的写法 insert into t_b_partner_vehicle(id, partner_id, vehicle_id) (seq_t_b_partner_vehicle.nextval,121, (select id from t_b_car_info where org_id in(1441,1427))) -- Error 单行子查询返回多行 -- 正确的写法 insert into t_b_partner_vehicle(id, partner_id, vehicle_i

Record is locked by another user --Oracle行锁解锁

Oracle修改表中记录时出现record is locked by another user的问题 在操作表时没有commit,导致表被锁,只要执行下面两行语句,就可以了将行锁解锁了. Select t2.username,t2.sid,t2.serial#,t2.logon_time from v$locked_object t1,v$session t2 where t1.session_id=t2.sid; -- 查看被锁表的sid 和 serial# 2.  alter system

MySQL学习之——锁(行锁、表锁、页锁、乐观锁、悲观锁等)

锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或县城并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一种供许多用户共享访问的资源.如何保证数据并发访问的一致性.有效性,是所有数据库必须解决的一个问题,锁的冲突也是影响数据库并发访问性能的一个重要因素.从这一角度来说,锁对于数据库而言就显得尤为重要. MySQL锁 相对于其他的数据库而言,MySQL的锁机制比较简单,最显著的特点就是不同的存储引擎支持不

MySQL中锁详解(行锁、表锁、页锁、悲观锁、乐观锁等)

原文地址:http://blog.csdn.net/mysteryhaohao/article/details/51669741 锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或线程并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一种供许多用户共享访问的资源.如何保证数据并发访问的一致性.有效性,是所有数据库必须解决的一个问题,锁的冲突也是影响数据库并发访问性能的一个重要因素.从这一角度来说,锁对于