카테고리 : MySQL/기술노트

MySQL Replication 아키텍처: source·replica와 수신·적용 스레드

MySQL 비동기 복제의 binlog·relay log 전달 경로와 수신·적용 스레드를 구분하고, 복제 지연과 장애를 단계별로 진단한다.

저자: MySQL 기술 노트 작성: 2026.09.08 약 13분 7,712자
다운로드

복제가 늦을 때 replica의 CPU부터 늘리는 대응은 원인을 잘못 짚을 수 있다. 네트워크에서 아직 받지 못한 변경, relay log에는 있지만 적용하지 못한 변경, 적용은 끝났지만 애플리케이션의 기존 스냅샷에서 보이지 않는 변경은 서로 다른 문제다. 복제의 기본 단위와 각 스레드의 책임을 알아야 장애를 올바른 구간으로 좁힐 수 있다.

이 장은 MySQL의 전통적인 binlog 기반 비동기 복제를 다룬다. source는 변경을 제공하는 서버이고, replica는 변경을 받아 자신의 데이터에 적용하는 서버다. 기본 역할은 서버 전체에 고정된 신분이 아니라 복제 연결의 방향으로 정해진다. 중간 서버는 상위 서버의 replica이면서 하위 서버의 source일 수 있다.

설명은 MySQL 8.0과 8.4 계열을 대상으로 한다. SQL 실행 결과는 격리된 MySQL 8.0 인스턴스에서 확인한 것으로, 복제 채널을 구성하지 않은 환경의 진단 쿼리와 GTID 집합 함수 검증이다. 실제 두 서버 간 전송, 장애 복구, 병렬 적용 성능을 재현한 결과는 아니다. Aurora의 클러스터 내부 복제는 마지막 절에서 별도로 구분한다.

1. 복제는 데이터 파일 복사가 아니라 변경 이벤트의 전달이다

InnoDB의 데이터 페이지를 source에서 replica로 그대로 보내는 것이 일반적인 MySQL binlog 복제의 동작은 아니다. source는 변경을 binary log에 기록하고, replica는 전달받은 이벤트를 해석하여 자신의 스토리지 엔진에서 변경을 실행한다. 초기 데이터 적재에는 백업 복원이나 Clone 같은 별도 절차가 필요하며, 지속적인 복제는 그 초기 상태와 맞는 로그 위치에서 이어져야 한다.

ROW 형식에서는 주로 행 변경 이벤트가 전달된다. 그렇다고 replica가 아무 실행 비용 없이 페이지를 붙여 넣는 것은 아니다. 대상 행과 인덱스를 찾고, 잠금을 획득하고, 데이터를 바꾸고, undo와 redo를 생성하며 트랜잭션을 커밋해야 한다. source에서 이미 수행한 쓰기 작업의 상당 부분이 replica에서도 다시 발생한다. DDL 등은 row 기반 복제에서도 문장 형태의 이벤트로 처리될 수 있으므로, “ROW이면 SQL 문장은 전혀 없다”는 설명도 정확하지 않다.

각 로그의 책임은 다음과 같이 구분한다.

구성 요소 위치 역할 혼동하면 안 되는 점
binary log source 복제와 시점 복구에 사용하는 변경 이력 InnoDB redo log와 다르다
relay log replica 수신한 복제 이벤트를 적용 전후에 보관하는 중간 로그 여기에 도착했다고 조회 결과가 바뀌지는 않는다
InnoDB redo log 각 서버 해당 서버의 변경 내구성과 crash recovery 지원 일반 binlog 복제의 전송 원본이 아니다
복제 메타데이터 replica 연결 설정과 수신·적용 진행 정보 관리 GTID나 위치 정보만으로 데이터 일치를 증명하지 못한다

source의 트랜잭션 처리에서는 InnoDB 커밋과 binlog 기록 사이의 일관성을 조정한다. 그러나 로컬 커밋의 내구성도 sync_binlog, innodb_flush_log_at_trx_commit 및 저장장치 보장에 영향을 받는다. 애플리케이션에 COMMIT 성공을 돌려주는 시점과 replica에서 그 변경을 조회할 수 있는 시점은 별개의 경계다.

2. source에서 replica까지의 실행 경로

flowchart LR
    C["클라이언트 쓰기"] --> S["source 트랜잭션 처리"]
    S --> B["binary log"]
    B --> D["source의 binlog dump 스레드"]
    D --> N["네트워크 연결"]
    N --> R["replica 수신 스레드"]
    R --> L["relay log"]
    L --> A["적용 단계: 단일 applier 또는 coordinator와 workers"]
    A --> I["replica InnoDB 커밋"]
    I --> Q["새 읽기에서 변경 관측"]

이 그림은 변경 전달 경로를 보여준다. redo와 binlog의 세부 flush 순서나 모든 내부 잠금을 나타내는 커밋 프로토콜 그림은 아니다. 마지막의 “새 읽기”도 중요하다. replica의 적용이 끝났더라도 이미 열린 REPEATABLE READ 트랜잭션의 consistent read는 이전 Read View를 계속 사용할 수 있다.

source의 binlog dump 스레드

복제 연결은 replica 쪽에서 source로 맺는다. source는 연결된 replica에 필요한 binlog 이벤트를 전송하는 스레드를 둔다. 프로세스 정보에서는 연결 방식에 따라 Binlog Dump 또는 Binlog Dump GTID 같은 명령으로 보일 수 있다. source의 이 스레드는 replica 데이터에 SQL을 실행하지 않는다. 전송 가능한 이벤트가 없으면 새 binlog 기록을 기다리는 상태가 정상이다.

replica의 I/O thread: receiver

I/O thread는 현재 문서에서 수신 스레드(receiver)라고도 부른다. source에 접속하고, 파일·위치 또는 GTID 기반 진행 정보를 사용하여 필요한 이벤트를 요청하며, 수신한 이벤트를 relay log에 기록한다. 인증·TLS·네트워크·source binlog 보존 문제가 주로 이 구간의 책임이다.

수신 스레드가 정상이어도 적용은 멈출 수 있다. 반대로 수신 연결이 끊긴 뒤에도 이미 relay log에 들어 있는 트랜잭션은 적용을 이어 갈 수 있다. 수신과 적용을 분리하는 이유는 네트워크 전달과 로컬 실행을 서로 완전히 직렬화하지 않고 완충하기 위해서다. 다만 무한한 완충 장치는 아니다. relay log 공간 제한이나 디스크 부족은 수신에도 영향을 미친다.

replica의 SQL thread: applier

SQL thread는 적용 스레드(applier)라는 역할 이름으로 이해하는 편이 정확하다. relay log의 이벤트를 읽고 실행하여 replica의 데이터를 변경한다. ROW에서도 이 이름을 사용하며, 원래 SQL 문자열을 그대로 재실행한다는 뜻은 아니다.

병렬 적용에서는 하나의 coordinator가 트랜잭션을 worker에 배정하고 여러 worker가 적용한다. 따라서 “복제는 언제나 I/O thread 하나와 SQL thread 하나뿐”이라는 모형은 입문용 단순화다. SQL_THREAD라는 제어 단위는 병렬 구성에서 coordinator와 workers를 함께 다룬다.

worker 수가 많다고 모든 트랜잭션이 병렬화되지는 않는다. 의존성이 있는 변경, 같은 행에 대한 경합, 큰 단일 트랜잭션, DDL, 커밋 순서 유지 대기가 병렬성을 제한한다. worker 증설은 이런 제약을 확인한 다음 검토할 수단이지, 복제 지연의 보편적인 해결책이 아니다.

3. 수신 완료와 적용 완료는 서로 다른 진행선이다

운영에서는 하나의 “복제 위치” 대신 다음 세 경계를 구분해야 한다.

  1. source 생성 경계: source가 생성한 변경 중 비교 대상으로 삼은 위치나 GTID 집합.
  2. replica 수신 경계: 수신 스레드가 확보한 이벤트와 트랜잭션의 진행 정보.
  3. replica 적용 경계: replica에서 실행·커밋한 트랜잭션의 진행 정보.

파일·위치 방식에서 Source_Log_FileRead_Source_Log_Pos는 수신 진행을, Relay_Source_Log_FileExec_Source_Log_Pos는 source 좌표로 표현한 적용 진행을 파악하는 데 쓰인다. Relay_Log_FileRelay_Log_Pos는 replica의 로컬 relay log 좌표이므로 source binlog의 바이트 위치와 직접 빼면 안 된다. 파일이 달라진 위치 역시 단순 숫자 차이로 지연량을 계산할 수 없다.

병렬 적용의 단일 위치는 각 worker의 모든 진척을 표현하지 못한다. 따라서 채널 전체 위치와 worker별 상태를 함께 읽어야 한다. GTID 환경에서는 트랜잭션 식별자의 집합으로 포함 관계를 비교할 수 있지만, GTID 차이는 지연 시간이나 전송 바이트 수가 아니다.

다음은 실제 운영 서버에서 수집한 값이 아닌, 설명용 GTID 집합으로 수신·적용 경계를 나누는 실행 가능한 예제다. source에 1~10이 있고, replica는 1~8을 받았으며 1~6을 적용했다고 가정한다. 이 함수 계산에는 서버의 gtid_mode=ON 설정이나 복제 채널이 필요하지 않다.

SET @source_set = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-10';
SET @received_set = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-8';
SET @applied_set = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-6';
SELECT GTID_SUBTRACT(@source_set, @received_set) AS not_received,
       GTID_SUBTRACT(@received_set, @applied_set) AS not_applied;
SELECT GTID_SUBSET(@source_set, @applied_set) AS source_fully_applied;

실행 결과(MySQL 8.0.x):

mysql> SET @source_set = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-10';

Query OK, 0 rows affected (0.00 sec)

mysql> SET @received_set = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-8';

Query OK, 0 rows affected (0.00 sec)

mysql> SET @applied_set = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-6';

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT GTID_SUBTRACT(@source_set, @received_set) AS not_received,
    ->        GTID_SUBTRACT(@received_set, @applied_set) AS not_applied;

+-------------------------------------------+------------------------------------------+
| not_received                              | not_applied                              |
+-------------------------------------------+------------------------------------------+
| aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:9-10 | aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:7-8 |
+-------------------------------------------+------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT GTID_SUBSET(@source_set, @applied_set) AS source_fully_applied;

+----------------------+
| source_fully_applied |
+----------------------+
|                    0 |
+----------------------+
1 row in set (0.00 sec)

앞의 차집합은 아직 받지 못한 범위를, 뒤의 차집합은 받았으나 적용하지 않은 범위를 나타낸다. 포함 관계 검사에서 0은 예제의 source 집합이 적용 집합에 전부 포함되지 않았음을 뜻한다. 실제로는 서로 다른 시점에 수집한 집합, 다른 채널, replica의 자체 쓰기, 이미 적용되어 수신 집합에서 정리된 이력 등을 고려해야 한다. 특히 RECEIVED_TRANSACTION_SET이 모든 과거 수신 이력을 영구히 보관한다고 가정해서는 안 된다.

gtid_executed도 서버 전체 집합이다. 채널별로 필터링한 데이터가 있거나 빈 트랜잭션을 넣어 오류를 건너뛴 이력이 있다면, GTID가 따라잡혔다고 해서 두 서버의 행 데이터가 일치하는 것은 아니다.

4. 진단 SQL: 대상 확인에서 worker 오류까지

다음 쿼리는 조회 중심으로 구성했다. 운영에서는 필요한 Performance Schema 조회 권한을 가진 계정을 사용하고, 오류 메시지에 테이블명이나 데이터 값이 포함될 수 있으므로 외부 공유 전에 내용을 검토한다. 결과의 Empty set은 이 문서의 테스트 환경에 구성된 복제 채널이 없기 때문이며, 정상 복제를 재현했다는 증거가 아니다.

4.1 서버 역할의 전제 확인

SELECT VERSION() AS mysql_version,
       @@GLOBAL.log_bin AS log_bin,
       @@GLOBAL.gtid_mode AS gtid_mode,
       @@GLOBAL.read_only AS read_only,
       @@GLOBAL.super_read_only AS super_read_only;
SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM performance_schema.global_variables
WHERE VARIABLE_NAME IN ('replica_parallel_workers',
                        'replica_preserve_commit_order')
ORDER BY VARIABLE_NAME;

실행 결과(MySQL 8.0.x):

mysql> SELECT VERSION() AS mysql_version,
    ->        @@GLOBAL.log_bin AS log_bin,
    ->        @@GLOBAL.gtid_mode AS gtid_mode,
    ->        @@GLOBAL.read_only AS read_only,
    ->        @@GLOBAL.super_read_only AS super_read_only;

+---------------+---------+-----------+-----------+-----------------+
| mysql_version | log_bin | gtid_mode | read_only | super_read_only |
+---------------+---------+-----------+-----------+-----------------+
| 8.0.46        |       0 | OFF       |         0 |               0 |
+---------------+---------+-----------+-----------+-----------------+
1 row in set (0.00 sec)

mysql> SELECT VARIABLE_NAME, VARIABLE_VALUE
    -> FROM performance_schema.global_variables
    -> WHERE VARIABLE_NAME IN ('replica_parallel_workers',
    ->                         'replica_preserve_commit_order')
    -> ORDER BY VARIABLE_NAME;

+-------------------------------+----------------+
| VARIABLE_NAME                 | VARIABLE_VALUE |
+-------------------------------+----------------+
| replica_parallel_workers      | 4              |
| replica_preserve_commit_order | ON             |
+-------------------------------+----------------+
2 rows in set (0.00 sec)

테스트 서버는 binlog를 끈 단독 인스턴스이므로 이 값을 source 설정의 모범 답안으로 복사하면 안 된다. 실제 source는 변경 전송에 사용할 binary log가 필요하다. read_only=ON은 일반 사용자 쓰기를 제한하지만 권한 예외가 있으며, super_read_only는 더 강한 보호에 사용한다. 복제 적용 스레드는 읽기 전용 제한과 구분되어 동작한다. 두 값이 모두 꺼져 있어도 그 서버에 replica 역할이 없다고 단정할 수는 없다.

replica_* 변수 이름은 초기 8.0과 차이가 있으므로, 해당 이름이 없는 구버전에서는 정확한 minor version의 문서를 확인한다. 위 쿼리는 8.0 후기와 8.4에서 사용하는 이름을 대상으로 한다. 또한 병렬 worker 설정값은 실행 중인 채널이나 정상 동작하는 worker 개수를 뜻하지 않는다.

4.2 수신 채널의 상태 확인

SELECT CHANNEL_NAME, SERVICE_STATE,
       LAST_ERROR_NUMBER, LAST_ERROR_MESSAGE
FROM performance_schema.replication_connection_status
ORDER BY CHANNEL_NAME;

실행 결과(MySQL 8.0.x):

mysql> SELECT CHANNEL_NAME, SERVICE_STATE,
    ->        LAST_ERROR_NUMBER, LAST_ERROR_MESSAGE
    -> FROM performance_schema.replication_connection_status
    -> ORDER BY CHANNEL_NAME;

Empty set (0.00 sec)

SERVICE_STATE와 최근 오류를 함께 확인한다. ON은 수신 서비스의 상태이지, source의 모든 커밋을 받아 놓았다는 확인서가 아니다. CONNECTING이면 연결 시도·재연결 상태를, OFF이면 의도적인 정지인지 오류로 중단했는지를 구분해야 한다. 빈 결과가 예상과 다르다면 먼저 올바른 서버에 접속했는지, 채널이 실제로 구성되어 있는지 확인한다.

오류 메시지만 보고 즉시 재설정하지 않는다. 접속 실패는 계정·TLS·네트워크 경로를, 필요한 binlog가 없다는 오류는 source 보존 정책과 복구 가능한 시작점을 검토해야 한다. 수신 실패를 해결하려고 SQL 적용 설정을 바꾸어도 원인에는 닿지 않는다.

4.3 coordinator와 worker 상태 확인

SELECT CHANNEL_NAME, SERVICE_STATE, LAST_ERROR_NUMBER
FROM performance_schema.replication_applier_status_by_coordinator
ORDER BY CHANNEL_NAME;
SELECT CHANNEL_NAME, WORKER_ID, SERVICE_STATE,
       LAST_ERROR_NUMBER, LAST_ERROR_MESSAGE
FROM performance_schema.replication_applier_status_by_worker
ORDER BY CHANNEL_NAME, WORKER_ID;

실행 결과(MySQL 8.0.x):

mysql> SELECT CHANNEL_NAME, SERVICE_STATE, LAST_ERROR_NUMBER
    -> FROM performance_schema.replication_applier_status_by_coordinator
    -> ORDER BY CHANNEL_NAME;

Empty set (0.00 sec)

mysql> SELECT CHANNEL_NAME, WORKER_ID, SERVICE_STATE,
    ->        LAST_ERROR_NUMBER, LAST_ERROR_MESSAGE
    -> FROM performance_schema.replication_applier_status_by_worker
    -> ORDER BY CHANNEL_NAME, WORKER_ID;

Empty set (0.00 sec)

단일 스레드 구성에는 coordinator 행이 없을 수 있으므로, coordinator 결과만으로 채널 부재를 판단하지 않는다. worker별 오류는 실제 적용 실패 지점을 좁히는 데 중요하다. 중복 키나 대상 행 불일치는 데이터·스키마의 차이를 의심해야 하며, 단순한 네트워크 오류와는 복구 방식이 다르다. 상태가 ON이더라도 worker가 잠금, 선행 트랜잭션, 디스크 I/O 또는 커밋 순서를 기다릴 수 있다. 필요하면 THREAD_IDperformance_schema.threads에 연결하고 잠금·대기 이벤트까지 조사한다.

최근 오류 필드는 과거 사건을 담을 수 있고, 조회 중 상태도 바뀔 수 있다. 오류 번호 한 번의 관측만으로 현재 장애를 확정하지 말고, 오류 발생 시각과 스레드 상태, 진행 위치의 시간에 따른 변화를 같이 수집한다.

5. 지연을 전송과 적용으로 나누어 해석하기

운영 replica에서는 SHOW REPLICA STATUS의 수신·적용 상태, 최근 오류, 위치 정보를 함께 읽을 수 있다. 이 장에서는 채널이 없는 서버에서 긴 상태 화면을 만들어 보여주는 대신 위의 좁은 Performance Schema 쿼리를 검증했다. 실제 상태 화면의 값과 복제 지연 재현은 구성된 복제 환경에서 별도로 확인해야 한다.

관측한 상황 우선 구분할 원인 다음 확인
수신 위치가 멈추고 적용이 relay log 끝에 도달함 source에 새 쓰기가 없는 정상 유휴 상태 또는 수신 경로 문제 source 쓰기 여부, receiver 상태·오류, 네트워크
수신은 전진하지만 적용 진행이 더딤 로컬 적용 병목 worker 오류·대기, 큰 트랜잭션, DDL, 디스크와 CPU
수신·적용이 모두 동작하나 지연이 계속 커짐 생성 속도가 지속 처리 능력을 초과 쓰기 유입량과 적용 처리량 추세, 자원 경합
복제 진행은 따라잡았는데 애플리케이션에서 옛 값이 보임 다른 replica로 접속, 오래된 Read View, 캐시 실제 접속 대상과 트랜잭션 경계

Seconds_Behind_Source=0은 데이터 최신성의 충분조건이 아니다. receiver가 느리게 읽는 동안 applier가 현재 relay log를 모두 소비하면, source에는 아직 못 받은 변경이 있어도 값이 0으로 보일 수 있다. 연결 장애를 아직 감지하지 못한 구간도 존재한다. NULL 역시 “0초”가 아니라 상태에 따라 계산할 수 없거나 정의되지 않는 상황으로 해석해야 한다.

복제 지연 경보는 최소한 서비스 상태, 오류, 진행 여부, 시간 기반 지연 신호를 조합한다. 일정 주기로 변경하는 heartbeat 행을 replica에서 관측하면 애플리케이션 관점의 최신성을 보완할 수 있지만, 시계 차이와 heartbeat 쓰기 중단도 따로 구분해야 한다. GTID 집합 포함 여부는 특정 커밋 집합을 따라잡았는지 확인하는 또 다른 관점이며, 초 단위 지연을 대체하는 값은 아니다.

읽기 직전 최신성이 필요한 업무는 일정 시간 동안 source로 읽기를 보내거나, 대상 replica에서 필요한 GTID 적용을 제한된 시간 동안 기다리는 정책을 설계한다. 대기가 끝난 뒤에도 기존 트랜잭션의 오래된 스냅샷을 재사용하지 않도록 해야 한다. “읽기는 모두 replica”라는 라우팅 정책만으로 read-after-write 일관성이 생기지는 않는다.

6. 장애와 내구성: 스레드 재시작보다 먼저 볼 것

비동기 커밋은 replica 적용을 기다리지 않는다

일반 비동기 복제에서 source는 replica 적용 완료를 기다리지 않고 클라이언트 요청을 끝낼 수 있다. source 장애 시 미수신 또는 미적용 트랜잭션이 존재할 수 있으며, 승격 후보를 정할 때 이 차이가 복구 목표에 영향을 준다. semi-sync도 ACK 정책과 대기 지점을 따져야 한다. 수신 확인을 모든 replica의 적용 완료나 모든 읽기의 최신성 보장과 혼동해서는 안 된다.

relay log 적체와 binlog 보존은 다른 용량 문제다

relay log가 커지면 replica의 수신·적용 균형과 저장공간을 점검한다. source binlog 보존은 replica가 장애나 유지보수 후 다시 필요한 이벤트를 요청할 수 있는 기간을 보장하는 문제다. 둘 중 한쪽이 충분하다고 다른 쪽이 안전해지는 것은 아니다. relay log 파일을 운영자가 임의로 지워 공간을 확보하면 재개에 필요한 데이터를 손상시킬 수 있다.

source에서 필요한 binlog가 이미 제거되었고 이를 확보할 다른 경로도 없다면, 현재 위치를 억지로 앞으로 옮기기보다 일관된 백업을 통한 재구축을 검토한다. 복제 연결을 다시 시작하는 명령만으로 사라진 변경 이력이 생성되지는 않는다.

replica의 직접 쓰기는 적용 오류의 원인이 된다

replica에서 별도 쓰기가 허용되면 source와 데이터가 달라질 수 있다. 이후 행 적용에서 중복 키나 행 부재 오류가 발생할 수 있으며, 오류를 건너뛰면 불일치를 더 키울 수 있다. 읽기 전용 정책, 관리자 권한, 스키마 변경 절차를 함께 관리해야 한다. 복제는 잘못 실행한 삭제나 DDL도 전달하므로 독립된 백업의 대체재가 아니다.

crash recovery는 데이터와 진행 정보가 함께 맞아야 한다

replica 재시작에는 InnoDB 복구뿐 아니라 relay log와 복제 진행 정보의 일관성도 중요하다. relay_log_recovery 및 관련 내구성 설정은 source 로그 가용성, 적용 방식, 정확한 버전의 복구 동작을 함께 검토한다. 이름만 보고 설정을 켜거나 장애 중 메타데이터를 초기화하는 방식은 피한다. 변경 전에 상태·오류·위치 증거를 보존하고, 복구 뒤 실제 데이터 검증까지 수행해야 한다.

7. Aurora MySQL에서는 어떤 부분이 다른가

같은 Aurora 클러스터의 writer와 Aurora Replica는 공유 클러스터 볼륨을 기반으로 동작한다. 각 reader가 일반 MySQL처럼 source binlog를 자신의 독립 데이터 저장소에 모두 재적용하는 구조로 설명하면 잘못된 진단으로 이어진다. 클러스터 내부 reader의 지연과 가용성은 Aurora 전용 관측 지표와 인스턴스 상태를 함께 확인해야 한다.

반면 Aurora와 외부 MySQL 사이, 또는 binlog 복제로 연결한 Aurora 클러스터 사이에는 이 장의 source·receiver·relay log·applier 구분이 적용된다. 같은 제품 이름 아래 두 복제 경로가 공존할 수 있으므로, 진단 전에 “어떤 연결의 지연인가”부터 확정한다. Aurora Global Database 역시 일반 binlog 채널과 같은 방식으로 취급해서는 안 된다.

Aurora의 복제 설정과 제어는 관리형 서비스가 제공하는 파라미터 그룹 및 엔진 버전에 맞는 저장 프로시저를 따라야 한다. Community MySQL의 서버 파일 수정이나 관리 명령을 그대로 이식하지 않는다. 여기의 SQL 검증은 Community MySQL에서 수행했으며, Aurora에서의 권한·객체 노출과 장애 동작까지 검증한 것은 아니다.

8. 운영 점검표

  • Seconds_Behind_Source=0

마무리

복제의 핵심은 “source의 변경을 replica가 따라간다”는 한 문장이 아니라 변경 생성, 전송·수신, 적용·커밋의 서로 다른 경계다. I/O thread와 SQL thread는 이 경계를 나누는 역할이고, 병렬 복제는 적용 역할 내부를 coordinator와 workers로 확장한다. 이 구분을 바탕으로 다음 단계에서는 binlog 형식, GTID 자동 위치 지정, 병렬 적용의 의존성, 장애 후 재개 절차를 구체적으로 다룰 수 있다.

참고 문서