1.1.4.7.共享池的重要视图
最后,我们再介绍关于共享池的一些重要视图
·v$shared_pool_advice
这个视图与Oracle的另外一个优化建议器——共享池建议器——相关。我们可以根据这个视图里面oracle所做的预测数据来调整共享池大小。它的预测范围是从当前值的10%到200%之间。视图的结构如下
字段 |
数据类型 |
描述 |
SHARED_POOL_SIZE_FOR_ESTIMATE |
NUMBER |
估算的共享池大小(M为单位) |
SHARED_POOL_SIZE_FACTOR |
NUMBER |
估算的共享池大小与当前大小比 |
ESTD_LC_SIZE |
NUMBER |
估算共享池中用于库缓存的大小(M为单位) |
ESTD_LC_MEMORY_OBJECTS |
NUMBER |
估算共享池中库缓存的内存对象数 |
ESTD_LC_TIME_SAVED |
NUMBER |
估算将可以节省的解析时间。这些节省的时间来自于请求处理一个对象时,重新将它载入共享池的时间消耗和直接从库缓存中读取的时间消耗的差值。 |
ESTD_LC_TIME_SAVED_FACTOR |
NUMBER |
估算的节省的解析时间与当前节省解析时间的 比。 |
ESTD_LC_MEMORY_OBJECT_HITS |
NUMBER |
估算的可以直接从共享池中命中库缓存的内存 对象的命中次数。 |
关于如何根据建议器采用合理的共享池大小的方 法,和前面提到的缓冲区建议器的使用方法类似,不再赘述。
·V$SHARED_POOL_RESERVED
前面提到了这个视图。这个视图存放了共享池保留 区的统计信息。可以根据这些信息来调整保留区。视图结构如下:
Column |
Datatype |
Description |
以下字段只有当参数SHARED_POOL_RESERVED_SIZE设置了才有效。 |
||
FREE_SPACE |
NUMBER |
保留区的空闲空间数。 |
AVG_FREE_SIZE |
NUMBER |
保留区的空闲空间平均数。 |
FREE_COUNT |
NUMBER |
保留区的空闲内存块数 |
MAX_FREE_SIZE |
NUMBER |
最大的保留区空闲空间数。 |
USED_SPACE |
NUMBER |
保留区使用空间数。 |
AVG_USED_SIZE |
NUMBER |
保留区使用空间平均数。 |
USED_COUNT |
NUMBER |
保留区使用内存块数。 |
MAX_USED_SIZE |
NUMBER |
最大保留区使用空间数 |
REQUESTS |
NUMBER |
请求再保留区查找空闲内存块的次数。 |
REQUEST_MISSES |
NUMBER |
无法满足查找保留区空闲内存块请求,需要从LRU列表中清出对象的次数。 |
LAST_MISS_SIZE |
NUMBER |
请求的内存大小,这次请求是最后一次需要从LRU列表清出对象来满足的请求。 |
MAX_MISS_SIZE |
NUMBER |
所有需要从LRU列表清出对象来满足的请求中的内存最大大小 |
以下字段无论参数SHARED_POOL_RESERVED_SIZE是否设置了都有效。 |
||
REQUEST_FAILURES |
NUMBER |
|
LAST_FAILURE_SIZE |
NUMBER |
|
ABORTED_REQUEST_THRESHOLD |
NUMBER |
|
ABORTED_REQUESTS |
NUMBER |
|
LAST_ABORTED_SIZE |
NUMBER |
我们可以根据后面4个字段值来决定如何设置保留区的大小以避免4031错 误的发生。
·v$db_object_cache
这一视图显示了所有被缓存在library cache中的对象,包括表、索引、簇、同义词、PL/sql存 储过程和包以及触发器。
字段 |
数据类型 |
说明 |
OWNER |
VARCHAR2(64) |
对象所有者 |
NAME |
VARCHAR2(1000) |
对象名称 |
DB_LINK |
VARCHAR2(64) |
如果对象存在db link的话,db link的名称 |
NAMESPACE |
VARCHAR2(28) |
库缓存的对象命名空间,包括:TABLE/PROCEDURE,BODY,TRIGGER,INDEX,CLUSTER,OBJECT,CURSOR,INVALID NAMESPACE,JAVA SHARED DATA,PUB_SUB,RSRC CONSUMER GROUP |
TYPE |
VARCHAR2(28) |
对象类型,包括:INDEX,TABLE,VIEW,SET,SYNONYM,SEQUENCE,PROCEDURE,FUNCTION,PACKAGE,PACKAGE BODY,CLASS,USER,DBLINK,JAVA CLASS,NON-EXISTENT,NOT LOADED,REPLICATION OBJECT GROUP,TYPE |
SHARABLE_MEM |
NUMBER |
对象消耗的共享池中的共享内存 |
LOADS |
NUMBER |
对象被载入次数。即使对象被置为无效了,这 个数字还是会增长。 |
EXECUTIONS |
NUMBER |
|
LOCKS |
NUMBER |
|
PINS |
NUMBER |
当前pin住 这个对象的用户数(如正在编译、解析对象)。 |
KEPT |
VARCHAR2(3) |
对象是否被保持,即调用了DBMS_SHARED_POOL.KEEP来永久将对象pin在 内存中。 (YES | NO) |
CHILD_LATCH |
NUMBER |
正在保护该对象的子latch的数量。 |
这三个视图都可以用于查询共享池中已经解析过的sql语句及其相关信息。
V$sql中列出了共享sql区 中所有语句的信息,它不包含GROUP BY字句,并且为每一条sql语句中单独存放一条记录;
V$sqlAREA中一条记录显示了一条共享sql区中的统计信息。它提供了有在内存中、解析过的和准备运行的sql语 句的统计信息;
V$sqlTEXT包含了库缓存中所有共享游标对应的sql语句。它将sql语句分片显示。
下面介绍一下我常用的V$sqlAREA的结构:
字段 |
数据类型 |
说明 |
sql_TEXT |
VARCHAR2(1000) |
游标中sql语句的前1000个字符。 |
SHARABLE_MEM |
NUMBER |
被游标占用的共享内存大小。如果存在多个子 游标,则包含所有子游标占用的共享内存大小。 |
PERSISTENT_MEM |
NUMBER |
用于一个打开这条语句的游标的生命过程中的 固定内存大小。如果存在多个子游标,则包含所有子游标生命过程中的固定内存大小。 |
RUNTIME_MEM |
NUMBER |
一个打开这条语句的游标的执行过程中的固定 内存大小。如果存在多个子游标,则包含所有子游标执行过程中的固定内存大小。 |
SORTS |
NUMBER |
所有子游标执行语句所导致的排序次数。 |
VERSION_COUNT |
NUMBER |
缓存中关联这条语句的子游标数。 |
LOADED_VERSIONS |
NUMBER |
缓存中载入了这条语句上下文堆(KGL heap 6)的子游标数。 |
OPEN_VERSIONS |
NUMBER |
打开语句的子游标数。 |
USERS_opening |
NUMBER |
打开这些子游标的用户数。 |
FETCHES |
NUMBER |
sql语句的fetch数。 |
EXECUTIONS |
NUMBER |
所有子游标的执行这条语句次数。 |
USERS_EXECUTING |
NUMBER |
通过子游标执行这条语句的用户数。 |
LOADS |
NUMBER |
语句被载入和重载入的次数 |
FIRST_LOAD_TIME |
VARCHAR2(19) |
语句被第一次载入的时间戳。 |
INVALIDATIONS |
NUMBER |
所以子游标的非法次数。 |
PARSE_CALLS |
NUMBER |
|
DISK_READS |
NUMBER |
所有子游标运行这条语句导致的读磁盘次数。 |
BUFFER_GETS |
NUMBER |
所有子游标运行这条语句导致的读内存次数。 |
ROWS_PROCESSED |
NUMBER |
这条语句处理的总记录行数。 |
COMMAND_TYPE |
NUMBER |
Oracle命令类型代号。 |
OPTIMIZER_MODE |
VARCHAR2(10) |
执行这条的优化器模型。 |
PARSING_USER_ID |
NUMBER |
第一次解析这条语句的用户的ID。 |
PARSING_SCHEMA_ID |
NUMBER |
第一次解析这条语句所用的schema的ID。 |
KEPT_VERSIONS |
NUMBER |
所有被DBMS_SHARED_POOL包标识为保持(Keep) 状态的子游标数。 |
ADDRESS |
RAW(4 | 8) |
指向语句的地址 |
HASH_VALUE |
NUMBER |
这条语句在library cache中hash值。 |
MODULE |
VARCHAR2(64) |
|
MODULE_HASH |
NUMBER |
模块的Hash值 |
ACTION |
VARCHAR2(64) |
|
ACTION_HASH |
NUMBER |
动作的Hash值 |
SERIALIZABLE_ABORTS |
NUMBER |
|
IS_OBSOLETE |
VARCHAR2(1) |
游标是否被废除(Y或N)。当子游标数太多了时可能会发生。 |
CHILD_LATCH |
NUMBER |
为了包含此游标的子latch数。 |
查看当前会话所执行的语句以及会话相关信息:
sql> select a.sid||'.'||a.SERIAL#,a.username,a.TERMINAL,a.program,s.sql_text
2 from v$session a,v$sqlarea s
3 where a.sql_address = s.address(+)
4 and a.sql_hash_value = s.hash_value(+)
5 order by a.username,a.sid;
... ...
sql>
·v$sql_plan
视图V$sql_PLAN包 含了library cache中所有游标的执行计划。通过结合v$sqlarea可以查出library cache中所有语句的查询计划。先从v$sqlarea中得到语句的地址,然 后在由v$sql_plan查出它的查询计划:
sql> select lpad(' ',2*(level-1))||operation "Operation",
2 options "Options",
3 decode(to_char(id),'0','Cost='||nvl(to_char(position),'n/a'),object_name) "Object Name",
4 substr(optimizer,1,6) "Optimizer"
5 from v$sql_plan a
6 start with address = 'C0000000FCCDEDA0'
7 and id = 0
8 connect by prior id = a.parent_id
9 and prior a.address = a.address
10 and prior a.hash_value = a.hash_value;
Operation Options Object Name Optimizer
------------------- -------------------- -------------------- ---------
SELECT STATEMENT Cost=0 CHOOSE
NESTED LOOPS
INDEX RANGE SCAN CSS_BL_CNTR_IDX1 ANALYZ
INDEX RANGE SCAN CSS_BKG_BL_ASSN_UQ1 ANALYZ
sql>
·v$librarycache
这个视图包含了关于library cache的性能统计信息,对于共享池的性能调优很有帮助。它是按照命名空间分组统计的,结构 如下:
字段 |
数据类型 |
说明 |
NAMESPACE |
VARCHAR2(15) |
library cache的命名空间 |
GETS |
NUMBER |
请求GET该 命名空间中对象的次数。 |
GETHITS |
NUMBER |
请求GET并 在内存中找到了对象句柄的次数(锁定命中)。 |
GETHITRATIO |
NUMBER |
请求GET的 命中率。 |
PINS |
NUMBER |
请求pin住 该命名中对象的次数。 |
PINHITS |
NUMBER |
库对象的所有元数据在内存中被找到的次数(pin命中)。 |
PINHITRATIO |
NUMBER |
Pin命中率。 |
RELOADS |
NUMBER |
Pin请求需要从磁盘中载入对象的次数。 |
INVALIDATIONS |
NUMBER |
命名空间中的非法对象(由于依赖的对象被修 改所导致)数。 |
DLM_LOCK_REQUESTS |
NUMBER |
GET请求导致的实例锁的数量。 |
DLM_PIN_REQUESTS |
NUMBER |
PIN请求导致的实例锁的数量. |
DLM_PIN_RELEASES |
NUMBER |
请求释放PIN锁的次数。 |
DLM_INVALIDATION_REQUESTS |
NUMBER |
GET请求非法实例锁的次数。 |
DLM_INVALIDATIONS |
NUMBER |
从其他实例那的得到的非法pin数。 |
其中PIN的 命中率(或未命中率)是我们系统调优的一个重要依据:
sql> select sum(pins) "hits",
2 sum(reloads) "misses",
3 sum(pins)/(sum(pins)+sum(reloads)) "Hits Ratio"
4 from v$librarycache;
hits misses Hits Ratio
---------- ---------- ----------
84962803 288 0.99999661
sql>
sql> select sum(pins) "hits",
3 ((sum(reloads)/sum(pins))*100) "Reload%"
4 from v$librarycache;
hits misses Reload%
---------- ---------- ----------
84963808 288 0.00033896
sql>
当命中率小于99%或未命中率大于1%时,说明系统中硬解析过多,要 做系统优化(增加Shared Pool、使用绑定变量、修改cursor_sharing等措施,性能优化不 是本文重点,不再赘述)。
·v$library_cache_memory
这个视图显示了各个命名空间中的库缓存内存对象的内存分配情况。一个内存对象是为了高效管理而组织在一起的一组内部内存。一个库对象可能包含多个内存对 象。
字段 |
数据类型 |
说明 |
LC_NAMESPACE |
VARCHAR2(15) |
Library cache命名空间 |
LC_INUSE_MEMORY_OBJECTS |
NUMBER |
属于命名空间并正被在共享池使用的内存对象 数。 |
LC_INUSE_MEMORY_SIZE |
NUMBER |
正在使用的内存对象的大小总(M未单位)。 |
LC_FREEABLE_MEMORY_OBJECTS |
NUMBER |
共享池中空闲的内存对象数。 |
LC_FREEABLE_MEMORY_SIZE |
NUMBER |
空闲内存对象的大小总和(M为单位)。 |
·v$sgastat
这个视图前面介绍过,是关于SGA使用情况的统计。其中,关于Shared Pool有详细的统计数据。
1.1.5.重做日志缓存(Redo Log Buffer)
Redo Log Buffer是SGA中一段保存数据库修改信息的缓存。这些信息被存储在重做条目(Redo Entry)中.重做条目中包含了由于INSERT、UPDATE、DELETE、CREATE、ALTER或DROP所做的修改操作而需要对数据库重新组织或重做的必须信息。在必要时,重做条目还可以用于数据库恢复。
重做条目是Oracle数据库进程从用户内存中拷贝到Redo Log Buffer中去的。重做条目在内存中是连续相连的。后台进程LGWR负 责将Redo Log Buffer中的信息写入到磁盘上活动的重做日志文件(Redo Log File) 或文件组中去的。
参数LOG_BUFFER决 定了Redo Log Buffer的大小。它的默认值是512K(一般这个大小都是足够 的),最大可以到4G。当系统中存在很多的大事务或者事务数量非常多时,可能会导致日志文件IO增加,降低性能。这时就可以考虑增加LOG_BUFFER。
但是,Redo Log Buffer的实际大小并不是LOB_BUFFER的设定大小。为了保护Redo Log Buffer,oracle为它增加了保护页(一般为11K):
sql> select * from v$sgastat where name = 'log_buffer';
POOL NAME BYTES
------------ -------------------------- ----------
log_buffer 7139328
1 row selected.
sql> show parameter log_buffer
NAME TYPE VALUE
------------------------------------ ----------- -------------------
log_buffer integer 7028736
sql>
1.1.6.大池(large pool)
大池是SGA中 的一块可选内存池,根据需要时配置。在以下情况下需要配置大池:
o用于共享服务(Shared Server MTS方式中)的会话内存和Oracle分布式事务处理的Oracle XA接口
o使用并行查询(Parallel Query Option PQO)时
oIO服务进程
oOracle备份和恢复操作(启用了RMAN时)
通过从大池中分配会话内存给共享服务、Oracle XA或并行查询,oracle可以使用 共享池主要来缓存共享sql,以防止由于共享sql缓 存收缩导致的性能消耗。此外,为Oracle备份和恢复操作、IO服务进程和并行查询分配的内存一般都是几百K,这么 大的内存段从大池比从共享池更容易分配得到(所以叫“大”池嘛^_^)。
参数LARGE_POOL_SIZE设 置大池的大小。大池是属于SGA的可变区(Variable Area)的,它不属于共享池。对于大池的访问,是受到large memory latch保 护的。大池中只有两种内存段:空闲(free)和可空闲(freeable) 内存段(关于不同类型内存段我们在后面介绍)。它没有可重建(recreatable)内存段,因 此也不用LRU链表来管理(这和其他内存区的管理不同)。大池最大大小为4G。
为了防止大池中产生碎片,隐含参数_LARGE_POOL_MIN_ALLOC设置了大池中内存段的最小大小,默认值是16K(同样,不建议修改隐含参数)。
此外,large pool是没有LRU链表的。
1.1.7.Java池(Java Pool)
Java池也是SGA中 的一块可选内存区,它也属于SGA中的可变区。
Java池的内存是用于存储所有会话中特定Java代码和JVM中数据。Java池的使用方式依赖与Oracle服务的运行模 式。
Java池的大小由参数JAVA_POOL_SIZE设 置。Java Pool最大可到1G。
在Oracle 10g以后,提供了一个新的建议器——Java池建议器——来辅助DBA调整Java池大小。建议器的统计数据可以通过视 图V$JAVA_POOL_ADVICE来查询。如何借助建议器调整Java池的方法和使用Buffer Cache建议器类似,可以参考Buffer Cache中关于建议器部分。
1.1.8.流池(Streams Pool)
流池是Oracle 10g中新增加的。是为了增加对流(流复制是Oracle 9iR2中引入的一个非常吸引人的特性,支持异构数据库之间的复制。10g中得 到了完善)的支持。
流池也是可选内存区,属于SGA中的可变区。它的大小可以通过参数STREAMS_POOL_SIZE来 指定。如果没有被指定,oracle会在第一次使用流时自动创建。如果设置了SGA_TARGET参数,Oracle会从SGA中分配内存给流池;如果没有指定SGA_TARGET, 则从buffer cache中转换一部分内存过来给流池。转换的大小是共享池大小的10%。
Oracle同样为流池提供了一个建议器——流池建议器。建议器的统计数据 可以通过视图V$STREAMS_POOL_ADVICE查询。使用方法参看Buffer Cache中关于优化器部分。