s 写到磁盘上,但不会立即将数据块写回磁盘,而是使用database writer(DBWn)在后台执行 lazy writes。
·将经常访问的块保持在buffercache中将不经常访问的块写入到磁盘
当DatabaseSmart Flash Cache(flash cache)开启时,buffer cache的一部分可以驻留在flash cache。这个buffer cache的扩展存储在flash disk device,它指一种使用flash memory的固态存储设备。数据库可以通过使用从flash memory 中读取buffers替换从磁盘中读取,这样将提高性能。
注意:Database Smart Flash Cache只有在Oracle EnterpriseLinux以及Solaris中才可以使用
Buffer States(Buffer的状态)
数据库使用内部算法来管理在缓存中的buffers。任意一个buffer拥有下面这些状态之一:
·Unused(未使用)
这种buffer是可以被使用的,因为它之前没被使用过,或者当前没被使用。这种类型的buffer是最容易被数据库所使用。
·Clean(干净)
这种buffer在之前被使用过 现在还包含一个块在某一个时间点的读一致性版本。这种块包含数据,但它"clean(干净)" ,那么它不需要被checkpoint。数据库可以pin住这个块并且重用它。
·Dirty(脏块)
这种buffer包含被修改过且还没有写入到磁盘的块。数据库checkpoint这个块后才可以重用它。
每个buffer都有一个访问模式:pinned或者free(未被pin)。当一个会话访问缓存中一个buffer时,它变为“pinned”,那么它不会被内存换出。多个会话不能同时修改一个pinned buffer。
数据库使用一个复杂的算法使buffer的访问更加高效。指向dirty或nondirty buffer的指针在同一个least recently used(LRU)列表上,这个列表有热端和冷端。一个冷buffer是指在最近没被使用过的buffer。一个热buffer是一个经常被访问以及最近被使用过的buffer。
注意:理论上,只有一个LRU,但是为了并发性,数据库实际使用了几个LRU。
Buffer Modes(buffer的模式)
当一个客户需要数据,Oracle数据库通过以下两种模式从数据库buffer cache中取回数据:
·Current mode(当前模式)
一个currentmode get,同样称之为 db block get。这是一种将当前在buffer cache中存在的块的检索方式。举个例子,如果一个未提交的事务更新了一个块中的两行,那么current mode get将这个块(包括未提交的行)取回。使用修改语句时数据库会频繁使用db block gets。
·Consistent mode(一致性模式)
一个consistentread get是获取一个块的读一致性版本。这种获取方法可能会用到undo数据。举个例子,如果一个未提交事务更新了一个块中的良好,如果一个其他session的查询需要用到这个块,那么数据库使用undo数据去创建出本块的一个读一致性版本块。(称之为consistent read clone ,读一致性克隆)这个读一致性版本块将不会包括刚才未提交事务做的修改。基本上,一个查询获取的块都是consistent mode。
Buffer I/O(buffer的I/O)
一个logical I/O(逻辑I/O),通常被称之为buffer I/O,指的是在buffer cache中buffer的读与写。当一个需要的buffer没能在内存中找到,那么数据库将执行一个physical I/O(物理I/O)从flash cache或磁盘中将buffer 复制到内存中,然后一个logical I/O把被缓存进来的buffer读出。
Buffer Writes(buffer的写)
database writer(DBWn)进程周期性的将又冷又脏的buffers写到磁盘。DBWn在下面情况将发生:
·一个服务进程没办法找到一个干净的buffer来放置新被读入到buffer cache的块。
像一些buffer变脏了,对应的空闲buffer将减少,如果数量低于一个内部阀值,而且又需要干净的buffer,那么服务进程将通知DBWn执行写出操作。
数据库使用LRU来确定哪些脏快要被写。当脏块位于LRU的冷端,那么数据库将把它们从LRU上移动到一个write queue(写出队列)。DBWn将按照队列顺序把这些buffer写入磁盘,如果可能将使用多块写入。这个机制预防LRU被脏快塞满并保证有干净的buffer可供重用。
·数据库必须推进checkpoint(检查点),checkpoint是redo线程上instance recovery(实例恢复)的起点位置。
·表空间变为redo-only状态或者变为offline。
Buffer Reads(buffer的读)
当clean buffer或unused buffer数量少时,数据库必须从buffer cache中移除一些buffer。这个算法根据flash cache是否开启将有所不同:
·Flash cache disabled(flash cache关闭)
数据库在需要的时候覆盖重用clean buffer。如果这个被覆盖的块,之后还会需要,那么数据库必须将它从磁盘中再次读入
·Flash cache enabled(flash cache开启)
DBWn可以将clean buffer的身体部分写入到flash cache,使得在内存中的这个buffer可以被重用。数据库将继续把这个clean buffer的头部留在LRU列表,用来跟踪buffer身体部分在flash cache中的位置。如果这个buffer在后面被请求,那么数据库可以将它从flash cache中读取(替代了之前从磁盘中读取)。
当一个客户端进程请求一个buffer,服务端进程将在buffer cache中搜索它。当数据库在内存中找到了这个buffer,那么将发生一个cache hit(cache 命中)。扫描的顺序如下:
1. 服务进程将扫描buffer cache去找这整个buffer。
如果进程着找到了整个buffer,那么数据库将对这个buffer执行logical read
2. 服务进程扫描flash cache LRU列表去找buffer的头
如果进程找到了buffer头,那么数据库将对这个buffer的身体部分执行optimized physical read(优化的物理读),将其从flashcache中读到内存cache。
3. 如果进程没有在内存中找到buffer(发生一个cache miss),那么服务进程执行下面步骤:
a. 从数据文件中拷贝块到内存(一个physical read 物理读)
b. 在其进入内存后,执行一个对该块的logical read(逻辑读)。
下图解释了buffer扫描的顺序。这个扩展后的buffer cache 包括内存中的buffer cache(包含整个buffer),以及flash cache(包含某些buffer的身体部分)。在图中