Oracle latch vs lock latch lock 队列行 无队列性 队列性 时长 很短 可能很长 层面 数据库资源层 业务应用层 目的 保证资源的完整性 保证业务操作的完整性 latch在sga中,并不会存在pga中,因为sga中才会存在并发。 latch主要存在两块: 共享池 - sql解析,sql重用 数据缓冲区 -数据访问,数据写入,数据读入 -修改数据块 -数据段扩展 latch获取方式 wait方式--如果无法获取请求的latch,则 1.spin 当一个会话无法获得需求的latch时,会继续使用cpu(cpu空转),达到一个间隔时,会 在此尝试申请latch,知道达到最大重试次数。 2.sleep 当一个会话无法获取需要的latch时,会等待一段时间,达到一个间隔时,在此尝试申请latch, 如此反复,知道达到最大的重试次数。 第一种是系统可以认为立马下次可以获取到latch,而第二种则sleep一段时间后再进行获取 Nowait方式 --如果无法获取请求的latch,则 不会发生sleep或者spin 转而获取其他的可用latch 对于绑定变量,olap中没必要使用绑定变量,因为sql执行不会太多。 而oltp中,建议使用绑定变量。 data buffer中的latch争用 1.表数据块争用。 2.热块索引数据热块 3.文件头修改 --并发修改 模拟下表数据块的争用 admin@ORCL> create table latch_table1 as select * from dba_objects; Table created. --创建访问的存储过程 admin@ORCL> create or replace procedure p1 as 2 l number; 3 begin 4 for i in 1 .. 8000 loop 5 select count(*) into l from latch_table1 where object_type = 'TABLE'; 6 end loop; 7 dbms_output.put_line('successfully'); 8 end; 9 / Procedure created. --三个会话同时执行访问latch表 admin@ORCL> select distinct sid from v$mystat; SID ---------- 10 admin@ORCL> exec p1; admin@ORCL> select distinct sid from v$mystat; SID ---------- 192 admin@ORCL> exec p1; admin@ORCL> select distinct sid from v$mystat; SID ---------- 71 admin@ORCL> exec p1; --捕获到PID 33在访问时遇到了latch争用的情况。 PID:持有lantch的进程。 SID:持有latch的会话。 LADDR:latch的地址 NAME:latch的名称 GETS:获得latch的次数。 admin@ORCL> select * from v$latchholder; PID SID LADDR NAME GETS ---------- ---------- -------------------- -------------------- ---------- 33 71 000007FF0E175D80 cache buffers chains 88877 --看在会话等待事件视图中总是有这3个会话的“latch 链表”的争用,原因当多个会话同时去访问相同数据块时,它们首先申请latch获得访问权限, 如果此时申请失败,将会产生“latch: cache buffers chains”等待事件,这是因为多个会话在争抢latch资源所致 admin@ORCL> select SID,EVENT from V$SESSION_WAIT where wait_class <> 'Idle'; SID EVENT ---------- ---------------------------------------------------------------- 10 latch: cache buffers chains 71 latch: cache buffers chains 192 latch: cache buffers chains --创建三个存储过程,测试下数据块修改导致的事件 admin@ORCL> create or replace procedure p2 2 as 3 l number; 4 begin 5 for i in 1..100 6 loop 7 update latch_table1 set object_type='TABLE' where object_type='TABLE'; 8 end loop; 9 dbms_output.put_line('successfully'); 10 end; 11 / Procedure created. admin@ORCL> create or replace procedure p3 2 as 3 l number; 4 begin 5 for i in 1..100 6 loop 7 update latch_table1 set object_type='INDEX' where object_type='INDEX'; 8 end loop; 9 dbms_output.put_line('successfully'); 10 end; 11 / Procedure created. admin@ORCL> create or replace procedure p4 2 as 3 l number; 4 begin 5 for i in 1..100 6 loop 7 update latch_table1 set object_type='VIEW' where object_type='VIEW'; 8 end loop; 9 dbms_output.put_line('successfully'); 10 end; 11 / Procedure created. --首先可以看出,当DML操作进行之前,访问相同的数据块导致了热块,数据块访问的争用。 我们看到DML操作不仅仅有cache buffer chains,还会产生buffer busy waits。 admin@ORCL> select * from v$latchholder; PID SID LADDR NAME GETS ---------- ---------- -------------------- -------------------- ---------- 31 192 000007FF0E176648 cache buffers chains 5798 admin@ORCL> select * from v$latchholder; PID SID LADDR NAME GETS ---------- ---------- -------------------- -------------------- ---------- 32 10 000007FF0E195158 cache buffers chains 1641739 admin@ORCL> select * from v$latchholder; PID SID LADDR NAME GETS ---------- ---------- -------------------- -------------------- ---------- 33 71 000007FF0E162EC8 cache buffers chains 1761049 admin@ORCL> select SID,EVENT from v$session_wait where wait_class <> 'Idle'; SID EVENT ---------- ---------------------------------------------------------------- 10 buffer busy waits 71 buffer busy waits 135 SQL*Net message to client 192 db file sequential read --针对热块的问题,可以使用minimize records_per_block; 指定每个数据块中可存放行数减少到最小(即4行) 但这样也会导致Oracle会读取更多的数据块来完成查询。 --说明索引数据块中出现热块的场景 create table t1 (id number , name varchar2(200)); drop table t1 purge; insert into t1 select object_id,object_name from dba_objects; create index t1_index on t1(id); execute dbms_stats.gather_table_stats('ADMIN','T1',cascade=>true); CREATE OR REPLACE PROCEDURE P10 AS L NUMBER; BEGIN FOR I IN 1..50000 LOOP SELECT COUNT(*) INTO L FROM T1 WHERE ID < 10000; END LOOP; DBMS_OUTPUT.PUT_LINE('SUCESSFULLY'); END; admin@ORCL> select s1.sid, s2.event 2 from v$session s1, v$session_wait s2 3 where s1.sid = s2.sid 4 and s1.status = 'ACTIVE' 5 and s2.event like '%buffer%'; SID EVENT ---------- ---------------------------------------------------------------- 6 latch: cache buffers chains 8 latch: cache buffers chains 197 latch: cache buffers chains --解决办法:创建反向索引
Oracle latch
猜你喜欢
转载自yangeoo.iteye.com/blog/1965450
今日推荐
周排行