前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >高级OWI之Mutex (互斥锁)

高级OWI之Mutex (互斥锁)

作者头像
SQLplusDB
发布2020-03-25 17:52:18
6220
发布2020-03-25 17:52:18
举报

前言

本文主要介绍高级OWI基础的Mutex (互斥锁)相关内容

概要

关于Mutex的概念,我们还是通过下面官方在线文档的描述有一个总体的印象:

Database Concepts 12.2 http://t.cn/R9NOV0I Mutexes A mutual exclusion object (mutex) is a low-level mechanism that prevents an object in memory from aging out or from being corrupted when accessed by concurrent processes. A mutex is similar to a latch, but whereas a latch typically protects a group of objects, a mutex protects a single object. Mutexes provide several benefits: A mutex can reduce the possibility of contention. Because a latch protects multiple objects, it can become a bottleneck when processes attempt to access any of these objects concurrently. By serializing access to an individual object rather than a group, a mutex increases availability. A mutex consumes less memory than a latch. When in shared mode, a mutex permits concurrent reference by multiple sessions.

通过上面的描述,我们知道Mutex和Latch一样都是低级别的保护内存对象的锁机制,并且具有以下的特点:

・一个Mutex仅保护一个对象,会减缓竞争 ・Mutex比Latch使用更少的内存 ・Mutex可以是共享模式的

另外,Mutex还具有以下特点:

・Mutex本身和保护对象是一体的,不像Latch一样有单独的latch池,而且Mutex本身占用内存也更小。 ・Mutex没有等待和持有队列,所以没有排队机制。 ・Mutex具有共享和排他两种模式

Mutex的演化

Mutex (KGX) 是Oracle 推出的用于替代部分Latch和Pin的功能内存锁机制,以下是部分演化历史:

・10.2.0.1版本开始实现Mutex功能(默认不使用,通过隐含参数_kks_use_mutex_pin控制)。

・10.2.0.2以后版本默认使用Mutex,但仅仅对共享游标的部分操作(KKS)使用Mutex保护。

・11.1 应用范围进一步扩大,对library cache(KGL)的同一Hash Bucket访问时也使用Mutex保护,出现了library cache mutex等。

・11.1.0.7以后的版本,Oracle针对于library cache(KGL)相关的Mutex, 追加了一个_kgl_mutex_wait_time隐含参数,用于控制获得Mutex过程中的获取动作;

当_kgl_mutex_wait_time不为0(默认值)时,如果获取超过spin的回数,仍未获取到Mutex的话,进程不再和以前版本一样进行退让(yielding)而进行睡眠(waiting),并且睡眠时间为_kgl_mutex_wait_time参数指定的值。

例:(11.2.0.2)

SQL> select a.ksppinm "Parameter",a.KSPPDESC "Description",b.ksppstvl "Value" from x$ksppi a, x$ksppcv b where a.indx = b.indx and a.ksppinm like '%_mutex%'; Parameter Description Value -------------------- ---------------------------------------- ---------- _kgl_mutex_wait_time KGL mutex wait time 0

・基于11g Enhancement Bug 10411618 (在PSU 11.1.0.7.9和PSU 11.2.0.2.2以后的版本进行了修改)等,Mutex机能进行了一系列的机能强化;

主要引入了包括以下参数,可以对Mutex的获得过程根据应用需要进行调整。

_mutex_spin_count: 用于控制在获得Mutex过程过程中spin的回数(默认255); 超过指定的spin的回数,进程会进行退让或者等待(yielding/waiting)。 (※Bug 10411618修正之前版本为固定值255) _mutex_wait_scheme: 用于控制Mutex的获得机制。(默认2) ・_mutex_wait_scheme = 0 (Yield) Bug 10411618加强的机能会被禁止; 和之前11.2.0.1版本的动作相同,超过指定的spin的回数仍然没有获得Mutex,进程不会发生睡眠(Sleep)而是进行退让(Yield)CPU,然后再spin。 ・_mutex_wait_scheme = 1 & _mutex_wait_time = T (SLEEP ) 如果获取超过spin的回数,仍未获取到Mutex的话,进程会进行睡眠(Sleep)然后再spin,并且每次睡眠时间为T毫秒(milli-seconds). ・_mutex_wait_scheme = 2 & _mutex_wait_time = T (EXP BACKOFF SLEEP ) 如果获取超过spin的回数,仍未获取到Mutex的话,会进行睡眠(Sleep)然后再spin,并且每次睡眠时间由称为指数退让算法(exponential backoff Sleep)决定,其最大的睡眠时间为T厘秒(centi-seconds)。 _mutex_wait_time: 用于和_mutex_wait_scheme并用,指定时间(默认1)。

注:

・关于指数退让算法(exponential backoff Sleep)可参考【高级OWI之Latch(闩锁)】一文中的介绍。

・在Bug 10411618 修正的版本中,_kgl_mutex_wait_time参数被_mutex_wait_time所替代。

例:(on Ver 11.2.0.2.2~12.2)

SQL> select a.ksppinm "Parameter",a.KSPPDESC "Description", b.ksppstvl "Value" from x$ksppi a, x$ksppcv b where a.indx = b.indx and a.ksppinm like '%_mutex%'; Parameter Description Value -------------------- --------------------- ---------- _mutex_wait_time Mutex wait time 1 _mutex_spin_count Mutex spin count 255 _mutex_wait_scheme Mutex wait scheme 2

・关于yielding和waiting:

yielding: 相当于Linux中sched_yield()这个函数的动作; 当前进程对CPU进行退让,可以让另一个级别等于或高于当前进程的进程先运行。 如果没有符合条件的进程,那么这个函数将会立刻返回,然后继续执行当前进程的程序。 waiting: 当前运行的进程睡眠一段时间,进入不可运行状态,这段时间会释放CPU。

新版本中Mutex获取过程中yielding/waiting/Pining逻辑的简要流程图,可以简要归纳如下:

参考:

andrey nikolaev’s blog

http://t.cn/RCRdmMb

Mutex waits. Part III. Contemporary Oracle wait schemes diversity.

Mutex的结构和获取

Mutex的实现一般需要使用操作系统平台的compare-and-swap (CAS) 操作,对于不支持CAS的操作系统平台如HP-UX PA-RISC,Oracle数据库会使用一段称为Mutex latches的代码模拟CAS操作。

但在12.2版本以后,由于Oracle数据库不再和HP-UX PA-RISC兼容,所以仅支持CAS操作的实现方式。

Mutex的结构中一般会包含以下信息:

Holder Id:以排他模式(X Mode)持有Mutex的会话ID。 Ref count:以共享模式(S Mode)持有Mutex的会话数。 mutex-related statistics:其他Mutex相关的统计信息。

当Mutex的Holder Id不为空时,表示该Mutex以排他模式(X Mode)被持有, 以排他模式(X Mode)被持有Mutex一般包括以下情况:

・某进程正以排他模式(X Mode)持有该Mutex; 此时Holder Id是持有Mutex的会话ID,Ref count为0。 ・以共享模式(S Mode)持有Mutex的进程数发生变化(增加或者减少); 因为更新Ref count的操作需要串行,所以需要排他模式(X Mode)持有。 此时Holder Id是正在更新Ref count的会话ID,Ref count可能不为0。 (这通常仅仅是个中间状态,会在极短的时间内完成,Ref count更新后,Holder Id重置为空)

如上所述,通过对Mutex的结构中Holder Id和Ref count的更新,可以实现对Mutex的模式控制,以下是以cursor: pin为例介绍mutex的获取和释放过程。

※注1:

・其他某进程正以排他模式(X Mode)持有该Mutex时,等待事件为cursor: pin S wait on X ・其他某进程由于更新Ref count的操作而以排他模式(X Mode)持有该Mutex时,等待事件为cursor: pin S

参考:

compare-and-swap (CAS)

https://en.wikipedia.org/wiki/Compare-and-swap

Mutex的类型和等待事件

根据Mutex保护的功能不同,可以把Mutex分成不同的类型;

为了方便诊断,Oracle针对不同类型的Mutex定义了不同的等待事件。

最常见的Mutex是Cursor相关(KKS)和library cache(KGL)相关的Mutex,相对应的最常见的等待事件包括如下:

cursor: mutex X cursor: mutex S cursor: pin X cursor: pin S cursor: pin S wait on X library cache: mutex X library cache: mutex S

对于各种Mutex的类型和等待事件,可参照MOS文档:

Troubleshooting: Waits for Mutex Type Events (Doc ID 1377998.1) FAQ: 'cursor: mutex ..' / 'cursor: pin ..' / 'library cache: mutex ..' Type Wait Events (Doc ID 1356828.1) Troubleshooting 'library cache: mutex X' Waits. (Doc ID 1357946.1)

其他内容将在以后的文章中进行介绍。

用碎片化的时间,一点一滴地学习一套系统化的知识。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Oracle数据库技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概要
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档