Oracle内存全面分析 3

前端之家收集整理的这篇文章主要介绍了Oracle内存全面分析 3前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1.1.3.3.Buffer Cache的重要视图

关于Buffer Cache,oracle提供一些重要视图,用于查询关于Buffer Cache的重要信息,为调整Buffer Cache、提高性能提供参考。下 面一一介绍它们

·v$db_cache_advice

上面我们提到了Oracle的建议器,其中有一个针对Buffer Cache的建议器。在我们设置了参数db_cache_advice为TRUE后,经过一段时间的系统运行,Oracle收 集到相关统计数据,并根据一定的数学模型,预测出DB_CACHE_SIZE在不同大小情况的性能 数据。我们就可以由视图V$DB_CACHE_ADVICE查出这些数据,并根据这些数据调整DB_CACHE_SZIE,使系统性能最优。

下面是关于这个视图的结构描述:

字段

数据类型

描述

ID

NUMBER

缓冲池标识号(从1到8,1-6对 应于DB_nK_CACHE_SIZE,DB_CACHE_SIZE与 系统标准块尺寸的序号相关,如DB_BLOCK_SIZE为8K, 则DB_CACHE_SIZE的标识号为3(2,4,8…)。7是DB_KEEP_CACHE_SIZE,8是DB_RECYCLE_CACHE_SIZE)

NAME

VARCHAR2(20)

缓冲池名称

BLOCK_SIZE

缓冲池块尺寸(字节为单位)

ADVICE_STATUS

VARCHAR2(3)

建议器状态:ON表示建议器在运行;OFF表示建议器已经关闭。当建 议器关闭了,视图中的数据是上一次打开所统计得出的。

SIZE_FOR_ESTIMATE

预测性能数据的Cache大小(M为单位)

SIZE_FACTOR

预测的Cache大小因子(即与当前大小的比例)

BUFFERS_FOR_ESTIMATE

预测性能数据的Cache大小(缓冲块数)

ESTD_PHYSICAL_READ_FACTOR

这一缓冲大小时,物理读因子,它是如果缓冲 大小为SIZE_FOR_ESTIMATE时,建议器预测物理读数与当前实际物理读数的比率值。如 果当前物理读数为0,这个值为空。

ESTD_PHYSICAL_READS

如果缓冲大小为SIZE_FOR_ESTIMATE时,建议器预测物理读数。

下面是从这个视图中查询出来的数据:

sql> select size_for_estimate,estd_physical_read_factor,estd_physical_reads
 2 from v$db_cache_advice
 3 where name = 'DEFAULT';
 
SIZE_FOR_ESTIMATE ESTD_PHYSICAL_READ_FACTOR ESTD_PHYSICAL_READS
----------------- ------------------------- -------------------
 16 2.0176 6514226
 32 1.7403 5619048
 48 1.5232 4917909
 64 1.3528 4367839
 80 1.2698 4099816
 96 1.1933 3852847
 112 1.1443 3694709
 128 1.1007 3553685
 144 1.0694 3452805
 160 1.0416 3362964
 176 1.0175 3285085
 192 1 3228693
 208 0.9802 3164754
 224 0.9632 3109920
 240 0.9395 3033427
 256 0.8383 2706631
 272 0.7363 2377209
 288 0.682 2202116
 304 0.6714 2167888
 320 0.6516 2103876
 
20 rows selected

当前我们的DB_CACHE_SIZE为192M,可以看到,它的 物理读因子为1,物理读数为3228693。 那么如何根据这些数据调整DB_CACHE_SIZE呢?给出一个方法,找到变化率较平缓的点作为 采用值。因为建议器做预测是,DB_CACHE_SIZE的预测值的增长步长是相同的,是16M。我们按照这一步长增加DB_CACHE_SIZE, 如果每次增加物理读降低都很明显,就可以继续增加,直到物理读降低不明显,说明继续增加DB_CACHE_SIZE没 有太大作用。当然,性能和可用资源是天平的两端,你需要根据自己系统的实际情况调整。

上面的例子中,我们可以考虑将DB_CACHE_SIZE调整到288M。因为在288M之前,物理读因子变化都比较大,而从288M到304M以后,这个因子变化趋缓。用一个二维图可以更容易看出这个变化来:

这一视图作为调整DB_CACHE_SIZE以提高性能有很大参考价值。但衡量Buffer Cache是否合适的重要指标还是我们前面提到的缓存命中率(Buffer Hit), 而影响缓存命中率往往还有其他因素,如性能极差的sql语句。

·V$BUFFER_POOL

这一视图显示了当前实例中所有缓冲池的信息。它 的结构如下:

字段

数据类型

描述

缓冲池ID,和上面视图描述相同。

RESIZE_STATE

VARCHAR2(10)

缓冲池当前状态。

STATIC:没有被正在调 整大小

ALLOCATING:正在 分配内存给缓冲池(不能被用户取消)

ACTIVATING:正在 创建新的缓存块(不能被用户取消)

SHRINKING:正在删 除缓存块(能被用户取消)

CURRENT_SIZE

缓冲池大小(M为单位)

BUFFERS

当前缓存块数

TARGET_SIZE

如果正在调整缓冲池大小(即状态不为STATIC),这记录了调整后的大小(M为单位)。 如果状态为STATIC,这个值和当前大小值相同。

TARGET_BUFFERS

如果正在调整缓冲池大小(即状态不为STATIC),这记录了调整后的缓存块数。否则,这个值和当前缓存块数相同。

PREV_SIZE

前一次调整的缓冲池大小。如果从来没有调整 过,则为0。

PREV_BUFFERS

前一次调整的缓存块数。如果从来没有调整 过,则为0。

LO_BNUM

9i后已经废弃字段

HI_BNUM

LO_SETID

HI_SETID

SET_COUNT

·v$buffer_pool_statistics

V$BUFFER_POOL_STATISTICS视图记录了所有缓冲池的统计数据。它的结构如下:

字段

数据类型

描述

ID

NUMBER

缓冲池ID,和上面视图描述相同。

NAME

VARCHAR2(20)

缓冲池名称

SET_MSIZE

缓冲池中缓存块的最大数

CNUM_REPL

在置换列表中的缓存块数

CNUM_WRITE

在写列表中的缓存块数

CNUM_SET

当前的缓存块数

BUF_GOT

读取过的缓存块数

SUM_WRITE

被写过的缓存块数

SUM_SCAN

被扫描过的缓存块数

FREE_BUFFER_WAIT

等待空闲块统计

WRITE_COMPLETE_WAIT

等待完成写统计

BUFFER_BUSY_WAIT

忙(正在被使用)等待统计

FREE_BUFFER_INSPECTED

确认了的空闲缓存块数(即可用的)

DIRTY_BUFFERS_INSPECTED

确认了的脏缓存块数

DB_BLOCK_CHANGE

修改过的数据块数

DB_BLOCK_GETS

读取过的数据块数

CONSISTENT_GETS

一致性读统计

PHYSICAL_READS

物理读统计

PHYSICAL_WRITES

物理写统计

查看当前的Buffer Cache命中率:

sql> select 1-(physical_reads)/(consistent_gets+db_block_gets)
 2 from v$buffer_pool_statistics;
 
1-(PHYSICAL_READS)/(CONSISTENT
------------------------------
 0.967658520581074
 
sql>
·v$bh

这一视图在深入定位缓冲区问题时很有用。它记录 了缓冲区中所有数据块对象。粒度非常细。这个视图最初的目的是用于OPS(Oracle Parallel Server Oracle平行服务器,9i后称为RAC)的,是用于保证RAC中各个节点的数据一致性 的。但是,我们可以通过它来查询Buffer Cache的使用情况,找出大量消耗Buffer Cache的对象。下面的语 句就可以完成这一工作:

sql> column c0 heading 'Owner' format a15
sql> column c1 heading 'Object|Name' format a30
sql> column c2 heading 'Number|of|Buffers' format 999,999
sql> column c3 heading 'Percentage|ofData|Buffer' format 999,999,999
sql> select
 2 owner c0,
 3 object_name c1,
 4 count(1) c2,
 5 (count(1)/(select count(*) from v$bh)) *100 c3
 6 from
 7 dba_objects o,
 8 v$bh bh
 9 where
10 o.object_id = bh.objd
11 and
12 o.owner not in ('SYS','SYSTEM')
13 group by
14 owner,
15 object_name
16 order by
17 count(1) desc
18 ;
 
C0 C1 C2 C3
--------------- ------------------------------ ---------- ----------
PLsqlDEV STANDARD_CITY 17290 72.5860621
DBOWNER MSG_LOG 2 0.00839630
DBOWNER COUNTRY_PK 1 0.00419815
DBOWNER PARAMETER 1 0.00419815
DBOWNER PARAMETER_PK 1 0.00419815
DBOWNER MSG_LOG_IDX1 1 0.00419815
 
6 rows selected
 
sql>

更重要的是,这个视图记录的粒度非常细,一条记 录对应了一个数据块。这对于我们做内存问题分析或分析Oracle行为时很有帮助。

下面是这个视图的结构:

说明

FILE#

缓存块对应的数据块所在的数据文件号。可以 通过视图DBA_DATA_FILES或V$DBFILES查 询

BLOCK#

缓存块对应的数据块编号

CLASS#

分类编号

STATUS

VARCHAR2(1)

缓存块的状态

FREE:空闲,没有被使用

XCUR:排斥(正在被使用)

SCUR:可被共享

CR:一致性读

READ:正在从磁盘读入

MREC:处于从存储介质恢复状态

IREC:处于实例恢复状态

XNC

缓存块上由于和其他实例争用导致的PCM(Parallel Cache Management并行缓存管理)x to null锁的数 量。这一字段已经被废弃。

LOCK_ELEMENT_ADDR

RAW(4 | 8)

缓存块上PCM锁的地址。如果多个缓存块的PCM锁地址相同,说 明他们被同一锁锁住。

LOCK_ELEMENT_NAME

LOCK_ELEMENT_CLASS

FORCED_READS

由于其他实例的PCM锁锁住了该缓存块,导致当前实例尝试重新请求读该缓冲块的次数

FORCED_WRITES

由于其他实例的PCM锁锁住了该缓存块,导致当前实例尝试重新请求写该缓冲块的次数

DIRTY

脏标志:Y –块被修改过,是脏块;N –不是脏块

TEMP

是否为临时块:Y –是;N –否。

PING

是否被ping住:Y –是;N –否。

STALE

是否是陈旧块:Y –是;N –否。

DIRECT

是否为直接读写块:Y –是;N –否。

NEW

字段被废弃,始终为N

OBJD

数据块所属对象的对象标号,可以查询dba_objects

TS#

NUMBER

1.1.4.共享池(Shared pool)

SGA中的共享池由库缓存(Library Cache)、字典缓存(Dictionary Cache)、用于并行执行消息的缓冲以及控制结构组成。

Shared Pool的大小由参数SHARED_POOL_SIZE决定。在32位系统 中,这个参数的默认值是8M,而64位系统 中的默认值位64M。最大为4G。

对于Shared Pool的内存管理,是通过修正过的LRU算法表来实现的。

下面分别介绍Shared Pool的几个组成部分。

1.1.4.1.库缓存(Library Cache)

Library Cache中包括共享sql区(Shared sql Areas)、PL/sql存储过程和包以及控制结构(如锁、库缓存句 柄)。

任何用户都可以访问共享sql区(可以通过v$sqlarea访问,随后会介绍 这个重要视图)。因此库缓存存在于SGA的共享池中。

·共享sql区和私有sql

Oracle会为每一条sql语 句运行(每运行一条语句Oracle都会打开一个游标)提供一个共享sql区(Shared sql Areas)和私有sql区(Private sql Areas属于PGA)。当发现两个(或多个)用户都在运行同一sql语句时,Oracle会重新组织sql区,使这些用户能重用共享sql区。但他们还会在 私有sql区中保存一份这条sql语句的拷 贝。

一个共享sql区 中保存了一条语句的解析树和查询计划。在多用户系统中,Oracle通过为sql语句使用同一共享sql区多次运行来节省内存。

当一条新的sql语句被解析时,Oracle从共享池中分配一块内 存来存储共享sql区。这块内存的大小与这条语句的复杂性相关。如果Shared Pool不够空间分配给共享sql区,Oracle将 释放从LRU链表中查找到最近最少使用的内存块,直到有足够空间给新的语句的共享sql区。如果Oracle释放的是一个共享sql区的内存,那么相应的语句在下次执行时需要再次解析并重新分配共享sql区。而从解析语句到分配共享sql区是一个比较消 耗cpu的工程。这就是为什么我们提倡使用绑定变量的原因了。在没有使用绑定变量时,语句中的变量 的数值不同,oracle就视为一条新的语句(9i后 可以通过cursor_sharing来控制),重复上面的解析、内存分配的动作,将大大消耗系统 资源,降低系统性能

·PL/sql程 序单元

Oracle对于PL/sql程 序单元(存储过程、函数、包、匿名PL/sql块和触发器)的处理过程和对单个的sql语句的处理过程相似。它会分配一个共享区来存储被解析、编译过的程序单元。同时分配一个私有区域来存放运 行程序单元的会话所指定的程序单元的参数值(包括本地变量、全局变量和包变量——这也叫做包的实例化)和用于执行程序所需的内存。如果多个用户运行同一个 程序单元,则他们共享同一个共享区域,并且各自保持一份私有区域,用于用户会话中指定的变量值。

而一个PL/sql程 序单元中的每条单个sql语句的处理过程则和上面描述的sql语 句的处理过程相同。要注意一点,尽管这些语句是从PL/sql程序单元中来的,但是Oracle还是会为这些语句分配一块共享sql区,同 时为每个用户分配一个相应的私有sql区。

数据块所在的表空间号,可以查询v$tablespaces

9i后已经废弃字段

原文链接:https://www.f2er.com/oracle/207937.html

猜你在找的Oracle相关文章