内存融合核心进程
LMS(Global Cache Service Process):这个进程负责完成GCS的大部分工作,它会维护GRD中数据块资源的信息,完成数据块在实例之间的传递工作,相关消息的发送和接收工作。每个数据库实例中会存在多个LMS进程,名称为LMS,默认的LMS进程数量是根据节点的CPU数量计算出来的。
LMD(Global Enqueue Service Daemon):这个进程主要负责GES相关资源的管理工作,GES资源主要指Oracle中的排队(Enqueue)资源,由于RAC数据库包含很多实例,每个实例都能够对相同的数据进行操作,所有需要LMD进程对这些队列资源进行管理和协调,每个数据库实例只包含一个LMD进程。
LCK(Instance Enqueue Process):这个进程主要负责实例锁(实例锁的含义并不是实例级别的锁,而是指这种锁管理的资源仅限于本地实例)管理,实例级别的锁包括:library cache lock,row cachelock等,实例级别的锁是由LCK进程通过广播的方式进行管理的,当一个进程需要持有一个实例锁时,LCK进程会以广播方式向所有远程实例的LCK进程发送这个请求,而远程实例收到这个请求之后,更新自己的信息并反馈信息(如果远程实例的某个进程以不兼容的方式持有了这个锁,对应实例的LCK进程会通知持有者进程释放对应的锁,然后再返回),每个实例默认情况下只包含一个LCK进程。
全局资源目录(Golabl Resource Directory)
GRD:在shared pool与buffer cache中保存和组织内存融合相关的所有资源的一种方式,每个数据库实例中都包含GRD的信息,所有实例的内存融合信息构成了整个GRD。LMS和LMD进程实现了对GRD的访问与管理,LMS进程负责GCS资源和锁,LMD进程负责GES资源和锁,服务器进程作为访问GRD的客户端,需要同LMS和LMD进程进行协作,完成客户端发送的请求,可以认为服务器进程是GRD的客户端,LMS和LMD进程是GRD的服务器进程。
PCM资源与PCM锁
对于RAC数据库,PCM资源指数据库的块(buffer),当客户端访问一个数据块时,LMS进程会创建一个PCM资源对应这个块,并创建保护这个资源的锁结构。PCM资源保存在buffer cache中,而PCM资源对应的锁保存在shared pool中。
PCM锁的属性
模式:PCM锁有3种模式,N(空),S(共享),X(独占)。
角色:PCM锁的角色对应数据块被修改的范围,本地(L)表示对应的块只在本地实例被修改过,全局(G)表示对应的块在多个远程实例中被修改过
PI:当一个数据块在多个实例被修改的时候,除了最新修改该块的实例(数据块最新版本),其他实例对应的块都被标识成PI(数据块次新版本),并且将PI对应的修改写入重做日志文件中。
任何持有最新版本数据块或PI数据块的实例都可以发起写请求。
发起写请求的实例并不一定是将buffer写入到数据文件的实例,将buffer写入数据文件的实例是持有最新版本数据块的实例。
最新版本的数据块被写入数据文件后,持有PI数据块的实例会清除PI数据块。
GES资源与非PCM锁
锁:由于数据库资源会被多个客户端同时访问(查询或修改),因此需要一些串行化的机制来保护资源的一致性,锁就是保护资源串行化的数据结构,由于锁管理是通过队列实现的,因此锁又称为排队资源。
锁模式
共享锁(S):这个模式允许相关的资源被共享,例如允许多个事务同时访问相同的表记录。
排他锁(X):这个模式防止相关的资源被共享,例如禁止多个事务同时修改相同的表记录。
直到事务结束,锁才会被释放。
锁的兼容性:当一个进程尝试以某个模式持有一个锁时,会查看这个锁的持有者队列中的进程都是以什么模式持有的这个锁,如果持有者队列中所有进程持有该锁的模式和申请者申请的模式是兼容的,那么申请者可以被赋予这个锁,申请被满足;反正,如果持有者队列中的某一个进程持有的该锁模式和申请者需要的模式不兼容,那么申请者就需要进入等待者队列,直到持有者队列中不兼容模式的锁被释放。
对于RAC数据库,GES资源指数据库中的各种排队资源(非PCM资源),GES资源也会被多个实例同时访问,因此也需要一些串行化机制来保护GES资源的一致性(非PMC锁)。GES资源与对应的锁都保存在shared pool中。
主节点
对于RAC数据库,由于数据库同时存在多个实例,而且每个实例都会对资源(无论是PCM资源还是非PCM资源)进行访问,GRD中的资源需要能够被多个实例同时访问,因此需要存在一个协调记录对应资源上的锁信息,并协调来自于多个实例的资源申请,主节点就是指用于保存资源的定义信息以及上面的所有锁信息,并负责协调资源申请的节点。当一个资源第一次被访问的时候,Oracle根据哈希算法计算出该资源所对应的节点,并将这个资源的定义信息以及资源上所有的锁信息保存在主节点上。
PCM资源申请过程
阶段1:资源申请节点发送申请到主节点。
阶段2:资源主节点将对应的请求发送给资源持有节点。
阶段3:资源持有节点将本地持有的资源锁进行相应的改变,之后将资源发送给资源申请节点。
阶段4:资源申请节点获得了需要的资源,并通知资源主节点更新资源的相关锁信息。
在实际应用中,一个资源的申请过程只会涉及两个实例(例如:资源的申请节点和主节点是同一个节点或资源的主节点和持有者节点是同一个节点),或者一个实例(3个节点都是一个节点),因此在RAC数据库中的3路申请或2路申请指一个资源申请的过程需要涉及3个节点或2个节点。
总结:LMS负责协调实例间数据块的传递,LMD负责协调全局锁,LCK负责协调实例锁。
消息(Message)
消息是RAC实例之间通信的实现方式,RAC中与内存融合相关的信息都是通过消息的方式进行传输的,消息可以分成两类:一类是需要立即进行传递而且要被及时反馈的消息(申请消息),另一类是可以异步发送的消息(当申请者获得了资源之后,向主节点发送的资源更新消息)。
流量控制(Flow Control)
请求端在发送消息时,就必须持有一个ticket,响应端在发送响应消息的同时也会把响应端的有效ticket数据一起发送,请求端在接收到这个ticket数据之后会进行判断,如果响应端的ticket数量小于请求端的有效ticket数量,那么请求端会暂停一段时间再发送消息,反之,请求端继续发送消息。
DRM(Dynamic Remastering)
一个四节点的RAC数据库,会有1/4的数据块的主节点信息被保存到每一个实例,同时也意味着一个节点访问数据块时有3/4的概率需要从远程节点获得该数据块的锁信息,这意味着会出现更多的2路或3路通信,从而造成更多的消息通信。在实际的应用中,一些数据块可能在非主节点上被访问很多次,而在主节点上却很少被访问,这种情况意味着会有大量的资源访问节点和资源主节点的消息产生,从而增加了私网的工作负载,影响数据库的性能。而DRM允许资源的主节点根据资源在各个节点的访问状态动态地调整。
通俗地说,如果联系一个节点就可以获取数据块,为嘛要联系多个节点呢。
DRM参数
_gc_policy_time:这个参数指定了Oracle统计每个节点对某个数据库对象访问次数的时间间隔,默认值为10分钟。
_gc_policy_minimum:这个参数指定了每分钟数据库对象至少要被访问多少次,才考虑修改它的主节点信息,默认值1500。
_gc_affinity_ratio:这个参数指定了当一个节点访问某一个数据库对象的次数超过了所有其他节点访问相同数据库对象的多少倍时,才考虑修改它的主节点信息,默认值50。
因此DRM发生的条件是:当在一段时间内(_gc_policy_time),如果一个数据库对象每分钟被访问的次数超过了一个阈值(_gc_policy_minimum),并且某一个节点访问该对象的次数超过了所有其他节点的访问次数的50倍(_gc_affinity_ratio),那么Oracle会陆续地(以windows为单位)将这个数据库对象对应的数据块的主节点信息迁移到访问次数最多的节点。
DRM迁移的是数据块的主节点信息,而不是将数据块的最新版本copy到访问次数最多的节点。
DRM由LMON,LMS,LMD,LCK进程协同工作,将数据块资源的主节点信息从一个节点迁移到另一个节点。