`

Oracle引起阻塞的情况

阅读更多

Oracle引起阻塞的情况

一、唯一性约束引起的阻塞:
在session1执行下面的语句中:
--创建一个表
create table t(x int primary key);
--在表中插入一条数据,并提交。
insert into t values(1);
commit;
--修改这条数据,但不提交。
update t set x = 2 where x= 1;


在Sessions2中,执行以下操作:
update t set x = 20 where x= 1;
那么此时会出现这样的情况(我是在PL/SQL Developer中执行的):
状态栏一直显示“正在执行”,这是因为Session1在修改这条数据,没有提交,数据库在等待你做出决定(提交还是回滚),
那么此时另一个用户修改这条数据时,数据库为了保证数据一致性,就只能让这个用户等待,直到你作出决定。
Session2去修改这条数据时就会被Session1阻塞,直到Session1释放锁。

Session1的SID:
select sid from v$mystat where rownum = 1;
SID
----------
88

Session2的SID:
select sid from v$mystat where rownum = 1;
SID
----------
246

可以从视图中看到这些信息:
select sid,type,id1,id2,lmode,request,block from v$lock where sid in (88,246) order by sid;
SIDTYPEID1ID2LMODEREQUESTBLOCK
188TM1572670300
288TX589844197707601
3246TX589844197707060
4246TM1572670300
Block=1表示正在阻塞其他的会话
TYPE=TM:表级共享锁
TYPE=TX:行级排他锁,如果一个表有多个段,每个段上都会加TM。
某个SID的REQUEST不等于0,那么说明它正在等待一个锁;如果BLOCK为1,则说明此SID持有了一个锁,并阻塞别人获得这个锁。

那么在实际情况中,我们可以通过查询v$lock查看是否有阻塞——获取SID。
然后根据SID查询用户使用的机器名称:
select machine from v$session where sid in (88,246);

 

--对表加分区试验:
--创建2个分区,x值小于20的在分区p1,大于等于20的在P2分区。
create table t(x int primary key) partition by range(x) (partition p1 values less than(20),partition p2 values less than(maxvalue));
--向T中插入1条数据,X=1,此时X<20因此在分区p1。此时数据并未提交。
insert into t values(1);

--查询v$lock视图,可以看到在表和p1分区上加了TM锁。
select sid,type,id1,id2,lmode,request,block from v$lock where sid in (88,246) order by sid;
SIDTYPEID1ID2LMODEREQUESTBLOCK
1246TM1572690300
2246TM1572700300
3246TX196616188629600

select object_id,object_name,subobject_name from dba_objects where object_id in (157269,157270);
OBJECT_IDOBJECT_NAMESUBOBJECT_NAME
1157269T
2157270TP1

可以看到,Object_id=157270的就是分区P1。


那么,此时删除T:
drop table t;
得到的结果是:ORA-00054: resource busy and acquire with NOWAIT specified

那么,删除分区p1呢?
alter table t drop partition p1
得到的结果是:ORA-00054: resource busy and acquire with NOWAIT specified

那么,删除分区p2呢?
alter table t drop partition p2;
结果:Table altered

为什么会这样呢?
因为p2上没有TM锁,因此可以执行DDL,因为事物并未影响到p2,因此在p2分区上做DDL是可以的。
在v$lock视图看到在p1分区insert1条数据,并未提交,此时持有一个TM锁。
Oracle允许同级别(或更低级别)的锁同时设置,但拒绝更高级别的锁。DDL操作是更高级别的锁。
因此是不被允许的。

刚刚将p2分区删除了,现在重新加上:
alter table t add partition p2 values less than (maxvalue);

insert1条数据(x>20因此落在p2分区):
insert into t values(30);、
--在分区p1查询
select * from t partition (p1);

从v$lock视图查询信息(向分区p1插入的数据已commit):
select sid,type,id1,id2,lmode,request,block from v$lock where sid in (88,246) order by sid;
SIDTYPEID1ID2LMODEREQUESTBLOCK
188TM1572690300
288TM1572730300
388TX655399281590600

可以看到,此时在p2上加了TM锁,因为数据未提交,还有一个TX锁。

 

二、select for update
人事部的员工A修改某雇员的工资:
1.页面查询此雇员的工资:
select sal from emp where ename = 'scott';
假定sal = 3000;

2.修改工资为原来的1.1倍,但是有事离开,并未点击提交按钮。

此时人事部B也来修改此雇员的工资。
1.查询此雇员的工资:
select sal from emp where ename = 'scott';
假定sal = 3000;

2.修改工资为原来的1.1倍,并提交,那么提交的SQL为:
update emp set sal = 1.1*sal where ename = 'scott';
commit;
那么此时此雇员的工资就是3000*1.1=3300;

A回来了,单击提交按钮,SQL:
update emp set sal = 1.1*sal where ename = 'scott';
commit;
那么此时此雇员的工资就是:3300*1.1=3630

那么此时A就会觉得奇怪,最开始的工资是3000,乘以1.1怎么就变成3630了呢?!
而且,如果A没发现的话,那此雇员的工资就变成了3630,这样就不对了。
由此看来,这是程序的一个BUG,在修改时并未保证不能被其他人修改。
一个简单的办法就是使用select...for update的方式,以排他的方式获取数据,在保证修改完成之前,其他用户无法修改。

但是这样存在另外一个问题:
用户A要修改时执行了select...for update操作,此时这条数据就被锁住了,如果A不提交,
那么用户B要修改时同样执行了select...for update操作,就会一直等待,对用户B来说,可能他都不知道怎么回事。

那么更好的方式就是加上nowait:
select * from emp where ename = 'scott' for update nowait;
这样就可以得到一个错误:
ORA-00054: resource busy and acquire with NOWAIT specified
那么程序就可以捕获这个异常,提示用户有其他用户正在修改。



三、外键和索引
如果有主外键关系,且满足下面3个条件的一个,就应该考虑给外键字段创建索引:
1.主表有频繁修改操作。
2.主表有频繁删除操作。
3.主表和从表经常做关联查询。

第1,2这2个条件,主表会在从表创建锁定,以保证主表修改的数据不会导致从表的数据引用上出现问题。
如果主表经常做修改和删除操作,或每次操作的记录很多,那么从表就要被锁定很长时间,影响其他用户的正常操作。
主表修改100行,从表就会扫描100次,以保证主表的没条数据的修改都不会对从表的引用产生影响。

--创建主表T
create table t (x int primary key);
--创建从表T1
create table t1 (x references t(x));
--向主表插入一些数据
insert into t select rownum from user_objects;
commit;
--向从表插入一些数据
insert into t1 select rownum from user_objects where rownum <= 100;
commit;

alter session set sql_trace = true;
ORA-01031: insufficient privileges
郁闷,公司的电脑,没权限。

从主表删除1条记录:
delete t where x = 1;
结果:ORA-02292: integrity constraint (IMSDATA.SYS_C0098495) violated - child record found

主表删除1条数据,会对从表执行一次全表扫描。
主表删除1000条数据,会对从表执行1000次全表扫描。

如果在外键字段创建了索引呢?
create index t1_idx on t1(x);

收集统计信息:
exec dbms_stats.gather_table_stats(user,'t',cascade => true);
exec dbms_stats.gather_table_stats(user,'t1',cascade => true);

set autotrace trace stat;
--让t1执行全表扫描
select /*+ full(t1) */ t1.x from t,t1 where t1.x = t.x and t1.x <= 100;
查看执行计划,T1执行了全表扫描。

--让Oracle自己选择执行计划
select t1.x from t,t1 where t1.x = t.x and t1.x <= 100;
此时,Oracle选择了使用索引关联查询。
分析2次执行计划,走索引的代价更小。
而且一般从表数据量很大,如果这种情况下没有索引,那查询就很慢了。








 

分享到:
评论

相关推荐

    让Oracle跑得更快—Oracle 10g性能分析与优化思路ch03.pdf

    - **等待与阻塞的区别**:Latch导致的等待通常不会像Lock那样引起阻塞,而是会等待当前持有Latch的进程释放Latch。因此,理解Latch的等待特性有助于正确诊断和解决性能问题。 - **系统设计与业务逻辑**:当系统中...

    oracle dba 日常检查手册

    + 锁资源监控,对阻塞了其它会话的锁进行告警,以及可用的锁 + 等待某回滚段完成的事务百分比 + 监控 SGA、Buffer Cache、I/O 等相关的性能数据 + 监控数据库会话的状况 四、常规检查 * 常规检查是指对数据库...

    ORACLE11G性能分析及优化对策

    - **锁的检测与解决**:通过查询`V$LOCK`等视图可以发现当前存在的锁情况,并结合`V$LOCKED_OBJECT`等视图进一步追踪引起锁的SQL语句。 #### 八、总结 为了有效提升Oracle 11g的性能,DBA和开发人员需要全面掌握...

    Oracle RAC环境下的阻塞(blocking blocked)介绍和实例演示

    1. **优化SQL语句**:分析并优化引起阻塞的SQL语句,减少锁定资源的时间。 2. **锁粒度控制**:通过调整事务隔离级别或使用行级锁来减少锁竞争。 3. **资源调度**:使用RAC的资源管理特性,如DBMS_RESOURCE_MANAGER...

    oracle性能诊断

    - **步骤二**:执行引起行锁等待的操作(如删除表中的一行数据)。 - **步骤三**:再次生成AWR快照以捕捉最新的性能数据。 - **步骤四**:通过AWR和ASH报告分析行锁等待的具体原因。 ##### 3. 分析结果 根据AWR和...

    oracle常见的锁查询和处理

    如果用户B尝试同时更新同一行,B会被阻塞直到A提交或回滚事务。同时,行级锁并不阻止其他用户读取被锁定的行,通过CR(Consistent Read)技术,未提交的更改对其他读取操作是不可见的。 表级锁(TM锁): 表级锁...

    Oracle 高级复制技术介绍及应用

    4. **事务紧密耦合**:与事务处理紧密关联,可能会引起阻塞、争用和锁定等问题。 5. **复杂性高**:解决高级复制过程中出现的问题通常较为复杂,需要对Oracle内部机制有深入的理解。 ### 五、Oracle高级复制技术的...

    oracle11g监听日志文件过大导致监听无法启动2

    6. **优化数据库操作**:如果日志文件过大是由于数据库操作异常引起的,那么需要对数据库进行性能调优,减少异常情况的发生,比如优化SQL语句,合理设置数据库参数等。 7. **故障转移**:在生产环境中,可以考虑...

    Oracle阻塞(blockingblocked)实例详解

    阻塞通常由事务间的并发操作引起,尤其是在未正确处理并发控制的情况下。例如,一个事务正在更新一行数据,而另一个事务在同一行数据上尝试进行修改时,就会发生阻塞。Oracle数据库使用锁定机制来确保数据的一致性,...

    让Oracle跑得更快 Oracle 10g性能分析与优化思路.part2.rar

    2.3 引起阻塞的其他情况 30 2.3.1 select for update 30 2.3.2 外键和索引 36 第3章 latch和等待 44 3.1 共享池中的latch争用 45 .3.2 数据缓冲池latch争用 54 3.2.1 表数据块 54 3.2.2 索引数据块 59 3.2.3 索引根...

    Oracle10g数据库自动诊断监视工具

    10. **RAC环境问题**:包括内部通信问题、LMS进程的锁请求阻塞、实例倾斜和RMAN操作引起的IO和CPU问题。 11. **其他问题**:例如,由于扩展磁盘分配导致的争用,移动对象高水位引发的冲突,以及Streams和AQ...

    Oracle 阻塞(blocking blocked)介绍和实例演示

    了解并解决Oracle阻塞问题对于数据库管理员(DBA)来说至关重要,因为长期的阻塞可能导致性能下降,甚至可能引起数据库的不稳定。 1. **阻塞的类型**: - **INSERT阻塞**:当两个或更多会话尝试插入具有相同主键或...

    ORACLE_DBA常用脚本.ppt

    通过监控锁资源,DBA可以了解哪些事务可能导致阻塞,并采取措施优化事务处理,减少锁冲突。 数据库对象建立包括表、索引、视图、存储过程等的创建和管理。DBA需要确保这些对象的创建符合业务需求,且结构合理,以...

    Oracle中查看引起Session阻塞的2个脚本分享

    这样可以帮助我们识别哪些用户、哪个会话可能在引起阻塞。例如,在例子中,"LIHUILIN"用户的两个会话(sid=14和sid=139)可能存在相互阻塞的情况。 第二个脚本更进一步,它显示了阻塞会话(blocker)与被阻塞会话...

    Oracle数据库性能优化实务闩锁及闩锁优化.ppt

    可以使用v$lock视图来观察锁的情况,并使用dba_waiters和dba_blockers来查找阻塞的情况。 Oracle RDBMS也是一个“程序”,需要通过锁机制来保证程序的逻辑。例如,创建一张表要插入sys.tab$和sys.obj$等数据字典表...

    Resolving_Oracle_Latch_Contention.rar_latch contention_oracle

    3. 锁升级:当Oracle为了保证数据一致性而升级行级锁到表级锁时,也可能引起Latch Contention。 4. 不合理的数据库配置:如缓冲池大小不足、并行度设置过高,都可能导致Latch竞争加剧。 三、诊断Latch Contention 1...

    oracle学习经典教程

    文档还讨论了死锁现象和锁引起的阻塞问题,并详细说明了Latch的概念及其与锁的区别。Latch是一种简短的锁定机制,用于保护内存结构的完整性,它与锁的主要区别在于作用范围和持续时间。 整体来看,该文档为学习...

    Oracle-IO问题及性能调优.docx

    * 控制文件的修改会引起 Oracle 修改控制文件。 用户数据修改 * Oracle 会将数据 cache 在内存中,对数据的读写尽量在内存中完成。 * Buffer Cache 中的数据缓存块被修改过后,就被标记为“脏”数据。 * DBWn 进程...

    基于Oracle的SQL优化.pdf

    阻塞可能是由于索引缺失、表之间的连接不当、SQL语句不当等原因引起的。 五、结论 基于Oracle的SQL优化是指对SQL语句的优化,以提高查询效率和性能。通过使用索引、优化SQL语句、使用存储过程、数据库设计优化等...

Global site tag (gtag.js) - Google Analytics