GTID和非GTID故障切换模式选择

MySQL 5.6版本引入GTID来解决主从切换时BINLOG位置点难定位的问题,MHA从0.56版本开始支持基于GTID的复制,在切换时可以采用GTID模式和非GTID模式两种模式进行切换,如何在发生故障切换时如何判断采用哪种切换方式呢?

在MHA/MasterFailover.pm的do_master_failover方法中定义了"主库宕机"情况下的故障切换流程,其中第一步就是检查配置文件和确定故障切换模式

相关代码:

    my ( $servers_config_ref, $binlog_server_ref ) = init_config();
$log->info("Starting master failover.");
$log->info();
$log->info("* Phase 1: Configuration Check Phase..\n");
$log->info();
MHA::ServerManager::init_binlog_server( $binlog_server_ref, $log );
$dead_master = check_settings($servers_config_ref);
if ( $_server_manager->is_gtid_auto_pos_enabled() ) {
$log->info("Starting GTID based failover.");
}
else {
$_server_manager->force_disable_log_bin_if_auto_pos_disabled();
$log->info("Starting Non-GTID based failover.");
}
$log->info();

在MHA\ServerManager.pm中判断是否采用GTID模式切换的方法:

sub is_gtid_auto_pos_enabled($) {
my $self = shift;
return if ( $self->{gtid_failover_mode} == );
return ;
} sub force_disable_log_bin_if_auto_pos_disabled($) {
my $self = shift;
my $log = $self->{logger};
if ( $self->{gtid_failover_mode} == ) {
my @slaves = $self->get_alive_slaves();
$log->info("Forcing disable_log_bin since GTID auto pos is disabled");
foreach my $slave (@slaves) {
$slave->{disable_log_bin} = ;
}
}
} $self->{gtid_failover_mode} = $self->get_gtid_status();

在MHA/ServerManager.pm判断群集是否使用GTID复制:

sub get_gtid_status($) {
my $self = shift;
my @servers = $self->get_alive_servers();
my @slaves = $self->get_alive_slaves();
return if ( $#servers < 0 );
foreach (@servers) {
return unless ( $_->{has_gtid} );
}
foreach (@slaves) {
return unless ( $_->{Executed_Gtid_Set} );
}
foreach (@slaves) {
return
if ( defined( $_->{Auto_Position} )
&& $_->{Auto_Position} == );
return if ( $_->{use_gtid_auto_pos} );
}
return ;
}

其中has_gtid的计算为:

use constant Has_Gtid_SQL             => "SELECT \@\@global.gtid_mode As Value";
sub has_gtid($) {
my $self = shift;
my $value = $self->get_variable(Has_Gtid_SQL);
if ( defined($value) && $value eq "ON" ) {
$self->{has_gtid} = ;
return ;
}
return ;
}

计算use_gtid_auto_pos的代码:

## MHA/Config.pm
my @PARAM_ARRAY =
qw/ hostname ip port ssh_host ssh_ip ssh_port ssh_connection_timeout ssh_options node_label candidate_master \
no_master ignore_fail skip_init_ssh_check skip_reset_slave user password repl_user repl_password disable_log_bin \
master_pid_file handle_raw_binlog ssh_user remote_workdir master_binlog_dir log_level manager_workdir manager_log \
check_repl_delay check_repl_filter latest_priority multi_tier_slave ping_interval ping_type secondary_check_script \
master_ip_failover_script master_ip_online_change_script shutdown_script report_script init_conf_load_script \
client_bindir client_libdir use_gtid_auto_pos/;
my %PARAM;
for (@PARAM_ARRAY) { $PARAM{$_} = ; } $value{use_gtid_auto_pos} = $param_arg->{use_gtid_auto_pos};
if ( !defined( $value{use_gtid_auto_pos} ) ) {
$value{use_gtid_auto_pos} = $default->{use_gtid_auto_pos};
$value{use_gtid_auto_pos} = if ( !defined( $value{use_gtid_auto_pos} ) );
}

如果配置文件中未指明参数use_gtid_auto_pos,则默认use_gtid_auto_pos=1。

计算Executed_Gtid_Set是查看show master status和show slave status两个命令输出结果中的Executed_Gtid_Set列信息。

计算Auto_Position是查看show slave status命令输出结果中MASTER_AUTO_POSITION列的值。

使用非GTID模式进行切换的场景有:

1、如果群集中任意节点未开启GTID(gtid_mode=0)或Executed_Gtid_Set集合为空。

2、群集中所有节点都未使用GTID复制模式(MASTER_AUTO_POSITION=0),且配置文件中设置use_gtid_auto_pos=0。

使用GTID模式进行切换的场景有:

1、如果群集中任意节点使用GTID复制,SHOW SLAVE STATUS输入结果中MASTER_AUTO_POSITION=1。

2、如果所有节点都开启GTID,且未配置参数use_gtid_auto_pos或配置参数use_gtid_auto_pos=1。

差异日志补偿

1、原主库日志补偿

在GTID故障切换模式下,无论原主库操作系统级别是否正常,都不会尝试从原主库上获取差异BINLOG。

如上图所示,在GTID故障切换模式下,不会进行Phase 3.2阶段,即不会尝试从原Master服务器中获取最新BINLOG。

在非GTID故障切换模式下,如果原主库操作系统级别正常,会尝试对比原主库BINLOG和最新从库的RELAY LOG,如果存在差异,会备份主库差异BINLOG并应用到从库上。

如上图所示,在非GTID故障切换模式下,会先进行Phase 3.1阶段,从拥有最新BINLOG的从库上获取差异日志,再进行Phase 3.2阶段,尝试从原Master服务器上获取最新BINLOG。

2、Binlog Server日志补偿

在GTID故障切换模式下,会对比候选主库的RELAY LOG和Binlog Server的BINLOG,如果Binlog Server含有最新日志,会根据Binlog Server进行日志补偿。

在非GTID模式下,无论Binlog Server是否最新日志,都不会根据Binlog Server进行日志补偿。

3、最新从库日志补偿

无论是GTID故障切换模式还是非GTID故障切换模式,都会挑选出“最新从库”,并对比“最新从库”RELAY LOG和“新主库” RELAY LOG,如果存在差异,则保存“最新从库”的日志并应用到“新主库上”。

在GTID故障切换模式下,可以给masterha_master_switch传入–wait_until_gtid_in_sync=1参数使其不等其它Slave完成数据同步,以加快切换速度。

GTID故障切换模式注意事项

如果群集因为某种原因导致主从节点上的Executed_Gtid_Set不同,如:

1、对从库进行直接授权,导致从库比主库拥有更多BINLOG,但该Binlog因各种原因被Purged掉

2、群集做过版本升级,从未使用GTID的版本升级到GTID版本,从库上曾一段时间内作为主库提供服务,但该时间段日志被Purged掉

有上诉类似问题时,将从库提升为主库并使用master_auto_position=1来配置复制,复制会因为新主库无法提供足够BINLOG事件而失败。

处理办法:

1、通过RESET MASTER和SET GLOBAL gtid_purged=''使得所有节点拥有相同的GTID 集合

2、将所有复制修改为基于POS点搭建的复制。

GTID和非GTID故障切换模式对比

1、无论时GTID故障切换模式还是非GTID故障切换模式,都会从“最新从库”获取差异日志。

2、非GTID故障切换模式下,会尝试从“原主库”获取差异日志,但不会从“BINLOG Server”获取差异日志。

3、GTID故障切换模式下,会从“BINLOG Server”获取差异日志,但不会从“原主库”获取差异日志。

MySQL MHA--故障切换模式(GTID模式和非GTID模式)的更多相关文章

  1. -_-#【userAgent】极速模式与非极速模式存在差异

    UC浏览器 Android 极速模式 UC浏览器 Android 非极速模式

  2. ORACLE归档模式和非归档模式的利与弊

    转: 在Oracle数据库中,主要有两种日志操作模式,分别为非归档模式与归档模式.默认情况下,数据库采用的是非归档模式.作为一个合格的数据库管理员,应当深入了解这两种日志操作模式的特点,并且在数据库建 ...

  3. XCode工程中ARC模式与非ARC模式共用(转)

    Xcode 项目中经常会融合一些老的代码,它们可能采用非ARC的模式.混合编译时,就会碰到编译出错的情况. 如何共用ARC模式和非ARC模式呢? XCode除了提供整个项目是否使用ARC模式的选择外, ...

  4. 深入 CSocket 编程之阻塞和非阻塞模式

    有时,花上几个小时阅读.调试.跟踪优秀的源码程序,能够更快地掌握某些技术关键点和精髓.当然,前提是对这些技术大致上有一个了解. 我通过几个采用 CSocket 类编写并基于 Client/Server ...

  5. 【bug】【userAgent】极速模式与非极速模式存在差异

    UC浏览器 Android 极速模式 UC浏览器 Android 非极速模式

  6. python 正则表达式与JSON-正则表达式匹配数字、非数字、字符、非字符、贪婪模式、非贪婪模式、匹配次数指定等

    1.正则表达式:目的是为了爬虫,是爬虫利器. 正则表达式是用来做字符串匹配的,比如检测是不是电话.是不是email.是不是ip地址之类的 2.JSON:外部数据交流的主流格式. 3.正则表达式的使用 ...

  7. 面试侃集合 | SynchronousQueue非公平模式篇

    面试官:好了,你也休息了十分钟了,咱们接着往下聊聊SynchronousQueue的非公平模式吧. Hydra:好的,有了前面公平模式的基础,非公平模式理解起来就非常简单了.公平模式下,Synchro ...

  8. CENTOS6.6 下mysql MHA架构搭建

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 本篇是自己搭建的一篇mysql MHA文章 前面的安装步骤基 ...

  9. 基于Docker Compose构建的MySQL MHA集群

    Docker MySQL MHA 基于Docker 1.13.1之上构建的MySQL MHA Docker Compose Project 可快速启动GTID模式下的MasterHA集群, 主用于My ...

随机推荐

  1. scrapy中的Pipeline

    当Item在Spider中被收集之后,它将会被传递到Item Pipeline,这些Item Pipeline组件按定义的顺序处理Item. 每个Item Pipeline都是实现了简单方法的Pyth ...

  2. 消息中间件 RabbitMQ 入门篇

    消息中间件 RabbitMQ 入门篇 五月君 K8S中文社区 今天   作者:五月君,来源:Nodejs技术栈 从不浪费时间的人,没有工夫抱怨时间不够.—— 杰弗逊 RabbitMQ 是一套开源(MP ...

  3. 【mybatis】子查询

    networkResource的 resultMap <resultMap id="NetworkResultMap" type="com.chinamobile. ...

  4. 运行应用-使用Deployment运行无状态应用程序

    以下介绍如何使用kubernetes的deployment对象运行应用程序. 目标 - 创建nginx deployment. - 使用kubectl列出有关部署的信息. - 更新部署 创建和探索ng ...

  5. IBM X3650 M4 安装 Windows Server 2008 R2

    1 准备好  Windows Server 2008 R2 安装用的U盘 2 采用PowerISO制作启动U盘: 或者用Rufus做启动U盘. 3 接上启动U盘 4 设置Bios启动模式为 UEFI ...

  6. spark 读写text,csv,json,parquet

    以下代码演示的是spark读取 text,csv,json,parquet格式的file 为dataframe, 将dataframe保存为对应格式的文件 package com.jason.spar ...

  7. Ribbon和Nignx的区别

    Ribbon属于客户端负载均衡:在调用接口的时候,会通过服务别名到eureka上获取服务的信息列表,缓存到jvm本地,在本地采用RPC远程调用技术去调用接口,实现负载均衡.可以设置调用的规则是请求总数 ...

  8. error adding symbols:DSO missing from command line

    编译时加上-lz,如果是使用eclipse,则在添加库z

  9. strlen()与sizeof()

    一.strlen() strlen()为计算字符串长度的函数,以‘\0’为字符串结束标志.注意:其传入参数必须是字符串指针(char*), 当传入的是数组名时,实际上数组退化成指针了. 二.sizeo ...

  10. 【C++/C】指针基本用法简介-A Summary of basic usage of Pointers.

    基于谭浩强老师<C++程序设计(第三版)>做简要Summary.(2019-07-24) 一.数组与指针 1. 指针数组 一个数组,其元素均为指针类型数据,该数组称为指针数组.(type_ ...