Mariadb(mysql) MHA failover 테스트

1. Mariadb 서비스 start (서버1 - Master, 서버2 - Slave)

$ service mysql start



2. MHA 상태 체크 및 MHA manager start (매니저 서버)

ssh 체크

$ masterha_check_ssh --conf=/etc/mha.cnf


replication 체크

$ masterha_check_repl --conf=/etc/mha.cnf


MHA manager start

MHA가 마스터 DB 모니터링 중에 장애가 감지되어 failover 가 발생 된 이후 일정 시간내에 장애에 대해서는 failover 가 진행 되지 않는다. failover 가 한번 처리 된 후 일정 시간안에는 failover가 되지 않으며 기본 값은 8시간이다. last_failover_minute으로 8시간을 1분으로 변경하여 실행하였다.

$ masterha_manager --conf=/etc/mha.cnf --last_failover_minute=1 &
$ masterha_check_status --conf=/etc/mha.cnf
mha (pid:14047) is running(0:PING_OK), master:192.168.100.126
$ 
$ tail -f /data/mariadb_mha/log/masterha/MHA.log  # MHA 로그 확인



3. 현재 Master, Slave 상태 체크

서버1 (Master)

-- 현재 Master가 보고 있는 mysqlbinlog의 파일과 위치를 출력
> show master status\G
*************************** 1. row ***************************
            File: mysql-bin.000003
        Position: 327
    Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)

-- 현재 서버가 Master라면 Slave 서버들의 정보 출력
> show slave hosts\G
*************************** 1. row ***************************
Server_id: 2
     Host:
     Port: 3306
Master_id: 1
1 row in set (0.00 sec)

-- 현재 서버가 Slave라면 해당 서버의 상태 출력. Master 서버이므로 출력하지 않는다.
> show slave status\G
Empty set (0.00 sec)

-- Master 서버는 read_only의 상태가 OFF 이다.
> show variables like 'read_only';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | OFF   |
+---------------+-------+
1 row in set (0.00 sec)


서버2 (Slave)

-- 현재 Master가 보고 있는 mysqlbinlog의 파일과 위치를 출력
> show master status\G
*************************** 1. row ***************************
            File: mysql-bin.000003
        Position: 327
    Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)

-- 현재 서버가 Master라면 Slave 서버들의 정보 출력. Slave 서버이기 때문에 출력하지 않는다.
> show slave hosts\G
Empty set (0.00 sec)

-- 현재 서버가 Slave라면 해당 서버의 상태 출력.
> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.100.126
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 10
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 327
               Relay_Log_File: mysqld-relay-bin.000005
                Relay_Log_Pos: 615
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 327
              Relay_Log_Space: 2794
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
               Master_SSL_Crl:
           Master_SSL_Crlpath:
                   Using_Gtid: No
                  Gtid_IO_Pos:
      Replicate_Do_Domain_Ids:
  Replicate_Ignore_Domain_Ids:
                Parallel_Mode: conservative
1 row in set (0.00 sec)

-- Slave 서버는 read_only의 상태가 ON 이다.
> show variables like 'read_only';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | ON   |
+---------------+-------+
1 row in set (0.00 sec)



4. 장애 발생

Master 서버에서 MariaDB 서비스 종료 (매니저 서버)

$ service mysql stop


MHA 로그 확인 (매니저 서버)

$ tail -f /data/mariadb_mha/log/masterha/MHA.log
...
----- Failover Report -----

mha: MySQL Master failover 192.168.100.126(192.168.100.126:3306) to 192.168.100.127(192.168.100.127:3306) succeeded

Master 192.168.100.126(192.168.100.126:3306) is down!

Check MHA Manager logs at penta:/data/mariadb_mha/log/masterha/MHA.log for details.

Started automated(non-interactive) failover.
Invalidated master IP address on 192.168.100.126(192.168.100.126:3306)
The latest slave 192.168.100.127(192.168.100.127:3306) has all relay logs for recovery.
Selected 192.168.100.127(192.168.100.127:3306) as a new master.
192.168.100.127(192.168.100.127:3306): OK: Applying all logs succeeded.
Failed to activate master IP address for 192.168.100.127(192.168.100.127:3306) with return code 10:0
Generating relay diff files from the latest slave succeeded.
192.168.100.127(192.168.100.127:3306): Resetting slave info succeeded.
Master failover to 192.168.100.127(192.168.100.127:3306) completed successfully.

마지막에 다음과 같이 성공적으로 failover가 작동하여 서버2번으로 Master가 선출되었다고 출력되었다.


MHA 모니터링 상황 확인 (매니저 서버)

$ masterha_check_status --conf=/etc/mha.cnf
mha is stopped(2:NOT_RUNNING).
$ masterha_check_repl --conf=/etc/mha.cnf
Wed Dec 28 10:45:33 2022 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Wed Dec 28 10:45:33 2022 - [info] Reading application default configuration from /etc/mha.cnf..
Wed Dec 28 10:45:33 2022 - [info] Reading server configuration from /etc/mha.cnf..
Wed Dec 28 10:45:33 2022 - [info] MHA::MasterMonitor version 0.57.
Wed Dec 28 10:45:34 2022 - [error][/usr/local/share/perl/5.26.1/MHA/ServerManager.pm, ln193] There is no alive slave. We can't do failover
Wed Dec 28 10:45:34 2022 - [error][/usr/local/share/perl/5.26.1/MHA/MasterMonitor.pm, ln427] Error happened on checking configurations.  at /usr/local/share/perl/5.26.1/MHA/MasterMonitor.pm line 329.
Wed Dec 28 10:45:34 2022 - [error][/usr/local/share/perl/5.26.1/MHA/MasterMonitor.pm, ln525] Error happened on monitoring servers.
Wed Dec 28 10:45:34 2022 - [info] Got exit code 1 (Not master dead).

MySQL Replication Health is NOT OK!

기존 Master 서버인 서버1의 MariaDB 장애가 발생하니 Failover가 작동하며 MHA Manager의 모니터링이 멈추었다.


실제 Failover 작동 확인 (현재 master가 된 서버2 정보 확인)

-- 현재 Master가 보고 있는 mysqlbinlog의 파일과 위치를 출력
> show master status\G
*************************** 1. row ***************************
            File: mysql-bin.000003
        Position: 327
    Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)

-- 현재 서버가 Master라면 Slave 서버들의 정보 출력.
-- 현재 서버2가 Failover로 Master로 선출되긴 했지만, 서버1의 Mariadb 서비스가 내려가 Slave가 없는 상태이므로 아무것도 출력하지 않는다.
> show slave hosts\G
Empty set (0.00 sec)

-- 현재 서버가 Slave라면 해당 서버의 상태 출력. Master 서버이므로 출력하지 않는다.
> show slave status\G
Empty set (0.00 sec)

-- Master 서버는 read_only의 상태가 OFF 이다.
> show variables like 'read_only';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

로그와 같이 실제로도 서버2가 Master 서버로 선출되어 Failover가 잘 작동된 것을 알 수 있다.



5. 복구

장애가 났던 서버1의 서비스를 복구해 보자.


서버1 복구 및 slave 설정 (서버1)

서버1의 mariadb 서비스를 기동한다.

$ service mysql start

장애가 발생되어 failover가 되게 되면 매니저서버에서 구동중인 MHA manager(모니터링)는 종료되게 된다 다시 모니터링을 하기 위해 기존의 master였던 서버1을 정상화 후 replication 설정을 한다.

-- 서버1 복구 후, 다운되어있을 때 업데이트된 현재 master인 서버2의 데이터를 서버1로 replicate 한다.
> CHANGE MASTER TO
-> MASTER_HOST='water2',					-- 현재 마스터서버 host명
-> MASTER_USER='rep',					-- 현재 마스터서버 replication 계정 user
-> MASTER_PASSWORD='Rep123!',			-- 현재 마스터서버 replication 계정 password
-> MASTER_LOG_FILE='mysql-bin.000001',	-- 현재 마스터서버의 logfile(show master status\G 참조)
-> MASTER_LOG_POS=2047;					-- 현재 마스터서버의 log 포지션(show master status\G 참조)

-- 서버1을 slave 시작
> start slave;

-- 복제 설정 여부 확인
> show slave status\G

만일 show slave status\G에서

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'

와 같은 에러가 발생했다면 Master에서 mysqlbinlog 파일명과 Position정보를 읽어오지 못해서 발생하는 에러이다.

Master 서버에서 show master status/G로 제대로 된 정보를 기입하자.


서버2(master)에서 설정 확인 (서버2)

> show slave hosts\G
*************************** 1. row ***************************
Server_id: 1
     Host:
     Port: 3306
Master_id: 2
1 row in set (0.00 sec)

서버1이 Slave로 동작하고 있다고 출력이 된다.


모니터링 다시 시작 및 로그 확인 (매니저 서버)

$ masterha_manager --conf=/etc/mha.cnf --last_failover_minute=1 &
$ tail -f /data/mariadb_mha/log/masterha/MHA.log



6. master 서버 스위치

현재 상태는 서버1이 slave, 서버2가 master로 뒤바뀐 상황이다. 이를 원래 상태인 서버1이 master, 서버2가 slave로 스위치를 해보자.


MHA manager 중지 (매니저 서버)

switch 시 매니저의 모니터링을 중지해야 한다.

$ masterha_stop --conf=/etc/mha.cnf
$ masterha_check_status --conf=/etc/mha.cnf
app1 is stopped(2:NOT_RUNNING).


switch 명령어로 Master 서버 변경 (매니저 서버)

$ masterha_master_switch --master_state=alive --conf=/etc/mha.cnf --new_master_host=192.168.100.126 --interactive=0

# --master_state=alive | dead
# master 서버가 장애로 인하여 수동적인 failover 를 하는 것이라면 --master_state=dead #라고 옵션을 사용한다.
# master 서버가 정상이라면 alive 라고 입력한다.

# --new_master_host=호스트명
# 새로운 마스터가 될 호스트명 입력

# --interactive=0 | 1
# 1번은 대화형으로 진행(default) 이며, 0번은 비대화식


masterha_master_switch 명령어 실행 시 Access denied 에러

masterha_master_switch 명령어 실행하니 아래와 같은 에러가 발생하였다.

$ masterha_master_switch --master_state=alive --conf=/etc/mha.cnf --new_master_host=192.168.100.126 --interactive=0
...
Got Error: DBI connect(';host=192.168.100.126;port=3306;mysql_connect_timeout=4','mha',...) failed: Access denied for user 'mha'@'water1' (using password: YES) at /usr/local/share/perl/5.26.1/MHA/DBHelper.pm line 206.
 at /data/mariadb_mha/scripts/master_ip_online_change line 132.

Wed Dec 28 16:29:55 2022 - [error][/usr/local/share/perl/5.26.1/MHA/ManagerUtil.pm, ln178] Got ERROR:  at /usr/local/bin/masterha_master_switch line 57.

해당 명령어가 DB에 접속을 하지 못해서 생기는 에러이다. DB 접속 계정인 mha의 비밀번호에 특수문자가 있어 발생하는 에러였다. 비밀번호 복잡도 정책을 낮추고 특수문자를 뺸 비밀번호로 변경하면 정상적으로 작동한다. 아래 명령어로 DB의 mha 계정 비밀번호에서 특수문자를 제거해주었다.

> set password for 'mha'@'%' = password('Mha123');


Master 서버에서 승격 여부 확인 (서버1)

> show slave status\G
Empty set (0.00 sec)

서버1이 master로 승격하여 slave 정보가 나오지 않는다.

하지만 서버2에서 slave hosts를 검색하 보면 여전히 1번 서버가 slave로 나올 수도 있으니 서버1에서 slave stop을 해준다.

> stop slave;


서버2가 다시 Master를 복제 후 slave 기동 (서버2)

서버1(Master)의 show master status\G를 참조하여 replication 설정 후 slave를 기동한다.

> CHANGE MASTER TO
> MASTER_HOST='water1',					-- 현재 마스터서버 host명
> MASTER_USER='rep',					-- 현재 마스터서버 replication 계정 user
> MASTER_PASSWORD='Rep123!',			-- 현재 마스터서버 replication 계정 password
> MASTER_LOG_FILE='mysql-bin.000001',	-- 현재 마스터서버의 logfile(show master status\G 참조)
> MASTER_LOG_POS=2047;					-- 현재 마스터서버의 log 포지션(show master status\G 참조)

> start slave;
Query OK, 0 rows affected (0.00 sec)

> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: water1
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 10
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 480
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 537
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 480
              Relay_Log_Space: 836
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
               Master_SSL_Crl:
           Master_SSL_Crlpath:
                   Using_Gtid: No
                  Gtid_IO_Pos:
      Replicate_Do_Domain_Ids:
  Replicate_Ignore_Domain_Ids:
                Parallel_Mode: conservative
1 row in set (0.00 sec)

> show variables like 'read_only';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | ON    |
+---------------+-------+
1 row in set (0.00 sec)


Master에서 연결 정보 확인 (서버1)

> show slave hosts\G
*************************** 1. row ***************************
Server_id: 2
     Host:
     Port: 3306
Master_id: 1
1 row in set (0.00 sec)


모니터링 재시작 (매니저 서버)

$ masterha_manager --conf=/etc/mha.cnf --last_failover_minute=1 &
$
$ tail -f /data/mariadb_mha/log/masterha/MHA.log

Leave a comment