RAC-Cache Fusion内存融合

RAC最核心复杂的一个功能是cache fusion,内存融合机制。通过内存融合将两个实例的内存融合到一起,感觉就像一个内存一样。就是通过锁的机制保持几个实例的内存相互通信

LCK--Lock Process
LCK进程主要用来管理实例间资源请求和跨实例调用操作,调用操作包括数据字
典等对象的访问;
 并处理非CACEH FUSIONCHACE资源请求(例如:DICTIONARY CACHErow cache的请求)
由于LMS进程负责主要的锁管理功能,所以每个实例只有一个LCK进程。

无数据传输模式的读取

无数据传输模式的读取就是一个实例要读取数据块,数据块不是在其他实例的内存上,而是在一个磁盘上面,无传输就是指不需要从一个实例到另外一个实例上面。

实例2要读取一个数据块的时候,在RAC模式下面,每次去请求一个资源的时候,就要申请锁,这样通过锁的机制保证各个实例去访问数据块的时候能够有一种队列的方式去访问。

一句话总结就是在RAC模式下面每次去访问数据块的时候就要去请求锁,只有获得了这个锁,或者称为资源的时候,这样才允许访问数据块,如果请求的时候发现数据块被别人持有了,那么就不能获得访问数据块的权限,这个情况下面就要处于等待。RAC下面就会经常出现GC的等待(GOLBAL CACHE 全局内存资源的等待)。

 

RAC下面,一个实例去请求数据块的时候,在集群里面有一个resource master,即管理资源的,访问数据块的时候首先去resource master里面去申请锁,因为是读数据块,所以是以一种共享锁的方式去请求,一旦申请成功之后就将共享锁赋予实例2,持有共享锁之后就可以去访问数据块了。现在这个数据块不在内存里面,而是在磁盘上面,那么就直接去磁盘上将数据块读取出来。

 

所有数据块的传递都是通过私有网络来传递的,如果网络带宽有问题会造成性能上面的延迟。


读到写操作的数据传输

现在实例2将磁盘上面的数据块读到内存里面了,现在实例1要去修改该数据块。

首先实例1因为要修改数据块,那么就要申请排他锁,一旦将数据块放在实例2上面了,实例2就会将信息注册到resource master里面,所以resource maste会知道数据块存在于实例2上面,由于实例1要修改的数据块在实例2上面,所以resource master会去通知实例实例2将数据块传输到实例1上面。因为实例2上面对数据块使用的是共享锁,那么要传输到实例1上面要使用排他锁,因为互斥,所以实例2要将共享锁释放。实例2将数据块的状态通知给实例1。在实例1拿到该数据块的时候将数据块的状态告诉给resource master。实例1要修改该数据块,那么就要在该数据块上面加上排他锁。

每一个实例申请到数据块之后,会将数据块状态汇报给resource master。即注册到里面,这样以便于使得resource master知道数据块的分布。即数据块所在的实例和锁的形式。

实例1获得数据块之后加上排他锁之后就会将数据块的状态告诉给resource master。之后将数据进行修改。


写到写的数据传输


现在实例1已经对要被修改的数据块持有排他锁了,并且对数据修改完了。实例四要修改该数据块,这种机制和上面都差不多。

实例1的数据块资源已经注册到resource master里面了,所以resource master知道实例4要修改的数据块在实例1上面。这个时候resource master会去通知实例1将上面的数据块的情况告诉给实例4,所以实例1将资源的状态告诉给实例4,之后实例1释放排他锁,这个时候数据块在实例1上面就没有排他锁了,这个时候就可以将数据块拷贝到实例4上面了,实例4对该数据块加上排他锁,同时将实例4的状态注册到resource master里面去,最后就是修改数据了。

这里要注意一点,当实例1要将数据块传输给实例4的时候,实例1创建了一个脏数据的前映像。读是不需要创建一个前映像的,写是要创建的,这是因为要保证数据安全性。即将实例1上面的数据块创建一份备份拷贝到实例4上面。这样是防止实例4出现问题。

 

前映像--past image

实例1上面开始修改数据块了,最初数据块的值1323,修改完为1324之后就提交了,在修改的时候产生了redo,同时会产生undo,在修改之前会在undo里面构造前映像块。所以每次修改之后都会产生undoredo,最后修改完到1328了,这个时候有一个会话链接到实例2上面了,要将这个数据块改为1329,现在实例2上面还没有这个数据块,所以这个时候实例2要去以排他的方式去请求数据块,这个时候要从实例1上面将数据块拷贝到实例2上面,但是在拷贝1328这个数据块到实例2上面去之前要保留一个修改之前的印象,即保留1328这个数据块在实例1上面。

 

为什么这样做,其实也就是在实例2出现故障的时候做实例恢复时候用的。1328数据块拷贝到实例2上面了,实例2开始修改,修改成为1329,同时产生undoredo,修改完成为1329之后,做了一次提交,这个时候实例2上面的内存里面的redo就写到磁盘上面了,写到磁盘上面之后突然实例2就宕机了。这个时候实例2在还没有做检查点的时候就宕机,内存里面的数据就丢失了,修改的数据块在实例1和实例2的内存里面都没有写到磁盘上面,实例1一直修改数据块但是没有提交,但是实例2修改后提交了,宕机了。

 

RAC里面一个实例挂了,其他实例还在工作,这个时候不需要数据库重启,只需要其他实例来接管就可以了,在各个实例里面,redo是放在共享存储里面的,就是每一个实例都可以访问其他实例里面的redo信息,也就是将提交的数据但是还没有写到磁盘上面的数据用宕机的redo日志来重新生成一遍。这个过程由其他实例来做,因为其他实例没有宕机。

 

之前在实例1上面构造的前映像1328,在实例2宕机之后读取实例2上面的redo日志,运用实例2上面的日志来修复实例1上面前映像。让其变为1329

 

RAC里面,redo是可以共享的,之所以允许实例互相访问就在于当某一个实例坏了,其他实例可以读取该实例的redo信息进行恢复。前映像就是利用宕机后实例的redo信息将数据块恢复到最新的状态。

 

 

写到读数据传输

当去读一个写的数据块会发生什么问题?

实例4已经获得了数据块,并且以一种排他的方式来修改这个数据块了,现在实例2要来访问实例4上面的数据块,实例2上面要以读的方式去访问数据块就需要获得共享锁,实例2还是要去resource master请求一个锁,但是请求的是一个share锁,之后resource master就会告诉实例所需的数据块在实例4上面,现在实例2请求的是share模式的锁,现在实例4并不需要将锁全部释放掉,因为一个资源上面可以加多个共享锁。

 

 

某个实例要访问数据块一定要把数据块复制到本地,如果不在本地,那么有两种可能,一种是数据在磁盘上面,直接从磁盘上面将数据读取到内存,另外是数据块在别的内存里面,就要去另外一个实例的内存里面去请求,这里就要看数据块所在的实例加了什么样的锁,如果加的是排他锁,我们申请的是共享锁,那么就要等到锁释放了


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值