Oracle RAC学习笔记01-集群理论

时间:2023-05-10 21:59:50

Oracle RAC学习笔记01-集群理论

写在前面:

最近一直在看张晓明的大话Oracle RAC,真实感受就是学到很多之前自己都没深入思考研究过的知识点,现在趁着节前头脑尚清醒,再结合实际工作中自己曾遇到的一些案例,就把这段时间自己学到的东西总结一下。

1.集群相关理论概述

一个集群(cluster)由2个或多个节点(nodes)组成。一般集群对外都会有统一的服务接口(**集群地址**),对内需要(**集群内部通信**)不断确定集群内部节点可用,一旦发生异常,可以通过(**集群仲裁**)驱逐问题Partition,使得集群能够不影响整体对外提供服务。

集群系统的设计一般都需要考虑2个经典问题:健忘和脑裂。

健忘:集群的配置文件,集群中各节点需要保证集群配置文件的一致性;

Oracle Clusterware集中记录这些信息到OCR,且整个集群只保留一份配置,各节点共用这份配置,解决了健忘的问题。

脑裂:集群内节点心跳通信故障时,集群需要决定具体哪个partition被踢出集群。

Oracle Clusterware采用两种心跳机制:网络心跳和磁盘心跳;当通过私有网络的网络心跳故障,需要使用voting disk的磁盘心跳来仲裁Partition剔除。

脑裂问题紧接着还涉及一个IO Fencing问题,即需要保护数据不被故障节点所修改破坏。RAC使用oprocd进程实现IO Fencing。

为了便于学习和理解,将RAC环境分为 存储层、网络层、集群层、应用层 4层来分别学习。

存储层

由SAN组成的存储层,由于RAC架构是共享存储,常规场景下只需要有一个存储。

但如果预算充足,为了进一步提高可用性,我们完全可以在存储层考虑使用2个存储,在存储层构建一个存储层面的集群。比如使用EMC的vplex,HDS的GAD(Global-Active Device)等。

这种存储级别的集群,在extended RAC架构中很常见。这一块基本都偏向于底层存储层面的知识,与RAC本身关系不大,不再多说。

网络层

public IP:集群各节点真实IP地址,和其他应用服务器连接在一个交换机上。

10g RAC VIP:在Public IP所在网卡上绑定一个VIP。

优点是:VIP是浮动的,使用VIP,可以避开对TCP协议栈超时的依赖。

11g RAC SCAN IP:在 VIP 基础上 再引入的scan IP,也有对应的scan IP的监听。

优点是:使用scan IP配置客户端连接,以后集群内部添加删除节点,不需改动客户端的tns配置。

private IP:集群内部互联IP,大数据量、低延迟要求,预算低用G级以太网,预算高用infiniband。

网络心跳(Network Heartbeat)使用这个private IP网络。

缓存融合(Cache Fusion)也是通过这个private IP网络进行传输。

集群层

集群层是在OS kernel和应用之间的一层。用来统一协调集群内各节点正常调度有序工作。

10g RAC 通过Oracle Clusterware来实现这一层的功能。

11g RAC 改名clusterware为GI。

GI除了名字上的不同,还有很多改变,比如将ASM安装的集成到GI中,比如GI的安装一般建议单独用户(grid)安装,而之前clusterware一般都是和数据库在同一用户(oracle)安装的等等,可以简单认为GI比clusterware更加完善细化了。

应用层

应用层是指在集群件之上的具体应用和资源。

RAC 按照用途主要把应用层分为2大类:nodeapps(节点应用) 和 database-related resource(数据库资源)。

nodeapps:GSD、ONS、VIP、Listener等。

database-related:Database、Instance、Service等。

2.Oracle Clusterware

Oracle Clusterware是Oracle自己开发的能支持所有平台的集群件,现在市场上还主要是用于RAC。

它的运行环境由两个磁盘文件、若干后台进程以及网络元素组成。

2.1 磁盘文件

两个磁盘文件,即OCR和Voting disk。

在10g RAC中,这两个文件必须放在真正的裸设备上,不可以放在ASM中。

在11g RAC中,这两个文件可以放在ASM上。

OCR:

负责维护整个集群的配置信息,包括RAC以及Clusterware资源,包括节点成员、数据库、实例、服务、监听器、应用程序等。

Voting disk:

存放在共享存储上,在集群出现“脑裂”时,仲裁哪个Partition最终获得集群的控制权。

2.2 后台进程

大家都知道的Clusterware最重要的进程:

CSS:管理集群内节点

CRS:管理集群资源

EVM:管理事件通知

我们具体来看clusterware中的主要后台进程:

ocssd: 用来管理集群内节点的加入/踢除。这个进程是clusterware中最关键的进程,如果该进程出现异常,会导致系统重启。

oprocd: 用来实现IO Fencing,早期Linux平台,使用hangcheck-timer模块来实现IO Fencing,从10.2.0.4开始,Linux平台也使用oprocd进程。

oclsomon: 用来监控css进程,如果发现进程挂起,会重启节点。

crsd: 用来管理集群内资源,是实现HA的主要进程。负责管理注册应用的start、stop、monitor、failover。

racgwrap脚本:CRSD会使用这个脚本来启动、关闭、检查实例的状态。

evmd: 负责发布CRS产生的各种事件。

racgimon: 用来监控集群健康状态,负责Service的启动、停止、故障转移。

2.3 网络元素

Oracle TAF是建立在VIP技术之上的。

TAF(Transparent Application Failover):对应用透明的故障转移。

文章前面在网络层概述提到过:VIP是浮动的,使用VIP,可以避开对TCP协议栈超时的依赖。

原因是:

TCP/IP实际的四层模型从下到上依次为:网络接口层(MAC)、网络层(IP)、传输层(TCP)、应用层(Listener)。

Public IP 和 VIP都属于网络层。

而当节点异常,对应的VIP会飘到其他节点,而其他节点没有该VIP地址的监听。VIP利用应用层的立即响应,避开对TCP协议栈超时的依赖。

3.Oracle RAC 原理

抛砖引玉:
GCS、GES、GRD、PCM这些东西是如何堆砌在一起的?
RAC的HA、LB、Cache Fusion...

3.1 数据库基本原理

数据库基本原理:同时保证并发和数据一致性。

1) 隔离级别

SQL-92标准中定义了四个隔离级别:Read Uncommitted、Read committed、Repeatable、Serializable。

Oracle 默认实现read committed隔离级别而不影响并发;这也曾是Oracle比较得意的地方。

2) 锁

数据库系统使用“锁”来控制“并发”。

Lock:代表一种控制机制,Lock框架包含3个组件:Resource Structure(资源)、Lock Structure(锁)、Enqueue(排队机制)。

Row-Level Lock:对于“数据记录”这种细粒度资源,Oracle使用的是行级锁。

行级锁共涉及以下4种数据结构:

ITL:块头ITL,用于记录哪些事物修改了这个数据块的内容,可以把它想成一个表格,每行记录一个事物,包括事物号、事物是否提交等重要信息。

记录头ITL索引:每条记录的记录头部有一个字段,用于记录ITL表项号,可以看作是指向ITL表的指针。

TX锁:这个锁代表一个事物,属于Lock机制。

TM锁:属于Lock机制,用于保护对象的定义不被修改。

无论一个事物修改多少个表的多少条记录,该事物真正需要的只是一个TX锁,每个表一个TM锁,内存开销非常小。而所谓的“行级锁”只是数据块头、数据记录头的一些字段,不会消耗额外资源。

因此,对于Oracle的“行级锁”必须要有正确的理解,它不是Oracle中通常意义上的“锁”,虽然有锁的功能,但是没有锁的开销。

Latch: Latch请求,获得,释放等操作是原子操作,一般几个硬件指令就可以完成。是一种低级锁,主要用于保护数据结构。

也就是说如果请求Latch得不到,不会释放CPU资源,而会不断尝试请求,只有在一定次数还不能获得时,才释放CPU。这就是Latch的spin机制。

锁模式:

--官方文档中v$lock中LMODE取值
0 - none
1 - null (NULL)
2 - row-S (SS)
3 - row-X (SX)
4 - share (S)
5 - S/Row-X (SSX)
6 - exclusive (X) --手工加锁语句语法参考
lock table &table_name in [ROW] SHARE, [[SHARE] ROW] EXCLUSIVE, SHARE UPDATE --2 - row-S (SS)
lock table t_second_p in row share mode;
lock table t_second_p in share update mode;
--3 - row-X (SX)
lock table t_second_p in row exclusive mode;
--4 - share (S)
lock table t_second_p in share mode;
--5 - S/Row-X (SSX)
lock table t_second_p in share row exclusive mode;
--6 - exclusive (X)
lock table t_second_p in exclusive mode; --查看被锁的对象
select * from v$locked_object;

3) SQL语句执行过程:

用户发出一条SQL语句,将主要经过解析、优化、产生执行计划、返回执行结果几个阶段。

如果解析后发现,在shared pool中已经有对应的执行计划,就可以直接拿来使用,相当于跳过了中间优化、产生执行计划2个步骤,这就是软解析。

这个过程中对Lock和Latch的使用:

前三个阶段目的就是产生执行计划,所谓“执行计划”就是对应shared pool中一个复杂的数据结构。

a. 为了产生这个数据结构,Oracle要计算SQL语句的哈希值,根据这个值确定要检索的“桶“(Hash Bucket),然后遍历这个桶中的”链表“,看是否有相同的SQL语句。如果没有,就要进行硬解析。

进程要从shared pool空闲空间中申请一块空间,用来存放编译后的执行计划。这就需要检索另一个”空闲链表“,从中申请一个大小合适的空闲块,申请成功后要更新这两个链表。在这个过程中,至少

涉及两个数据链表的访问,这个访问是”排他“(exclusive)的,不允许其他进程同时修改乃至访问,这就需要对”链表“加锁,这种锁用的就是Latch机制。

b. 在语句编译和执行过程中,“引用对象”的结构不能被更改。在编译前,需要把表的”元数据“加载到内存,在随后编译和执行过程中,这个内容保持不变,也就是不能让其他用户改变这个表的结构。

这里使用的就是TM Lock。

c. 执行阶段,要在buffer cache中定位到数据块,同样根据数据块地址查找“桶”中的“链表”找到最终的数据块。在这个过程中,链表数据结构也不能被修改,同样是使用latch保护。访问数据块

中的记录时,也要限制其他进程的访问,使用的是行级锁进行保护。

3.2 RAC环境并发控制

1) DLM、Cache Fusion、Non-Cache Fusion

由于要解决多个节点的并发,所以额外引入了DLM(Distribute Lock Management)。

DLM在Oracle发展的不同时期,名字也不相同,在OPS时期,叫做PCM;而在RAC时期叫做Cache Fusion。

在RAC中,DLM是以数据块作为粒度单位进行协调。

DLM协调集群各节点对资源使用的功能就叫做同步。在DLM中,根据资源数量、活动密集程度将资源分成了两类:PCM Resource、Non-PCM Resource。[也称Cache Fusion Resource、Non-Cache Fusion Resource]

对应两种资源,DLM提供的锁也是两种:PCM Lock、Non-PCM Lock。[也称Cache Fusion Lock、Non-Cache Fusion Lock]

在RAC数据库*有两大类四种锁:

Local Lock:用于本地进程的并发控制,就是与传统单实例一样的,Latch 和 Lock。

Global Lock:用于集群间的并发控制,就是 PCM Lock 和 Non-PCM Lock。

典型的Non-Cache Fusion资源就是row cache和library cache。

PCM Lock 有三种模式,分别对应SGA中数据块的状态如下:

PCM Lock Mode    Buffer state
X XCUR
S SCUR
NULL CR

2) GRD

Cache Fusion要解决的首要问题是:数据块拷贝在集群节点间的状态分布图。RAC是通过GRD来实现的。

GRD位于每个实例的SGA中,所有实例的GRD汇总在一起才是一个完整的GRD。

GRD中记录的是PCM Lock信息,这种锁有三个属性:Mode、Role、PI。

Mode:X、S、NULL。

Role:L和G。

PI:Past Image主要能够加速Crash Recovery的恢复过程。

书中模拟一个场景:4节点RAC,针对一个数据块,这个数据块的Master node是节点2。PCM Lock用ModeRolePastimage格式描述,比如SL0代表Share Mode、Local Role、0个Past Image。

分别对并发读、读并发写、写并发写、写入磁盘、写并发读等情形,描述了集群相关节点的GRD、PCM Lock的变化过程,体会到Cache Fusion具体是如何工作的。限于篇幅,这里不再赘述。

总之,无论是单实例还是RAC,实例要修改数据块,必须获得这个数据块的当前版本。

3.3 RAC架构

**1) SGA的变化 **

多了一个GRD(Global Resource Directory)部分,GSD的功能前面已经说过。

2) 后台进程的变化

LMSn GCS(Global Cache Service),这个进程是Cache Fusion的主要进程,负责数据块在实例间的传递。

LMD GES(Global Enqueue Service),这个进程负责在多个实例之间协调对数据块的访问顺序。它与LMSn进程的GCS服务还有GRD共同构成RAC最核心的功能Cache Fusion。

LCK 这个进程负责Non-Cache Fusion资源的同步访问。

LMON 各个实例等LMON进程会定期通信,检查集群中各节点的健康状态。负责集群重构、GRD恢复等操作,它提供的服务叫做CGS(Cluster Group Services)。

LMON提供节点监控功能:通过一个保存在GRD中的位图来记录(0代表节点关闭,1代表节点正常);

LMON检测到实例级别的“脑裂”时,会通知clusterware解决,如果等待超时,LMON进程会自动触发IMR(Instance Membership Recovery)。

LMON进程提供的IMR功能可以看作是Oracle在数据库层提供的“脑裂”,“IO隔离”机制。(LMON也借助两种心跳:网络心跳、控制文件的磁盘心跳)。

DIAG DIAG监控实例的健康状态,并在实例运行错误时收集诊断数据到Alert.log日志中。

GSD GSD进程负责从客户端工具,比如srvctl接收用户命令,为用户提供管理接口。

3) 文件

spfile 需要被所有节点访问,存放在共享存储上。

redo thread 每个实例都需要自己的一套redo log。需要被所有节点访问,存放在共享存储上。

archived log 建议存放在共享存储上。当然也有其他设计方式。

undo tablespace 每个实例都需要有一个单独的回滚表空间。存放在共享存储上。

4) SCN

在RAC中,由GCS负责全局维护SCN的产生,ORACLE 10g RAC 缺省使用的是Broadcast算法,可以从alert.log中看到。

5) Cache Fusion、GCS、 GES

GCS负责数据块在实例间的传递;

GES负责锁管理。

3.4 RAC和Clusterware的交互

RAC集群和节点集群是两个层次的集群,两个集群都有脑裂、IO隔离等问题。

两个集群有各自的故障检测机制,二者之间的机制可以有重叠也可以不同。

在RAC这一层出现节点故障时,首先会通知clusterware这种异常,等待clusterware完成集群重构,完成后再通知RAC,RAC集群再开始自己的重构,但是RAC并不完全依赖于clusterware解决问题,如果发生等待超时,RAC的LMON进程会自动触发IMR执行节点排除。

Reference

- 张晓明. 大话Oracle RAC[M]. 人民邮电出版社, 2011.
- 张晓明. 大话Oracle Grid[M]. 人民邮电出版社, 2014.