MySQL 복제(Replication) 란?
MySQL 복제는 한 서버(Master/Source)의 변경 사항을 다른 서버(Slave/Replica)로 비동기 전파해 데이터를 동일하게 유지하는 내장 기능입니다. 핵심은 바이너리 로그(binlog) 입니다. Master는 모든 쓰기 이벤트를 binlog에 기록하고, Replica가 이를 받아 재실행해 같은 상태에 도달합니다.
- 읽기 부하 분산: 읽기 쿼리를 Replica로 분산
- 고가용성(HA): Master 장애 시 Replica를 승격
- 백업 오프로딩: Replica에서 덤프를 떠 Master 부하 회피
MySQL 8.0부터 공식 용어가 Master/Slave → Source/Replica로 바뀌었습니다. 이 글은 구버전 호환을 위해 두 표기를 병기합니다.
복제 토폴로지와 동작 흐름
[Master] --(binlog write)--> binlog
| Dump Thread(전송)
v
[Replica] -- IO Thread --> relay log -- SQL Thread --> 적용| 스레드 | 위치 | 역할 |
|---|---|---|
| Binlog Dump Thread | Master | Replica에 binlog 이벤트 전송 |
| IO Thread | Replica | 이벤트 수신 → relay log 기록 |
| SQL Thread | Replica | relay log를 읽어 실제 적용 |
binlog 포맷은 ROW(권장), STATEMENT, MIXED 세 가지가 있습니다. 데이터 정합성이 가장 안전한 ROW를 사용합니다.
1. Master 설정
/etc/mysql/mysql.conf.d/mysqld.cnf (또는 /etc/my.cnf)를 수정합니다.
[mysqld]
# 서버마다 유일해야 함
server-id = 1
# 바이너리 로그 활성화
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
# GTID 기반 복제(권장)
gtid_mode = ON
enforce_gtid_consistency = ON
# binlog 보관 기간(초) — 7일
binlog_expire_logs_seconds = 604800
# 복제 대상 DB만 기록하고 싶을 때(선택)
# binlog_do_db = appdb재시작 후 복제 전용 계정을 만듭니다.
-- Master에서 실행
CREATE USER 'repl'@'192.168.1.%' IDENTIFIED WITH caching_sha2_password BY 'StrongReplPass!2026';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
FLUSH PRIVILEGES;
-- 현재 binlog 위치 확인(비-GTID 방식에서 필요)
SHOW MASTER STATUS\G출력 예시:
File: mysql-bin.000004
Position: 1547운영 중인 Master라면 일관된 스냅샷을 위해 mysqldump --single-transaction --master-data=2 --source-data=2 로 덤프를 뜬 뒤 Replica에 적재해야 합니다.
2. Replica 설정
[mysqld]
server-id = 2
relay_log = /var/log/mysql/mysql-relay-bin.log
gtid_mode = ON
enforce_gtid_consistency = ON
# Replica를 읽기 전용으로 보호(관리자도 막으려면 super_read_only)
read_only = ON
super_read_only = ON
# 재기동 후 복제 위치를 테이블에 안전 저장
relay_log_recovery = ONGTID 방식 복제 시작 (MySQL 8.0)
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '192.168.1.10',
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'StrongReplPass!2026',
SOURCE_PORT = 3306,
SOURCE_AUTO_POSITION = 1,
GET_SOURCE_PUBLIC_KEY = 1;
START REPLICA;좌표(binlog 위치) 방식 — 구버전/MariaDB 호환
CHANGE MASTER TO
MASTER_HOST = '192.168.1.10',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'StrongReplPass!2026',
MASTER_LOG_FILE = 'mysql-bin.000004',
MASTER_LOG_POS = 1547;
START SLAVE;3. 복제 상태 진단
-- MySQL 8.0
SHOW REPLICA STATUS\G
-- 구버전/MariaDB
SHOW SLAVE STATUS\G확인해야 할 핵심 필드:
| 필드 | 정상 값 | 의미 |
|---|---|---|
| Replica_IO_Running | Yes | Master 접속/수신 정상 |
| Replica_SQL_Running | Yes | relay log 적용 정상 |
| Seconds_Behind_Source | 0 | 복제 지연(초) |
| Last_IO_Error | (빈 값) | 네트워크/인증 오류 |
| Last_SQL_Error | (빈 값) | 적용 중 SQL 오류 |
IO/SQL 두 스레드가 모두 Yes 이고 Seconds_Behind_Source 가 0 또는 낮은 값이면 정상입니다.
4. 반동기 복제(Semi-Sync)
비동기 복제는 Master가 Replica의 수신을 기다리지 않아 페일오버 시 데이터 유실 가능성이 있습니다. 반동기는 최소 1대의 Replica가 이벤트를 relay log에 받았음을 확인한 뒤 커밋을 완료합니다.
-- Master
INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';
SET GLOBAL rpl_semi_sync_source_enabled = 1;
SET GLOBAL rpl_semi_sync_source_timeout = 1000; -- ms, 초과 시 비동기로 폴백
-- Replica
INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so';
SET GLOBAL rpl_semi_sync_replica_enabled = 1;
STOP REPLICA IO_THREAD; START REPLICA IO_THREAD;타임아웃이 지나면 자동으로 비동기로 전환되므로 "반동기는 절대 유실 없음"이 아닙니다. 진짜 무유실이 필요하면 Group Replication/InnoDB Cluster를 검토하세요.
5. 복제 지연 원인과 대응
| 증상 | 원인 | 대응 |
|---|---|---|
| SQL Thread 적용 지연 | 단일 스레드 적용 | replica_parallel_workers 로 병렬 적용 |
| 특정 시점 급증 | 대량 배치/ALTER | 야간 배치, pt-online-schema-change |
| IO Thread 지연 | 네트워크 대역 | 압축(SOURCE_COMPRESSION_ALGORITHMS) |
-- 병렬 복제 활성화(논리 클록 기반)
STOP REPLICA SQL_THREAD;
SET GLOBAL replica_parallel_type = 'LOGICAL_CLOCK';
SET GLOBAL replica_parallel_workers = 4;
SET GLOBAL replica_preserve_commit_order = ON;
START REPLICA SQL_THREAD;6. 깨진 복제 복구
데이터 충돌로 SQL Thread가 멈춘 경우, 원인을 파악한 뒤 GTID 단위로 건너뜁니다.
-- 충돌 이벤트의 GTID 확인 후, 빈 트랜잭션을 주입해 스킵
SET GTID_NEXT = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:42';
BEGIN; COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START REPLICA;이벤트 스킵은 데이터 불일치를 남깁니다. 근본 원인을 확인하고, 정합성이 의심되면 pt-table-checksum 으로 Master-Replica를 비교하세요.
7. 페일오버 (수동 승격)
Master 장애 시 Replica를 새 Master로 승격하는 기본 절차입니다.
-- 1) 승격할 Replica에서 복제 중단 및 정보 정리
STOP REPLICA;
RESET REPLICA ALL;
-- 2) 읽기 전용 해제
SET GLOBAL super_read_only = OFF;
SET GLOBAL read_only = OFF;이후 애플리케이션의 DB 엔드포인트를 새 Master로 전환합니다. 자동화가 필요하면 Orchestrator, MHA, ProxySQL/MySQL Router 같은 도구를 함께 사용합니다.
정리
| 항목 | 권장 설정 |
|---|---|
| binlog 포맷 | ROW |
| 복제 좌표 | GTID(SOURCE_AUTO_POSITION=1) |
| Replica 보호 | super_read_only = ON |
| 데이터 유실 방지 | 반동기 + 타임아웃 짧게 |
| 적용 성능 | 병렬 복제(LOGICAL_CLOCK) |
| 정합성 점검 | pt-table-checksum 정기 실행 |
| 자동 페일오버 | Orchestrator / MHA / Router |
MySQL 복제는 binlog → Dump → IO → SQL의 흐름만 정확히 이해하면 진단이 명확해집니다. GTID와 반동기, 병렬 복제를 조합하면 읽기 분산과 HA를 안정적으로 운영할 수 있습니다.
이 가이드는 AI 도구를 활용해 초안을 구성하고 사람이 명령어·문맥을 검토해 발행했습니다. 운영체제와 도구 버전에 따라 결과가 달라질 수 있으므로 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요.
질문 & 답변 (Q&A)
이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.