如磁盘上数据文件的最小io单元叫block一样,buffer cache的最小单元(或者说结构)叫buffer,每个buffer跟x$bh中每条记录有一一对应关系。
从使用维护buffer这个角度讲,存在一些链表主要的有LRU list 和dirty list(checkpoint queue),当从磁盘读取数据到buffer中时,需要到LRU list上寻找free buffer,如果没有则采用LRU算法把一些buffer清空,然后继续。buffer修改后,从LRU list上移到dirty list上,dirty list根据低重做值排序,由dbwr写出到数据文件。
LRU list上的latch是cache buffer lru chain,latch的数量由_db_block_lru_latches控制,当这个latch竞争激烈,可能是数据老化,全表扫描频繁。
从如何搜索buffer这个角度讲,存在这么一个数据结构,有一定数量的hash bucket,每个bucket下面是一个双向链表cache buffer chain,链表上挂着一个一个buffer。如何搜索一个buffer在哪里,以及如何定位一个buffer应该放到哪里,是通过hash算法找到那个bucket,然后遍历cache buffer chain。bucket的数量由_db_block_hash_buckets控制。
这个链表上的latch是cache buffer chain,latch的数量由_db_block_hash_latches控制,主要是热点块的问题,可以结合v$session_wait,v$latch_children,x$bh,v$sqltext,dba_extents找到sql。
------ ------ ------ ------
shared pool的最小单元叫chunk,每个chunk跟x$ksmsp中每条记录有一一对应关系,chunk的状态有4种:free(空的),recreate(需要释放的),freeable(一会儿可以释放的),perm(不能释放的)。
可用的chunk由一个叫free list的结构管理,它是由一定数量的bucket组成,oracle9i中有255个bucket,后面的bucket容量较前面的大。每个bucket下面是chunk list。
reserved pool是单独开辟出来的供连续的大内存分配,大小由shared_pool_reserved_size决定。当需要一块内存时,先扫描free list,如果找到就分割使用,找不到就通过LRU算法释放一些recreate的,合并一些free的,如果还不够,则到reserved pool中分配一块比_shared_pool_reserved_min_alloc这个值大的空间。
如果sql没有绑定变量,则一次一次地分割shared pool,很可能产生大量碎片导致ORA-04031错误。除了绑定变量,还可检查shared_pool_size,shared_pool_reserved_size,shared_pool_reserved_min_alloc这些参数的值,当然,bug也有可能。
shared pool中最重要的latch是shared pool latch,library cache latch。shared pool latch是管理和搜索free list时需要获取的,在oracle9i中有7个。library cache latch是增加新的sql到library cache时需要获取的,它的数量由_kgl_latch_count控制。如果sql没有充分共享,反复解析,很容易造成这两个latch的竞争或者ORA-04031错误。解决办法是sql中尽量使用绑定变量,除此,数据库里使用cursor_sharing参数强制绑定变量,当然这个参数有副作用,或者强制刷新共享池alter system flush shared_pool,当然这个治标不治本。
还有library cache pin,library cache lock,通常发生在授予权限,重编译对象,以及存在较复杂的dependence的时候。
阅读(2179) | 评论(0) | 转发(0) |