Cache Fusion
要了解RAC工作原理的中心需要知道Cache Fusion这个重要概念,这个文章就是用来说明什么是Cache Fusion。要发挥Cache Fusion的作用,要有一个前提条件,那就是互联网络的速度要比访问磁盘的速度要快!否则,没有引入Cache Fusion的意义。而事实上,现在1000m的互联都很常见。
什么是Cache Fusion?
Cache Fusion就是通过互联网络在集群内各节点的SGA之间进行块传递,以避免首先将块推送到磁盘,然后再重新读入其他实例的缓存中这样一种低效的实现方式(OPS的实现)。当一个块被读入RAC环境中某个实例的缓存时,该块会被赋予一个锁资源(与行级锁不同),以确保其他实例知道该块正在被使用。之后,如果另一个实例请求该块的一个副本,而该块已经处于前一个实例的缓存内,那么该块会通过互联网络直接被传递到另一个实例的SGA。如果内存中的块已经被改变,但改变尚未提交,那么将会传递一个CR副本。这就意味着只要可能,数据块无需写回磁盘即可在各实例的缓存之间移动,从而避免了同步多实例的缓存所花费的额外I/O。很明显,不同的实例缓存的数据可以是不同的,也就是在一个实例要访问特定块之前,而它又从未访问过这个块,那么它要么从其他实例cache fusion过来,或者从磁盘中读入。
这里还是有一些问题需要思考的:
1、在所有实例都未读取该块,而第一个实例读取时,是怎么加的锁,加的什么锁?如果此时有另一个实例也要读这个块,几乎是同时的,那么Oracle如何来仲裁,如何让其中一个读取,而另一个再从前者的缓存中通过cache来得到?
2、如果一个块已经被其他实例读入,那么本实例如何判断它的存在?
3、如果某个实例改变了这个数据块,是否会将改变传递到其他实例,或者说其他实例是否会知道并重新更新状态?
4、如果一个实例要swap out 某个块,而同时其他实例也有这个块的缓存,修改过的和未修改过的,本实例修改的和其他实例修改的,如何操作? truncate一张表,drop一张表... 和单实例有何不同?
5、应该如何设计应用,以使RAC真正发挥作用,而不是引入竞争,导致系统被削弱?
6、RAC下锁的实现。锁是在各实例的SGA中保留的资源,通常被用于控制对数据库块的访问。每个实例通常会保留或控制一定数量与块范围相关的锁。当一个实例请求一个块时,该块必须获得一个锁,并且锁必须来自当前控制这些锁的实例。也就是锁被分布在不同的实例上。而要获得特定的锁要从不同的实例上去获得。但是从这个过程来看这些锁不是固定在某个实例上的,而是根据锁的请求频率会被调整到使用最频繁的实例上,从而提高效率。
要实现这些资源的分配和重分配、控制,这是很耗用资源的。这也决定了RAC的应用设计要求比较高。
假设某个实例崩溃或者某个实例加入,那么这里要有一个比较长的再分配资源和处理过程。
在都正常运行的情况下会重新分配,以更加有效的使用资源;
在实例推出或加入时也会重新分配。在alert文件中可以看到这些信息。
而Cache Fusion及其他资源的分配控制,要求有一个快速的互联网络,所以要关注与互联网络上消息相关的度量,以测试互联网络的通信量和相应时间。
对于前面的一些问题,可以结合另外的概念来学习,它们是全局缓存服务和全局队列服务。
全局缓存服务(GCS):要和Cache Fusion结合在一起来理解。全局缓存要涉及到数据块。全局缓存服务负责维护该全局缓冲存储区内的缓存一致性,确保一个实例在任何时刻想修改一个数据块时,都可获得一个全局锁资源,从而避免另一个实例同时修改该块的可能性。进行修改的实例将拥有块的当前版本(包括已提交的和未提交的事物)以及块的前象(post image)。如果另一个实例也请求该块,那么全局缓存服务要负责跟踪拥有该块的实例、拥有块的版本是什么,以及块处于何种模式。LMS进程是全局缓存服务的关键组成部分。
(大致知道了实现方式,但还有很多细节需要了解)
(猜想:Oracle目前的cache fusion是在其他实例访问时会将块传输过去再构建一个块在那个实例的SGA中,这个主要的原因可能是interconnect之间的访问还是从本地内存中访问更快,从而让Oracle再次访问时可以从本地内存快速获取。但是这也有麻烦的地方,因为在多个节点中会有数据块的多个copy,这样在管理上的消耗是很可观的,Oracle是否会有更好的解决方案出现在后续版本中?如果interconnect速度允许的话...)
全局队列服务(GES):主要负责维护字典缓存和库缓存内的一致性。字典缓存是实例的SGA内所存储的对数据字典信息的缓存,用于高速访问。由于该字典信息存储在内存中,因而在某个节点上对字典进行的修改(如DDL)必须立即被传播至所有节点上的字典缓存。GES负责处理上述情况,并消除实例间出现的差异。处于同样的原因,为了分析影响这些对象的SQL语句,数据库内对象上的库缓存锁会被去掉。这些锁必须在实例间进行维护,而全局队列服务必须确保请求访问相同对象的多个实例间不会出现死锁。LMON、LCK和LMD进程联合工作来实现全局队列服务的功能。GES是除了数据块本身的维护和管理(由GCS完成)之外,在RAC环境中调节节点间其他资源的重要服务。
SQL> set linesize 1000
SQL> r
1* select * from gv$sysstat where name like 'gcs %'
INST_ID STATISTIC# NAME CLASS VALUE STAT_ID
---------- ---------- ------------------------------ ---------- ---------- ----------
1 44 gcs messages sent 32 5981 2765451804
2 44 gcs messages sent 32 3632 2765451804
SQL> select * from gv$sysstat where name like 'ges %';
INST_ID STATISTIC# NAME CLASS VALUE STAT_ID
---------- ---------- ------------------------------ ---------- ---------- ----------
1 45 ges messages sent 32 3760 1145425433
2 45 ges messages sent 32 4447 1145425433
SQL>
这里可以看到gcs和ges消息的发送个数。
(如果没有使用DBCA来创建数据库,那么要SYSDBA权限来运行CATCLUST.SQL脚本来创建RAC相关的视图和表)
以后将更加深入的理解这些概念。
怎样配制interconnect互联网络以保证高效运行?
1、硬件
2、参数设定
net.core.rmem_max最大的TCP数据接收缓冲
net.core.wmem_max
最大的TCP数据发送缓冲。
net.core.rmem_default
net.core.wmem_max 。
Cache Fusion
提供传输的扩展性,在实例间传输block 的image,跟踪资源的当前位置和状态,每个实例的sga的目录结构中保存有资源信息
Cache Fusion模型
Global Resoure Directory由Global Cache Service 来管理
记录资源的模式、资源的角色、block在实例中的状态、在各个活动的节点发布资源的master、在必要的时候重新发布master(例如实例的启动和关闭)
Global Cache Service
1、资源模式,三种
null (默认的)
share(s) (查询)
exclusive(x) (可以改变block的内容,其它的实例就是null mode)
2、资源角色,两种
local:
第一次请求资源的初试模式;只有一个实例可以有这个block的dirty copy
global:
当一个Block在多个实例中变dirty时,Local就变成了Global Block只能由Global Cache Service写到磁盘中
Cache Fusion Block的传输
例如:有ABCD四个节点,Global Cache Service: GCS
1. Read with no transfer
如果C节点需要向共享磁盘文件上读一个Block,那么它向Global Cache Service 发送请求,这个时候请求被定向到节点D,D是这个Block的Master(每个资源都有Master)。GCS把资源授权为Share Mode和Local Role,在目录中记录下了他的状态(目录在节点D),然后通知C,C把这个资源从Null改成Share。C开始I/O,现在C有了这个Block以Share模式从磁盘文件读取。
2. Read to write transfer
B也要这个Block,并且不仅是读,而且还要改变它的内容。B向D(这个Block的Mater)的GCS发出请求,GCS向C发出请求,要求C把这个Block给B,C把Block给B,B收到后,告诉GCS,现在B可以修改这个block了。
3. Write to write transfer
A向D节点的GCS发出请求,GCS告诉B节点放弃他的Exclusive锁,并且把当前的Image传到A,如果这个请求没有完成,就会放到GCS的队列里。B把这个Block传到A,这个时候,要写Log,强制Lg Flush,把模式变成Null。发送到A,并且告诉它这个Exclusive的资源可以用了。A收到了这个Block的Image,会通知GCS并且告诉它Block的Status是Exclusive。这个时候,B不能对这个Block做操作,虽然在它的Buffer Cache中,它还有这个Block的Copy。
4. Write to read transfer
C要读这个Block,先向D(Master)发出请求,GCS要求A把它传输到C,A接受到请求完成它的工作,这可能会在A写Log和Log Flush在发送这个Block之前。A会把它的Exclusive锁降低到Share模式。C把从A收到的Block的SCN取出来,建设成一个资源Assumption信息为GCS更新Global Resource Directory。
通过设置参数gc_files_to_locks,可以关闭Cache Fusion。这样就象8i的OPS一样,别的节点要访问数据快,必须等待别的节点提交,写回数据文件中。
Cache Resoure的Rematering
Cache Resoure在一个节点上不再需要继续Master,Dynamic Remastering能把它移动到不同的节点。GCS和GES使用动态的Remastering:在一个新实例加入到这个Active Set之后重新分发资源,在一个实例离开这个Active Set之后重新分发资源。