Aurora Global Database와 binlog replication의 차이
Aurora Global Database의 스토리지 기반 리전 간 복제와 MySQL binlog 복제를 비교하고, 지연 관측·재해복구·외부 연계의 선택 기준을 정리한다.
1. 리전 간 복제라는 목적만으로 같은 기술은 아니다
Aurora Global Database와 MySQL binlog replication은 모두 다른 위치에 데이터 사본을 유지할 수 있지만, 변경을 전달하고 적용하는 계층이 다르다. 이 차이는 단순한 성능 비교를 넘어 관측해야 할 지표, 장애 원인, 승격 절차, 외부 시스템 연결 가능성을 결정한다. Global Database의 지연을 SQL worker 수로 해결하려 하거나, binlog 채널의 정상 상태를 Global Database의 재해복구 준비 완료로 해석하면 진단부터 잘못된다.
핵심 구분은 다음과 같다. Global Database는 Aurora 스토리지 계층을 이용하는 관리형 리전 간 복제이고, binlog 복제는 MySQL 변경 이벤트를 수신하여 대상 DB 엔진에 적용하는 논리 복제다. Global Database의 내부 전송을 MySQL binlog 스트림이나 일반적인 테이블 파일 복사와 동일시하지 않는다.
이 글은 Aurora MySQL을 기준으로 두 방식의 운영 계약을 비교한다. SQL은 폐기용 Community MySQL 8.0에서 설정·관측 객체·GTID 집합 연산을 실행한 예제다. 실제 Aurora 클러스터 생성, 리전 장애, Global Database 전환, 복제 성능 측정은 수행하지 않았다. 서비스 동작과 메트릭 정의는 아래 AWS 공식 문서를 기준으로 설명하며, 로컬 SQL 결과를 Aurora 실측값으로 제시하지 않는다.
2. 변경이 이동하는 경로를 먼저 구분한다
2.1 Global Database: DB 엔진 바깥의 복제 경로
Global Database는 하나의 primary 리전과 다른 리전의 secondary 클러스터로 구성된다. 쓰기는 primary 클러스터에서 먼저 처리되고, 변경은 전용 인프라를 통해 secondary 리전의 스토리지로 비동기 복제된다. secondary의 DB 인스턴스는 해당 리전에서 읽기 부하를 처리한다. 서로 다른 리전의 클러스터가 하나의 물리 볼륨을 동시에 공유하는 구조는 아니다.
AWS는 이 복제가 DB 엔진이 아니라 클러스터 스토리지 볼륨을 이용한다고 설명한다. 따라서 secondary에 MySQL relay log를 쌓고 일반 binlog applier가 같은 이벤트를 재실행하는 모델로 이해하면 안 된다. replica_parallel_workers를 높이는 것은 Global Database의 리전 간 복제 병렬도를 조정하는 방법이 아니다.
AWS가 제시하는 통상적인 초 단위 미만의 전송 지연은 동기 복제나 지연 상한 보장이 아니다. primary의 커밋 성공을 받았더라도 그 직후 다른 리전에서 같은 행이 보인다고 단정할 수 없다. 스토리지 전달 지연 외에도 reader의 반영 상태와 조회 트랜잭션의 Read View가 가시성에 영향을 줄 수 있다.
2.2 Binlog 복제: 수신과 적용이 분리된 엔진 작업
MySQL binlog 복제에서는 source가 binary log에 기록한 이벤트를 replica의 receiver가 받아 relay log에 보관한다. applier는 이를 읽어 대상 엔진에 적용한다. 병렬 복제가 활성화되어 있으면 coordinator가 트랜잭션을 worker에 배정하며, 트랜잭션 의존성과 커밋 순서 정책이 실제 병렬성을 제한한다.
ROW 형식에서도 대상 엔진의 인덱스 갱신과 잠금 획득 같은 작업이 필요하다. 네트워크 수신은 정상인데 긴 트랜잭션, hot row, 느린 저장장치, 대상의 조회 부하로 적용이 뒤처질 수 있다. 따라서 지연을 볼 때에는 받지 못한 변경과 받았지만 적용하지 못한 변경을 나누어야 한다. worker가 많다고 모든 트랜잭션을 독립적으로 적용할 수 있는 것은 아니다.
flowchart TB
subgraph G["Aurora Global Database"]
A["Primary 리전 writer"] --> B["Primary 클러스터 스토리지"]
B -->|"전용 인프라를 통한 비동기 복제"| C["Secondary 리전 스토리지"]
C --> D["Secondary reader"]
end
subgraph L["MySQL binlog 복제"]
E["Source 커밋과 binlog"] --> F["Replica receiver"]
F --> H["Relay log"]
H --> I["Applier와 worker"]
I --> J["대상 InnoDB 데이터와 인덱스"]
end
두 경로는 대안이면서 동시에 공존할 수 있다. 리전 재해복구에는 Global Database를 사용하고, 외부 MySQL 또는 CDC 소비자 연결에는 별도의 binlog 경로를 사용하는 구성이다. 이때 두 경로의 지연, 보존 기간, 장애 상태는 서로 다른 운영 대상이다. 지원 조합과 전환 후 binlog 소비자의 재연결 방식은 대상 엔진 버전에서 별도로 확인해야 한다.
3. 목적별로 비교하는 운영 계약
| 비교 항목 | Aurora Global Database | MySQL binlog replication |
|---|---|---|
| 변경 전달 계층 | Aurora 스토리지 기반 리전 간 복제 | MySQL binary log 이벤트의 수신·적용 |
| 주된 목적 | Aurora 리전 재해복구, 지역별 읽기 | MySQL 계열 간 복제, 이관, 외부 연계 |
| 대상 범위 | Global Database 구성원인 Aurora 클러스터 | 호환되는 MySQL·Aurora 등과 binlog 소비자 |
| 적용 부하 해석 | 일반 MySQL SQL worker 모델과 다름 | 대상 엔진의 잠금·인덱스·I/O와 worker 처리량에 영향받음 |
| 선택적 복제 | 테이블별 binlog 필터를 설정하는 구조가 아님 | 구성에 따라 필터 가능하나 데이터 완전성과 DDL 해석 주의 |
| 진행 상태 | Global Database 전용 서비스 상태와 지연 메트릭 | 채널 상태, 수신·적용 위치, GTID, worker 오류 |
| 역할 전환 | 관리형 switchover·failover 절차 | 배포 방식에 따른 쓰기 차단·적용 경계 확인·승격 절차 |
| 외부 변경 스트림 | 내부 스토리지 복제를 일반 CDC 입력으로 사용하지 않음 | 별도 소비자가 binlog를 읽는 연계 가능 |
여기서 binlog는 복제 프로토콜이고, 자동 장애조치·라우팅·이전 writer 차단까지 모두 제공하는 고가용성 제품을 뜻하지 않는다. 반대로 Global Database가 관리형이라고 해서 애플리케이션 연결 풀, DNS 캐시, 미확정 트랜잭션 재처리까지 서비스가 대신 해결하는 것도 아니다.
선택 기준은 “어느 쪽이 무조건 더 빠른가”보다 “어떤 복구 및 연계 계약이 필요한가”다. Aurora의 전체 데이터 사본을 다른 리전에 유지하려는 목적과, 외부 MySQL에 특정 업무 데이터를 보내려는 목적은 같지 않다. 두 요구가 모두 있으면 하나의 지표나 하나의 승격 절차로 통합하려 하지 않는다.
4. 진단 SQL: binlog 설정과 채널의 존재를 구별한다
4.1 설정값으로 알 수 있는 것과 없는 것
다음 조회는 로컬 MySQL의 binlog·GTID 관련 설정만 확인한다. MySQL 8.0 이상에서 사용할 수 있으며, 운영에서는 해당 객체를 조회할 권한이 필요하다.
SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM performance_schema.global_variables
WHERE VARIABLE_NAME IN (
'log_bin', 'binlog_format', 'gtid_mode', 'enforce_gtid_consistency'
)
ORDER BY VARIABLE_NAME;
실행 결과(MySQL 8.0.x):
mysql> SELECT VARIABLE_NAME, VARIABLE_VALUE
-> FROM performance_schema.global_variables
-> WHERE VARIABLE_NAME IN (
-> 'log_bin', 'binlog_format', 'gtid_mode', 'enforce_gtid_consistency'
-> )
-> ORDER BY VARIABLE_NAME;
+--------------------------+----------------+
| VARIABLE_NAME | VARIABLE_VALUE |
+--------------------------+----------------+
| binlog_format | ROW |
| enforce_gtid_consistency | OFF |
| gtid_mode | OFF |
| log_bin | OFF |
+--------------------------+----------------+
4 rows in set (0.01 sec)
검증 인스턴스는 binlog를 끈 상태이므로 log_bin=OFF다. binlog_format=ROW가 조회된다고 해서 binlog가 활성화된 것은 아니다. GTID 설정 역시 채널이 실제로 연결되어 있는지와는 별개의 조건이다.
Aurora에서 이 결과를 읽을 때도 binlog 활성 여부만으로 Global Database 가입 여부를 판단하지 않는다. Global Database 내부 복제는 binlog 활성화를 전제로 하는 경로가 아니다. 반대로 외부 복제·CDC 때문에 binlog가 켜져 있다고 Global Database의 리전 간 전달이 binlog로 바뀌는 것도 아니다. 서비스 구성원과 역할은 RDS의 Global Database 구성 정보에서 별도로 확인한다.
4.2 채널을 관측한다고 Global Database를 관측하는 것은 아니다
다음 조회는 binlog 복제의 수신·적용 상태 테이블에 관측 행이 있는지 확인하는 시작점이다. 집계값은 채널 건전성을 보장하지 않으며, worker 수와 채널 수를 같게 해석해서도 안 된다.
SELECT 'receiver_channels' AS observation, COUNT(*) AS observed_rows
FROM performance_schema.replication_connection_status
UNION ALL
SELECT 'applier_channels', COUNT(*)
FROM performance_schema.replication_applier_status
UNION ALL
SELECT 'applier_workers', COUNT(*)
FROM performance_schema.replication_applier_status_by_worker;
실행 결과(MySQL 8.0.x):
mysql> SELECT 'receiver_channels' AS observation, COUNT(*) AS observed_rows
-> FROM performance_schema.replication_connection_status
-> UNION ALL
-> SELECT 'applier_channels', COUNT(*)
-> FROM performance_schema.replication_applier_status
-> UNION ALL
-> SELECT 'applier_workers', COUNT(*)
-> FROM performance_schema.replication_applier_status_by_worker;
+-------------------+---------------+
| observation | observed_rows |
+-------------------+---------------+
| receiver_channels | 0 |
| applier_channels | 0 |
| applier_workers | 0 |
+-------------------+---------------+
3 rows in set (0.00 sec)
로컬 검증은 복제 채널을 구성하지 않았으므로 모든 값이 0이다. 이는 재현 환경의 정상적인 관측 결과이며, 복제 지연이 0이라는 뜻은 아니다. Aurora에서도 이 테이블의 행이 없다는 이유만으로 Global Database가 중단됐다고 결론 내리지 않는다.
실제 binlog 장애에서는 채널 이름을 먼저 식별한 다음 receiver의 SERVICE_STATE와 마지막 오류, worker별 오류·진행 상태를 확인한다. SHOW REPLICA STATUS의 지연값 하나만으로 source의 마지막 커밋까지 적용됐다고 단정하지 않는다. 수신 연결이 끊긴 경우, 적용 worker가 대기하는 경우, 필터로 일부 변경이 제외된 경우에는 서로 다른 후속 조사가 필요하다.
5. 지연 지표의 이름보다 측정 경계를 읽는다
Global Database에는 binlog 채널과 별도의 관측 경계가 있다. 현재 AWS CloudWatch 문서에 정의된 다음 지표는 secondary 리전에서 제공되며 단위는 모두 밀리초다. 실제 엔진 버전·리전·구성에서의 노출 여부는 적용 전에 확인한다.
| 지표 | AWS 문서상 측정 의미 | 운영 해석 |
|---|---|---|
AuroraGlobalDBReplicationLag |
Primary와 secondary 클러스터의 replication server 사이에서 업데이트가 복제되는 평균 경과 시간 | 전송 경로를 관찰하되 업무 데이터 복구 경계와 동일시하지 않음 |
AuroraGlobalDBProgressLag |
사용자 트랜잭션과 시스템 트랜잭션을 포함하여 secondary 스토리지 볼륨이 primary보다 뒤처진 정도 | 스토리지 전체 진행 상태를 해석하는 관측점 |
AuroraGlobalDBRPOLag |
사용자 트랜잭션 기준으로 secondary가 primary보다 뒤처진 정도 | 재해복구 시 데이터 손실 위험을 평가하는 관측점 |
평균 지연만 낮다고 최악의 복구 시점이 보장되는 것은 아니다. 대상 secondary 리전, 지표의 dimension, 집계 구간, 수집 시각, 데이터 누락을 함께 확인한다. 장애 순간에 메트릭 전달 자체가 끊길 수 있으므로 마지막 관측값을 현재 상태처럼 취급하지 않는다. 경보에는 허용 지연뿐 아니라 메트릭 미수집 상태의 처리 정책도 필요하다.
또한 낮은 스토리지 복제 지연은 모든 SELECT의 최신 읽기를 보장하지 않는다. 장기 실행 중인 REPEATABLE READ 트랜잭션은 이미 만든 Read View를 계속 사용할 수 있다. 복제 지연, reader 반영, 애플리케이션 캐시, 트랜잭션 스냅샷을 분리해서 조사해야 한다.
rds.global_db_rpo는 AWS의 Aurora PostgreSQL용 RPO 관리 설명에 등장하는 파라미터다. 이름만 보고 Aurora MySQL에 동일한 제어 기능이 있다고 가정해서는 안 된다. RPO 지표가 존재한다는 사실과 primary 커밋을 제어하는 RPO 강제 기능은 별개다.
6. GTID는 binlog 진행 경계이지 전역 데이터 일치 인증서가 아니다
Binlog 복제에서 GTID는 트랜잭션 이력을 집합으로 다루게 해준다. 계획된 승격에서는 쓰기를 통제한 상태에서 source의 기준 집합과 후보 replica의 실행 집합을 비교할 수 있다. 그러나 이 비교를 Global Database의 내부 스토리지 진행 상태 확인으로 대체해서는 안 된다.
아래 예제의 UUID와 집합은 설명용으로 정한 입력이다. 실제 서버에서 채집한 GTID가 아니며, 트랜잭션을 생성하거나 복제하지 않는다. 검증하는 대상은 GTID_SUBSET()과 GTID_SUBTRACT()의 계산 결과뿐이다.
SET @source_boundary = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-3';
SET @candidate_executed = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-2';
SELECT GTID_SUBSET(@source_boundary, @candidate_executed) AS boundary_reached,
GTID_SUBTRACT(@source_boundary, @candidate_executed) AS missing_gtids;
SET @candidate_executed = @source_boundary;
SELECT GTID_SUBSET(@source_boundary, @candidate_executed) AS boundary_reached,
GTID_SUBTRACT(@source_boundary, @candidate_executed) AS missing_gtids;
실행 결과(MySQL 8.0.x):
mysql> SET @source_boundary = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-3';
Query OK, 0 rows affected (0.00 sec)
mysql> SET @candidate_executed = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-2';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT GTID_SUBSET(@source_boundary, @candidate_executed) AS boundary_reached,
-> GTID_SUBTRACT(@source_boundary, @candidate_executed) AS missing_gtids;
+------------------+----------------------------------------+
| boundary_reached | missing_gtids |
+------------------+----------------------------------------+
| 0 | aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3 |
+------------------+----------------------------------------+
1 row in set (0.00 sec)
mysql> SET @candidate_executed = @source_boundary;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT GTID_SUBSET(@source_boundary, @candidate_executed) AS boundary_reached,
-> GTID_SUBTRACT(@source_boundary, @candidate_executed) AS missing_gtids;
+------------------+---------------+
| boundary_reached | missing_gtids |
+------------------+---------------+
| 1 | |
+------------------+---------------+
1 row in set (0.00 sec)
첫 조회에서는 기준 트랜잭션이 모두 포함되지 않았으므로 boundary_reached=0이고, 누락된 GTID가 반환된다. 두 번째 조회는 두 입력 집합을 같게 바꿨으므로 1과 빈 문자열을 반환한다. 이 결과는 입력 집합에 대한 판단이지, 실제 데이터 검증이나 승격 성공 증명이 아니다.
운영에서는 다음 제한이 중요하다.
- 기준 집합 채집 후 source가 계속 쓰면 그 집합은 최종 업무 경계가 아니다. 쓰기 차단과 경계 채집 순서가 맞아야 한다.
- 기준 집합의 포함 여부와 후보에만 있는 추가 이력의 유무는 다른 검사다. 후보의 독자 쓰기, 다른 채널의 이력, 초기화 이력을 구분한다.
- 복제 필터나 빈 GTID 트랜잭션으로 실행 이력에 포함되어도 해당 업무 행이 존재하지 않을 수 있다. 필요한 경우 데이터 대조와 업무 불변식 검증이 뒤따라야 한다.
- GTID 미사용 구성에는 같은 검사를 그대로 적용할 수 없다. 파일·위치 기반의 경계를 해당 구성에 맞게 관리해야 한다.
7. 재해복구: 계획 전환과 장애 전환을 나눈다
7.1 계획된 switchover
Global Database의 switchover는 정상 상태의 클러스터를 대상으로 리전 역할을 바꾸는 관리형 절차다. AWS는 secondary를 primary와 동기화한 뒤 전환하여 데이터 손실 없는 RPO 0을 제공한다고 설명한다. 이것이 무중단이나 기존 연결의 영구 유지까지 의미하지는 않는다.
운영자는 대상 리전의 인스턴스 용량, 파라미터, 네트워크, 인증 정보, 애플리케이션 배포 상태를 먼저 확인해야 한다. Global Database writer endpoint를 사용하면 전환 후 새 primary를 가리키도록 관리되지만, DNS 변경 전파와 연결 풀의 기존 연결 폐기·재접속은 검증해야 한다. 기존 primary의 cluster endpoint나 별도의 proxy endpoint를 고정 사용했다면 그 경로의 전환 절차도 따로 필요하다.
7.2 비계획 failover
Primary 리전 장애에서는 마지막 변경이 secondary에 도달했는지 확인하지 못할 수 있다. Global Database의 비동기 복제 특성상 failover에는 데이터 손실 가능성이 있다. AWS가 설명하는 통상적인 초 단위 RPO·분 단위 RTO는 모든 장애에 대한 보장값이 아니다. 실제 목표는 장애 감지, 전환 판단, 서비스 작업, DNS·재접속, 애플리케이션 검증까지 포함해 훈련으로 확인한다.
커밋 응답을 받지 못한 요청은 특히 주의한다. 서버에서는 커밋됐지만 응답만 유실됐을 수 있고, 반대로 새 primary에 그 변경이 없을 수도 있다. 단순히 실패한 요청을 모두 재전송하는 대신 업무 요청 ID, 멱등 처리, 외부 결제·메시지 이력 대조를 준비한다. 이전 리전 복구 후에도 예전 연결 경로나 독립 시스템이 임의로 쓰기를 재개하지 않도록 관리형 상태와 애플리케이션의 쓰기 경로를 확인한다.
Binlog 기반 수동 승격도 같은 업무 문제를 가진다. 여기에 receiver/applier 상태, 실행 경계, 이전 writer 쓰기 차단, 보존 binlog로 복구 가능한 범위까지 운영자가 조합해야 한다. 관리형 전환의 존재 여부가 다를 뿐, 데이터 손실과 미확정 요청을 판단해야 한다는 책임은 사라지지 않는다.
8. Write forwarding과 외부 CDC의 오해
Global Database의 write forwarding은 secondary에서 받은 쓰기를 primary로 전달하는 기능이다. 변경은 primary에서 먼저 수행된 뒤 secondary에 복제된다. 각 리전에서 독립적으로 커밋하는 multi-writer 구성이 아니며, 리전 간 왕복 지연도 없어지지 않는다. 지원 SQL과 읽기 일관성 설정은 Aurora MySQL 버전 및 기능 활성 조건을 확인해야 한다.
외부 CDC는 또 다른 문제다. Global Database의 내부 스토리지 전송을 일반적인 MySQL binlog API로 읽을 수 있다고 가정하지 않는다. CDC에 필요한 binlog를 별도로 구성했다면 로그 보존 기간, 소비자 checkpoint, failover 이후 새 source의 이력 연속성, 중복 전달·누락 처리까지 시험한다. Global Database 전환 성공이 CDC 연속성 검증을 대신하지 않는다.
비용도 경로별로 해석한다. Global Database의 secondary 리전 스토리지·인스턴스·복제 관련 비용과, binlog 보관 및 외부 전송·적용 부하는 구분한다. 특정 지연 수치만 비교하지 말고 같은 쓰기 부하와 복구 요구를 전제로 비용·장애 대응 범위를 함께 비교해야 한다.
9. 설계 및 전환 점검표
10. 정리
Global Database와 binlog 복제를 가르는 기준은 거리보다 복제 계층이다. 스토리지 기반 리전 간 복제에는 서비스 전용 진행 지표와 관리형 전환 절차를 적용하고, binlog 복제에는 수신·적용 분리, GTID 또는 로그 위치, 대상 엔진의 처리 상태를 적용한다. 어느 쪽에서도 “지연이 낮다”는 관측 하나만으로 최신 읽기, 무손실 장애 전환, 외부 CDC 연속성을 모두 증명할 수 없다.
이 구분을 확립하면 다음 단계인 백업·시점 복구 설계도 명확해진다. 복제는 변경을 다른 위치로 전달하는 기술이므로 잘못된 삭제 역시 전달할 수 있다. 재해복구용 사본과 과거 정상 시점으로 돌아가는 복구 수단은 서로 보완하도록 설계해야 한다.