← 스터디 홈
1편 · 약 8분

바이너리 로그란 무엇인가

왜 바이너리 로그인가

MySQL을 운영하다 보면 세 가지 문제가 반드시 찾아온다. 레플리카 서버에 데이터를 동기화해야 할 때, 실수로 지워진 데이터를 특정 시점으로 복원해야 할 때, 그리고 실시간으로 데이터 변경을 외부 시스템에 전달해야 할 때다. 바이너리 로그(Binary Log, binlog)는 이 세 가지를 가능하게 하는 MySQL의 핵심 로그 파일이다.

binlog는 데이터나 스키마를 변경하는 이벤트만 순서대로 기록한다. SELECT 같은 읽기 쿼리는 포함하지 않는다. MySQL 8.0부터는 기본으로 활성화된다.

세 가지 핵심 용도

소스 서버INSERT / UPDATEDELETE / DDL
binlog 파일binlog.000001binlog.000002binlog.index
소비자레플리카 (복제)mysqlbinlog (PITR)Debezium (CDC)
MySQL 소스에서 생성된 binlog는 복제·복구·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 버전·서버 버전·헤더 길이 기록
QueryDDL 또는 STATEMENT 포맷 DML의 SQL 텍스트
Table_map변경 대상 테이블 구조와 임시 ID 매핑 (ROW 포맷용)
Write_rowsINSERT에 해당하는 행 데이터 (ROW 포맷)
Update_rowsUPDATE의 변경 전·후 행 데이터 (ROW 포맷)
Delete_rowsDELETE 대상 행 데이터 (ROW 포맷)
Xid트랜잭션 커밋 완료 표시, InnoDB XID와 연결
Rotate다음 binlog 파일명을 담는 마지막 이벤트

InnoDB 2PC: redo log와 binlog의 동기화

InnoDB는 트랜잭션 커밋 시 2단계 커밋(2PC)으로 redo log와 binlog를 원자적으로 동기화한다.

  1. Prepare: InnoDB redo log에 PREPARED 상태로 기록하고 디스크에 flush.
  2. 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 -p

References

  • 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