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次执行计划,走索引的代价更小。
而且一般从表数据量很大,如果这种情况下没有索引,那查询就很慢了。
相关推荐
- **等待与阻塞的区别**:Latch导致的等待通常不会像Lock那样引起阻塞,而是会等待当前持有Latch的进程释放Latch。因此,理解Latch的等待特性有助于正确诊断和解决性能问题。 - **系统设计与业务逻辑**:当系统中...
+ 锁资源监控,对阻塞了其它会话的锁进行告警,以及可用的锁 + 等待某回滚段完成的事务百分比 + 监控 SGA、Buffer Cache、I/O 等相关的性能数据 + 监控数据库会话的状况 四、常规检查 * 常规检查是指对数据库...
- **锁的检测与解决**:通过查询`V$LOCK`等视图可以发现当前存在的锁情况,并结合`V$LOCKED_OBJECT`等视图进一步追踪引起锁的SQL语句。 #### 八、总结 为了有效提升Oracle 11g的性能,DBA和开发人员需要全面掌握...
1. **优化SQL语句**:分析并优化引起阻塞的SQL语句,减少锁定资源的时间。 2. **锁粒度控制**:通过调整事务隔离级别或使用行级锁来减少锁竞争。 3. **资源调度**:使用RAC的资源管理特性,如DBMS_RESOURCE_MANAGER...
- **步骤二**:执行引起行锁等待的操作(如删除表中的一行数据)。 - **步骤三**:再次生成AWR快照以捕捉最新的性能数据。 - **步骤四**:通过AWR和ASH报告分析行锁等待的具体原因。 ##### 3. 分析结果 根据AWR和...
如果用户B尝试同时更新同一行,B会被阻塞直到A提交或回滚事务。同时,行级锁并不阻止其他用户读取被锁定的行,通过CR(Consistent Read)技术,未提交的更改对其他读取操作是不可见的。 表级锁(TM锁): 表级锁...
4. **事务紧密耦合**:与事务处理紧密关联,可能会引起阻塞、争用和锁定等问题。 5. **复杂性高**:解决高级复制过程中出现的问题通常较为复杂,需要对Oracle内部机制有深入的理解。 ### 五、Oracle高级复制技术的...
6. **优化数据库操作**:如果日志文件过大是由于数据库操作异常引起的,那么需要对数据库进行性能调优,减少异常情况的发生,比如优化SQL语句,合理设置数据库参数等。 7. **故障转移**:在生产环境中,可以考虑...
阻塞通常由事务间的并发操作引起,尤其是在未正确处理并发控制的情况下。例如,一个事务正在更新一行数据,而另一个事务在同一行数据上尝试进行修改时,就会发生阻塞。Oracle数据库使用锁定机制来确保数据的一致性,...
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 索引根...
10. **RAC环境问题**:包括内部通信问题、LMS进程的锁请求阻塞、实例倾斜和RMAN操作引起的IO和CPU问题。 11. **其他问题**:例如,由于扩展磁盘分配导致的争用,移动对象高水位引发的冲突,以及Streams和AQ...
了解并解决Oracle阻塞问题对于数据库管理员(DBA)来说至关重要,因为长期的阻塞可能导致性能下降,甚至可能引起数据库的不稳定。 1. **阻塞的类型**: - **INSERT阻塞**:当两个或更多会话尝试插入具有相同主键或...
通过监控锁资源,DBA可以了解哪些事务可能导致阻塞,并采取措施优化事务处理,减少锁冲突。 数据库对象建立包括表、索引、视图、存储过程等的创建和管理。DBA需要确保这些对象的创建符合业务需求,且结构合理,以...
这样可以帮助我们识别哪些用户、哪个会话可能在引起阻塞。例如,在例子中,"LIHUILIN"用户的两个会话(sid=14和sid=139)可能存在相互阻塞的情况。 第二个脚本更进一步,它显示了阻塞会话(blocker)与被阻塞会话...
可以使用v$lock视图来观察锁的情况,并使用dba_waiters和dba_blockers来查找阻塞的情况。 Oracle RDBMS也是一个“程序”,需要通过锁机制来保证程序的逻辑。例如,创建一张表要插入sys.tab$和sys.obj$等数据字典表...
3. 锁升级:当Oracle为了保证数据一致性而升级行级锁到表级锁时,也可能引起Latch Contention。 4. 不合理的数据库配置:如缓冲池大小不足、并行度设置过高,都可能导致Latch竞争加剧。 三、诊断Latch Contention 1...
文档还讨论了死锁现象和锁引起的阻塞问题,并详细说明了Latch的概念及其与锁的区别。Latch是一种简短的锁定机制,用于保护内存结构的完整性,它与锁的主要区别在于作用范围和持续时间。 整体来看,该文档为学习...
* 控制文件的修改会引起 Oracle 修改控制文件。 用户数据修改 * Oracle 会将数据 cache 在内存中,对数据的读写尽量在内存中完成。 * Buffer Cache 中的数据缓存块被修改过后,就被标记为“脏”数据。 * DBWn 进程...
阻塞可能是由于索引缺失、表之间的连接不当、SQL语句不当等原因引起的。 五、结论 基于Oracle的SQL优化是指对SQL语句的优化,以提高查询效率和性能。通过使用索引、优化SQL语句、使用存储过程、数据库设计优化等...