
好的,我们将聚焦于 Oracle 共享池中两个关键的内存块类型——freeable 和 recr,以及管理它们生命周期的核心机制——LRU 链表。这部分内容是理解共享池如何高效运作和进行深度调优的关键。
1. 核心概念:recr 与 freeable Chunks
在共享池中,Chunk 的类型定义了它的行为和生命周期。recr 和 freeable 是两种最重要的“可释放”类型。
官方/专业解释
-
recr(Recreatable) Chunks:- 定义: 这是共享池中最主要的 Chunk 类型。它用于存储那些可以被自动重建的库缓存(Library Cache)对象。
- 存储内容: SQL 语句的解析树、执行计划、PL/SQL 包的代码等。
- 核心特性: 如果内存不足,这些 Chunk 可以被 aged out(老化移出)。之后如果需要,可以通过重新解析 SQL 或重新加载包来完全重建它们的内容。其生命周期由 LRU 算法严格管理。
-
freeableChunks:- 定义: 一种特殊的、状态介于“已分配”和“完全空闲”之间的 Chunk。它当前已被某个会话或操作占用,但 Oracle 知道可以在必要时(内存压力下)将其状态更改为
free。 - 存储内容: 通常与会话的私有信息或某些中间状态相关。例如,一个会话的 PGA 中的某些结构可能会在共享池中分配一个
freeablechunk 作为临时映射。 - 核心特性: 它不像
recr块那样有严格的重建路径,但其释放的“成本”比recr块更低。内存管理器在需要空间时,会优先尝试释放freeable块,然后再去 aged outrecr块。
- 定义: 一种特殊的、状态介于“已分配”和“完全空闲”之间的 Chunk。它当前已被某个会话或操作占用,但 Oracle 知道可以在必要时(内存压力下)将其状态更改为
通俗解释
让我们回到**“教研室”和“自助仓储中心”**的比喻:
-
recrChunks (可重建块):- 就像教研室里装着“教案”的文件夹。教案是老师根据教科书(SQL 文本)和教学大纲(数据字典)编写出来的。
- 关键点: 如果教研室空间不够,管理员可以把教案扔掉(aged out)。下次要上课时,老师只需要拿着教科书重新写一份就行了(重新解析)。虽然费点时间(硬解析性能开销),但知识没有丢失。
-
freeableChunks (可释放块):- 就像教研室里老师自己带来的一个临时收纳箱,里面放了些个人教学工具。这个箱子目前正在被使用。
- 关键点: 如果教研室空间紧张,管理员可以请老师先把他的收纳箱拿回家去(释放为
free)。这不会破坏任何教案(不需要重建),只是让老师暂时不方便。等空间充裕时,老师可以再把它拿回来。释放它的“代价”比让老师重写一份教案要小。
总结区别:
recr块的内容是可重建的知识,扔掉后需要“重新思考”才能恢复。freeable块的内容是可移动的实物,拿走后再拿回来即可,不需要“重新思考”。
2. 原理:LRU 链表与老化机制 (Aging)
recr 块的生命周期由一个类似于 Buffer Cache 但更复杂的 LRU(Least Recently Used)算法管理。
官方/专业解释
-
LRU 链表结构:
- 库缓存中的
recr对象(如 SQL 游标)的 Chunk 被组织在一个或多个 LRU 链表上。 - 链表有一个 MRU(Most Recently Used)端 和一个 LRU 端。
- 当一个 Chunk 被访问时(例如,一个 SQL 语句被再次执行),它会被“触摸”(touched),并有机会被移动到更靠近 MRU 端的位置。
- 库缓存中的
-
老化机制 (Aging):
- 每个
recr对象都有一个关联的使用计数(Use Count) 和一个时间戳。 - 当内存管理器需要为新的分配请求寻找空间时,它会扫描 LRU 链表(从 LRU 端开始),寻找可以释放的候选对象。
- 对象的“年龄”是其未被访问的时间长度以及其使用计数的函数。一个很长时间没人用、且使用计数低的对象会被优先 aged out。
- 这个过程是增量式的,持续发生在数据库运行过程中,以避免在内存耗尽时进行大规模的紧急清理。
- 每个
-
freeable块的释放:freeable块通常不通过严格的 LRU 链表管理。当内存管理器需要空间时,它会直接检查并尝试释放这些块,因为它们释放的代价更低,且不需要“重建”。
通俗解释
想象教研室有一个 “教案使用热度排行榜”(LRU 链表)。
- MRU 端(最近使用): 排行榜顶端是最近刚被使用过的教案(例如,今天刚上完的课的教案)。
- LRU 端(最近最少使用): 排行榜底端是很久没人用的教案(例如,上个学期某一门课的教案)。
管理规则(老化机制):
- 每当一个老师用了某份教案,这份教案就会被拿到排行榜顶端。
- 教研室空间总是有限的。当有新教案需要放入时,管理员就会去排行榜底端查看。
- 他会把那些放在最底下、积满了灰尘的教案(
recrchunks)找出来,直接扔掉(aged out),腾出空间放新教案。 - 在扔底部的旧教案之前,管理员可能会先看看有没有老师可以把临时收纳箱(
freeablechunks) 先带回家,这是一个更温和的腾空间方式。
这个“排行榜”机制确保了常用的教案总是触手可及(缓存在内存中,实现软解析),而不常用的教案会被自动清理,从而最高效地利用有限的教研室空间。
3. 相关查询与管理 SQL 命令
查询 1:查看 recr 和 freeable 块的整体情况
这是最关键的诊断查询,直接查看 x$ksmsp 底层视图。
SELECT
KSMCHCLS AS chunk_type,
COUNT(*) AS number_of_chunks,
ROUND(SUM(KSMCHSIZ) / 1024 / 1024, 2) total_size_mb,
ROUND(MIN(KSMCHSIZ) / 1024, 2) min_size_kb,
ROUND(MAX(KSMCHSIZ) / 1024, 2) max_size_kb,
ROUND(AVG(KSMCHSIZ) / 1024, 2) avg_size_kb
FROM x$ksmsp
WHERE KSMCHCLS IN ('recr', 'freeable')
GROUP BY KSMCHCLS
ORDER BY total_size_mb DESC;
结果分析:
- 如果
recr的number_of_chunks极多且avg_size_kb很小,可能意味着应用程序没有使用绑定变量,产生了大量微小的、不同的 SQL 语句,导致共享池碎片化和管理开销增大。 freeable的大小通常远小于recr。
查询 2:查看哪些对象占用了最多的 recr 空间
-- 注意:此查询代价较高,谨慎在生产环境使用
SELECT KSMCHCOM AS component,
COUNT(*) AS chunks,
ROUND(SUM(KSMCHSIZ) / 1024 / 1024, 2) size_mb
FROM x$ksmsp
WHERE KSMCHCLS = 'recr'
GROUP BY KSMCHCOM
HAVING SUM(KSMCHSIZ) > 1 * 1024 * 1024 -- 大于1MB
ORDER BY size_mb DESC;
如果发现 sql area 占用了绝大部分空间,就需要检查应用是否使用了绑定变量。
查询 3:监控库缓存的活动与老化(宏观视图)
虽然不直接显示 LRU 链表,但 V$LIBRARYCACHE 视图反映了其最终结果。
SELECT namespace,
gets, -- 查找请求次数
gethits, -- 命中次数(在内存中找到)
gethitratio, -- 命中率 (>95% 通常表示健康)
pins, -- 执行次数
pinhitratio,
reloads, -- 失效后重新加载的次数(即被aged out后又被解析)
invalidations
FROM v$librarycache
ORDER BY gets DESC;
关键指标:
reloads: 这个值如果很高,直接表明 LRU 老化机制正在频繁工作。对象被 aged out 后不久又被需要,导致不得不进行硬解析。这是共享池压力过大或大小不合适的明确信号。gethitratio: 命中率低也意味着很多对象不在内存中,同样指示压力。
管理命令与优化建议
-
解决高
reloads/ 低命中率:- 首要优化: 确保应用程序使用绑定变量。这是减少
recr块数量、增大其平均尺寸、降低碎片化最有效的方法。 - 增加共享池大小: 如果确实需要缓存大量不同的对象。
ALTER SYSTEM SET shared_pool_size = 2G; - 固定关键对象: 对于重要的、频繁使用的大包,将其钉在内存中,防止被老化。
EXEC DBMS_SHARED_POOL.KEEP('APP_MAIN_PKG', 'P');
- 首要优化: 确保应用程序使用绑定变量。这是减少
-
刷新共享池(最后手段):
ALTER SYSTEM FLUSH SHARED_POOL;这会清除所有
recr和freeable对象,强制所有后续 SQL 进行硬解析。仅在确认共享池出现严重错误或碎片化且其他方法无效时使用,因为会导致短期性能骤降。 -
监控与预警:
- 定期监控
V$LIBRARYCACHE的reloads和gethitratio。 - 设置预警,当
reloads在短时间内急剧增加或命中率跌破阈值时通知 DBA。
- 定期监控
通过理解 recr 和 freeable 块的行为以及背后的 LRU 老化原理,你可以将共享池的监控从“黑盒”状态变为“白盒”状态,能够精准地预测、诊断和解决与之相关的性能问题,从而确保数据库的稳定和高性能运行。
欢迎关注我的公众号《IT小Chen》
429

被折叠的 条评论
为什么被折叠?



