mysql gtid怎么解决master宕机

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql gtid怎么解决master宕机相关的知识,希望对你有一定的参考价值。

参考技术A mysql 5.6 全局事务 ID(GTID)实现原理(三)这是 MySQL 5.6 全局事务 ID(GTID) 系列的第三篇博客。 在之前的两篇博客中,第一篇? 介绍了全局事务 ID 的定义与数据结构。第二篇? 介绍了 MySQL 5.6 新增的全局事务状态(Gtid_state)。

MySQL MHA--故障切换模式(GTID模式和非GTID模式)

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 1 if ( $self->gtid_failover_mode == 1 );
  return 0;



sub force_disable_log_bin_if_auto_pos_disabled($) 
  my $self = shift;
  my $log  = $self->logger;
  if ( $self->gtid_failover_mode == 2 ) 
    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 = 1;
    
  


$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 0 if ( $#servers < 0 );
  foreach (@servers) 
    return 0 unless ( $_->has_gtid );
  
  foreach (@slaves) 
    return 0 unless ( $_->Executed_Gtid_Set );
  
  foreach (@slaves) 
    return 1
      if ( defined( $_->Auto_Position )
      && $_->Auto_Position == 1 );
    return 1 if ( $_->use_gtid_auto_pos );
  
  return 2;

其中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 = 1;
    return 1;
  
  return 0;

计算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$_ = 1; $valueuse_gtid_auto_pos = $param_arg->use_gtid_auto_pos; if ( !defined( $valueuse_gtid_auto_pos ) ) $valueuse_gtid_auto_pos = $default->use_gtid_auto_pos; $valueuse_gtid_auto_pos = 1 if ( !defined( $valueuse_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 gtid怎么解决master宕机的主要内容,如果未能解决你的问题,请参考以下文章

初识MariaDB之8——GTID主从复制

MySQL 5.7 GTID模式下 skip 1032 Error

mysql change master导致gtid丢失

mariadb10.x启用gtid复制时提示mysql.gtid_slave_pos找不到的解决方案

mysql -- GTID

mysql常见错误解决办法