XL0代表Exclusive mode、Local Role、0个Past Image
读-读并发
假设4个节点的RAC环境,这四个节点分别是A、B、C、D,其中B是,master节点,假设初始访问数据DB1在A、B、C、D均没有。其中SCN是100;
实例A:GCS服务进程LMSn把这个请求转给Resource Master,即B节点
实例B:查询自己的GRD目录发现这个块没有被任何节点使用,同意A的请求
实例A:从磁盘读取数据块到缓存中,SCN是100,获得PCM lock(share mode,local role)
实例B:将读取信息记录到GRD
假设这时实例C也要读取这个数据块
实例C:向实例B发送请求
实例B:向实例A发出通知,让实例A发送数据
实例A:发送数据给实例C,并要求实例C要以share mode模式访问数据块,如果这时实例A已经释放,也需要通知实例C从磁盘访问
实例C:通知实例B,更新GRD
实例B:检查GRD,发现实例A以share mode持有数据块,于是想实例A发出请求,请求其Mode装换成NULL mode,
意味着实例A可以释放这块数据锁占有的内存空间。
实例A:向实例C发送数据块,并释放自己的PCM锁
实例C:获得exclusive mode PCM锁,通知实例B,更新GRD
实例B:更新GRD,删除实例A持有的条目
实例C:修改数据块后,数据块SCN升级为110
整个过程时通过内联心跳来拷贝的,没有任何IO操作
实例B:查看GRD,确定实例C持有当前版本(current version),于是向实例C转发请求
实例C:发送数据块,将自己的锁降级为NULL-MODE
将log写到redo log file
将buffer标识为null mode,PI=1,表示现在持有的这个数据块的PI版本,必须等到current version写到磁盘才能清空。
发送的数据块是current state的,也就是带着修改的内容发送的,cache fusion的传送过程时跨事务边界的,也就是说不必等待实例C上的事务完成,就可以发送这个PI数据块。
实例B:更新GRD
实例D:对写入数据块做相关操作,SCN更新为114
实例C:通知实例B写入磁盘.
实例B,查看GRD,确定实例D持有current version,向实例D发送写请求
实例D:把数据块写入到磁盘,同时在日志中记录一条BWR记录,并把锁降级为XL0
实例D:通知实例B,写成功
实例B:通知所有拥有PI的实例,可以清空其PI空间,对于实例D,已经有了BWR记录,不用清空LOG buffer,
如果多个实例有PI,则都要清空,这些实例会记录一条BWR在log中
实例C:清空内存空间,并在log buffer中记录BWR记录,同时释放锁。
在集群环境中,只有当需要清空的数据块是current或PI版本是,才需要发出些请求,也就是对数据块做过修改,才发出写请求。
实例B:查找GRD,实例D持有current version,向实例D转发请求
实例D:发送数据块,模式降级为SG1
实例A,获得数据块,获得share模式