共享池的改进与ORA-04031的变化

自Oracle9i起,共享池可通过子缓冲池(SubPool)管理,提高并发性并减少竞争。子缓冲池数量受_KGHDSIDX_COUNT参数影响,可根据CPU数量及共享池大小动态调整。在Oracle10g中引入了子分区的概念,进一步提升了内存管理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自eygle
从Oracle 9i开始,Shared Pool可以被分割为多个子缓冲池(SubPool)进行管理,以提高并发性,减少竞争Shared Pool的每个SubPool可以被看作是一个Mini Shared Pool,拥有自己独立的Free List、内存结构以及LRU List。同时Oracle提供多个Latch对各个子缓冲池进行管理,从而避免单个Latch的竞争(Shared Pool Reserved Area同样进行分割管理)。SubPool最多可以有7个,Shared Pool Latch也从原来的一个增加到现在的7个。如果系统有4个或4个以上的CPU,并且SHARED_POOL_SIZE大于250MB,Oracle可以把Shared Pool分割为多个子缓冲池(SubPool)进行管理,在Oracle 9i中,每个SubPool至少为128MB。
如果你看到过类似如下信息,那就意味着你可能遇到了SubPool的问题,如下所示:
Tue Dec 11 17:14:49 2007
Errors in file /oracle/app/admin/ctais2/udump/ctais2_ora_778732.trc:
ORA-04031: unable to allocate 4216 bytes of shared memory
("shared pool","IDX_DJ_NSRXX_P_NSRMCCTAIS2","sga heap(2,0)","library cache")
ORA-04031: unable to allocate 4216 bytes of shared memory
("shared pool","IDX_DJ_NSRXX_P_NSRMCCTAIS2","sga heap(2,0)","library cache")
Tue Dec 11 17:14:51 2007
Errors in file /oracle/app/admin/ctais2/bdump/ctais2_pmon_393248.trc:
ORA-04031: unable to allocate 4216 bytes of shared memory
("shared pool","unknown object","sga heap(2,0)","library cache")
Oracle 9i中多个子缓冲池的结构如图所示。

子缓冲池的数量受一个新引入的隐含参数_KGHDSIDX_COUNT影响。可以手工调整该参数(仅限于试验环境研究用),观察共享池管理的变化,可以通过如下步骤转储默认情况以及修改后的Shared Pool,再进行观察:
alter session set events 'immediate trace name heapdump level 2';
alter system set "_kghdsidx_count"=2 scope=spfile;
startup force;
alter session set events 'immediate trace name heapdump level 2';
以下是概要输出,注意在前者的跟踪文件中,sga heap(1,0)指共享池只存在一个子缓冲,后者则存在sga heap(1,0)以及sga heap(2,0)两个子缓冲池:
[oracle@jumper udump]$ grep "sga heap" eygle_ora_25766.trc
HEAP DUMP heap name="sga heap"  desc=0x5000002c
HEAP DUMP heap name="sga heap(1,0)"  desc=0x5001ef0c
[oracle@jumper udump]$ grep "sga heap" eygle_ora_25786.trc
HEAP DUMP heap name="sga heap"  desc=0x5000002c
HEAP DUMP heap name="sga heap(1,0)"  desc=0x5001ef0c
HEAP DUMP heap name="sga heap(2,0)"  desc=0x50023c04
子缓冲池的分配的算法很简单:
l  每个子缓冲池必须满足一定的内存约束条件;
l  每4颗CPU可以分配一个子缓冲池,子缓冲池的数量最多7个。
在Oracle 9i中,每个SubPool容量至少128MB,而在Oracle 10g中,每个子缓冲池至少为256MB。如前所述,SubPool的数量可以通过_kghdsidx_count参数来控制,但是没有参数可以显式地控制SubPool的大小。
根据以上规则,在一个12颗CPU的系统中,如果分配容量为300MB的Shared Pool,Oracle 9i将创建两个SubPool,每个容量大约150MB,如果共享池容量增加到500MB,Oracle将创建3个SubPool,每个大约166MB。
不管Oracle 9i中的128MB以及Oracle10g中的256MB,这样的SubPool在许多复杂的系统中,都可能是过小的,在这些情况下,可能要增大SubPool。可以通过控制Shared Pool大小以及SubPool的数量来改变SubPool的大小。一些Bug以及内部测试表明500MB的SubPool可能会带来更好的性能,所以从Oracle 11g开始,每个SubPool至少为512MB。
除大小控制之外,在Oracle 10g中,Oracle仍然对共享池的管理做出了进一步改进,那就是对单个子缓冲池进行进一步的细分。现在默认,Oracle 10g会将单个缓冲池分割为4个子分区进行管理(这可能是因为通常4颗CPU才分配一个SubPool),使用类似如上的方法在Oracle 10gR2中进行测试:
alter session set events 'immediate trace name heapdump level 2';
alter system set "_kghdsidx_count"=2 scope=spfile;
startup force;
alter session set events 'immediate trace name heapdump level 2';
分析得到的日志,当仅有一个子缓冲池时,Shared Pool被划分为sga heap(1,0)~sga heap(1,3)共4个子分区:
 [oracle@eygle udump]$ grep "sga heap" eygle_ora_13577.trc
HEAP DUMP heap name="sga heap"  desc=0x2000002c
HEAP DUMP heap name="sga heap(1,0)"  desc=0x2001b550
HEAP DUMP heap name="sga heap(1,1)"  desc=0x2001c188
HEAP DUMP heap name="sga heap(1,2)"  desc=0x2001cdc0
HEAP DUMP heap name="sga heap(1,3)"  desc=0x2001d9f8
当使用两个子缓冲池时,Shared Pool则被划分为8个子分区进行管理如下:
 [oracle@eygle udump]$ grep "sga heap" eygle_ora_13618.trc
HEAP DUMP heap name="sga heap"  desc=0x2000002c
HEAP DUMP heap name="sga heap(1,0)"  desc=0x2001b550
HEAP DUMP heap name="sga heap(1,1)"  desc=0x2001c188
HEAP DUMP heap name="sga heap(1,2)"  desc=0x2001cdc0
HEAP DUMP heap name="sga heap(1,3)"  desc=0x2001d9f8
HEAP DUMP heap name="sga heap(2,0)"  desc=0x20020640
HEAP DUMP heap name="sga heap(2,1)"  desc=0x20021278
HEAP DUMP heap name="sga heap(2,2)"  desc=0x20021eb0
HEAP DUMP heap name="sga heap(2,3)"  desc=0x20022ae8
Oracle 10g中多缓冲池结构如图所示。


通过一个内部表X$KGHLU([K]ernel [G]eneric memory [H]eap manager State of [L]R[U] Of Unpinned Recreatable chunks)可以查询这些子缓冲池的分配:
SQL> select addr,indx,kghluidx,kghludur,kghluops,kghlurcr from x$kghlu;
通过这一系列的算法改进,Oracle中Shared Pool管理得以不断增强,较好地解决了大Shared Pool的性能问题;Oracle 8i中,过大Shared Pool设置可能带来的栓锁争用等性能问题在某种程度上得以解决。从Oracle 10g开始,Oracle开始提供自动共享内存管理,使用该特性,用户可以不必显示设置共享内存参数,Oracle会自动进行分配和调整,虽然Oracle为用户提供了极大的便利,但是了解自动化后面的原理对于理解Oracle的运行机制仍然是十分重要的。
虽然多缓冲池技术使Oracle可以管理更大的共享池,但是SubPool的划分可能也会导致各分区之间的协调问题,甚至可能因为内存分散而出现ORA-04031错误。最常见的问题是某个子缓冲池(SubPool)可能出现过度使用,当新的进程仍然被分配到这个SubPool时,可能会导致内存请求失败(而此时其他SubPool可能还有很多内存空间)。
因为子缓冲池存在的种种问题,从Oracle 10g开始,允许内存请求在不同SubPool之间进行切换(Switch),从而提高了请求成功的可能(但是显然切换不可能是无限制的,所以问题仍然可能存在)。


                
电动汽车数据集:2025年3K+记录 真实电动汽车数据:特斯拉、宝马、日产车型,含2025年电池规格和销售数据 关于数据集 电动汽车数据集 这个合成数据集包含许多品牌和年份的电动汽车和插电式车型的记录,捕捉技术规格、性能、定价、制造来源、销售和安全相关属性。每一行代表由vehicle_ID标识的唯一车辆列表。 关键特性 覆盖范围:全球制造商和车型组合,包括纯电动汽车和插电式混合动力汽车。 范围:电池化学成分、容量、续航里程、充电标准和速度、价格、产地、自主水平、排放、安全等级、销售和保修。 时间跨度:模型跨度多年(包括传统和即将推出的)。 数据质量说明: 某些行可能缺少某些字段(空白)。 几个分类字段包含不同的、特定于供应商的值(例如,Charging_Type、Battery_Type)。 各列中的单位混合在一起;注意kWh、km、hr、USD、g/km和额定值。 列 列类型描述示例 Vehicle_ID整数每个车辆记录的唯一标识符。1 制造商分类汽车品牌或OEM。特斯拉 型号类别特定型号名称/变体。型号Y 记录关联的年份整数模型。2024 电池_类型分类使用的电池化学/技术。磷酸铁锂 Battery_Capacity_kWh浮充电池标称容量,单位为千瓦时。75.0 Range_km整数表示充满电后的行驶里程(公里)。505 充电类型主要充电接口或功能。CCS、NACS、CHAdeMO、DCFC、V2G、V2H、V2L Charge_Time_hr浮动充电的大致时间(小时),上下文因充电方法而异。7.5 价格_USD浮动参考车辆价格(美元).85000.00 颜色类别主要外观颜色或饰面。午夜黑 制造国_制造类别车辆制造/组装的国家。美国 Autonomous_Level浮点自动化能力级别(例如0-5),可能包括子级别的小
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值