解析

shared pool



图解:

library cache里面,暂时可以认为存储着:

1、SQL以及对应的执行计划(所占空间比较小);

2、存储过程、函数、触发器、包,它们编译后的对象(所占空间往往比较大,特别是包所占的比较大)

对于shared pool管理和研究的时候,row cache一般不会出现问题,所以一般情况我们都不研究row cache,会出问题的经常是library cache,所以我们经常研究它

如果要执行包里面的一个存储过程的时候,oracle就会把整个包头(包规范)的部分调到library cache里面去,这时候就可能造成比较大的一个对象突然被调到library cache里去,这时候有可能会报4013错误;所以写包的时候,尽量不要把过多的存储过程或者函数放到一个包里面去

在shared pool里,有时候可能造成比较大的一个对象突然被调到library cache里去,这时候有可能会报4013错误,所以为shared pool专门设了一个,一个比较大的对象突然被调到library cache里去的空间:reserved空间,用来存储突然来的大对象的空间,占shared pool空间大小的5%,

假设library cache的大小为5G,缓存着大量的SQL以及SQL的执行计划,现在,要去执行一个SQL,就在library cache里面的这些大量的SQL以及SQL的执行计划里面找,这就有一个问题,该怎么找呢?假设library cache里面有100万行,然后一个一个去对比,就要找100万次,这显然就不合适;

管理SQL以及SQL的执行计划

链(chain)

那么library cache里面是如何组织和管理SQL以及SQL的执行计划的,以便于很方便的找到要执行的SQL?



图解:

用链把一个一个的SQL链起来,假设library cache有500M大小,用4个链来管理SQL;对于SQL1来说:SQL1经过hash以后,得到hash值,然后计算:hash值/4的余数(0、1、2、3......):如果余数 = 0,就把SQL1挂在0号链上;如果SQL1在library cache里面,server process就认为SQL1一定在0号链上,然后在0号链上找,不需要在另外的链上找;另外假设SQL2,经过hash,然后计算余数,假设余数 = 1,就在1号链上找,最终没有找到,它就不找了,因为也不可能在其他的链上,然后SQL2就要产生硬解析了

链的特点:

1、链的一种访问方式:只能遍历,不能随机访问(找到链的头部就可以一个一个的找,一直找到链的尾部)

2、一种链一种作用(比如SQL经过hash,然后挂在链上的,找的时候也是SQL经过hash然后在链上找)

library cache里面的链:就是SQL经过hash值的方式挂起来的(当初怎么组织的,找的时候就怎么找)

library cache的大小,会影响链的数量(library cache多大,链的数量是多少,这个是oracle自己去调整、适应的;我们也可以调整相关的参数来调整链的数量)

一个链可以认为是一个bucket(桶)

Hash(其实就是一个函数)

例如对于SQL:select name from t where id = :x;

oracle会把SQL语句里面的每一个字母,转换成一个ASCII码值,每一个字母对应着一个编码,

一个SQL --> 一堆的文本字母 --> 一堆的数字

hash值与SQL的几种对应关系:

1、如果SQL1和SQL2完全相同,那么它们的hash值一定相等

2、如果SQL1和SQL2不相同,那么它们的hash值一定不相等

3、如果SQL1和SQL2的hash值相等,但是SQL1和SQL2不一定相同

所以比较两个SQL时:

1、如果两个SQL的hash值不相等,那么两个SQL就不相;

2、如果两个SQL的hash值相等,那么还要比较两个SQL,一个字母一个字母的去比较

free空间

free里面的chunk是如何管理的?

也是使用链来管理的

从free空间里面找空闲的chunk(内存块),怎么找?

根据大小来找;比如现在我们需要一个4k大小的,就在free里面找一个4k的chunk,不行就找比4k大一点点的(比如:5k、8k、12k),然后找5k的,所以free里面是通过一种以free chunk的大小的链把一个一个的chunk挂在上面的



图解:

有三个链:2k、8k、16k,现在需要一个9k的,就在8k的链上找,找到一个12k的,可以,就用一下,用了9k还剩下3k,又挂到2k的链上。

游标(cursor)

一个SQL以及SQL对应的执行计划,叫做一个cursor,在library cache里面

父游标(parent cursor)

父游标说的是:SQL文本;同一个SQL可能对应多个执行计划(因为访问的用户不同,表的名字一样(都是t表),但是表的内容不一样;或者因为绑定参数的值的不同(同一个值,一个表里有1000万行,另外一个表里只有10行(这里表的名字相同)),执行计划也可能不同)

子游标(children cursor)

子游标就是:执行计划;子游标的个数不定,根据实际情况而定(比如10个、100个不确定)

version count(版本数量)

例如一个父游标有10个子游标,那么它的版本数量就是10

latch:锁(内存锁、闩锁),用来保护链的



图解:

现在有一个问题:oracle有好多上的server process,;假设server process1执行SQL1,server process2执行SQL2,然后server process1执行SQL1的时候要解析,在library cache里面没找到,SQL1就要发生硬解析;执行SQL2的时候,同样也如此,SQL2也需要硬解析;同时解析;

在解析的时候,就需要在free里面找一个free chunk,把它写进去;假设解析SQL1需要一个,9k的free chunk,解析SQL2,需要一个10k的free chunk,所以都需要在8k的链上找,这就有一个并发的问题:假设SQL1和SQL2找到相邻的两个free chunk;SQL1就要把它找到的free chunk2拿下来,把free chunk1指向free chunk3;SQL2把找到的free chunk3拿下来,然后把free chunk2指向free chunk4;这时候,free chunk2和free chunk3都没了,链就断了,所以对于这种情况链就需要并发保护,使用锁(latch)来进行保护;

latch(对于0号链申请的一个内存结构),用来保护0号链的,现在server process1读这个latch(里面有没有写相关信息),发现里面是空的,server process1就以S的方式写上,server process1以S的方式来访问0号链;

latch里面是空的,说明没有进程来对这个链进行保护修改;然后server process2也要来访问0号链,发现有一个进程在以S的方式访问,server process2想加一个X方式,但是server process1以S的方式持有着latch,server process2也想持有着latch,但是S和X不兼容,所以server process2就不能持有着latch,这时候server process2就发生一次latch misses(latch丢失);

假设server process1在cpu1上工作,server process2在cpu2上工作(有两个cpu),这时候,还有一个server process3在等着cpu空出来再进去,现在对于server process3来说两种选择:

1、server process2退出来(latch丢失),再进入cpu2,server process3工作一段时间以后退出来,server process2再进去,继续执行之前未执行完的操作,这个过程叫做:context switch(CS);

2、server process1持有latch的时间非常短,很短的时间内就执行完了,这时候,server process2不出来,它执行一个for循环,占用着cpu2,等server process1执行完S之后释放了latch就进去,这时候server process3就可以使用cpu1了;

再有假设,有四个cpu,server process2不出来,占用着cpu2,这时候server process3也持有着latch,server process2又再一次latch丢失了,然后server process4又持有着latch,server process2空转cpu,server process2又再一次latch丢失,server process2多次latch丢失以后,server process2就转为sleep状态,然后就退出cpu了,其他的server process就可以占用这个cpu了

因此,如果数据库出现严重的latch征用,就会表现出cpu很繁忙

sleep状态,说明出现了多次latch misses(latch丢失)

当server process1想访问0号链的时候,有两种访问方式:

1、S(共享锁)的方式(读链,在链上找大小)

2、X(排他锁)的方式(修改链,就是往链上挂东西和往链上摘东西)

S方式和X方式的关系

例如:1、SQL1:S 2、SQL1:S 3、SQL1:X

SQL2:S SQL2:X SQL2:S

1、SQL1和SQL2可以同时进行(S、S可以兼容)

2、SQL1和SQL2不能同时进行,要等SQL1找完了,SQL2再去修改(S、X不兼容)

3、SQL1和SQL2不能同时进行,要等SQL1修改完了,SQL2再去找(S、X不兼容)

latch的另外一种情况:

多个链用一个latch来保护,就很有可能出现latch丢失,所以我们可以通过调整参数来让多个链让多个latch来保护

latch的种类(绝大部分):

1、父latch:library cache latch

2、子latch:每一个链上latch(library cache latch里面一个一个的latch)

latch的工作方式:

1、sp1:S方式持有着latch

sp2:X方式,出现latch misses,空转着cpu,多次latch misses以后,变为sleep状态

2、sp1:S方式持有着latch 0

sp2:X方式,也想持有着latch 0,出现latch misses;但是sp2从latch 0上的链上能找到想要的东西,从latch 1上的链上也能找到想要的东西,一样;这时候,sp2就跑到latch 1去找东西了

但是绝大多数都是以第一种工作方式(willing to waiter)工作:愿意等,或者必须等的

19、解析2_1(链、chunk、锁)的更多相关文章

  1. [转帖]深度解析区块链POW和POS的区别

    深度解析区块链POW和POS的区别 Proof of Work 还有Proof of Stake 之前理解程了 state ... 股权的意思 还有 delegated proof of Stake ...

  2. Apache Common-collection 反序列化利用链解析--TransformedMap链

    Apache Common-collection 反序列化利用链解析 TransformedMap链 参考Java反序列化漏洞分析 - ssooking - 博客园 (cnblogs.com) poc ...

  3. synchronized互斥锁实例解析

    目录 synchronized互斥锁实例解析 1.互斥锁基础使用:防止多个线程同时访问对象的synchronized方法. 1.1.多个线程调用同一个方法 1.2.多个线程多个锁,升级为类锁 2.线程 ...

  4. 用RUST写流媒体服务器实战——rtmp chunk 深入解析

    用RUST写流媒体服务器实战--rtmp chunk 深入解析 最近几个月断更了,把精力放在了新的开源项目上,一个用rust写的流媒体服务xiu. 实现过程中踩了不少坑,今天说下rtmp中的chunk ...

  5. InnoDB锁机制分析

    InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工作机制.通过 ...

  6. [转载] 数据库分析手记 —— InnoDB锁机制分析

    作者:倪煜 InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工 ...

  7. python面试题解析(网络编程与并发)

    1.答: 应用层 与其它计算机进行通讯的一个应用,它是对应应用程序的通信服务的.例如,一个没有通信功能的字处理程序就不能执行通信的代码,从事字处理工作的程序员也不关心OSI的第7层.但是,如果添加了一 ...

  8. Spring框架之spring-webmvc源码完全解析

    Spring框架之spring-webmvc源码完全解析 Spring框架提供了构建Web应用程序的全功能MVC模块.Spring MVC分离了控制器.模型对象.分派器以及处理程序对象的角色,支持多种 ...

  9. 玩转直播系列之RTMP协议和源码解析(2)

    一.背景 实时消息传输协议(Real-Time Messaging Protocol)是目前直播的主要协议,是Adobe公司为Flash播放器和服务器之间提供音视频数据传输服务而设计的应用层私有协议. ...

  10. SpringMVC视图解析器

    SpringMVC视图解析器 前言 在前一篇博客中讲了SpringMVC的Controller控制器,在这篇博客中将接着介绍一下SpringMVC视 图解析器.当我们对SpringMVC控制的资源发起 ...

随机推荐

  1. 在 macOS 上安装 fish

    安装 fish brew install zsh 将默认 shell 切换为 fish 由于 Homebrew 安装的 fish 不在标准 shell 列表 /etc/shell 里,因此要先将 fi ...

  2. 解密华为问界M7 Pro:智能出行的全新里程碑与技术亮点

    解读华为问界M7 Pro的智能里程碑 引言 2024年8月,智能出行领域迎来了一个激动人心的时刻--问界M7 Pro的重磅发布.这款智能SUV,不仅是华为在汽车领域的又一次大胆尝试,更是鸿蒙智行系统的 ...

  3. sicp每日一题[1.41]

    Exercise 1.41 Define a procedure double that takes a procedure of one argument as argument and retur ...

  4. 生产级Redis 高并发分布式锁实战2:缓存架构设计问题优化

    对于大多数高并发场景,都是读多写少.比如商品信息,医生挂号信息等.提交订单页只有一个操作. 对于一个普通的缓存架构设计,实现商品的增删改查功能,代码如下: Controller 层 @RestCont ...

  5. linux磁盘分区之后,lsblk没有显示

    可以看出  fdisk 创建一个 sda4 的分区  并保存退出, 但是 不管是使用 fdisk -l ,还是 lsblk 都无法显示出来, 那么导致问题的原因,主要是因为新创建了分区之后,系统没有重 ...

  6. Mybatis骚操作-通用查询工具类

    老项目大多都有对JDBC进行了封装,可以直接执行SQL的工具类,在做项目升级改造的时候(这里仅指整合mybatis),要么全部调整成dao-xml的形式(会有改动代码多的问题,而且看代码时需要xml和 ...

  7. 前端使用 Konva 实现可视化设计器(22)- 绘制图形(矩形、直线、折线)

    本章分享一下如何使用 Konva 绘制基础图形:矩形.直线.折线,希望大家继续关注和支持哈! 请大家动动小手,给我一个免费的 Star 吧~ 大家如果发现了 Bug,欢迎来提 Issue 哟~ git ...

  8. Angular 18+ 高级教程 – Component 组件 の Dependency Injection & NodeInjector

    前言 在 Dependency Injection 依赖注入 文章中,我们学习了 50% 的 Angular DI 知识,由于当时还不具备组件知识,所以我们无法完成另外 50% 的学习. 经过了几篇组 ...

  9. argmax经过sigmoid和不经过sigmoid区别

    起因 今天和同组讨论了一下网络输出时,在torch.argmax之前经过torch.sigmoid和不经过sigmoid的区别. 主要起因是实验结果图像不同 图1 不经过sigmoid 图2 经过si ...

  10. netCore 封装一个检验邮箱的类

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...