1편 · 약 8분
바이너리 로그란 무엇인가
왜 바이너리 로그인가
MySQL을 운영하다 보면 세 가지 문제가 반드시 찾아온다. 레플리카 서버에 데이터를 동기화해야 할 때, 실수로 지워진 데이터를 특정 시점으로 복원해야 할 때, 그리고 실시간으로 데이터 변경을 외부 시스템에 전달해야 할 때다. 바이너리 로그(Binary Log, binlog)는 이 세 가지를 가능하게 하는 MySQL의 핵심 로그 파일이다.
binlog는 데이터나 스키마를 변경하는 이벤트만 순서대로 기록한다. SELECT 같은 읽기 쿼리는 포함하지 않는다. MySQL 8.0부터는 기본으로 활성화된다.
세 가지 핵심 용도
소스 서버INSERT / UPDATEDELETE / DDL
→
binlog 파일binlog.000001binlog.000002binlog.index
→
소비자레플리카 (복제)mysqlbinlog (PITR)Debezium (CDC)
- 복제(Replication): 레플리카가 소스의 binlog를 읽어 같은 이벤트를 재실행한다.
- 포인트인타임 복구(PITR): 풀 백업 이후의 binlog를 재실행해 특정 시각으로 복원한다.
- CDC(Change Data Capture): Debezium 같은 도구가 binlog를 스트리밍해 Kafka 등에 전달한다.
파일 구조와 이벤트 타입
binlog는 binlog.000001, binlog.000002처럼 번호가 붙은 이진 파일 시리즈다. 파일 하나가 max_binlog_size(기본 1 GB)에 도달하거나 서버가 재시작되면 새 파일로 교체(rotate)된다. binlog.index는 현재 유효한 파일 목록을 텍스트로 관리한다.
각 파일 안은 이벤트(Event) 단위로 채워진다.
| 이벤트 타입 | 설명 |
|---|---|
Format_description | 파일의 첫 이벤트. binlog 버전·서버 버전·헤더 길이 기록 |
Query | DDL 또는 STATEMENT 포맷 DML의 SQL 텍스트 |
Table_map | 변경 대상 테이블 구조와 임시 ID 매핑 (ROW 포맷용) |
Write_rows | INSERT에 해당하는 행 데이터 (ROW 포맷) |
Update_rows | UPDATE의 변경 전·후 행 데이터 (ROW 포맷) |
Delete_rows | DELETE 대상 행 데이터 (ROW 포맷) |
Xid | 트랜잭션 커밋 완료 표시, InnoDB XID와 연결 |
Rotate | 다음 binlog 파일명을 담는 마지막 이벤트 |
InnoDB 2PC: redo log와 binlog의 동기화
InnoDB는 트랜잭션 커밋 시 2단계 커밋(2PC)으로 redo log와 binlog를 원자적으로 동기화한다.
- Prepare: InnoDB redo log에 PREPARED 상태로 기록하고 디스크에 flush.
- Commit: binlog에 이벤트 기록 후 fsync, 이후 InnoDB를 최종 커밋.
서버가 중간에 죽으면 재시작 시 binlog에 Xid가 있으면 커밋, 없으면 롤백한다. 두 로그가 항상 일관된 상태를 유지하는 이유다.
주요 설정 변수
-- my.cnf 또는 SET PERSIST로 조정
log_bin = /var/lib/mysql/binlog
max_binlog_size = 1073741824 -- 1 GB (기본값)
binlog_expire_logs_seconds = 604800 -- 7일 (기본값)
sync_binlog = 1 -- 커밋마다 fsync (권장)
expire_logs_days는 MySQL 8.0에서 deprecated.binlog_expire_logs_seconds를 사용한다.
mysqlbinlog로 읽기
# 현재 binlog 파일 목록 확인
mysql -e "SHOW BINARY LOGS;"
# 파일 이벤트 텍스트로 출력
mysqlbinlog /var/lib/mysql/binlog.000003
# 특정 시각 범위 이벤트만 재실행 (PITR)
mysqlbinlog --start-datetime="2026-06-10 09:00:00" \
--stop-datetime="2026-06-10 10:00:00" \
binlog.000003 | mysql -u root -pReferences
- https://dev.mysql.com/doc/refman/8.4/en/binary-log.html
- https://dev.mysql.com/doc/internals/en/binlog-event-type.html
- https://www.dolthub.com/blog/2024-06-17-mysql-replication/
- https://arpitbhayani.me/blogs/mysql-replication-internals/
- https://www.burnison.ca/notes/fun-mysql-fact-of-the-day-everything-is-two-phase