본문 바로가기

DBA 이야기/MySQL

MHA 다른 버젼의 MySQL Replication 구조 online switch 하기

MHA에서 master와 slave(들) 간의 MySQL Version이 다르면, switch 시에 에러가 나면서

switch가 실패하는 케이스가 발생한다.

<에러코드>


Fri Jan  2 10:36:22 2015 - [info]  Searching from all slaves which have received the latest relay log events..

Fri Jan  2 10:36:22 2015 - [info]   Not found.

Fri Jan  2 10:36:22 2015 - [info]  Searching from all slaves..

Fri Jan  2 10:36:22 2015 - [info]   Not found.

Fri Jan  2 10:36:22 2015 - [error][/db/programs/mha/module/MHA/MasterRotate.pm, ln232] Failed to get new master!

Fri Jan  2 10:36:22 2015 - [error][/db/programs/mha/module/MHA/ManagerUtil.pm, ln177] Got ERROR:  at /db/programs/mha/module/masterha_master_switch line 53



문제는 Slave 서버들이 여러개일 경우, Slave간에 new master로 승격할 Slave를 선정 시에

MySQL Version에 대한 비교 체크를 하게 되는데, new master로 승결될 Slave 서버가 다른Slave 서버보다 버젼이 높으면 체크로직에 의해 new master로 승격되지 못한다.


<체크 로직>


sub get_bad_candidate_masters($$$) {

......

    if (

         $_->{no_master} >= 1

      || $_->{log_bin} eq '0'

      || $_->{oldest_major_version} eq '0'

.......



[MHA 기능 추가] 
-Master 보다 더 높은 버젼의 Slave를 Master로 승격 시키기 
*정확히는 Slave들 간에 더 높은 버젼의 Slave를 Master로 승격 가능하게 해주는 옵션 

사용 사례 : MySQL 무중단 버젼 Upgrade등 

-수정해야 하는 파일 : 
1. Config.PM 
2. ServerManager.PM 
3. MHA config 파일 (app1.cnf or masterha_default.cnf) 

1> ignore_version 이라는 옵션을 받을 수 있게 합니다. 
수정파일 : Config.PM 

 1. 파라미터 열에 변수 넣어주기 (소스 상단에 있습니다.) 
  my _ARRAY =
    qw/ 변수들 나열.... ignore_version/;
  ignore_version 변수를 추가 해줍니다.


 2. mha 내의 선언 변수가 받을 수 있게 해줍니다.(비슷한 로직 근처에 넣어줍시다.) 
 ##### Debug Begin : ignore_version Option #####
    $value{ignore_version} = $param_arg->{ignore_version};
    if ( !defined( $value{ignore_version} ) ) {
      $value{ignore_version} = $default->{ignore_version};
    }
 ##### Debug END : ignore_version Option #####

2> 승격될 Slave의 버젼이 다른 Slave보다 높더라도 무시하게 해줍니다. 
수정파일 : ServerManager.PM 

 1. master로 승격되면 안되는 slave 필터링 함수 내에 코드 삽입(get_bad_candidate_master()) 
sub get_bad_candidate_masters($$$) {
  my $self                    = shift;
  my $latest_slave            = shift;
  my $check_replication_delay = shift;
  my $log                     = $self->{logger};

  my      = $self->get_alive_slaves();
  my _servers = ();
  foreach () {
  ##### Debug Begin : ignore_version Option #####
    if (
       defined ($_->{ignore_version}) && ($_->{ignore_version} eq '1'
       || lc $_->{ignore_version} eq "on")
       )
    {
  ##   Change the value from 0 to 1 for oldest_major_version check disable
       $_->{oldest_major_version} = '1';
        printf("'ignore_verion' configuration is set. 'oldest_major_version' value changed to 1.\n");
    }
  ##### Debug END : ignore_version Option #####
    if (
         $_->{no_master} >= 1
      || $_->{log_bin} eq '0'
      || $_->{oldest_major_version} eq '0'
      || (
        $latest_slave
        && ( $check_replication_delay
          && $self->check_slave_delay( $_, $latest_slave ) >= 1 )
      )
      )
    {
      push( _servers, $_ );
    }
  }
  return _servers;
}

3> mha conf파일에 옵션을 넣어 줍니다. 

## Ignore_version 
ignore_version=1 

-------------------------------------------------------------------------------- 

글을 쓰다가 귀찮아서 이미 다른 곳에 쓴 글 복사 붙이기함.