云贝教育 |【技术文章】存储对象的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 加载向量数据…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...