MySQL MGR源码分析2 - 从start group_replication看MGR代码框架
此文已由作者温正湖授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
上一篇我们从方案层面讲解了MGR的成员管理和故障恢复。本篇从源码层面捋一捋,通过本篇介绍,除了能够了解如何将一个节点加入到group中,也可以了解在这个过程中,节点是如何进行分布式通信模块进行初始化,上层如何响应底层上发的消息,事务进入MGR后是如何通过pipeline一步步执行的,等待。
start group_replication处理逻辑
该命令用于将一个正在运行且已经install了group_replication.so插件的mysqld加入到group中。又可以根据是否设置了group_replication_bootstrap_group来分为创建一个新的group或加入一个已有的group。start group_replication对应的实现函数为plugin_group_replication_start,其做些基本的检查后交由initialize_plugin_and_join()来执行节点加入group的任务,下图为该函数的主要执行流程。
下面我们注意对其9个阶段进行逐一分析:
1、调用Gcs_operations::initialize()来创建gcs_interface对象并设置gcs日志系统;
2、根据用户配置的MGR参数设置GCS,其中最重要的逻辑是调用Gcs_xcom_interface::initialize_xcom()来进行MGR目前唯一执行的gcs实现xcom的初始化,该函数详见后续小节描述。
3、设置本节点的MGR成员管理对象,包括本节点信息维护对象local_member_info和集群信息维护对象group_member_mgr,此时group_member_mgr还只有本地节点的信息。
4、initialize_recovery_module()函数初始化节点的MGR recovery模块,包括创建Recovery_module对象,为其设置节点上线策略(认证完上线还是回放完上线),设置全局故障恢复节点donor节点连接失败重试的次数和失败重连的时间间隔。Recovery_module模块在start group_replication命令返回后,负责将节点从恢复中变为在线状态。
5、接下来调用configure_and_start_applier_module()函数配置和启动节点的MGR Applier_module模块,该模块是MGR的核心模块之一,用于对通过xcom进入该节点的包括用户事务数据包(package)在内的众多行为(action)/事件(event)进行分发、认证和执行。
首先创建一个Applier_module对象,并将其赋予Recovery_module模块;接着对Applier_module对象进行初始化,包括创建用于缓存等待处理的消息的队列incoming,初始化模块的处理机制pipeline;最后启动一个新的线程,并制定处理函数applier_thread_handle(),用于具体处理这些入队的消息。MGR使用pipeline管道的方式处理每个消息,pipeline设置和初始化详见后续小节分析。
6、在单主模式下,调用initialize_asynchronous_channels_observer()进行节点异步复制通道的操作行为监听。主要监听行为是io thread和sql thread启动操作。原因是在单主模式下,只有primary节点能接收外部写请求,所以需要禁止MGR单主模式的secondary节点启动非MGR的异步复制和回放Relay log的通道。而多主模式下各节点均可写,不存在该限制。
7、下一步initialize_group_partition_handler()用于初始化MGR的网络分区处理对象group_partition_handler。应对MGR中的节点因为网络问题导致相互间无法进行正常的通信。当有节点无法连上其他节点时,就会启动handler->partition_thread_handler()网络分区处理线程,若在超时时间内()网络无法恢复,则会进行网络分区处理,包括退出group并rollback已进入MGR的事务等。
8、调用start_group_communication()启动节点与group中其他节点的通信是及其重要的步骤。直接决定了该节点是否能够正常加入group。
该函数首先设置节点的自增列的自增区间和自增初始值。然后初始化group集群视图变化状态设置监听对象view_change_notifier,该notifier会设置和监控视图变化情况并作出相应处理,初始化非常重要的events_handler,该handler是向gcs注册的事件回调接口,用于处理gcs(paxos)返回的各种消息/事件,包括用户事务数据包、group变化的控制包等。接着,view_change_notifier设置view_changing变量,表示正式进入视图切换阶段(当view_changing重新变为false时,start group_replication即可返回)。最后调用Gcs_operations::join()函数执行将该节点加入group的操作,该函数详见后续小节描述。
9、以上就是start group_replication命令所要执行的所有操作,在完成这些操作后,initialize_plugin_and_join()调用view_change_notifier->wait_for_view_modification()来等待view_changing变为false,之命令返回。若返回值非零,则意味着加入失败,需要进行操作回滚。若返回值为零,则节点进入故障恢复流程,最终将节点设置为在线状态。
Gcs_xcom_interface::initialize_xcom()
initialize_xcom()用于初始化节点的xcom实例。但此时该实例仍未运行和加入的group。
如上图所示,该函数主要是初始化xcom实例的group信息及相关对象,设置将该xcom加入group所需的种子节点,注册各种xcom消息的回调处理函数,创建xcom的各种操作接口xcom_proxy,最后创建Gcs_xcom_engine对象,并调用Gcs_xcom_engine::initialize()来启动节点的xcom处理引擎,xcom引擎通过独立线程的处理函数process_notification_thread来调用2.2.1.3.3设置的回调函数处理各种xcom消息。process_notification_thread的处理逻辑如下所示:
paxos消息接收和执行
上面我们说了m_notification_queue消息的执行框架,那么这些消息如何加入m_notification_queue队列呢,详见下图例子:
deliver_to_app是MGR最底层paxos将已达成一致性的消息发送给上层的主要接口之一,其调用在该类消息处理函数xcom_receive_data()进行处理,处理操作很简单,经创建一个Data_notification对象,参数中指定了具体的消息处理函数,最后将其push到我们上面所述的m_notification_queue队列。我们进一步看看do_cb_xcom_receive_data()如何处理该消息:
首先,将从paxos接收到的消息进行pipeline处理(注意跟Applier_module的pipeline相区分),目前pipeline仅可注册一个stage,即Gcs_message_stage_lz4,用于对paxos消息进行压缩。可通过参数group_replication_compression_threshold来设置进行消息压缩的阈值。
接着,若消息类型为进行视图切换时产生的成员状态交换消息(CT_INTERNAL_STATE_EXCHANGE),调用process_control_message()函数进行处理。否则,判断是否正在进行视图切换,若是,则暂时buffer住这些消息,等到视图完成切换后(即成员加入group后)再处理。否则,调用上层为每种消息注册的回调函数on_message_received()进行处理。
下面,我们简要介绍process_control_message()和on_message_received():
on_view_changed是各个节点对视图切换的响应,是视图切换关键性的函数,包含了对加入节点、退出节点的处理,处理完成后还会判断是否需要发起选主,如果是节点加群那么还会调用故障恢复模块recovery_module函数start_recovery()。其处理流程如下:
on_message_received()是个消息分发枢纽,其操作如下:
如上图所示,根据消息类型的不同,分别调用不同的处理函数,其中对于单主模式新primary完成relay log回放后的消息和事务性消息(事务和视图数据包)均进入到applier_module的incoming队列按顺序执行。其他三种消息分别是用于节点间进行事务执行状态周期性同步的CT_PIPELINE_STATS_MEMBER_MESSAGE消息,该消息是performance_schema.replication_group_member_stats和replication_group_members的主要数据来源。会触发节点进入流控模式。CT_RECOVERY_MESSAGE消息用于在节点完成故障恢复后将自己设置为在线状态前给group发送的广播消息,确保其他节点及时感知节点状态变化。CT_CERTIFICATION_MESSAGE是周期性发送的,用于对applier_module模块的冲突检测数据库进行无用信息purge的消息。
Applier_module的pipeline实现
MGR使用pipeline管道的方式处理每个消息,pipeline设置和初始化详见第5小节分析。目前官方设置了3个pipeline处理器(handler),分别是CATALOGING_HANDLER、CERTIFICATION_HANDLER和SQL_THREAD_APPLICATION_HANDLER,其中CATALOGING_HANDLER用于待处理的事件进行分类,主要通过判断事件类型是否为binary_log::TRANSACTION_CONTEXT_EVENT来设置事务开始的标志,并判断是否为SINGLE_VIEW_EVENT来标识处理视图变更事件。CERTIFICATION_HANDLER是最核心的pipeline处理器,在各个节点采用相同的规则独立进行事务认证,包括认证模块初始化和销毁、事务快照版本解析、对事务进行冲突检测和在视图变更的时候初始化冲突检测数据库等。
SQL_THREAD_APPLICATION_HANDLER用于并行回放通过了认证的异地事务,更新本地的数据库版本。3个pipeline的汇总信息如下图所示:
Gcs_operations::join()
该接口用于在start group_replication时将节点加入group。具体流程如下:
首先进行通信(gcs_communication)和控制(gcs_control)接口初始化,确保从gcs层发送上来的各种消息能够被正确执行。最后调用Gcs_xcom_control::join()来执行最终的节点入群操作,该函数判断是创建group还是加入group场景,并在Gcs_xcom_control::do_join()中进行对应处理,do_join在Gcs_xcom_interface::initialize_xcom()的基础上完成最后的加入操作,流程如下:
先创建m_xcom_thread线程,通过proxy->xcom_init()进行最后的初始化,让xcom实例进入运行状态;在确保xcom实例通信正常的情况下,分别调用proxy->xcom_client_boot()或proxy->xcom_client_add_node()创建一个group或加入已存在的group。
梳理总结
上面就是start group_replication命令的全部操作。经过上面介绍后,还有2个大疑问没有解释清楚:
1、该命令在什么时候返回?
上面我们只是说在view_changing为false的时候返回,那么该变量什么时候会变为false呢,首先需要明确的是在前述的Plugin_gcs_events_handler::on_view_changed()函数中设置,对于执行该命令的节点,会在Plugin_gcs_events_handler::handle_joining_members()函数中调用view_change_notifier->end_view_modification()设置,并进行广播:
2、在介绍process_control_message()时我们知道该函数是接收了CT_INTERNAL_STATE_EXCHANGE消息后调用执行的。那么该消息是在什么场景下发出的?
下面我们从源头开始进行简单介绍:
detector_task是paxos层的一个定时任务机制,用于发现group的成员变化情况,并进行相应的处理。对于我们所述的场景,有一个新的节点加入paxos group中,所以会触发该任务发送一个view_msg消息。最终调用do_cb_xcom_receive_global_view进行处理。具体逻辑为:
该函数会获取自己节点的状态信息get_exchangeable_data(),并使用Gcs_xcom_state_exchange::broadcast_state()来广播一个CT_INTERNAL_STATE_EXCHANGE。
网易云免费体验馆,0成本体验20+款云产品!
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 干货|盘点国内真正的大数据分析产品
【推荐】 一步一步学习JNI
MySQL MGR源码分析2 - 从start group_replication看MGR代码框架的更多相关文章
- [python] 基于词云的关键词提取:wordcloud的使用、源码分析、中文词云生成和代码重写
1. 词云简介 词云,又称文字云.标签云,是对文本数据中出现频率较高的“关键词”在视觉上的突出呈现,形成关键词的渲染形成类似云一样的彩色图片,从而一眼就可以领略文本数据的主要表达意思.常见于博客.微博 ...
- Nginx源码分析:3张图看懂启动及进程工作原理
编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由陈科在高可用架构群分享.转载请注明来自高可用架构公众号「ArchNotes」. 导读:很多工程师及架构师都希望了解及掌握高性能服务器 ...
- HashMap的源码分析与实现 伸缩性角度看hashmap的不足
本文介绍 1.hashmap的概念 2.hashmap的源码分析 3.hashmap的手写实现 4.伸缩性角度看hashmap的不足 一.HashMap的概念 HashMap可以将其拆分为Hash散列 ...
- 鸿蒙内核源码分析(汇编汇总篇) | 所有的汇编代码都在这里 | 百篇博客分析OpenHarmony源码 | v40.03
百篇博客系列篇.本篇为: v40.xx 鸿蒙内核源码分析(汇编汇总篇) | 汇编可爱如邻家女孩 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪 ...
- jQuery-1.9.1源码分析系列(十六)ajax——ajax框架
ajax的介绍就不多说了,点击可看. 既然是ajax框架,那么闲谈一谈jQuery的ajax处理思路. 现在的浏览器都支持ajax,只不过不同的浏览器使用方法可能有不同(IE使用new window. ...
- 详解Tomcat系列(一)-从源码分析Tomcat的启动
在整个Tomcat系列文章讲解之前, 我想说的是虽然整个Tomcat体系比较复杂, 但是Tomcat中的代码并不难读, 只要认真花点功夫, 一定能啃下来. 由于篇幅的原因, 很难把Tomcat所有的知 ...
- jQuery-1.9.1源码分析系列完毕目录整理
jQuery 1.9.1源码分析已经完毕.目录如下 jQuery-1.9.1源码分析系列(一)整体架构 jQuery-1.9.1源码分析系列(一)整体架构续 jQuery-1.9.1源码分析系列(二) ...
- Go Mobile 例子 audio 源码分析
看这个源码分析前,建议先看更简单地例子 basic 的源码分析(http://www.cnblogs.com/ghj1976/p/5183199.html), 一些基础知识本篇将不再提及. audio ...
- Robotium源码分析之运行原理
从上一章<Robotium源码分析之Instrumentation进阶>中我们了解到了Robotium所基于的Instrumentation的一些进阶基础,比如它注入事件的原理等,但Rob ...
随机推荐
- 数据结构 - 链栈的实行(C语言)
数据结构-链栈的实现 1 链栈的定义 现在来看看栈的链式存储结构,简称为链栈. 想想看栈只是栈顶来做插入和删除操作,栈顶放在链表的头部还是尾部呢?由于单链表有头指针,而栈顶指针也是必须的,那干吗不让它 ...
- spark调试环境搭建
到目前为止,基于RDD的spark streamming实时应用和离线应用(主要解析日志)已经写了一些,但是对spark的了解还是很少,所以决心花点精力,对spark做一些比较深入的了解和学习.参照之 ...
- SpringBoot2.1.3修改tomcat参数支持请求特殊符号
最近遇到一个问题,比如GET请求中,key,value中带有特殊符号,请求会报错,见如下URL: http://xxx.xxx.xxx:8081/aaa?key1=val1&a.[].id=1 ...
- 来自AJPFX的二分法查找
package com.heima.array; public class Demo2_Array { /** * * A:案例演示 * ...
- 《基于Node.js实现简易聊天室系列之引言》
简述:这个聊天室是基于Node.js实现的,完成了基本的实时通信功能.在此之前,对node.js和mongodb一无所知,但是通过翻阅博客,自己动手基本达到了预期的效果.技术,不应该是闭门造车,而是学 ...
- myeclipse 跟踪struts 源码失败
解决办法: 找到工程jar包所在的位置,点击右键:properties 点击external folder 找到 这个包下的src文件夹 导入之后, 源码会变色
- 【PostgreSQL-9.6.3】Red Hat 4.4.7下的安装
1. 下载源码包https://www.postgresql.org/ftp/source/v9.6.1/ 2. 上传到/opt目录下 3. 创建postgres用户及dba组,并修改压缩包的属主属组 ...
- WebSocket 的一些简单页面推送使用
因为做通信项目的时候,需要实时获取每个分机的当前状态,发现websocket还不错,只是对浏览器的要求比较高, 针对特定用户推送消息,网上有一些 public class GetHttpSession ...
- 批处理 reg add /?
C:\Users\Administrator>reg add /? REG ADD KeyName [/v ValueName | /ve] [/t Type] [/s Separator] [ ...
- 中国版 Office 365 (X-Tenant / Tango) 功能验证报告 - 2 基本步骤
说明: 1. 前期准备 - 在Azure上模拟出生产环境: 包括父域域控.子域域控.父域的Exchange Server.子域的Exchange Server.对Exchange Server, 需要 ...