MHA chooses the main library source code analysis

Students of Zhishutang's 5th MySQL practical class and 10th MySQL optimization class, currently serving as a teaching assistant.

Before MHA selects a new master library, it will first divide the living slaves into several arrays, namely latest (the most advanced slave array), pref (the array that is preferentially selected as the master), and bad (will not be selected. Become the master's slave), slaves (an array of all living slaves). Then 5 selections are made to pick the new master from the above groups.

select latest array

foreach (@slaves) {
my $a = $latest[0]{Master_Log_File};
my $b = $latest[0]{Read_Master_Log_Pos};
if (
!$find_oldest
&& (
( !$a && !defined($b) )
|| ( $_->{Master_Log_File} gt $latest[0]{Master_Log_File} )
|| ( ( $_->{Master_Log_File} ge $latest[0]{Master_Log_File} )
&& $_->{Read_Master_Log_Pos} > $latest[0]www.wanmeiyuele.cn{Read_Master_Log_Pos} )
)
)
{
@latest = ();
push( @latest, $_ );
}
elsif (
$find_oldest
&& (
( !$a && !defined($b) )
|| ( $_->{Master_Log_File} lt $latest[0]{Master_Log_File} )
|| ( ( $_->{Master_Log_File} le $latest[0]{Master_Log_File} )
&& $_->{Read_Master_Log_Pos} < $latest[0]{Read_Master_Log_Pos} )
)
)
{
@latest = ();
push( @latest, $_ );
}
elsif ( ( $_->{Master_Log_File} eq $latest[0]{Master_Log_File} )
&& ( $_->{Read_Master_Log_Pos} == $latest[0]{Read_Master_Log_Pos} ) )
{
push( @latest, $_ );
}
}

The main structure of the above code is a foreach loop and an if judgment. The foreach loop processes all live slaves. There are three judgment conditions for if judgment, which are mainly judged according to the size of Master_Log_File and Read_Master_Log_Pos. The first and second are to find the front and back slave respectively. If the conditions are met, then empty the latest array and put those that meet the conditions into the latest array. The third condition is used to find the same slave as Master_Log_File and Read_Master_Log_Pos in the latest array, and put it into the latest array. In this way, all the top ones are put into the latest array.

select pref array

foreach (@servers) {
    next if ( $_->{dead} eq '1' );
    if ( $_->{candidate_master} >= 1 ) {
      push( @ret_servers, $_ );
    }
  }

All configuration servers are processed in a loop, the dead slave is skipped, and the slave with parameter candidate_master=1 is put into the pref array and will be preferentially elected as the new master.

select bad array

 foreach (@servers) {
    if (
         $_->{no_master} >= 1
      || $_->{log_bin}www.365soke.cn  eq '0'
      || $_->{oldest_major_version} eq '0'
      || (
        $latest_slave
        && ( $check_replication_delay
          && $self->check_slave_delay( $_, $latest_slave ) >= 1 )
      )
      )
    {
      push( @ret_servers, $_ );
    }
  }

It is also a server that processes all configurations in a loop. If one of the following three conditions is met, it will be selected into the bad array, which means that these slaves will not be elected as new masters.

  1. Added parameter no_master=1

  2. binlog is not enabled

  3. If the delay is too large, how can it be considered that the replication delay is too large?

 ( $latest->{Master_Log_File} gt $target->{Relay_Master_Log_File} )
|| ( $latest->{Read_Master_Log_Pos} >
$target->{Exec_Master_Log_Pos} + 100000000 )

The latest here is the first latest slave selected above, but all latest are the same, so it doesn't matter which one you choose for comparison. Either latest's master_log_file > comparator's Relay_Master_Log_File. Or both are the same, but the latest's Read_Master_Log_Pos > the comparator's Exec_Master_Log_Pos+100 million. If the parameter check_repl_delay=0 is set, the replication delay will not be checked.

select slaves array

As long as the slave is alive, it will be put into the slaves array.

It should be noted here that a slave can be placed in multiple arrays. It is not that a slave can only be stored in an array.

First choice:

return $latest[0] if ( $#pref <www.feihuanyule.com  0 && $#bad < 0 && $latest[0]->{latest_priority} );

If the number of slaves in the pref and bad arrays is 0, the first slave in the latest array is selected as the master.

Second choice:

$log->info(
" Searching from candidate_master slaves which have received the latest relay log events.."
) if ( $#pref >= 0 );
foreach my $h (@latest) {
foreach my $p (@pref) {
if ( $h->{id} eq $p->{id} ) {
return $h
if ( !$self->get\_server\_from\_by\_id( \@bad, $p->{id} ) );
}
}
}
$log->info(" Not found.") if ( $#pref >= 0 );

Cyclically compare the slaves of the latest array and the perf array. If the same slave exists and the slave is not in the bad array, the slave will be elected as the new master.

Third choice:

foreach my $s (@slaves) {
foreach my $p (@pref)www.hbs90.cn/ {
if ( $s->{id} eq $p->{id} ) {
my $a = $self->get_server_from_by_id( \@bad, $p->{id} );
return $s unless ($a);
}
}
}

Cyclic comparison of the slaves in the slaves array pref array, if there is a slave that is the same and not in the bad array, it will become the new master.

Fourth choice:

foreach my $h (@latest) {
my $a = $self->get_server_from_by_id( @bad, $h->{id} );
return $h unless ($a);
}

Loop the latest array. If the slave to be looped is not in the bad array, the slave will become the master. That is to say, even if candidate_master=1 is added, the slave will not necessarily become the master library.

Fifth choice:

foreach my $s (@slaves)www.yibaoyule1.com/ {
my $a = $self->get_server_from_by_id( @bad, $s->{id} );
return $s unless (www.huayi1.cn/ $a);
}

Loop from the living slave. If the looped slave is not in the bad array, then the slave will become the main library. If the main library cannot be found after 5 selections, then the main library selection fails and failover fails.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324385357&siteId=291194637