ORACLE Buffer cache 的调整与优化.docx
《ORACLE Buffer cache 的调整与优化.docx》由会员分享,可在线阅读,更多相关《ORACLE Buffer cache 的调整与优化.docx(32页珍藏版)》请在冰豆网上搜索。
ORACLEBuffercache的调整与优化
--==============================
--Buffercache 的调整与优化
(一)
--==============================
BufferCache是SGA的重要组成部分,主要用于缓存数据块,其大小也直接影响系统的性能。
当BufferCache过小的时候,将会造成更多的
freebufferwaits事件。
下面将具体描述BufferCache的作用,调整与优化。
一、SGA的所有组件
从动态视图v$sga_dynamic_components获取SGA的相关信息
SELECT component, current_size, min_size FROM v$sga_dynamic_components;
COMPONENT CURRENT_SIZE MIN_SIZE
-----------------------------------------------
sharedpool 71303168 71303168
largepool 4194304 4194304
javapool 4194304 4194304
streamspool 4194304 4194304
DEFAULT buffercache 113246208 113246208
KEEPbuffercache 0 0
RECYCLEbuffercache 0 0
DEFAULT 2Kbuffercache 0 0
DEFAULT 4Kbuffercache 0 0
DEFAULT 8Kbuffercache 0 0
DEFAULT 16Kbuffercache 0 0
DEFAULT 32Kbuffercache 0 0
ASMBufferCache 0 0
二、Buffercache介绍
1.Buffercache的类型通常包括
defaultbuffercache
keepbuffercache
recyclebuffercache
nkbuffercaches
与Buffercache打交道的后台进程为DBWn,与之对应的数据文件通常位于system 表空间,sysaux表空间,undo表空间,datafile 等
Buffercache是SGA的一部分,其内容是由用户进程从数据文件读取出来的数据块,并且所有的用户共享这些数据块。
通常,服务
器进程为提高I/O性能,会一次性读多个数据块。
对于Buffercache中的脏数据则由DBWn进程写入到数据文件。
同样为提高性能,DBWn
进程也会一次写多个数据块。
Buffercache会拥有一个数据块的多个副本,当前块的最新副本仅有一份,而该数据块老的或旧的副本可
能有多份,用于块的读一致性。
Buffercache采用LRU算法来淘汰掉过时的数据块。
Buffercache中存在检查点队列以及LRU链表。
2.Buffercache的几个相关参数
Buffercache能有由多个独立的且具有不同blocksize的缓冲池(bufferpool)组成。
DB_BLOCK_SIZE:
参数决定了数据库主块的块大小,该块的大小通常被系统表(system,sysaux)空间和主要的Buffercache(recycle,keep,
defaultbuffercache)所使用
决定主要的Buffercache大小的几个参数
db_cache_size
db_keep_cache_size
db_recycle_cache_size
3.Buffercache中块的四种状态
pinned:
意味着多个会话在相同的时段写同一个数据块,其他的会话等待访问块。
clean:
优先要淘汰掉的数据块,即不是pinned状态,也不会被再次使用的块.该块可能和磁盘上的块处于同步状态,也可能是一个读一致性块
free/unused:
即Buffercache中的块处于空闲状态或未使用状态,通常是由于实例刚刚启动。
dirty:
已发生变化的数据块,且没有进程再使用该块,则在agedout之前需要立即由DBWn 写入到数据文件。
服务器进程将数据块从数据文件填充到Buffercache,当Buffercache中不再需要使用到数据块的副本时,而DBWn进程则将脏数据
写入到数据文件,用于将数据块由 pinned 状态变为free 状态。
4.参数db_block_checksum
该参数设置为true,则一个指定的校验码被同时写入到数据块,用于防止磁盘,I/O系统损坏导致数据的丢失。
三、客户端服务器进程从Buffercache获取数据的过程
1.服务器进程使用一个哈希函数来检查所需的数据块是否已经位于Buffercache。
如果在Buffercache中找到所需的数据块,则该块根据使
用的频率放置到LRU队列中特定的位置。
此时的读数据块为逻辑读,且不在需要执行后续步骤。
如果不在Buffercache中,则转到下一步。
2.服务器进程搜索LRU列表中是否存在可用的空闲空间存放新的数据块。
在搜索LRU列表同时时,已经被修改的脏数据将被服务器进程放置到
检查点队列。
3.检查点队列长度超出预设大小的阙值或服务器进程搜索空闲块操作预设的次数(由隐藏参数_db_block_max_scan_pct所指定的值,表示已
经扫描的bufferheader数量占整个LRU链表上的bufferheader的总数量,在i中该限定值为40%),则服务器进程通过DBWn将脏数据从
Buffercache写出到数据文件。
4.当可用的空闲块被找到后,服务器进程从数据文件读入块到DatabaseBuffercache并放置到LRU队列中。
如果所得到的块不是一致性读块
,则服务器进程从undosegment中重构一致性块。
Buffercache与DBWn密切相关,下面给出DBWn触发的条件
脏缓冲列表达到指定的阙值大小
搜索LRU空闲队列达到预设的阙值次数
发生检查点事件
数据库关闭时
表空间实现热备份时
表空间离线
在段被删除时
更多有关体系结构请参考:
Oracle实例和Oracle数据库(Oracle体系结构)
四、对buffercache调优,命中率等
1.调整buffercache调优规则
调优的目标:
尽可能在Buffercache中找到数据,降低等待可用空闲块的时间
调试方法:
waitevents
cachehitration
v$db_cache_adviceview
调整手段
降低SQL命令对数据块的请求,如避免使用select*from 语句
增加缓冲池的大小
不同访问方式使用不同的缓冲池(bufferpools)
缓存常用的表到内存
并行读或排序操作不使用cache,直接从磁盘读入到PGA及内存
2.决定Buffercache的几个指标
下面的查询中列出了涉及到buffercache的几个重要指标数
SELECT NAME, VALUE
FROM v$sysstat
WHERE NAME IN ('sessionlogicalreads',
'physicalreads',
'physicalreadsdirect',
'physicalreadsdirect(lob)',
'consistentgets',
'dbblockgets',
'freebufferinspected',
'freebufferrequested',
'dirtybuffersinspected',
'pinnedbuffersinspected');
NAME VALUE
-------------------------------------------
sessionlogicalreads 139********5
dbblockgets 274690511
consistentgets 139********7
physicalreads 21335058151
freebufferrequested 21085155516
dirtybuffersinspected 156801
pinnedbuffersinspected 432841
freebufferinspected 968639
physicalreadsdirect 4995527
SessionLogicalReads:
所有的逻辑读的数据块的数量。
FreeBufferInspected指标:
为寻找空闲buffer之前所检查块的总数量,即跳过块的数量。
如果该值接近脏数据块的数量,则表明空闲块很少,该值应尽可能小
于脏块的数量。
FreeBufferWaits:
当session在LRUlist上没有寻找到空闲可用数据块或者搜寻可用的内存数据块被暂停的时候,该发生该事件,此为等待DBWn将脏
块写入到数据文件的等待数。
除此之外,会话在做一致性读时,需要构造数据块在某个时刻的前映像(image),此时需要申请内
存来存放这些新构造的数据块,如果内存中无法找到这样的内存块,也会发生这个等待事件。
BufferBusyWaits:
用户服务器进程已找到所需的数据块,但该块正被其它进程使用或多个进程同时要修改该块,此时需要等待的时间。
当一个会话需要读取一个数据块,但这个数据块正在被另一个会话读取到内存中时,此时同样发生BufferBusyWaits事件。
SELECT event
,total_waits
FROM v$system_event
WHERE event IN ('freebufferwaits','bufferbusywaits');
EVENT TOTAL_WAITS
------------------------------------
bufferbusywaits 35216021
查询event事件名称
SELECT NAME
,parameter1
,parameter2
,parameter3
FROM v$event_name
WHERE NAME='bufferbusywaits';
NAME PARAMETER1 PARAMETER2 PARAMETER3
----------------------------------------------------------------------------------
bufferbusywaits file# block# id
产生Bufferbusywaits的几种情形
DATABLOCK,数据块的竞争,该情形通常是基于表段和索引段上的竞争,下面的处理办法
尽可能缩小SQL语句的查询字段,查询范围,如不使用select* 查询,将like子句改为直接赋值等
检查索引的合理性。
如使用了sequence生成的索引,其索引键通常位于相同的块,因此可以使用反向索引避免此问题
使用自动段空间管理或增加空闲列表,以避免多个进程同时插入相同的块
查询视图v$session_wait来获得热点块的文件ID,块ID,通过这些信息来获得对象ID,进一步对该对象进行调整
UNDOHeader
基于UNDO段头部的竞争,如果未使用自动撤销段管理模式,则需要增加更多的回滚段
UNDOBLOCK
基于UNDO段块的竞争,如果未使用自动撤销段管理模式,则需为回滚段分配更大的尺寸
产生FreeBufferwaits的几种情形
DBWn进程来不及将数据写入到数据文件,导致需要等待被释放的空间
I/O系统速度过于缓慢
确保数据库文件是否分布在不同的磁盘上,或增加更高性能的磁盘
资源等待造成I/O系统过慢,如latch等待
确保数据库文件是否分布在不同的磁盘上,或增加更高性能的磁盘
Buffercache太小,导致DBWn来不及将脏数据写入到数据文件
需要增大buffercache的尺寸
Buffercache太大,而单一的DBWn进程需要多次才能将数据写入到文件
减少buffercache的尺寸,或增加更多的DBWn进程
3.评估Cache的命中率
计算命中率的思想
1-(物理读的次数-总的请求次数)
计算命中率
SELECT ROUND(1 - ((physical.value - direct.value - lobs.value) / logical.value),3) *100 ||'%'
"BufferCacheHitRatio"
FROM v$sysstatphysical,
v$sysstatdirect,
v$sysstatlobs,
v$sysstatlogical
WHERE physical.name = 'physicalreads'
AND direct.name = 'physicalreadsdirect'
AND lobs.name = 'physicalreadsdirect(lob)'
AND logical.name = 'sessionlogicalreads';
physicalreads
从Oracle级别来理解,从磁盘读数据块的次数,一次可以读多块,由参数db_file_multiblock_read_count来控制。
此种读方式使用
了dbcache.
形象示意:
db_file ==> db_cache ==> pga
physicalreadsdirect
有些数据块不会先从硬盘读入内存再从内存读入PGA再传给用户,而是绕过SGA直接从硬盘读入PGA。
比如并行查询以及从临时表空
间读取数据。
这部分数据块由于不缓存使得hitratio不会被提高。
其在计算hitratio时应当被扣除。
形象示意:
db_file ==> pga
通常,disk sort / hash , exp direct=Y ,都会有physicalreadsdirect
scott@ORCL> select name from v$statname where statistic# in (54,55,56);
NAME
----------------------------------------------------------------
physicalreads
physicalreadscache --使用buffercache
physicalreadsdirect --不使用buffercache
physicalreadsdirect (lob)
对于大值对象,如LOB数据类型以及LOB段,Oracle可以绕过buffercache而直接使用PGA,其原理等同于physicalreadsdirect
使用physicalreadsdirect,physicalreadsdirect (lob)的优点:
对于一个大操作,需要请求大量数据块,假设又使用并行执行,且执行次数就那么一次,这个时候就适合使用direct方式,
如果还是走buffercache则需要把buffercache里已缓存的数据库都清空
注意physicalwrite /direct 同理
sessionlogicalreads
发出的总的请求次数,此处是指从databasebuffercache中请求块。
对于一致性读,则这些缓冲包含来自回滚段的数据
下面是另一种不同的计算命中率的方法,通常用在10g和11g之中
SELECT NAME,
physical_reads,
db_block_gets,