这是一篇学习Performance Tuning——Tuning the Shared Pool的学习笔记,主要是基本的概念。
共享池体系结构
共享池的基本用途是充当元数据高速缓存。共享池多数是用来支持共享SQL和PL/SQL程序包的执行的。
共享池的主要组件包括:
- 库高速缓存,它将共享的SQL和PL/SQL代码以及对象元数据存储在按名称空间进行区分的各个区域中
- 数据字典高速缓存,它报错数据字典表中的 row images,又称row cache(行高速缓存)
- 结果高速缓存(results cache)保存查询结果集和查询碎片,因此后续查询可直接从该高速缓存中检索结果
共享池中的空间分配由最近最少使用(LRU(least recently used))的算法进行管理。
———————–
共享池操作
通过LRU算法来管理共享池:
- 新对象需要内存分配
- 可重新创建的对象将在高速缓存中到期释放
- 对象由内存块构成
- 内存分配是一个整块
- 块是持续的
- LRU操作有闩锁(latch)或互斥(mutex)进行保护
当新对象需要使用内存时,Oracle数据库服务器就会从共享池中删除可释放的对象。大多数情况下,这些新对象是需要使用库高速缓存中内存的新语句(游标),但也可以是行高速缓存中的数据字典对象以及其它对象。
Oracle DB使用LRU算法确定要删除的对象。服务器进程扫描LRU列表以删除最近最少使用的对象,并检查是否有足够的连续内存以满足请求。如果找不到足够的连续内存,将受到错误ORA-04031;除非已启用自动共享内存管理器(此情况下将请求其它内存区组)。
SQL和PL/SQL语句不要求对整个语句或块使用连续内存。共享池中用来表示SQL语句的内存堆以块为单位进行分配。块不必是连续的,但每个快分配必须是连续的。块大小可以不同,但在可能的情况下,都以1KB或4KB块为单位分配内存,以便创建更统一的内存分配。结果相同类型的对象和块大小是稳定状态下进行分配和到期释放的。此分配方法可减少碎片。实践表明,在大多数情况下,它还可以减少总内存使用量。
共享池LRU扫描和分配是使用闩锁或互斥保护的操作。操作期间的争用表现为闩锁等待和互斥等待。
——————————-
The Library Cache
- 存储与游标(cursors)关联的复杂对象元数据
- 存储供用户共享的SQL语句和PL/SQL块
- 允许游标共享
从优化的角度来看,library cache是共享池最重要的部分。如果library cache得到了适当的优化,则shared pool的其它组件通常都可以高效工作。
与游标关联的复杂对象元数据存储在库高速缓存中。Oracle数据库服务器使用库高速缓存来存储SQL语句和PL/SQL块,以便用户可以共享语句,从而减少分析类似语句的需要。与游标关联的这些类型中的每一种数据都有一个指定给分配的名称(或名称空间)。通过使用此命名可以将内存使用情况显示为某种类型的分配的综合。例如,sqlarea名称空间将显示SQL和PL/SQL可执行代码的所有分配。表/过程和索引名称空间将显示各自对象类型的分配。
实例收集每个名称空间的统计信息。sqlarea名称空间通常是最活跃的区域之一。使用sqlatea名称空间可判断是否适当调整了共享池的大小。
V$LIBRARYCACHE中的每一行都包含保留在库高速缓存中的一类项目的统计信息,这些统计信息按NAMESPACE列的值进行分组。显示的统计信息针对整个名称空间。
表中具有下列 NAMESPACE 值的行反映 SQL 语句和 PL/SQL 块的库高速缓存活动:SQL AREA、TABLE/PROCEDURE、BODY 和 TRIGGER。
具有其它 NAMESPACE 值的行反映服务器用于依赖性维护的对象定义的库高速缓存活动:INDEX、CLUSTER、OBJECT、PIPE、JAVA SOURCE、JAVA RESOURCE 和 JAVA DATA。
与名称空间相关的关键字包括:
- GETS:显示请求有关相应项目的信息的总次数
- PINS:显示执行 SQL 语句或过程的次数
- RELOADS:显示在执行阶段中,包含语句的分析表示的共享 SQL 区域在库高速缓存中到期释放,以腾出空间供其它语句使用的次数。Oracle 服务器隐式重新加载语句并再次对其进行分析。
- INVALIDATIONS:显示由于修改从属对象而已变得无效的语句数。DDL 和针对从属对象收集统计信息是导致无效的原因。无效也会导致重新加载。
———————————————
闩锁(latch)或互斥(mutex)
闩锁是一个内存对象允许:
- -在不产生损坏的情况下共享资源
- -对更新和分配的独占访问
- -对读取的共享访问
互斥对象允许:
- -在不产生损坏的情况下共享资源
- -对读取的共享访问
- -对更新的独占访问
- -每个对象都有自己的互斥
闩锁和互斥执行相同的功能,用于在多个进程访问资源时防止资源受到损坏。闩锁是一种廉价锁。单个闩锁通常保护SGA中的多个对象。互斥是“互斥对象”的简写形式。与闩锁类似,互斥是一种低级串行化机制,用来控制对SGA中共享数据结构的访问。需要进行串行化以免对象出现以下情况:
- 有人正在访问对象的同时,他人对该对象取消分配
- 有人正在修改对象的同时,他人对该对象进行读取
- 有人正在修改对象的同时,他人对该对象进行修改
- 有人正在读取对象的同时,他人对该对象进行修改
闩锁和互斥都是serialization mechanisms(串行化机制)
互斥是一个更快、更多的扩展途径来管理library cache当允许更多的颗粒监视。
注意:闩锁和互斥是独立的机制。也就是说,进程可以同时持有闩锁和互斥。
互斥的优点:
- 产生假争用的可能性较小:闩锁通常保护多个对象。在闩锁保护一个或多个热对象的时候,当访问由该闩锁保护的任何对象时,闩锁本身就会变成一个串行化点。这可能是一个假争用点,在此处争用的目标是保护机制(即闩锁),而不是尝试访问的目标对象。与闩锁不同,使用互斥可以为每个受保护的结构创建一个互斥。这意味着产生假争用的可能性将大大降低,因为每个结构都可以由自己的互斥进行保护。
- 可替换闩锁和pin:如果所有会话都以S(共享)模式引用互斥,则许多会话可以并行引用互斥。以S模式引用互斥的会话总数称为引用计数。互斥的引用计数将存储在互斥本身中。互斥也可以仅由一个会话以X(独占)模式持有。
互斥有双重性质,它们既可以充当串行化机制(例如闩锁),又可以充当pin(例如,防止对象到期释放)。例如,互斥的引用计数可以替代库高速缓存pin。在执行游标时,每个会话并不先创建一个库高速缓存pin,然后再删除一个库高速缓存pin,而是递增和递减引用计数(因此引用技术可替代n个不同的pin)。
————————————————
闩锁和互斥:视图和统计信息
闩锁视图:
- V$LATCH
- V$LATCH_MISSES
- V$LATCH_PARENT
- V$LATCH_CHILDREN
- V$LATCHHOLDER
- V$LATCHNAME
闩锁等待事件:
- latch: latchname
互斥视图:
- V$MUTEX_SLEEP
- V$MUTEX_SLEEP_HISTORY
互斥等待事件:
- cursor:mutex X
- cursor:mutex S
- cursor:pin X
- cursor:pin S
- cursor:pin S wait on X
闩锁和互斥等待事件用作指出特定问题的诊断信息。在共享池中,许多闩锁操作已由互斥替代。与闩锁相比,互斥操作的速度更快而且具有更少的争用,但它们仍有与其相关联的等待。
当顶级等待事件包括闩锁等待时,以上视图将提供更多详细资料。这些视图是 Statspack 和 AWR 报表闩锁部分的基础。
V$LATCH 显示按闩锁名称分组的闩锁等待的汇总。一个闩锁可具有多个同名子闩锁。
V$LATCH_MISSES 显示有关获得闩锁的失败尝试的统计信息。
与共享池有关的两个常见闩锁等待事件为:
- 闩锁:共享池 – 保护共享池内存分配
- 闩锁:行高速缓存对象 – 保护对数据字典高速缓存的访问和更新
可在以下 V$ 视图中查看与互斥有关的等待和休眠的详细资料:
V$MUTEX_SLEEP 显示特定 mutex_type/location 组合的休眠和等待时间的概要。
当特定 mutex_type/location 组合由特定持有会话持有时,V$MUTEX_SLEEP_HISTORY 将按时间显示针对该组合休眠的会话。
互斥等待事件有两个类别:
- cursor:mutex 是对父游标操作和统计信息操作的会话等待,其中互斥由处于不相容模式的另一个会话所持有。
- cursor:pin 事件是对游标 pin 操作的等待,其中互斥已替代了 latch:library cache pin。
互斥等待事件有两种类型:
- 很少出现的短期事件。当一个进程尝试在另一个进程正在对互斥进行更改时更新该互斥,则会出现这些事件。在等待互斥变为可用期间,等待进程将延长而不是休眠。例如,当其它进程正在更新某个共享游标的引用计数 (pin) 时,cursor:pin S 就会递增。
- 当某个进程必须等待其它进程完成其操作时,就会出现长期事件。例如,如果某个进程希望进行独占访问,但互斥由其它进程独占持有或共享,cursor:mutex X 就会递增。
————————————————————————
用于优化共享池的诊断工具
V$SGASTATS 或 V$SGAINFO 视图显示所有 SGA 结构的大小。V$SGASTATS 更详细地显示共享池的各个片断。V$SGAINFO 提供 SGA 组件的概要信息,其中包括区组大小以及 max_memory 大小。
只要共享池中有可用的空闲内存,共享池的内容就不会到期释放。使用下列动态视图可以诊断与库高速缓存相关的性能问题:
- V$LIBRARYCACHE:有关库高速缓存管理的统计信息
- V$LIBRARY_CACHE_MEMORY:有关每个名称空间使用的内存的统计信息
- V$SQLAREA:有关所有共享游标的完整统计信息。其中包括为确保向后兼容的 SQL 语句中的前 1000 个字符以及作为 CLOB 的完整 SQL 语句。
- V$SQL:有关共享 SQL 区域的统计信息,所输入的原始 SQL 文本的每个子级都对应一行。V$SQL 视图是类似于 V$SQLAREA 的视图,但前者不包含 GROUP BY 子句,该子句会使查询 V$SQLAREA 视图的成本变得很高。
- V$SQLSTAT:可代替其它 V$SQL* 视图使用的低影响视图。
- V$SQLTEXT:以多行显示的没有截断的完整 SQL 文本。
- V$SQLTEXT_WITH_NEWLINES:与 V$SQLTEXT 视图等效,只有一点例外:为了提高可读性,V$SQLTEXT_WITH_NEWLINES 没有用空格替代 SQL 语句中的换行符和制表符
- V$DB_OBJECT_CACHE:高速缓存的数据库对象,包括程序包,以及表和同义词等对象,SQL 语句会引用这些对象
这些视图保存了原始信息,格式化后的信息供 AWR 和 Statspack 报表使用。Statspack 和 AWR 报表使用这些视图,还包含获取其中任何一个快照时在库高速缓存中找到的 SQL 语句的相关信息。