这是在网上看到的一篇文章,感觉这个知识点挺重要的,特地分享出来。

Oracle数据库使用闩锁来管理内存的分配和释放。假设,某个用户进程(假设其为A)发出一条update语句,要去更新58号数据块里的某条记录。则该用户进程对应的服务器进程在写内存的时候,找到58号数据块,并往里写内容。A在写58号数据块的过程中,这时,另一个用户进程B发出insert语句,要将某个新的记录插入到58号数据块里。如果没有一定的保护机制,A正要写入的空间可能会被B抢先写入,或者相反,B正要写入的空间也可能会被A抢先写入。不管哪个用户先抢先写入,造成的结果就是,58号数据块里的数据都混乱了,因为这时,A和B之间的数据互相交织在一起了。

因此,必须使用latch对此进行保护。简单来说,任何进程要写数据块时,都必须先获得latch,在写入过程中,一直持有该latch,写完以后,释放该latch。对于上面的例子来说,当A在写入58号数据块时,先获得latch,然后开始写。而当A正在写入的过程中,B也要写58号数据块。这时B在尝试获得latch时,发现该latch正被其他用户(也就是A)持有,因此B进入等待状态。直到A写完数据块并释放latch以后,B才能获得latch,获得latch以后,才能在58号数据块里写入数据。

这里只是以写数据块为例来说明为何要使用latch。而事实上,latch不仅仅用于写数据块,比如对于shared pool来说,其内存单位就不是数据块了。latch也不仅仅用于写操作,只要涉及内存地址的读和写,都需要通过获得latch来实现串行化,一次只能有一个服务器进程在读或者写内存地址。

Oracle在实例管理中,不管是buffer cache、shared pool还是log buffer,都引入了各种各样的latch。

实现latch时,实际是由操作系统的旗语(semaphore:也叫信号量)来完成的。为了便于理解,可以把它们想象为,通过某个变量值的变化而实现的。变量值为0则说明latch当前没有被其他进程获取,否则如果为非0值,则说明它已经被其他进程所获取了。Oracle在设计latch的时候将其定义为轻量级锁,因此它的操作非常快,以微秒(microsecond,也就是百万分之一秒)来计算。

latch分为两种类型:

愿意等待(Willing-To-Wait)

大部分的latch都属于这种类型。这种类型的latch都是通过Test-And-Set的方式来实现的。也就是说,如果当前进程不能获得latch的时候,会绕着CPU旋转,而不放弃CPU。这也就是所谓的SPIN CPU,实际就是执行一段空循环,类似执行下面一段代码(其中的N由Oracle内部来控制):

loopexit when i>= N i := i+1;null;end loop;

进程之所以不释放CPU而是绕着CPU旋转,是由于latch操作本身是一个很快速的动作,因此可能等一会就能获得latch了。当进程一旦获得CPU,但是获得不了latch时,如果这时候立刻放弃CPU,那么需要进行上下文切换,下次再次尝试获得latch时,又要进行上下文切换,可能反而要消耗更多的时间。因此,进程在不能获得latch的时候,会执行上面这段代码,绕着CPU转一会,然后再次尝试获得latch,如果仍然不能获得,则再次旋转CPU。当反复旋转CPU并尝试获得latch的的次数超过某个上限(该上限由隐藏参数控制)时,这时进程会释放CPU,并进入睡眠(Sleep)状态。进程一旦进入睡眠状态,则会抛出一个对应的等待事件,并记录在视图v$session_wait里,说明当前该进程正在等待的latch的类型等信息。初始状态下,一个进程会睡眠0.01秒。然后醒过来,并再次尝试获得latch。如果旋转CPU的次数达到上限以后,仍然不能获得latch,则再次进入睡眠,这时会睡眠两倍的时间,依此类推,直到达到睡眠的最大值:0.2秒。

这是在数据库服务器具有多个CPU时的情形,如果只有一个CPU,就不存在旋转CPU的情况,一旦获得不了latch,就进入睡眠。

总的来说,当进程尝试获取Willing-To-Wait类型的latch时,如果失败,则进程会一直尝试对latch的获取,不断循环,直到获得latch为止,或者是达到所指定的上限值为止。当达到上限值时,进程进入睡眠。

不等待(No-Wait)

这种类型的latch比较少,对于这种类型的latch来说,都会有很多个可用的latch。当一个进程请求其中的一个latch时,会以no-wait模式开始请求。如果所请求的latch不可用,则进程不会等待,而是立刻请求另外一个latch。只有当所有的latch都不能获得时,才会进入等待。

从另外一个角度来说,latch分为单个latch(Solitary latch,比如shared pool latch以及redo allocation latch等)和latch组(比如library cache latch、cache buffers lru chain latch以及cache buffers chains latch等)。latch组包括父latch和子latch。单个latch和父latch都是定义在数据库软件代码里的,而且都是静态分配的。对于每种类型的latch,只有一个父latch。而子latch则根据参数或默认值而动态设定,而且子latch的访问独立于父latch。通常来说,父latch只用于汇总显示报表的目的。
如果latch资源被争用,通常都会表现为CPU资源使用过高。而反过来说,如果我们发现CPU资源很紧张,利用率总是在90%以上,甚至总是在100%,其主要原因有以下几点。

SQL语句没有使用绑定变量。如果没有使用绑定变量,或者书写SQL时随意性过大,比如大小写混用等。则Oracle对每一条SQL语句都要进行解析,也就是要非常频繁地读写shared pool里的内存块,从而导致与解析SQL相关的latch争用。

执行SQL语句时,扫描的数据块过多,或者说SQL语句写的比较低效,导致要扫描很多的数据块才能返回所要的记录。因为在查找、扫描数据块的过程中,进程也要获得latch,直到找到数据块为止。

为何一旦latch资源发生争用,就会导致CPU繁忙呢?可以想象一下,假设某个进程(A)执行一条SQL语句需要访问10000个数据块,那么该进程在扫描数据块的过程中,一直持有latch。而另一个进程B也要执行SQL,但是由于A持有了latch,导致B无法获得,于是旋转一会CPU,再去获得latch,直到进入睡眠才释放CPU。接下来C进程也要执行SQL,同样的,由于A持有了latch,导致C无法获得,于是也旋转一会CPU,再去获得latch,直到进入睡眠才释放CPU。如果类似B和C的进程很多的话,那我们会发现,CPU总是在被旋转,也就是在做空的循环,而无法做其他的事情。因此,体现出CPU的使用率过高。

要解决latch的争用,关键在于共享SQL语句(比如使用绑定变量、规范SQL的书写等)以及优化SQL语句,使其搜索以及扫描的数据块的个数下降到最低。

原文地址

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25701553/viewspace-695621/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/25701553/viewspace-695621/

oracle 闩锁(latch)概述相关推荐

  1. oracle中栓锁,oracle 闩锁介绍

    oracle通过闩锁(latch)和锁定(lock)来实现资源的串行化.闩锁和锁定相同点是:都是用于实现保护数据的完整与准确性.不同点是:闩锁是 一个低级别,轻量级的锁,获得和释放的速度非常快.而锁定 ...

  2. ORACLE 闩锁介绍

    oracle通过闩锁(latch)和锁定(lock)来实现资源的串行化.闩锁和锁定相同点是:都是用于实现保护数据的完整与准确性.不同点是:闩锁是一个低级别,轻量级的锁,获得和释放的速度非常快.而锁定则 ...

  3. 闩锁(latch)概述

    第10章 闩锁.锁定和并发性数据库系统本身是一个多用户并发处理系统,在同一个时间点上,可能会有多个用户同时操作数据库.这里就涉及两个很重要的问题.这些用户之间的操作不会互相破坏.比如两个用户同时在相同 ...

  4. oracle中栓锁,特定的闩锁和互斥场景

    1. Library Cache Mutex等待 库缓存是共享池的一部分,在共享池里有SQL的缓存定义.PL/SQL和JAVA类.对库缓存的修改收到library cache mutex的保护.在Or ...

  5. 常见latch闩锁等待

    常见latch闩锁等待 参考<oracle性能优化实务> 与共享池有关的latch闩锁等待(共享池不足或碎片化问题导致) shared pool library cache library ...

  6. oracle sysobject,SQL2000数据库提示未能读取并闩锁页 sysobjects 失败数据库修复

    SQL2000数据库提示未能读取并闩锁页 sysobjects 失败数据库修复 哈尔滨海月数据恢复中心为哈尔滨某速达用户成功解决SQLServer2000数据库DBCC检测提示"未能读取并闩 ...

  7. oracle 闩情况,理解oracle锁和oracle闩(3)TX锁和TM锁

    oracle没有锁管理器和锁列表,这样可以避免行级锁维护的开销和行级锁数量不足导致的争用问题.在Oracle的每行数据上,都有一个标志位来表示该行数据是否被锁定,要查看某一行是否被锁定,必须直接找到这 ...

  8. 介绍了Oracle数据库锁的种类及研究

    http://www.dedecms.com/web-art/shujuku/Oracle/20061008/37324.html 介绍了Oracle数据库锁的种类及研究 来源:ZDNET 作者:佚名 ...

  9. sql 闩锁 原因_如何识别和解决SQL Server中的热闩锁

    sql 闩锁 原因 描述 (Description) In SQL Server, internal latch architecture protects memory during SQL ope ...

最新文章

  1. Gartner评出2017年最值得关注的11个顶级信息安全技术
  2. CCS中各个项目文件的作用
  3. 为解决Thymeleaf数字格式化问题而想到的几种方案
  4. bentley 二次开发_Bentley的基本概念
  5. 操作系统原理: 操作系统概述
  6. [蓝桥杯][2017年第八届真题]拉马车(String)
  7. 【程序设计】流程图的规范和绘制
  8. linux下mysql连接错误解决
  9. Microsoft Updater Application Block 1.2.1 核心设计(core design) [翻译]
  10. 888. 公平的糖果棒交换
  11. C-snowflake uuid 生成器
  12. 慧翔PMP培训及感想
  13. Microbiome:鸡肠道微生物宏基因集(张和平、魏泓、秦楠点评)
  14. wordpress php格式,PHP_WordPress自定义时间显示格式,在帮King改他的私人情侣博客模 - phpStudy...
  15. [ HIT - CSAPP ] 哈尔滨工业大学 - 计算机系统 - 期末大作业“Hello‘s P2P’”
  16. 聘用协议_聘用合同谈判
  17. Python中匿名函数详解
  18. 百度paddleOcr安装与使用
  19. 天枰游戏(智力开发)
  20. 安装Docker Desktop报错WSL 2 installation is incomplete.

热门文章

  1. logline: 是时候聊一聊前端的日志了
  2. 【无标题】免费源码资源,游戏源码下载
  3. Basic Block
  4. 主板中的电池是怎样放电的?
  5. 树莓派官方系统安装教程
  6. 小白学习记录篇01---C语言和C++的区别以及C语言中文件的含义(不足之处欢迎大佬补充提醒。)
  7. mysql 性能优化,减轻数据库的压力。(减少数据库查询的次数)
  8. selenium实现163邮箱登录
  9. iOS开发学习笔记-C语言学习(一)
  10. recon-ng的使用