云贝教育 |【技术文章】存储对象的LIBRARY CACHE LOCK/PIN实验(一)
注: 本文为云贝教育 刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。
实验环境
操作系统:Red Hat Enterprise Linux release 8.8 (Ootpa)
数据库:oracle Version 19.3.0.0.0
一、存储对象的LOCK和PIN
在生产环境上,我们碰到的大部分library cache pin等待主要源头是存储过程。那该现象底层原理是什么?接下来通过实验来把这个等待链梳理清晰。
该实验的逻辑:
1、会话1执行某个运行时间很长的存储过程
2、会话2尝试编绎、修改、删除该存储过程
备注:以下操作在PDB下操作

dump library_cache 命令参考
1.1 创建存储过程

test_library_cache_lock_pin在内存中属于存储类型
1.2 dump库缓存
此时存储过程刚创建编绎完成,查看此时存储过程的dump信息。
1)查看存储过程的dump信息

接下来针对以上dump进行解析
2)解析dump信息
1.library cache对象信息

重点关注存储过程的library cache类型、句柄和堆上持有的锁类型。
- 存储过程只是编绎,并未执行,所以对象上的PIN和LOCK都是0
- 没有子游标信息
2.依赖信息

可以看到,存储过程有4个依赖对象
- DBMS_RANDOM
- STANDARD
- LIBRARY_CACHE_LOCK_PIN
- SYS_STUB_FOR_PURITY_ANALYSIS
3.底层调用的表信息
以表对象LIBRARY_CACHE_LOCK_PIN为例,查看 Handle=0x70b57c08的对象信息

· 表对象的类型Namespace=TABLE/PROCEDURE(01) Type=TABLE(02)
· 持有的锁LockMode=0 PinMode=0
4.存储过程的heap信息

可以看到存储过程包括
- heap0
- heap1
- heap2
- heap4
- heap7
- heap13
可以看到,存储过程没有heap6
1.3 调用存储过程
通过调用存储过程,看下执行存储过程中,调用的锁信息
1)在调用存储过程之前,调整一下存储过程内存,让它延时100000秒执行完成。

2)查看修改之后的存储过程对象信息

相比之前的dump,多了一个依赖对象信息。
3)调用该存储过程

看看执行存储过程的时候,对象上的pin和lock

1.执行语句的pin和lock

存储过程的类型也是游标,和SQL不一样,它属于存储对象
注:SQL类型是游标,属于瞬时对象,瞬时对象的LOCK锁只有0和N。
2.父游标heap0信息

可以看到父游标heap 0上的pins=0,表示heap上未加pin锁。
同时可以看到子游标句柄也在父游标heap 0中。这里的ChildTable,表示有几个子游标,这里id=0,表示只有一个子游标。
3.子游标信息

观察如下
- 子游标句柄上的申请的锁为LockMode=N PinMode=S,因为该游标正在执行,PIN是保护这个游标的OBJECT部分,也就是堆的部分。子游标的对象信息被保护,此时如果想修改这个对象,需要获取X模式的PIN锁,无法获取到
- 可以观察到,只有子游标下的HEAP0和HEAP6的Flags=I/-/P/A/-/-/-。这里P表示被PIN住。
4.通过依赖对象Handle=0x76a09550找到存储过程的信息
这里的对象信息就是存储过程调用的存储过程。

存储过程本身的 LockMode=N PinMode=S ,因为它在执行过程中需要申请的锁。
5.NamespaceDump 命名空间

Child Cursor:记录了子游标下的heap0和heap6的生成信息。Heap0=0x73c1f2f0 Heap6=0x6af3b320和DataBlocks中heap0、heap6的Pointer信息对应。
总结
创建创建过程,未执行
| object name | LOCK | PIN |
| ORCLPDB1.SYS.TEST_LIBRARY_CACHE_LOCK_PIN | 0 | 0 |
执行存储过程的时候
| object name | LOCK | PIN |
| BEGIN test_library_cache_lock_pin; END; | N | S |
| ORCLPDB1.SYS.TEST_LIBRARY_CACHE_LOCK_PIN | N | S |
二、library cache pin竞争
从上面的实验我们知道,存储过程在执行过程中,针对TEST_LIBRARY_CACHE_LOCK_PIN持有的LOCK=N,PIN=S。
2.1 设想生产环境场景
设想场景1:在另一个会话中执行删除存储过程的命令

设想场景2:修改存储过程定义

设想场景3:编绎存储过程
![]()
通过实验发现,会话1在执行存储过程的时候,如果另外一个会话针对存储过程执行DDL操作,例如修改、 删除或编绎,会等待library cache pin。

2.2 通过dump验证
执行存储过程BEGIN test_library_cache_lock_pin; END;

执行语句的信息ORCLPDB1.SYS.TEST_LIBRARY_CACHE_LOCK_PIN

2.3 在执行compile之后,查看dump信息
这里我们看编绎命令的句柄

子游标句柄上的锁

#这里可以看LockMode=N PinMode=X,因为是修改操作,所以compile在子游标句柄上申请X模式的PIN琐,N模式的LOCK琐。PIN住的目的是为了获得句柄上的独占锁,为后面修改做准备。
2.4 存储对象上的dump

2.5 对象上的琐
存储过程对象上能申请到LockMode=X ,表示complie语句已经获得TEST_LIBRARY_CACHE_LOCK_PIN上模式X的LOCK锁。为什么能获取到?因为执行compile之前对象上的LockMode=N,N锁不阻塞X锁获取。
PinMode=S,表示此时execute语句是分析阶段,所以需要获取共享pin锁。那如果compile进入执行阶段,需要获取x模式的pin锁,与execute阶段锁冲突,所以无法获取X模式的pin锁。
这也是为什么compile会话只等待libary cache pin,而不等待libarary cache lock的原因。


如果此时在表上执行DDL,会报资源ORA-00054

修改DDL锁参数

发现此时的锁已经不是library cache上的,而是enq表锁,阻塞源是正在执行的存储过程,该存储过程调用了表,而表上的操作是dml,如果是dql还会报错吗?
实验证明,依然报错

三、分析验证
通过等待事件可以确认产生等待的对象,那如何确认等待链关系?
3.1 hangalayze
生成日志
1) 查看等待链关系

PL/SQL lock timer堵塞了library cache pin,那哪个会话是源头,哪个会话是受害者?

看下被堵塞会话session id: 426(等待libraray cache pin)的调用关系
| 序号 | 函数 | 定义 | 作用 |
| 0 | ssthrdmain | operating system dependent system main for every thread in a threaded oracle | |
| 1 | opimai_real | oracle program interface main real oracle start point | |
| 2 | sou2o | main oracle executable entry point. reads environment var ORACLE_SPAWNED_PROCESS. | |
| 3 | opidrv | oracle program interface route current request driver, entry side into two task interface | |
| 4 | piodr | oracle program interface oracle code request driver, route the current request | |
| 5 | opiino | oracle program interface initialize opi | |
| 6 | opitsk | oracle program interface two task function dispatcher | |
| 7 | ttcpip | two task common pipe read/write | 1-7都是操作系统层调用 |
| 8 | kpoal8 | kernel programmatic interface oracle V8 bundled execution | |
| 9 | kpooprx | kernel programmatic interface oracle open, parse, and optionally execute | 准备执行 |
| 10 | opiosq0 | oracle program interface prepare to parse a sql command 0 | 解析 |
| 11 | opiexe | oracle program interface execute | 执行 |
| 12 | kkpcrt | kernel compile compilation create | 创建编绎存储过程任务 |
| 13 | (kkdl)GetCodeObject | kernel compile dictionary lookup ?? | 查找编绎需要的数据字典 |
| 14 | (kkdllk)0 | kernel compile dictionary lookup lock an object ?? | 给对象加锁(编绎需要在存储过程上加X模式LOCK锁) |
| 15 | kglpin | kernel generic library cache management pin heaps and load data pieces of an object ?? | 句柄上X模式LOCK锁加成功,进一步需要PIN住对象上的heap |
| 16 | kglpnal | kernel generic library cache management pin allocate | 申请X模式的pin琐 |
| 17 | kslwaitctx | kernel service latching and post-wait wait for n centi-seconds or until posted wait context; wait until timeout | 申请失败,进入post-wait等待状态 |
| 18 | ksliwat | kernel service latching and post-wait inner wait function; setup a wait that times out | 继续等待,直到超时 |
| 19 | skgpwwait | operating system dependent kernel generic post/wait wait | 继续等待 |
| 20 | semtimedop | SYSCALL: semaphore timed operation | |
| 21 | sspuser | operating system dependent system process management handle SIGUSR2 for Oracle | |
| 22 | ksdxcb | kernel service debug internal errors ksdx callback for sosd layer signal handler | |
| 23 | ksdxfstk | kernel service debug internal errors dump abridged os stack | |
| 24 | ksedsts | kernel service error debug dump the call stack short stack |
继续查看等待链关系

LEAF是阻塞源头,NLEAF是被阻塞者
2) 对比动态性能视图结果
SID=426
1.查看历史等待情况
v$session_event
session id: 426中wait history中排名前3等待一致

2.查看会话当前等待情况
v$session

或
v$session_Wait

与waiting for 'library cache pin' with wait info信息一致
3.查看等待事件的P1,P2,P3

查看等待事件详情

P1RAW=00000000769C3C80,就是存储过程的handle地址
P3RAW=00011D5500010003
00011D55表示ojbect_id

0001表示namespace,从dump中得知01对应的Namespace=TABLE/PROCEDURE(01)
003表示pinmode,3表示x模式的pin锁
00011D55转换十进制73045,对象TEST_LIBRARY_CACHE_LOCK_PIN的OBJECT_ID
四、总结
通过以上实验,我们对存储对象相关操作产生的library cache pin有了很清晰的认识,那如果是library cache lock相关竞争,又该如何模拟验证?接下来的实验暂时留给读者,期待我们下一篇文章。
相关文章:
云贝教育 |【技术文章】存储对象的LIBRARY CACHE LOCK/PIN实验(一)
注: 本文为云贝教育 刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。 实验环境 操作系统:Red Hat Enterprise Linux release 8.8 (Ootpa) 数据库:oracle Version 19.3.0.0.0 …...
C# 快速模指数运算 快速求余运算
此方法解决这样一个问题,就是a^b mod m 的余数是多少。 如果直接计算a^b,方次很大的时候,会溢出,而且时间很长。 当然指数很小的时候直接用自带的Math函数就行,如果指数很大的时候,可以用以下的方法。 原…...
Chisel入门初步0
注:以下所有配置在Ubuntu22.04笔记本中运行 chisel模板构建 复制项目模板文件 git clone https://github.com/schoeberl/chisel-examples.git安装vscode插件Metals 打开顶层目录,并设置为项目文件夹 打开终端输入 tree -L 3 # 查看三层目录结构得到…...
MySQL 8.0中移除的功能(一)
以下项目已经过时并在MySQL 8.0中被删除。如果有替代方案,请务必更新应用程序以使用这些替代方案。 对于在MySQL 8.0中被删除的功能,如果从MySQL 5.7源复制到MySQL 8.0副本时,可能会导致语句失败,或者在源和副本上产生不同的效果…...
可抓取性和可索引性:它们是什么以及如何影响搜索引擎优化
什么是可抓取性? 网页的可抓取性是指搜索引擎(如谷歌)发现网页的难易程度。 谷歌发现网页的过程称为爬行。它使用称为网络爬虫(也称为机器人或蜘蛛)的计算机程序。这些程序会跟踪网页之间的链接,以发现新…...
Django教程第4章 | Web开发实战-三种验证码实现
系列:Django学习教程 验证码的存在是为了防止系统被暴力破解攻击,几乎每个系统都有验证码。下面将介绍三种生成验证码方式。 您可以根据你自己的需要进行学习。 手动生成验证码 安装绘图依赖,利用的是画图模块 PIL 以及随机模块 random 在后…...
深度探讨 Golang 中并发发送 HTTP 请求的最佳技术
💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 在 Golang 领域,并发发送 HTTP 请求…...
VUE指令(二)
vue会根据不同的指令,针对不同的标签实现不同的功能。指令是带有 v- 前缀的特殊标签属性。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。 8、v-for:基于数据循环,多次渲染整个…...
开源对象存储服务器MinIO本地部署并结合内网穿透实现远程访问管理界面
文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器,可以在各种环境中运行,例如本地、Docker容器、Kubernetes集群等。它兼…...
【TypeScript】tsconfig.json文件到底是干啥的?作用是什么?
参考学习博文: 掌握tsconfig.json 一、tsconfig.json简介 1、tsconfig.json是什么? TypeScript 使用 tsconfig.json 文件作为其配置文件,当一个目录中存在 tsconfig.json 文件,则认为该目录为 TypeScript 项目的根目录。 通常…...
wagtail的数据模型和渲染
文章目录 前言页面数据模型数据库字段部分搜索部分编辑面板基础面板结构化面板父页面/子页面类型规则页面URLs自定义页面模型的URL模式获取页面实例的URL 模板渲染为页面模型添加模板模板上下文自定义模板上下文更改模板动态选择模板Ajax 模板 内联模型在多个页面类型之间重用内…...
OpenHarmony4.0适配LVDS屏幕驱动
1.概述 手头有一块RK3568的开发板OK3568-C,但是还没有适配OpenHarmony,用的还是LVDS屏幕,但是官方和网上好像还没有OpenHarmony4.0的LVDS屏幕驱动的通用实现,所以决定尝试了一下适配该开发板,完成LVDS屏幕驱动的适配&…...
【playwright】新一代自动化测试神器playwright+python系列课程01-playwright驱动浏览器
Playwright驱动浏览器 安装 Playwright 时,Playwright默认自动安装了三种浏览器(Chromium、Firefox 和 WebKit)。我们可以驱动这三种浏览器中的任意一种。 使用with上下文管理器 启动chromium浏览器 python # # author: 测试-老姜 交流…...
POSIX API与网络协议栈
本文介绍linux中与tcp网络通信相关的POSIX API,在每次调用的时候,网络协议栈会进行的操作与记录。 POSIX API Posix API,提供了统一的接口,使程序能得以在不同的系统上运行。简单来说不同的操作系统进行同一个活动,比…...
互联网加竞赛 基于卷积神经网络的乳腺癌分类 深度学习 医学图像
文章目录 1 前言2 前言3 数据集3.1 良性样本3.2 病变样本 4 开发环境5 代码实现5.1 实现流程5.2 部分代码实现5.2.1 导入库5.2.2 图像加载5.2.3 标记5.2.4 分组5.2.5 构建模型训练 6 分析指标6.1 精度,召回率和F1度量6.2 混淆矩阵 7 结果和结论8 最后 1 前言 &…...
腾讯云 IPv6 解决方案
产品矩阵全覆盖 腾讯云全线产品 All in IPv6;云服务器、私有网络、负载均衡、内容分发、域名解析、DDoS 高防等都已支持 IPv6。 全球 IPv6 基础设施 腾讯云在全球开放25个地理区域,运营53个可用区;目前已有多个地域提供 IPv6 接入能力。 …...
Appium 自动化测试
1.Appium介绍 1,appium是开源的移动端自动化测试框架; 2,appium可以测试原生的、混合的、以及移动端的web项目; 3,appium可以测试ios,android应用(当然了,还有firefoxos)…...
深入浅出Android dmabuf_dump工具
目录 dmabuf是什么? dmabuf_dump工具介绍(基于Android 14) Android.bp dmabuf_dump.cpp 整体架构结构如下 dmabuf_dump主要包含以下功能 前置背景知识 fdinfo 思考 bufinfo Dump整个手机系统的dmabuf Dump某个进程的dmabuf 以Table[buff…...
Guava RateLimiter预热模型
本文已收录至我的个人网站:程序员波特,主要记录Java相关技术系列教程,共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源,让想要学习的你,不再迷茫。 什么是流量预热 我们都知道在做运动之前先得来几组…...
【搭建个人知识库-3】
搭建个人知识库-3 1 大模型开发范式1.1 RAG原理1.2 LangChain框架1.3 构建向量数据库1.4 构建知识库助手1.5 Web Demo部署 2 动手实践2.1 环境配置2.2 知识库搭建2.2.1 数据收集2.2.2 加载数据2.2.3 构建向量数据库 2.3 InternLM接入LangChain2.4 构建检索问答链1 加载向量数据…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
