source: https://my.oschina.net/u/3635497/blog/3025812
RAC系统中,对于节点和节点之间数据块一致性的保证是通过消息的机制来保证的,也就是我们常说的gcs和ges的这些消息来确保的。这些消息分别有LMD和LMS的进程在实例之间进行传输。
LMD负责处理message的信息,如块的状态,lock level等信息。而LMS会负责数据块的传输。我们这不讨论一致性的机制,主要关注在消息传输的流量和控制上。
不管是LMS还是LMD的消息传递,这些信息传输,都是通过UDP的协议透过进行消息的传递的。而在实例之间进行消息传输的时候,消息的传递是彼此交互式的,不能由一个节点一直发送,而另外一个节点只负责持续的负责接收。所以在实例之间传输的时候就要平衡,传输消息的几率,控制彼此之间的合理流量,RAC里通过引入ticket的概念对彼此之间传输的流量和几率进行控制。
对于ticket概念的理解和best practice,Oracle有两篇相关文档可以参考:
Resolving ORA-481 and "terminating the instance due to error 481" (Doc ID 1950963.1)
Best Practices and Recommendations for RAC databases using very large SGA (e.g. 100 GB) (Doc ID 1619155.1)
这里我们可以看到,Oracle是通过某一个节点持有的ticket的数量对发送和接受消息进行流量控制的。一个节点发送一则消息队列的同时会带着一个ticket到对端,对端的ticket会增加。本地的ticket会减少,本地节点会根据可用的buffer和已经收到的信息以及发送的请求ticket的信息(null-req)计算本地可用的tickets。当本地没有ticket可用,本地的LMS/LMD就会进入消息等待队列,并持续的检查ticket latch里的信息,判断是否有可用的ticket的信息可用。直到对端发送回message,并带回可用的tickets后,本地才能再继续发送消息到对端。
我们可以查询动态视图:GV$GES_TRAFFIC_CONTROLLER 来获取每个节点上avalible的tickets数量,并且可以通过TCKT_WAIT判断LMS或者LMD是否正在等待ticket。如果我们持续的看到这里彼此都在等待,说明UDP buffer里package信息,没有被及时的处理,或者在传输的过程丢掉了。当然,我们也可以凭经验看lms/lmd在crash之前里的队列的消息传输情况来判断是否是ticket不足引发的问题。这不如直接获取的GVGESTRAFFICCONTROLLER来获取每个节点上avalible的tickets数量,并且可以通过TCKTWAIT判断LMS或者LMD是否正在等待ticket。如果我们持续的看到这里彼此都在等待,说明UDPbuffer里package信息,没有被及时的处理,或者在传输的过程丢掉了。当然,我们也可以凭经验看lms/lmd在crash之前里的队列的消息传输情况来判断是否是ticket不足引发的问题。这不如