甲骨论16课buffer_cache作用概述
数据一致性出现问题是灾难性的。DBA很长时间都用于数据库更稳定高效的优化上。
查看数据库块大小:
1) >exportNLS_LANG=american_america.zhs16gbk
2) >sqlplus / as sysdba
3) >show parameter block
数据库block块是oracleIO的最小单位。区是为段分配的最小单位。表就是段, 表建立后就给段分一个区。区extent由物理连续的块构成。块保存多行数据。行一般在同一块中,行链接、行迁移、log、rot这四种情况同一行位于多个块中。
建表:
1) >create table t2(id int,namevarchar2(20));
2) >insert into t2 values (1,’xkj’);
3) >commit; //提交后才能被保存,数据库提交后才能被其它用户访问。
对于每次读数据,寻道时间耗时最长。如果需要一行数据,oracle就把整个块读入内存。再次需要这个块的数据时就不用再次寻道。实际读取需求行的上下文的机率是很大的。
Oracle能计算数据所在行的所在块,原理在后面介绍。
bufferCache的作用是:减少物理IO、构造cr块。
bufferCache的命中率比sharedPool命中率更重要,未命中就会产生物理读,产生寻道。
建立会话:
1) #su oracle
2) #exportNLS_LANG=american_america.zhs16gbk
3) #sqlplus / as sys dba
4) >select * from t2;
5) rollback;//回滚未提交数据;构造cr块
只要未提交就可以回滚,并且别的会话就看不见修改。
甲骨论17课 buffer_cache内存组织结构剖析
内存块结构:
l CBC(数据缓冲链cash buffer chain)以地址的方式连接buffer cache中的所有的块。当由block地址找block的时候,需要使用到CBC chain 。
l LNU(最近最少使用least recent used)按照free、clean、dirty顺序链接buffer cache中的块。
l LNU也实现了按使用频率从低到高,前为冷端,后为热端。
l LRUW将脏块连接起来,最少访问的脏块要排在前面,优先将最少访问的脏块写入磁盘。
l CHECKPOINT QUEUE检查点队列,按照脏块第一次脏的时间点排起来,检查点队队的意义以后讲。
区别:share_pool中的trunk并不相同,而buffer_cache中的block大小相同。
甲骨论18课buffer_cache大小的设置及依据
DBwriter触发情况:
l 每隔3秒钟触发
l free和clean的缓存太少,需要批量的写一批脏缓存
l 数据库关闭时,将脏缓存全部写回磁盘
修改DBwriter:(一般设为处理器核数/8)
1) >show parameter writer;
2) >alter system set db_writer_processes=2;
3) >重启数据库
buffer_cache设置:
1) >selectcomponent,current_size,min_size from v$sga_dynamic_components;
2) 增加sga_max_size
3) 增加sga_target
4) >alter system setdb_cache_size=20M,scope=both;
推荐配置是DB_CACHE_SIZE=SGA_MAX_SIZE/2~SGA_MAX_SIZE*2/3
查看buffer_cache大小与物理读频率关系:
>SELECTsize_for_estimate “Cache Size (MB)”
,size_factor
,buffers_for_estimate “Buffers”
estd_physical_read_factor est_read_factor
,estd_physical_reads estd_phy_red
,estd_physical_read_time est_phy_red_t
FROMv$db_cache_advice
WHERENAME=’DEFAULT’ AND block_size=(SELECT VALUE FROM v$parameter WHERENAME=’db_block_size’);
甲骨论19课buffer状态深入剖析
Block状态:
l 0,FREE,no valid block image
l 1,XCUR, a current modeblock,exclusive to this instance磁盘中的CR块读到内存中成为CUR块。
l 2,SCUR,a current mode block,shared with other instances
l 3,CR,a consistent read block image
l 4,READ,buffer is reserved for a block being read from disk
l 5,MREC,a block in media recovery mode
l 6,IREC,a block in instance recovery mode
l 7,WRITE
l 8,pi
>selectdistinct state from x$bh; //查看数据中块的状态。
读入buffer_cache中的数据块称为CUR块,修改CUR块时同时在redoLogBuffer中记录撤消方法。修改后的块,进行复制并按redoLogBuffer进行撤消,生成的块称为CR块。在未提交前,其它用户访问的数据并非修改后的块同,而是其对应的CR块,提交commit后CR块无效。
CR块的作用就是修改提交前,假装没修改被其它用户访问。
当一个数据库对应一个实例时,只有XCUR。只有在RAC才能出现SCUR。具体内容以后讲。
READ状态指缓存正在从磁盘读入块Block。介质恢复MREC和实例恢复IREC在备份恢复中讲。
>alter systemflush buffer_cache; //清空buffer_cache,在项目中属较危险操作,会引发大量的物理IO。
查询一个对象所占的对象的情况:
>selecto.object_name,decode(state,0,’free’;1,’xcur’,2,’scur’,3,’cr’,4,’read’,5,’mrec’,6,’irec’,7,’write’,8,’pi’)
state,count(*) blocks
from x$bh b,dba_objects o
where b.obj=o.data_object_id
and o.object_name=’T2’
group by o.object_name,state
order by blocks desc;
甲骨论20课使用各种SQL来熟知buffer_cache使用情况
信息来源x$bh表:
l >select distince object_name,DBARFIL,DBABLK from x$bha,dba_objects b
where a.obj=b.object_id and object_name=’T2’//查询某个object所占的块
l >select class ,flag,state,lru_flag from x$bh where dbarfil=1 anddbablk=61433; //查询某个块的状态,数字对应的block状态在上节有解释
l >select o.object_name,decode(stare,0,’free’,1,’xcur’,2,’scur’,3,’cr’,4,read’,5,’mrec’,6,’irec’,7,’write’,8,’pi’)
state,count(*) blocks
from x$bh b,dba_objects o
where b.obj=o.data_object_id and state <> 0
group by o.object_name,state
order by blocks asc; //查看各个object占用了多少block
l >SELECT
obj object,
dbarfil file#,
dbablk block#,
tch touches
FROM
x#bh
WHERE
tch>10
ORDER BY
tch desc; //寻找热块,touch记录块被读的次数,读的越多说明块越热。LRU链也是根据块的touch变量,对块进行排序链接的。
l select sum(blocks) from dba_data_files;//查询buffer_cache中的块总和
l >select decode(state,0,’free’,1,decode(lrba_seq,0,’available’,’being_used’),3,’being_used’,state)“BLOCK_STATUS”,count(*) from x$bh group by decode(state,0,’free’,1,decode(lrba_seq,0,’available’,’being_used’),3,’being_used’,state);
//显示空闲块FREE、干净块AVAILABLE、BEING_USED脏块
l select sum(pct_bufgets) “Percent” from(select rank() over (order bybuffer_gets desc) as rank_bufgets,to_char(100*ratio to_report(buffer_gets) over(),’999.99’) pct_bufgets from v$sqlarea) where rank_bufgets <11;
//最浪费内存的前10个语句占所有语句的比例,建议控制在5%以内
l >select disk_reads,substr(sql_text,1,4000) from v$sqlarea orderby disk_reads desc;
//找出消耗物理IO资源最大的SQL语句
l >list 1* select disk_reads,substr(sql_text,1,4000) from v$sqlareaorder by disk_reads asc;
//按物理IO量升序排列sql语句
l >iostat 1 10; //查看物理IO繁忙程度
l >vmstat 1 10 //查看物理IO繁忙程度
l >top //查看物理IO繁忙程度
l >mpstat 1 10 //查看所有CPU使用繁忙程度
l >mpstat –P 0 1 //查看0号CPU繁忙程度
l >select BUFFER_GETS, substr(sql_text,1,4000) from v$sqlarea orderby disk_reads asc;
网友评论