mutex----我是搬运工

看吕大的书,其中对mutex的介绍让人心动,因此我做一次搬运工。

mutex与latch区别:

mutex latch

没有等待队列,没有持有队列,抢占机制


使用队列


spin255次,在spin 期间无法获得,转入睡眠,自己醒来


spin 2000次,在spin 期间无法获得,转入睡眠,等待唤醒


使用引用计数器 (reference count),在64 位中占用 8字节,其实前4为 SID,后4 为引用计数器,如果引用计数器为 0,说明mutex 为独占模式


在latch池中,每一个 latch一块内存,所有 latch组成 latch池


植入对象内部


与对象分离

v$mutex_sleep_history.mutex_value查看mutex value

select sid, event, p1raw, p2raw, state, wait_class

from v$session

where wait_class <> ‘Idle‘

order by event;

如果event为library cache:mutex X,那么p2raw就是阻塞进程的mutex的当前mutex_value,其中前端是SID,可以找到阻塞的会话。

mutex类型:

常见类型有:cursor parent、library cache、hash table、cursor pin、cursor stats

在v$mutex_sleep和v$mutex_sleep_history中的mutex_type列对应mutex类型

不同mutex type对应不同的等待事件,通常如下:

hash table、cursor parent、cursor stats类型的mutex对应 cursor:mutex

library cache类型的mutex对应 library cache:mutex

cursor pin类型的mutex对应 cursor:pin

硬解析所有mutex都会出现,软软解析只会cursor pin类型的mutex

library cache:mutex X

11g前使用library cache latch保护hash bucket和其后的链表,11g开始不再用,而是换成library cache:mutex

无论软解析还是硬解析,进程都要独占方式获得library cache:mutex ,然后才能访问hash链,如果遇到竞争,产生等待事件,那这里的等待事件是library cache:mutex X

在v$mutex_sleep或是v$mutex_sleep_history的location列可以看到mutex miss是kglhdgn1  62 或是在awr报告中大mutex sleep summary部分看到location为kglhdgn1  62竞争多,说明在搜索hash bucket后的链表时遇到竞争

搜索hash链的目的是找到父游标句柄,找到父游标句柄后,要再次申请以独占方式持有library cache:mutex,成功后才能访问父游标句柄内的信息。如果在申请时遇到竞争,产生等待事件,这里的等待事件也是library cache:mutex X 。此处理的 mutex miss通常是kgldhgn2 106 。在此处mutex保护下,进程获得父游标句柄上的library cache lock,成功后,mutex被释放。也就是说,此处的mutex是代替以前版本的library cache lock latch(11g前是使用library cache lock latch,11g后换成library cache:mutex)

在子游标句柄,还有其他对象的句柄上都会有同样的mutex和library cache lock

hash table:mutex

找到父游标句柄,也加上了library cache lock,接下来,从父游标句柄中取出父游标堆0的地址,并访问父游标堆0。父游标堆0中包含了子游标句柄地址,这些子游标句柄地址构成了了游标列表,如下图:

访问父游标堆0的目的是在子游标列表中查找子游标句柄,这里当然要持有mutex。此处会持有两种类型的mutex:一种是cursor parent,另一种是hash table

oracle先持有cursor parent类型的mutex,访问父游标堆0中的其他信息,然后释放。再持有hash table类型的mutex,搜索了子游标列表,查找子游标句柄,找到后释放。这两种类型的mutex对应等待事件都是cursor:mutex S

搜索子游标列表,从mutex类型上推测应为hash table:mutex。它只保护子游标列表,如果此类型mutex遇到竞争,说明,某sql语句版本太多。其实hash table:mutex承担了之前版本中的library cache pin和library cache pin latch的作用。

cursor pin

整个解析过程会先访问hash链表,然后访问父游标句柄,父游标堆0,再访问子游标句柄,最后是子游标堆0和包含执行计划的堆6

对子游标堆0和堆6所加的mutex的类型是cursor pin,对应的等待事件是cursor:pin S或cursor:pin S wait on X

堆6的cursor pin类型的mutex比较特殊,这个mutex并不在子游标堆6中,它在父游标堆0中,因为子游标堆6的DS在父游标堆0中。

硬解析时需要独占、共享模式多次持有父游标堆0与子游标堆6上的mutex

软解析时通常不需要访问子游标堆0,可以从父游标堆0中找到子游标堆6,直接访问子游标堆6中的执行计划

软软解析时子游标堆6的DS地址保存在PGA中

通过mutex判断解析问题

硬解析:

需要所有mutex,申请多次shared pool latch,软解析只需要少量的shared pool latch,软软解析不需要shared pool latch

因此:如果shared pool latch竞争激烈,一定是硬解析过多,还有一种情况,版本过多。

同一父游标下多个子游标同时硬解析,会造成library cache lock竞争和保护子游标列表的mutex也会竞争,为hash table型的mutex

因此:如果library cache lock和hash table型的mutex同时出现,硬解析过多

如果只有hash table型的mutex,说明版本过多

在awr中mutex sleep summary可以查看,并做相应判断。

软解析:

搜索hash bucket后链表时,需要加library cache型的mutex

访问父游标句柄时,也需要加library cache型的mutex

访问父游标堆0、搜索子游标句柄列表时,需要hash table型的mutex

访问子游标句柄时,还是用需要加library cache型的mutex

访问子游标堆6,读取执行计划时,需要cursor pin型的mutex

补充:动态游标,在解析后,如果使用绑定变量,将变量值传入共享池,这一步要独占library cache型mutex

静态游标,绑定变量不传入共享池,也就不需要library cache型mutex

软软解析:

在PGA cache cursor列表中搜索子游标堆6DS地址,不需要任何mutex、latch

根据得到的子游标堆6的DS地址,访问共享池中子游标堆6,读取执行计划,需要共享模式的cursor pin型mutex,此处可能遇到的等待事件为cursor:pin S

如果使用绑定变量,将绑定变量值传入共享池,这一步要独占library cache型mutex。同样,如果是静态游标,绑定变量不传入共享池,也就不需要library cache型mutex

执行、抓取结束后,需要释放共享cursor pin型mutex,此处也可能遇到等待事件cursor:pin S

总结:

如果只有cursor pin型和library cache型的mutex竞争,那是软软解析

如果还有其他mutex等待,那是软解析

如果还有shared pool latch等待,那是硬解析

解决解析阶段竞争:

硬解析:一般有如下3种原因

没有使用绑定变量

父游标版本过高

共享池小

第一种,没有绑定变量,查询v$sqlarea.sql_text,看相似语句是否过多。修改应用是上上策,cursor_sharing参数不是好方法

第二种,父游标版本过高,查询v$sql_shared_cursor。11g的adaptive cursor sharing(ACS),可能会造成版本过多问题,oltp环境,可以考虑关闭此特性。

第三种,共享池小,可能使用瞬时LRU与周期LRU比值判断,如小,则加大

软解析:两种解决方法

调整应用,减少软解析

调整session_cached_cursors,化软解析为软软解析

总结:

硬解析过多,可以使用绑定变量、加大共享池,化硬解析为软解析

软解析过多,可以调大session_cached_cursors,化软解析为软软解析

软软解析一个小测试:

建立两个连接

SQL> select sid from v$mystat where rownum=1;

SID
----------
       226

SQL> select sid from v$mystat where rownum=1;

SID
----------
       242

在每个会话中执行如下:

declare
mcur number;
mstat number;
v_name varchar2(40);
begin
mcur:=dbms_sql.open_cursor;
for i in 1 .. 10000000 loop
dbms_sql.parse(mcur,‘select * from moe where id=1‘,dbms_sql.native);
mstat:=dbms_sql.execute(mcur);
end loop;
dbms_sql.close_cursor(mcur);
end;
/

查看上面两个会话的等待事件:

select sid,event,p1raw,p2raw,p3raw from v$session where sid in (‘226‘,‘242‘);

SID EVENT           P1RAW            P2RAW            P3RAW
---------- --------------- ---------------- ---------------- ----------------
       226 cursor: pin S   00000000D756DDA2 0000000000000001 0000000400000000
       242 cursor: pin S   00000000D756DDA2 0000000000000002 0000000900000000

解决如下:

在226中执行如下:

declare
mcur number;
mstat number;
v_name varchar2(40);
begin
mcur:=dbms_sql.open_cursor;
for i in 1 .. 10000000 loop
dbms_sql.parse(mcur,‘select /* sess_226 */ * from moe where id=1‘,dbms_sql.native);
mstat:=dbms_sql.execute(mcur);
end loop;
dbms_sql.close_cursor(mcur);
end;
/

在242中执行如下:

declare
mcur number;
mstat number;
v_name varchar2(40);
begin
mcur:=dbms_sql.open_cursor;
for i in 1 .. 10000000 loop
dbms_sql.parse(mcur,‘select /* sess_242 */ * from moe where id=1‘,dbms_sql.native);
mstat:=dbms_sql.execute(mcur);
end loop;
dbms_sql.close_cursor(mcur);
end;
/

查看两个会话的等待:

SQL> select sid,event,p1raw,p2raw,p3raw from v$session where sid in (‘226‘,‘242‘);

SID EVENT                         P1RAW            P2RAW            P3RAW
---------- ----------------------------- ---------------- ---------------- ----------------
       226 SQL*Net message from client   0000000062657100 0000000000000001 00
       242 SQL*Net message from client   0000000062657100 0000000000000001 00

to be continued...

#end

整理自:oracle内核技术揭密 吕海波著

时间: 2024-07-31 05:25:46

mutex----我是搬运工的相关文章

SharePoint 2013: A feature with ID has already been installed in this farm

使用Visual Studio 2013创建一个可视web 部件,当右击项目选择"部署"时报错: "Error occurred in deployment step 'Add Solution': A feature with ID 15/3e472a61-bbc9-4242-87c7-a07e8e3fab99 has already been installed in this farm. Use the force attribute to explicitly re-

[python] 线程简介

参考:http://www.cnblogs.com/aylin/p/5601969.html 我是搬运工,特别感谢张岩林老师! python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. 程序是运行在系统上的具有某种功能的软件,比如说浏览器,音乐播放器等. 每次执行程序的时候,都会完成一定的功能,比如说浏览器帮我们打开网页,为了

支持向量机(SVM)的详细推导过程及注解

我是搬运工:http://my.oschina.net/wangguolongnk/blog/111353 支持向量机的原理很简单,就是VC维理论和最小化结构风险.在阅读相关论文的时候,发现很多文 章都语焉不详,就连<A Tutorial on Support Vector Machines for Pattern Recognition>这篇文章对拉格朗日条件极值问题的对偶变换都只是一笔带过,让很多人觉得很困惑.下面我将就SVM对线性可分的情况作详尽的推 导. 如上图所示,有一堆训练数据的正

Android中xml tool属性

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0309/2567.html 我是搬运工.. 总结而言tool属性就是为了在IDE中预览布局效果. 举例:我们在布局时,添加了一个TextView,为了预览效果,我们可能会添加 android:text = "this is a test" 但是往往预览后后我们就会忘记删除这句代码.面对这种情况,我们就可以使用tool属性 tool:text = "this

深入理解SVM之对偶问题

我是搬运工:http://my.oschina.net/wangguolongnk/blog/111349 1. 支持向量机的目的是什么? 对于用于分类的支持向量机来说,给定一个包含正例和反例(正样本点和负样本点)的样本集合,支持向量机的目的是寻找一个超平面来对样本进行分割,把样本中的正例和反例用超平面分开,但是不是简单地分看,其原则是使正例和反例之间的间隔最大. 超平面是什么呢?简单地说,超平面就是平面中的直线在高维空间中的推广.那么,对于三维空间,超平面就是平面了.对于更高维的空间,我们只能

在mac os下的Apache服务器的cgi中运行python

我是搬运工.. Running Python Programs on the Mac OS X Apache Web Server The Mac OS X operating system includes a pre-configured Apache web server and also includes the libraries needed to run Python. Thus, Python CGI scripts can be run without any configur

[C++]C++的模板编程

我是搬运工,原文地址:http://www.cppblog.com/besterChen/archive/2010/07/22/121000.html 当我们越来越多的使用C++的特性, 将越来越多的问题和事物抽象成对象时, 我们不难发现:很多对象都具有共性. 比如 数值可以增加.减少:字符串也可以增加减少. 它们的动作是相似的, 只是对象的类型不同而已. C++ 提供了“模板”这一特性, 可以将“类型” 参数化, 使得编写的代码更具有通用性. 因此大家都称模板编程为 “通用编程”或 “泛型编程

css3 html5画心

以下内容不是原创 我是搬运工 1. <!DOCTYPE HTML><html> <head> <meta charset="UTF-8"/> <title>myHeart</title> <style type="text/css"> *{ margin: 0; padding: 0; } .heart{ position:absolute; left: 50%; top:50%;

sencha touch pull-refresh-panel 面板下拉刷新

转自:http://www.cnblogs.com/mlzs/archive/2013/06/04/3117518.html 此效果手机未测试,目测没问题,我是搬运工... 演示地址:http://scaljeri.github.io/pull-refresh-panel/ 源码地址:https://github.com/scaljeri/pull-refresh-panel 效果图: 使用示例: http://www.cnblogs.com/mlzs/p/3382229.html

WEB渗透测试之漏扫神器

AppScan 对现代 Web 应用程序和服务执行自动化的动态应用程序安全测试(DAST) 和交互式应用程序安全测试 (IAST).支持 Web 2.0. JavaScript 和 AJAX 框架的全面的 JavaScript 执行引擎.涵盖 XML 和 JSON 基础架构的 SOAP 和 REST Web 服务测试支持 WSSecurity 标准. XML 加密和 XML 签名.详细的漏洞公告和修复建议.40 多种合规性报告,包括支付卡行业数据安全标准 (PCI DSS).支付应用程序数据安全