要了解read mostly locking,必须先了解cache Fusion,我也重新学习了下cache Fusion
cache Fusion的主要思路,就是将全局锁(PCM LOCK,BL,Buffer Cache Management类型的锁)在模式之外,添加了一个持有者角色的概念。
1. PCM LOCK的模式有3种,X/S/N
2. PCM LOCK的持有角色有2种,LOCAL与GLOBAL
1. 当一个块需要获取时,节点必须在该块上获得S模式的LOCAL锁
2. 当一个块需要修改时,节点必须在该块上获得X模式的锁,X模式的锁和S模式的读取锁是不兼容的,其必须让其他节点转化成N模式的锁
3. 当一个脏块出现在1个以上的节点上中,那么在被DBWR写回磁盘前,他就要从LOCAL角色升级到GLOBAL角色的,也就是说,GLOBAL角色的块,一定是个脏块,其他实例想要获取该块,必须通过实例传输,不能从磁盘读取,因为磁盘读取的块是旧块,需要前滚才能得到current块,而前滚只在恢复时才可能
4. 相反,如果一个块不是GLOBAL角色,那么其就是LOCAL角色。LOCAL角色的块不一定不是脏块,当就算其为脏块,其也只在修改它的实例上存在,如果其需要被传输到其他节点,其将升级为GLOBAL
5. 如果一个块角色是GLOBAL的,那么如果在上面持有S/X锁,那么说明该块在该节点是最新的,可以直接用,但是如果持有N锁,说明该块不是最新的,需要从其他节点获取。也就是说GLOBAL模式的块,无论如何也不能从磁盘读取
6. 如果一个块角色是LOCAL的,那么说明该块在磁盘上的版本也是最新的,可以从磁盘读取。如果其在脏的状态下需要传输到其他节点,那么其就会升级为GLOBAL的。
7. 当一个GLOBAL脏块被DBWR写回磁盘后,其将重新变为LOCAL的
8. 当一个脏块变为GLOBAL角色后,其他非当前持有该块的实例,必须保证持有的这个块,这个块当前被称为PI(POST IMAGE)块,直到MASTER通知其可以释放。为何必须持有PI块?因为一旦持有CUREENT块的节点宕机,该节点相关的恢复动作并不会重构这个块的current块。所以这个PI块必须被持有
从cache Fusion的机制上来看,读取必须要先向MASTER节点请求S锁
read mostly locking也就是提前在该对象在所有节点上都赋予S锁,这样就省掉了GRANT这一步。
由于持有S锁,也保证了磁盘中的块也就是最新快,当通过网络传输块的时间大于了磁盘传输块的时间时,将切换到从磁盘直接读取。在LMD进程的TRC中我们可以看到:
|
2012-12-16 00:04:19.002005 : Setting 3-way CR grants to 0 global-lru off? 0 -- 切换为通过cacheFusion获取
*** 2012-12-16 00:04:50.252 2012-12-16 00:04:50.252862 : Setting 3-way CR grants to 1 global-lru off? 0 -- 切换为从磁盘获取
*** 2012-12-16 00:05:52.135 2012-12-16 00:05:52.135770 : Setting 3-way CR grants to 0 global-lru off? 0
*** 2012-12-16 00:06:27.068 kjddt2vb: valblk [0.1d3a] > local ts [0.1d39] -- 通过cacheFusion获取的响应时间高于从磁盘获取
*** 2012-12-16 00:06:28.130 kjddt2vb: valblk [0.1d3c] > local ts [0.1d3b]
*** 2012-12-16 00:06:31.050 kjddt2vb: valblk [0.1d3e] > local ts [0.1d3d] |
从cache Fusion的机制上来看,修改必须先向MASTER节点请求X锁,其他节点必须转换到兼容的锁模式下
read mostly locking采用一个特殊的锁方式:anti-lock,反锁定。当节点需要X锁时,其将向所有节点广播消息,要求这些节点打开anti-lock。当anti-lock请求被广播后,如果存在节点打开了anti-lock锁定,该块上的所有S/X锁请求都将转换到cache Fusion的锁定机制,如果没节点打开了anti-lock锁定,就不需要转换而直接授予X锁。
当read-mostly locking 被dissolved时,或者脏块被写会到磁盘并且X锁被降级转换后,Anti-locks才将被清理
read-mostly locking由于预先授予了S锁,所以其可以极大的减少gc cr grant 2-way,gc current block 2-way,gc current block 3-way等待。同时,其将从磁盘读取数据块,这将增加IO的压力,会增加db file sequential read等待。
在read-mostly locking下,写的成本将增加,这是由于需要先进行anti-lock的广播,在转化为普通的锁定模式。这将增加gc current grant busy等待,也将增加gc cr grant 2-way以及一些块传输的等待EVENT
read-mostly locking需要高速磁盘支持,如果IO存在瓶颈,可以通过_gc_read_mostly_locking=FALSE关闭
当对象X请求过多时,Oracle将自动dissolve read-mostly locking机制,当X请求减少时,会考虑重新初始化read-mostly locking
read-mostly locking & DRM
对象上read-mostly locking的dissolve和initiate通过DRM协议完成,也就是说read-mostly locking是DRM的一部分
在10g时,可以通过_gc_affinity_limit(_gc_affinity_ratio)和_gc_affinity_minimum(_gc_policy_minimum)提高DRM的阀值,避免过量的DRM甚至达到关闭DRM的目的
但是11g虽然设置参数可以使DRM不发生,但是其无法关闭read-mostly locking这个特性,其只是关闭了对象上的read-mostly locking是否在进行切换,这说不定还会增加写的开销
_gc_read_mostly_locking参数用于控制read mostly locking
当然通过参数_gc_affinity_time(_gc_policy_time)和_gc_undo_affinity来关闭DRM,可以附带关闭掉read-mostly locking
Reader bypass是一个和read-mostly locking互斥的特性,用于提高读写竞争较多的应用的性能。
Reader bypass用于在当前块已经在本节点内存时,减少开始写以前的权限请求等待。当开始块更新时,并不等待其他节点的S锁释放,获得X锁授权,而是先立刻授予一个weak X lock,获得weak X lock后,立刻可以更新块,但是更新后不许提交,直到其他节点的S锁关闭或者转换到NL模式。当其他节点S锁关闭后,会通过LMS向weak X lock的节点发消息,所有节点都关闭后,将从weak X lock转换的X锁
gc current grant busy等待多的对象将从Reader bypass中受益。但是,如果COMMIT在X锁定获得前提交,那么COMMIT将在gc current grant busy上等待。所以COMMIT提交的频率将影响Reader bypass的效果
reader bypass的使用时间统计在gcs reader bypass grant immediate等待中查看
通过参数_gc_bypass_readers关闭
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8242091/viewspace-751579/ ,如需转载,请注明出处,否则将追究法律责任。