您的位置:首页 > 数据库 > Oracle

7.Oracle深度学习笔记——内存架构之SGA Buffer Cache

2016-01-21 23:10 459 查看
7.Oracle深度学习笔记——内存架构之SGA Buffer Cache
欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/50558162

Buffer cache是存储数据块的,数据库从数据文件中读取。一个buffer是缓存管理器暂时缓存当前或最近使用的数据块的内存地址。所有并发连接到数据库的用户可以共同访问buffer cache.

1.  Buffer Cache的目的:

l  优化物理IO

l  让访问频繁的块保持在buffercache中,不用非常频繁的写块到磁盘

当数据库使能DatabaseSmart Flash Cache (flash cache)的时候,部分buffer cache可以保持在flash cache中。把buffers缓存在flash cache中要比从磁盘读快很多。

         使用DB_FLASH_CACHE_FILE and DB_FLASH_CACHE_SIZE来配置多个flash 设备。

2.  Buffer 状态

         数据库使用内部算法来管理CACHE中固定缓存。一个BUFFER可以是下列任意状态:

n  未使用:缓存从未被使用或当前未被使用,这个类型数据库最容易使用

n  干净的:之前使用过,限制只包含读一致的块。不用做checkpoint.数据库可以pin住block然后再使用。

n  脏的:包含修改过的数据,未写到磁盘,数据库在使用前必须checkpoint.

每个buffer有一个访问模式:pinned或free(unpinned). 一个pinned 的buffer,当一个会话访问的时候不会从内存中老化出来。多个会话不同同时修改一个pinned 的buffer.

3.  Buffer模式

当客户端请求数据时候,ORACLE通过一下模式从数据库buffercache中获取buffer.

3.1         当前模式

当前模式获取,也叫作db blockget.从缓存中直接获取一个块。例如,一个未提交的交易更新了块中固定两行,当前模式后去,直接从块中获取这些未提交的行。

3.2         一致性模式

一直读获取是后去一个读一致的块。可能使用UNDO数据。例如,一个未提交的交易更新了块中的两个,如果不同会话请求修改过的块,那么数据库使用UNDO 数据来创建一个读一致块(不包括未提交更新)。

4.  Buffer I/O

逻辑IO,就是我们所说的bufferIO. 当请求的buffer没有在内存中找到时,数据库会进行物理IO将BUFFER从磁盘或FLASH 中读到内存中,然后再用给一个逻辑IO来读缓存的BUFFER。

4.1         Buffer替换算法

为保证buffer访问的高效,数据库必须绝对哪些buffer缓存在内存,哪些从磁盘获取。数据使用给如下算法:

4.1.1             块级基于LRU 替换算法

至少一个LRU列,包含指针指向脏的和干净的BUFFERS。 LRU有一个热端和冷段。冷 BUFFER表示最近为使用的,热BUFFER表示经常访问,最近也被访问的。概念上,只有一个LRU,但是为了数据并发,数据库经常使用多个LRU列表。

4.1.2               对象级基于热度 替换算法

从12.1.0.2开始,自动大表缓存特性使得,表扫描在以下场景可以使用不同的算法。

         并行查询:在单实例和RAC下,当DB_BIG_TABLE_CACHE_PERCENT_TARGET初始化为非0 ,PARALLEL_DEGREE_POLICY设置为AUTO或adaptive的时候,并行查询可以使用大表CACHE。

         串行查询:只在单实例配置,当DB_BIG_TABLE_CACHE_PERCENT_TARGET初始化为非0串行查询可以使用大表CACHE。

         当表不能放到内存时候,数据库基于访问模式来决定哪些BUFFER来缓存。

         例如,如果表只有95%在内存,那么数据库选择5%的块留在磁盘而不是读到内次再写到磁盘,这样会引起抖动。当CACHE多个大对象时候,数据库考虑将热的表变得更热,将冷的表变的更冷,这样影响到哪个块被CACHE。

         初始化参数DB_BIG_TABLE_CACHE_PERCENT_TARGET设置这个算法BUFFER CACHE的百分比

4.2         Buffer写

数据库写进程周期性写冷、脏BUFFER到磁盘。DBW在以下环境下写BUFFERS。

l  服务进程不能找到干净的缓存来将行块读入到数据库的BUFFER CACHE中

如果BUFFER是脏的,空闲的BUFFER数量下降。如果数量下降到一个阈值,然后需要干净的BUFFER,那么服务进程会通知DBW来写。

l  数据库必须提前checkpoint,CHECKPOINT是REDO进程实例恢复的开始

l  表空间改变为只读或下线

4.3         Buffer读

当干净或未使用的BUFFER数量低的时候,数据库必须从BUFFERCACHE中移除。算法取决于FLASH CACHE是否使能。

如果FLASH CACHEDISABLED

         数据库根据需要重新使用干净的BUFFER,并覆盖。如果覆盖的BUFFER后续又需要,那从磁盘中读取。

如果FLASH CACHE ENABLED

         DBW将干净的BUFFER 写到FLASH CACEH中,使能重新使用内存中的BUFFER。数据库将BUFFERHEADER保存在LRU列表,可以定位到FLASH CACHE中的BUFFER BODY。如果后续被需要,那么可以直接从FLASH CACHE中读取,而不是从磁盘中读取。

4.4         Buffer Touch次数

数据库使用TOUCHCOUNT来记录LRU列表上BUFFER被访问的频率。这个机制使得数据库在BUFFER 被PIN住的时候增加计数,而不是经常的从LRU列表上移除。

PS:数据库不会经常物理移动块,只是在列表上改变指针的位置。

         当BUFFER被PIN住的时候,数据库会决定TOUCHCOUNT是不是上次增加的。如果是3秒之前,那么继续增加,如果在3秒内增加过,那么不再增加。防止BUFFER的计算爆发增长。例如插入多个行到一个数据块,数据块会将这些插入视为一个TOUCH。

如果BUFFER在LRU的冷端,但是TOUCHCOUNT很高,那么BUFFER会移动到热段。如果TOUCH COUNT很低,那么BUFFER 从CACHE中老化出去。

5.  Buffer Pools

Buffer pool是一个buffer的集合。数据块的BUFFERCAHCHE 分成一个或多个BUFFER POOLS,以同样的方式管理块。POOL老化或缓存块没有根本的区别。

                   可以手动配置不同BUFFERPOOL。

                   可以指定特定的对象到合适的BUFFERPOOL。

                   这样可以隔离段到热、温、冷的BUFFER POOLS

如下:

l  DEFAULT POOL

通常缓存的地方。Default pool一个BUFFER POOL。其他POOL的配置对DEFAULTPOOL没有影响。

从12.1.0.2开始,BIG TABLECACHE是DEFAULT POOL的可选项,使用基于问题,对象级别的替换算法。

l  KEEP POOL

KEEP POOL 是给哪些访问频繁,但是因为空间为题不得不老化离开DEFAULT POOL的块。

KEEP POOL的目标是保留对象在内存,避免IO操作。

l  RECYCLE POOL

用于哪些使用不频繁的块。防止浪费CACHE中不必要的空间。

6.  Buffer和全表扫描

数据库使用复杂的算法来管理表扫描。默认,将缓存插入到LRU列表的中间,避免热块换出。

                   如果全表扫描,需要将表中高水位下所有行读取。如果大小超过BUFFER CACHE大小,一次全表扫描会清除所有BUFFER CHACHE。

l  默认全表扫描方式

如果是小表,则加载到内存。

如果是中表,一个算法更具上一次表扫描的之间,BUFFER的老化时间和BUFFER CACHE中的空间来决定。

如果是大表,数据库典型的使用直接路径读。这样绕过SGA,直接读到PGA。对于中表,也可能使用直接读。

         从12.1.0.2开始,数据库自动计算内存SGA是否足以存放整个数据库,以及CACHEING 表访问是否性能受益。如果达标,那么很多其他内部标准也会部分,ORACLE对待所有表就是小表。当然数据库不会缓存标记为NOCACHE的 LOBs

l  并行查询执行

当数据库有很大内存时候,数据库缓存并行查询数据,而不是使用直接读方式。典型的,并行查询一般在低并发的数据仓库中。

l  CACHE属性

在极少情况下,我们不需要缓存。所以可以指定altertable … cache来将大表读取到BUFFER CACHE中。这样数据库会空出BUFFER CACHE来读取表。当然使用这个要小心,因为会清除CACHE中大量的其他块。

l  KEEP属性

对于大表,可以使用ALTER TABLE …STORAGE BUFFER_POOL KEEP来让块加载到KEEP POOL中。

l  强制全表缓存模式

在一些场景下,可以显示的使用ALTERDATABASE … FORCE FULL DATABASE CACHING语句来强制缓存整个数据库。这个模式在12.1.0.2上可用。

Oracle建议只有在BUFFERCACHE的大小远比数据库大小大的时候,可以使用。这个建议适合于单实例和RAC。

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: