
我将为您深入解析Oracle Real Application Clusters (RAC) 的核心基石——缓存融合(Cache Fusion)。这是Oracle实现多节点共享数据库架构的关键技术,其复杂性和精巧程度代表了Oracle数据库设计的巅峰。
第一部分:官方定义与核心作用
一、官方定义 (Official Definition)
缓存融合是一种高级的集成缓存机制,它是Oracle RAC架构的核心。它允许一个数据库实例的缓冲区缓存(Buffer Cache)直接通过高速互连网络(如Infiniband)为另一个数据库实例的缓冲区缓存提供数据块,而无需首先将数据块写入磁盘。 这意味着集群中的所有实例的缓冲区缓存被有效地“融合”成一个逻辑上统一的、被所有实例共享的庞大缓存池。
二、核心作用 (Purpose)
- 维持数据一致性:确保集群中任何一个实例在任何时刻看到的数据块都是一致的,无论该数据块在哪个实例的内存中被修改。
- 减少磁盘I/O:极大化地减少了为实现集群范围内数据一致性而必须进行的磁盘读写操作(这是早期并行服务器技术的主要瓶颈),从而提供了近乎线性的扩展能力。
- 实现可扩展性:多个实例可以同时处理读写工作负载,通过缓存融合协调对共享数据的访问,使得增加实例可以提升整体数据库的处理能力。
通俗解释:
将Oracle RAC集群比作一个联合图书馆,每个分馆(实例)都有自己的藏书室(Buffer Cache)。
- 旧方式(无缓存融合):分馆A的读者想借一本只有分馆B才有的书。分馆B必须先把这本书运回中央书库(磁盘),然后分馆A再派人去中央书库取回来。这个过程非常慢。
- 缓存融合方式:分馆之间有一个高速传送带(高速互连网络)。分馆A直接给分馆B发个消息:“请把《XXX》这本书传给我”。分馆B通过传送带直接把书送到分馆A的藏书室。书始终在分馆之间流通,无需每次都放回中央书库。这就实现了资源的共享和高效利用。
第二部分:深入底层原理与管理机制
缓存融合的实现依赖于三个核心全局服务和一个通信层。
一、核心组件
- 全局缓存服务 (GCS - Global Cache Service):
- 作用:缓存融合的“大脑”。它负责跟踪每个数据块在集群所有实例中的状态和位置(主节点/Master Node),并协调实例间的块传输请求。GCS维护着一个全局资源目录(GRD),记录着每个数据块的当前状态和锁信息。
- 全局队列服务 (GQS - Global Queue Service):
- 作用:管理全局入队(Enqueue)资源,如库缓存锁和字典缓存锁,确保这些逻辑结构在集群中也是一致的。
- 全局资源目录 (GRD - Global Resource Directory):
- 作用:GCS和GQS所使用的内存中心库,存储着所有共享资源(数据块、锁)的当前状态。GRD并不集中存储,而是分布式地存在于所有活动实例的内存中。每个资源都有一个主节点(Master Instance),由该节点负责管理该资源的所有锁请求。
- 高速互连网络 (High-Speed Interconnect):
- 作用:实例间进行缓存融合块传输的“高速公路”。通常使用专用的万兆以太网或InfiniBand网络,与对外的业务网络隔离,以确保极低的延迟和高带宽。
二、缓存融合的详细过程:块状态与锁模式
每个数据块在全局缓存中都有两种属性:锁模式(PCM Lock) 和数据状态(Data Mode)。
- 锁模式(PCM Lock):表示实例对该块的访问权限。
- N(空):无锁。
- S(共享):实例可以读取该块。
- X(独占):实例可以修改该块。
- 其他(如SSX):更复杂的模式。
- 数据状态(Data Mode):表示该块在实例内存中的映像版本。
- CR(一致性读):通过应用UNDO构建的历史版本。
- XCUR(当前独占):唯一的、可修改的当前版本。
- SCUR(共享当前):只读的当前版本。
- PI(过去映像):这是缓存融合的核心概念。当一个实例将脏块发送给另一个实例后,它必须在自己的缓存中保留一份该块的旧版本(PI)。这样,如果实例自己需要回滚或进行恢复,它不需要再去打扰当前拥有最新版本的实例。
三、缓存融合操作流程举例
场景: 实例1需要更新数据块100,而该块的当前最新版本(XCUR)在实例2的内存中。
- 请求权限:
- 实例1的服务器进程向GCS发出请求:“我需要以独占(X)模式访问块100”。
- GCS查询GRD,发现块100的当前主节点是实例2,且当前被实例2以X模式持有。
- 协调与传输:
- GCS(或直接)发送消息给实例2(资源主节点):“实例1需要块100的X锁”。
- 实例2的LMS(全局缓存服务进程)执行以下操作:
- a) 如果块100是脏的(已被实例2修改),则通过互连网络直接将块100的当前映像发送给实例1。这就是“缓存融合”的传输。
- b) 实例2将其本地块100的状态从XCUR降级为NULL,但保留一个PI(过去映像) 作为备份。
- c) 实例2通知GCS:“所有权已转移”。
- 完成操作:
- GCS授予实例1对块100的X锁。
- 实例1收到块100的数据,在内存中将其状态设置为XCUR。
- 实例1现在可以修改块100了。
整个过程,块100始终没有被写入磁盘。 数据直接在实例2和实例1的内存之间流动。
第四部分:争用、等待事件与排查解决
缓存融合虽然强大,但也引入了新的等待事件和潜在的争用点,主要围绕全局缓存(gc)等待。
1. 全局缓存等待事件 (Global Cache Wait Events)
这些是RAC环境中最重要的性能指标。
gc cr block busy/gc current block busy:- 场景:实例请求一个块(CR或Current),源实例已经发送了块,但请求实例在接收后无法立即使用该块,因为该块在缓冲区中正被另一个会话访问(
buffer busy waits)。 - 本质:这通常是热点块争用在RAC环境中的体现。多个会话频繁访问同一个块(如小表的全表扫描、索引根块、频繁更新的行)。
- 排查与解决:
- 排查SQL:
-- 找到热点块 SELECT * FROM ( SELECT o.OWNER, o.OBJECT_NAME, o.OBJECT_TYPE, bh.DBPFILEN, bh.DBBLKNO, COUNT(*) NUMBER_OF_WAITS FROM GV$SESSION_WAIT w, GV$BH bh, DBA_OBJECTS o WHERE w.EVENT LIKE 'gc%block busy%' AND w.P1 = bh.FILE_ID AND w.P2 = bh.BLOCK_ID AND bh.OBJD = o.DATA_OBJECT_ID GROUP BY o.OWNER, o.OBJECT_NAME, o.OBJECT_TYPE, bh.DBPFILEN, bh.DBBLKNO ORDER BY NUMBER_OF_WAITS DESC ) WHERE ROWNUM <= 5; - 解决方案:
- 应用设计:避免热点块,使用序列缓存(
CACHE子句)、反向键索引(Reverse Key Index)来分散插入热点。 - 优化SQL:减少对同一块的频繁访问。
- 应用设计:避免热点块,使用序列缓存(
- 排查SQL:
- 场景:实例请求一个块(CR或Current),源实例已经发送了块,但请求实例在接收后无法立即使用该块,因为该块在缓冲区中正被另一个会话访问(
gc cr block 2-way/gc current block 2-way:- 场景:请求实例直接向主实例请求块,主实例拥有该块并直接发送。这是最理想、最快速的传输方式。如果这种事件是主要等待,通常意味着传输本身是正常的,但如果等待时间过长,可能表明互连网络延迟高或带宽不足。
- 排查与解决:
- 使用
ping、ipref等工具检查互连网络延迟和带宽。 - 确保使用专用的高速网络(如InfiniBand)。
- 使用
gc cr block 3-way/gc current block 3-way:- 场景:请求实例向主实例A请求块,但主实例A发现该块的最新版本在另一个实例B中,于是请求实例需要再向实例B请求块。3-way传输比2-way慢。
- 影响:增加了延迟,表明资源的主节点(Master)和当前持有者(Owner)不在一起,GCS需要额外跳转。
- 解决方案:这通常是正常操作的一部分,但如果比例过高,可能表明工作负载分布不均。
gc buffer busy:- 场景:与单实例的
buffer busy waits类似,但发生在全局缓存级别。一个实例正在等待GCS授予它访问某个块的权限,因为另一个实例正在请求该块或正在对其进行操作。 - 排查与解决:同
gc cr block busy,定位并解决热点块。
- 场景:与单实例的
2. 互连网络瓶颈
- 场景:
gc类等待事件的平均等待时间(AVG_MS)持续很高(例如 > 10毫秒,而良好状态下应 < 5毫秒)。 - 排查:监控操作系统级别互连网络的吞吐量和丢包率。查看AWR报告中的“Interconnect Performance”部分。
- 解决方案:升级网络硬件(切换到InfiniBand)、优化网络配置(Jumbo Frames)、平衡工作负载以减少跨实例的块传输。
3. 日志写竞争
- 场景:虽然缓存融合处理数据块,但重做日志仍然是本地的。一个实例的
LGWR进程写日志文件慢,会阻塞该实例释放全局锁,进而导致其他实例的gc等待。 - 等待事件:
log file sync(在某个实例上)伴随其他实例出现gc等待。 - 解决方案:确保每个实例的日志文件放在本地、高性能、专有的存储上(如高速SSD),避免所有实例的日志文件共享同一个慢速的存储阵列。
第五部分:常用监控SQL
-
查看全局缓存等待事件排名:
SELECT INST_ID, EVENT, TOTAL_WAITS, TIME_WAITED_MICRO, ROUND(TIME_WAITED_MICRO / TOTAL_WAITS / 1000, 2) AVG_MS FROM GV$SYSTEM_EVENT WHERE EVENT LIKE 'gc%' ORDER BY TIME_WAITED_MICRO DESC; -
查看全局缓存负载分布:
SELECT INST_ID, SUM(`CR REQUESTS`) CR_REQS, SUM(`CURRENT REQUESTS`) CUR_REQS FROM GV$LIBRARY_CACHE GROUP BY INST_ID; -- 这可以帮助判断实例间负载是否均衡 -
识别热点块(如前文所述)。
-
监控互连网络流量(Linux示例,需在OS层执行):
# 查看指定网卡(如eth1)的流量和丢包 ifconfig eth1 # 或使用更先进的工具 ip -s link show ib0 # 对于InfiniBand网络
总结
官方总结:缓存融合是Oracle RAC的架构核心,它通过全局缓存服务(GCS)、全局资源目录(GRD)和高速互连网络,实现了集群实例间缓冲区缓存的直接传输,在保证数据一致性的同时,极大减少了磁盘I/O,提供了线性扩展能力。其性能主要受全局缓存等待事件(如gc cr block busy)和互连网络性能的影响。
通俗总结:Oracle RAC通过缓存融合,将多个数据库实例的“内存”(缓存)用“高速光纤”(互连网络)连接起来,组成了一个“超级大脑”。
- 好处:数据不用再笨拙地来回倒腾到磁盘共享,而是直接在内存间“瞬间传送”,速度极快。
- 代价与挑战:这个“超级大脑”内部的通信(缓存融合)变得极其频繁和复杂。一旦出现“抢东西”(热点块争用)或者“神经传导慢”(网络延迟),整个系统的反应就会变慢。
- DBA的使命:就是当好这个“超级大脑”的“神经科医生”和“交通警察”——优化应用避免“抢东西”(减少热点),保障“神经网络”的高速畅通(优化互连),确保各个“脑区”工作量均衡(负载均衡),这样才能让RAC集群发挥出真正的威力。
欢迎关注我的公众号《IT小Chen》
1474

被折叠的 条评论
为什么被折叠?



