AWS 기술 블로그

Amazon RDS MySQL 블루/그린 배포환경에서 전환 작업 이후 복구 환경 구성을 위한 동기화 기법

Amazon AuroraAmazon Relational Database Service(Amazon RDS) 고객은 블루/그린 배포 자체 관리에 도움이 되도록 데이터베이스 복제 및 프로모션 가능한 읽기 전용 복제본을 사용할 수 있습니다. 이런 블루/그린 배포 방식에서 데이터베이스 업그레이드 작업을 한 후 문제가 있으면 기존 장비로 다시 복구를 진행해야 합니다. 하지만 이미 신규 장비에는 새로운 데이터가 쌓여 있어 일부 데이터를 버리거나 수동으로 변경된 데이터를 찾아서 재반영하는 작업을 진행해야 했습니다.

이 블로그에서는 블루/그린 배포환경에서 전환 작업 후에 MySQL의 Binlog를 활용하여 복구 환경을 구성하기 위한 방법을 확인할 수 있습니다.

블루/그린 배포 전 확인 사항

RDS MySQL에서 블루/그린 배포를 사용하려면 파라미터 그룹에서 binlog_format 파라미터의 값을 OFF에서 ROW로 변경하여 Binlog를 활성화해야 합니다.

기존 인스턴스로의 Binlog 동기화를 설정하기 위해서는 신규 인스턴스에서도 Binlog를 활성화해야 사용이 가능합니다. Binlog를 사용하고 있는지 확인하는 방법은 RDS MySQL 서버에 접속하여 명령어로 확인할 수 있습니다.

MySQL> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+

전환 작업 시 애플리케이션 중단이 가능한 경우

블루/그린 환경에서 전환 작업을 완료했다면 새로운 인스턴스로 새로운 데이터가 유입되기 시작합니다. 블루/그린 배포 환경을 사용하는 이유 중 하나는 데이터베이스 업그레이드를 할 때 최대한 짧은 다운타임을 갖기 위함입니다.
만약 애플리케이션을 중단시키고 데이터베이스를 업그레이드하는 경우에는 show master status 로 변경된 인스턴스에서 최신 Binlog의 위치를 찾을 수 있습니다.

Patched MySQL> show master status;
+----------------------------+----------+--------------+------------------+-------------------+
| File                       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-changelog.000005 |      439 |              |                  |                   |
+----------------------------+----------+--------------+------------------+-------------------+

여기서 찾은 Binlog 파일 이름과 위치로 기존 인스턴스에 Binlog 동기화 를 설정할 수 있습니다.

전환 작업 시 애플리케이션 중단이 불가능한 경우

블루/그린 환경을 통해 전환하는 상황에서는 최소한의 다운타임을 위해 애플리케이션 서비스 중단을 하지 못하는 경우가 있습니다. 이런 경우 새로 변경된 인스턴스에는 이미 새로운 데이터들이 들어와서 Binlog 위치가 변경되고 있기 때문에 전환된 시점에서의 Binlog 위치를 바로 찾기는 어려운 상황입니다. 하지만 서비스가 지속적으로 운영되는 환경에서도 우리는 문제 상황에 대비하기 위하여 기존 장비로의 복구 작업을 준비해야 합니다.

Binlog 를 다운받아서 서버가 변경된 지점을 찾는 방법

단계 1 : Binlog 다운 받기

이런 상황에서 우리는 Binlog를 다운받아서 직접 열어보는 방법을 택할 수 있습니다. Binlog를 다운받기 위해서는 Binlog의 파일 이름을 알고 있어야 해당 Binlog 파일을 다운받을 수 있습니다. RDS MySQL에서 현재 보관 중인 Binlog 파일 리스트 확인하여 다운받을 Binlog 파일명을 지정할 수 있습니다.

Patched MySQL> show binary logs;
+----------------------------+-----------+
| Log_name                   | File_size |
+----------------------------+-----------+
| mysql-bin-changelog.000002 |       154 |
| mysql-bin-changelog.000003 |       154 |
| mysql-bin-changelog.000004 |      7365 |
| mysql-bin-changelog.000005 |       439 |
+----------------------------+-----------+

확인된 Binlog를 직접 접근해서 이벤트를 확인 할 수 있습니다.

# mysqlbinlog \
--read-from-remote-server \
--host=mydbreplsourceinstance.123456789.us-east-1.rds.amazonaws.com \
--port=3306 \
--user binlog_user \
--password \
--result-file=/tmp/mysql-bin-changelog.000004 \
mysql-bin-changelog.000004
Enter password:

단계 2 : Binlog 파일 안에서 서버 ID 확인 하기

Binlog를 다운받았다면 우리는 서버가 전환된 지점을 찾아야 합니다. 여기서는 MySQL Binlog의 특징을 이용할 수 있습니다. MySQL에서 Binlog는 실제 DML이 들어온 서버의 ID를 Binlog에 기록하게 됩니다. 이는 Binlog 동기화가 걸려있는 모든 MySQL 서비스에서 볼 수 있는 특징입니다.

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#230307  3:18:42 server id 285769449  end_log_pos 123 CRC32 0x2ea24d50  Start: binlog v 4, server v 5.7.12-log created 230307  3:18:42 at startup
ROLLBACK/*!*/;
BINLOG 'query information..
'/*!*/;
# at 123
#230307  3:18:42 server id 285769449  end_log_pos 154 CRC32 0x7a70384e  Previous-GTIDs
# [empty]
# at 154
#230307  8:24:50 server id 285769449   end_log_pos 219 CRC32 0x6605d4e5  Anonymous_GTID  last_committed=0        sequence_number=1       rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#230307  8:24:50 server id 285769449   end_log_pos 328 CRC32 0xd6a98672  Query   thread_id=20    exec_time=0     error_code=0
SET TIMESTAMP=1678177490/*!*/;
SET @@session.pseudo_thread_id=20/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create database replTest

단계 3 : Binlog파일 안에서 서버 ID가 변경된 지점을 찾기

Binlog의 특징을 알고 있다면 다운받은 Binlog에서 서버 ID가 변경되는 지점을 찾을 수 있습니다. 서버 ID가 변경되는 지점이 있는 Binlog 파일 이름과 해당 위치를 가지고 기존 인스턴스에 Binlog 동기화를 알맞은 위치에서 할 수 있습니다.

# at 2270
#230307 8:55:32 server id 719944619 end_log_pos 2345 CRC32 0x3a1c024b Query thread_id=41 exec_time=0 error_code=0
SET TIMESTAMP=1678179332/*!*/;
BEGIN
/*!*/;
# at 2345
#230307 8:55:32 server id 719944619 end_log_pos 2405 CRC32 0xb9f6db15 Table_map: `dlongtest`.`dlongtest` mapped to number 103
# at 2405
#230307 8:55:32 server id 719944619 end_log_pos 2449 CRC32 0x9911650b Write_rows: table id 103 flags: STMT_END_F

BINLOG '
Query information
'/*!*/;
# at 2449
#230307 8:55:32 server id 719944619 end_log_pos 2480 CRC32 0x25674031 Xid = 3901
COMMIT/*!*/;
# at 2480
#230307 8:56:55 server id 2086108034 end_log_pos 2557 CRC32 0x9b384149 Anonymous_GTID last_committed=8 sequence_number=9 rbr_only=no original_committed_timestamp=1678179415491199 immediate_commit_timestamp=1678179415491199 transaction_length=195
# original_commit_timestamp=1678179415491199 (2023-03-07 08:56:55.491199 UTC)
# immediate_commit_timestamp=1678179415491199 (2023-03-07 08:56:55.491199 UTC)
/*!80001 SET @@session.original_commit_timestamp=1678179415491199*//*!*/;
/*!80014 SET @@session.original_server_version=80023*//*!*/;
/*!80014 SET @@session.immediate_server_version=80023*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 2557
#230307 8:56:55 server id 2086108034 end_log_pos 2675 CRC32 0x69791a43 Query thread_id=18 exec_time=0 error_code=0 Xid = 4790
SET TIMESTAMP=1678179415/*!*/;
SET @@session.sql_mode=2097152/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=255,@@session.collation_connection=255,@@session.collation_server=255/*!*/;
/*!80011 SET @@session.default_collation_for_utf8mb4=255*//*!*/;

확인된 Binlog 위치와 파일명을 이용하면 신규 인스턴스에서 기존 인스턴스로 Binlog 동기화를 진행할 수 있습니다.

Binlog 다운로드 없이 서버가 변경된 지점을 찾는 방법

실제 서비스에서는 Binlog를 하나씩 다운받아 비교하려면 많은 시간이 걸립니다. 그렇기 때문에 우리는 시간을 줄이기 위해 쿼리를 사용해서 Binlog의 이벤트 내용을 볼 수 있습니다. 이를 통하여 서버 ID가 변경된 지점을 찾을 수 있습니다. Binlog 내용을 확인하기 위해서 Binlog 파일명을 우선 확인합니다.

Patched MySQL> show binary logs;
+----------------------------+-----------+
| Log_name                   | File_size |
+----------------------------+-----------+
| mysql-bin-changelog.000001 |      3415 |
| mysql-bin-changelog.000002 |       154 |
| mysql-bin-changelog.000003 |       154 |
| mysql-bin-changelog.000004 |      7365 |
| mysql-bin-changelog.000005 |       439 |
+----------------------------+-----------+

변경된 지점의 Binlog 파일의 이벤트에서 서버 ID가 변경된 지점을 찾을 수 있습니다.

Patched MySQL> show binlog events in 'mysql-bin-changelog.000001' LIMIT 37,8;
+----------------------------+------+----------------+------------+-------------+------------------------------------------------------------+
| Log_name                   | Pos  | Event_type     | Server_id  | End_log_pos | Info                                                       |
+----------------------------+------+----------------+------------+-------------+------------------------------------------------------------+
| mysql-bin-changelog.000001 | 2405 | Write_rows     |  719944619 |        2449 | table_id: 103 flags: STMT_END_F                            |
| mysql-bin-changelog.000001 | 2449 | Xid            |  719944619  |        2480 | COMMIT /* xid=3901 */                                      |
| mysql-bin-changelog.000001 | 2480 | Anonymous_Gtid | 2086108034  |        2557 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                       |
| mysql-bin-changelog.000001 | 2557 | Query          | 2086108034 |        2675 | TRUNCATE TABLE mysql.rds_replication_status /* xid=4790 */ |
| mysql-bin-changelog.000001 | 2675 | Anonymous_Gtid | 2086108034 |        2752 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                       |
| mysql-bin-changelog.000001 | 2752 | Query          | 2086108034 |        2859 | TRUNCATE TABLE mysql.rds_history /* xid=4792 */            |
| mysql-bin-changelog.000001 | 2859 | Anonymous_Gtid | 2086108034 |        2938 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                       |
| mysql-bin-changelog.000001 | 2938 | Query          | 2086108034 |        3023 | BEGIN                                                      |
+----------------------------+------+----------------+------------+-------------+------------------------------------------------------------+

확인된 Binlog 위치와 파일명을 이용하면 신규 인스턴스에서 기존 인스턴스로 Binlog 동기화를 진행할 수 있습니다.

전환 이후 기존 인스턴스로 동기화 구성이 완료되었다면 애플리케이션 오류가 발생한 상황에서 기존 장비로 복구 작업을 진행할 수 있습니다. 복구를 위해서는 기존 인스턴스로 애플리케이션에서 사용하는 인스턴스 엔드포인트를 배포 후 복구 작업이 가능합니다.

결론

이번 작업으로 블루/그린 배포 환경에서 전환 작업 이후 장애 복구에 대비하기 위한 기존 인스턴스로의 동기화 구성을 마치게 되었습니다. 이 작업을 수행해 보시면 문제 상황에 대응할 수 있는 복구 환경 구성할 수 있습니다. 여러 사전 작업으로 장애 복구를 대비할 수 있는 환경을 만들어 간다면 점점 더 견고하게 서비스를 운영할 수 있을 것으로 기대합니다.

Daeheon Oh

Daeheon Oh

오대헌 테크니컬 어카운트 매니저는 데이터베이스에 대한 경험을 바탕으로 Enterprise support 고객에게 데이터베이스를 안정적으로 서비스 될 수 있도록 고객과 함께 효율적인 아키텍처와 운영 방식을 구성하는 역할을 수행하고 있습니다.