[MySQL] Orchestrator 응용 - 1 (auto-rejoin)

Dong yeong Kim·2023년 9월 8일
0

DBMS

목록 보기
8/15

OS : CentOS 7.9 64bit

MySQL : 8.0.34 - commercial

Replica Set : 1(Soure), 2(Replica)

Server
VIP : 10.1.247.13
node1(DB) : 10.1.247.10
node2(DB) : 10.1.247.11
node3(DB, Orchestrator) : 10.1.247.12


지난 포스팅에서, Orchestrator 구성을 다루었습니다.
이번에는, Orchestrator 운영 중 필요할 수 있는 구성들과 VIP를 이용한 HA를 도달하는것이 목적입니다.


Hooks

DB 운영 중 여러가지 상황으로 Switchover 혹은 Failover가 필요할 때가 있습니다.
오케스트레이터는 아래와 같은 후크를 제공하며, 이름에서 쉽게 유추할 수 있습니다.

### Default Sample (/usr/local/orchestrator/orchestrator-sample.conf.json)
{
  "PreGracefulTakeoverProcesses": [ 
    "echo 'Planned takeover about to take place on {failureCluster}. Master will switch to read_only' >> /tmp/recovery.log"
  ],
  "PreFailoverProcesses": [
    "echo 'Will recover from {failureType} on {failureCluster}' >> /tmp/recovery.log"
  ],
  "PostFailoverProcesses": [
    "echo '(for all types) Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:{failedPort}; Successor: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],
  "PostUnsuccessfulFailoverProcesses": [],
  "PostMasterFailoverProcesses": [
    "echo 'Recovered from {failureType} on {failureCluster}. Failed: {failedHost}:
    {failedPort}; Promoted: {successorHost}:{successorPort}' >> /tmp/recovery.log"
  ],
  "PostIntermediateMasterFailoverProcesses": [],
  "PostGracefulTakeoverProcesses": [
    "echo 'Planned takeover complete' >> /tmp/recovery.log"
  ],
}

PreGracefulTakeoverProcesses : 수동 Switchover시 사전의 프로세스를 정의합니다.

PreFailoverProcesses : Failover시 사전의 프로세스를 정의합니다.

PostFailoverProcesses : Feilover시 사후의 프로세스를 정의합니다.

PostUnsuccessfulFailoverProcesses : Failover 실패 시 사후의 프로세스를 정의합니다.

PostMasterFailoverProcesses : 성공적인 복구가 끝나면 실행됩니다.

PostIntermediateMasterFailoverProcesses : 중간 마스터(Chain Slave) 혹은 복제 그룹 멤버의 복구 후 실행됩니다.

PostGracefulTakeoverProcesses : 수동 Switchover시 사후의 프로세스를 정의합니다.


우리는 이런 Hook 과정 안에 있는 Hook Parameters로 인자를 전달받아 커스텀 작업이 가능합니다.

  "PreFailoverProcesses": [
    "echo 'Will recover from {failureType} on {failureCluster}' >> /tmp/recovery.log"
  ]
### recovery.log
Will recover from DeadMaster on node2:3306

위의 예시는, PreFailoverProcess가 진행될 경우, echo로 /tmp/recovery.log에 특정한 메시지를 전달합니다. 여기서, {failureType}{failureCluster}의 값을 전달받습니다.


Auto-re-launch replication during graceful takeover

예기치 못한 이유로 Master 서버가 장애가 발생한 것이 아닌, 관리자가 수동으로 Master <-> Slave의 Role Change를 하는 경우는 특정한 목적이 존재합니다. (업그레이드 등)
Orchestrator는 MHA4MySQL 이나, MariaDB의 Maxscale와 다르게 수동 takeover 시 Replication을 다시 맺어주는 기능은 지원하지 않습니다.

여기서 Hook과정의 인자들을 전달 받아 해당 문제를 해결 할 수 있습니다.

Orchestrator는 Manual Recovery가 기본이므로, 일부 파라미터의 수정이 필요합니다.
(출처 : Hoing - Orchestrator Refactoring)

  • RecoverMasterClusterFilters
  • Master 장애에 대해서 자동 복구할 클러스터를 지정하는 옵션입니다.
    예를 들어, "node1", "node2"와 같이 기술되어 있다면, 여러 노드에서 지정된 2개에 대해서만 자동 복구가 진행됩니다.

    위와 같이 명시적으로 입력할 수도 있고, 정규식(Regex)으로도 입력 가능합니다.
    "RecoverMasterClusterFilters": [
    "myoltp", // cluster name includes this string
    "meta[0-9]+", // cluster name matches this regex
    "alias=olap", // cluster alias is exactly "olap"
    "alias~=shard[0-9]+" // cluster alias matches this pattern
    ]

  • PromotionIgnoreHostnameFilters

  • Slave 노드 중 Master로 승격 될 대상에서 제외 할 노드를 입력합니다.

  • RecoveryPeriodBlockSeconds
  • 장애가 발생 후 자동 복구가 되면 해당 파라미터에 지정된 시간 동안은 자동 복구를 차단합니다. (Default : 3600초)

    예시 구현을 위해 아래와 같이 파라미터를 수정하도록 하겠습니다.

    ~]# cd /usr/local/orchestrator
    ~]# cp -rp orchestrator.conf.json cp orchestrator.conf.json.back
    ~]# vi orchestrator.conf.json
    ### 파일 변경 내역 ###
    (1) 변경 없음
      "PromotionIgnoreHostnameFilters": [],
    (2) 3600 -> 10
      "RecoveryPeriodBlockSeconds": 10,
    (3) _master_pattern_  -> *
      "RecoverMasterClusterFilters": [
        "*" ## 모든 노드에 매칭
      ],
    (4) _intermediate_master_pattern_  ->  *
      "RecoverIntermediateMasterClusterFilters": [
        "*"
      ],

    위와 같이 수정 후 Orchestrator 웹에서 Configuration 파일을 Reload 합니다.

    아래는 정현호님의 스크립트 파일입니다.
    해당 파일을 오케스트레이터 서버에 업로드합니다.
    takeover_replication_start.sh

    스크립트를 살펴보도록 하겠습니다.

    #!/bin/bash
    
    
    ## PATH
    export PATH=$PATH:/usr/local/mysql/bin
    
    failuretype=`cat /usr/local/orchestrator/log/detected_failuretype.log`
    
    if [ "$failuretype" = "DeadMaster" ]
    
        then
        ## Failure Master Host IP
        failed_host_ip=`mysql --login-path=orchuser -sN -e "select ipv4 from orchestrator.hostname_ips where hostname='$1'"`
    
        failed_host_db_port=`mysql --login-path=orchuser -sN -e "select port from orchestrator.database_instance where hostname='$1'"`
    
        topologyuser=`grep -i MySQLTopologyUser /usr/local/orchestrator/orchestrator.conf.json | awk '{print $2}' | sed "s/,//g" | sed "s/\"//g"`
        topologypassword=`grep -i MySQLTopologyPassword /usr/local/orchestrator/orchestrator.conf.json | awk '{print $2}' | sed "s/,//g" | sed "s/\"//g"`
    
        db_version=`mysql --login-path=orchuser -sN -e "select substr(version,1,1) from orchestrator.database_instance where hostname='$1'"`
    
        if [ "$db_version" = "5" ]
            then
            mysql -u$topologyuser -p$topologypassword -h $failed_host_ip -P $failed_host_db_port -sN  -e "start slave"
    
            else
            mysql -u$topologyuser -p$topologypassword -h $failed_host_ip -P $failed_host_db_port -sN  -e "start replica"
        fi
    fi
    
    
    echo "Graceful Takeover Replica Start"
    

    failuretype=`cat /usr/local/orchestrator/log/detected_failuretype.log`

    detected_failuretype.log에서 값을 가져와, DeadMaster 일 경우 프로세스를 진행합니다.

    Orchestrator 에서는 DeadMaster를 아래와 같이 정의합니다.

    DeadMaster:
    Master MySQL access failure
    All of master's replicas are failing replication
    1. 마스터 MySQL에 엑세스 실패할 경우
    2. 모든 Replica Node가 Replication에 실패할 경우
      failed_host_ip=`mysql --login-path=orchuser -sN -e "select ipv4 from orchestrator.hostname_ips where hostname='$1'"`
    
      failed_host_db_port=`mysql --login-path=orchuser -sN -e "select port from orchestrator.database_instance where hostname='$1'"`

    Orchestrator에 기본적으로 제공되는 테이블의 정보를 가져옵니다.
    여기서 $1이란, Bash 기본 문법이며, 해당 메소드의 첫번째 인자값을 의미합니다.
    여기서의 첫번째 인자값이란 아래와 같이 전달됩니다.

  • Orchestrator.conf
  • ...
    
    "PostGracefulTakeoverProcesses": [
       "echo 'Planned takeover complete' >> /usr/local/orchestrator/log/recovery.log"
     ],
    TO(아래와 같이 수정)
    "PostGracefulTakeoverProcesses": [
       "echo 'Planned takeover complete' >> /usr/local/orchestrator/log/recovery.log",
       "/usr/local/orchestrator/takeover_replication_start.sh {failedHost} >> /usr/local/orchestrator/log/recovery.log"
     ],
     ...
     

    PostGracefulTakeoverProcesses, 즉 수동으로 Takeover 후의 작업을 커스텀하는데,
    여기서는 {failedHost} 인자, 결론적으로 기존 Master 노드의 hostname을 가리킵니다.

    그리하여, 위의 {failed_host_ip}{failed_host_db_port} 값을 가져오면 아래와 같습니다.

    mysql> select ipv4 from orchestrator.hostname_ips where hostname='node1';
    +-------------+
    | ipv4        |
    +-------------+
    | 10.1.247.10 |
    +-------------+
    1 row in set (0.00 sec)
    
    mysql> select port from orchestrator.database_instance where hostname='node1';
    +------+
    | port |
    +------+
    | 3306 |
    +------+
    1 row in set (0.00 sec)
    

    --login-path 라는 옵션이 있는데, 이는 mysql 접속을 간단하게 하기 위함이며 필요에 따라 수동으로 설정해도 무방합니다.

     topologyuser=`grep -i MySQLTopologyUser /usr/local/orchestrator/orchestrator.conf.json | awk '{print $2}' | sed "s/,//g" | sed "s/\"//g"`
     topologypassword=`grep -i MySQLTopologyPassword /usr/local/orchestrator/orchestrator.conf.json | awk '{print $2}' | sed "s/,//g" | sed "s/\"//g"`
    
     db_version=`mysql --login-path=orchuser -sN -e "select substr(version,1,1) from orchestrator.database_instance where hostname='$1'"`
    
     if [ "$db_version" = "5" ]
         then
         mysql -u$topologyuser -p$topologypassword -h $failed_host_ip -P $failed_host_db_port -sN  -e "start slave"
    
         else
         mysql -u$topologyuser -p$topologypassword -h $failed_host_ip -P $failed_host_db_port -sN  -e "start replica"
        fi
    fi
    
    
    echo "Graceful Takeover Replica Start"

    Orchestrator.conf에서 정의한 topologyuser, topologypassword를 이용하여 {failed_host_ip}, {failed_host_db_port}에 접근 후 복제를 시작합니다.

    Takeover 되었으므로, 기존 마스터가 Slave가 되야하기에 해당 과정이 필요한 것입니다.

    해당 과정을 수행하면 Orchestrator가 Graceful Takeover 후 절체된 Master에 대해 Auto-rejoin를 수행하게 됩니다.


    다음 포스팅은, VIP를 이용한 HA 구현에 대해 알아보도록 하겠습니다.

    출처 : hoing.io

    profile
    날 것의 기술 '불'로그

    0개의 댓글