binlog 운영·보존·모니터링
운영자의 binlog 걱정 세 가지
binlog를 실제로 운영할 때 반복되는 고민은 크게 세 가지다.
- 디스크가 찬다 — 만료 설정을 잘못하거나 레플리카가 멈추면 binlog가 무한 쌓인다.
- 어디까지 삭제해도 되는지 모른다 — 잘못 삭제하면 레플리카가 깨진다.
- 무슨 이유로 복제가 늦는지 보이지 않는다 — 지표 없이 장애를 감지하기 어렵다.
이 챕터는 이 세 가지 문제를 각각 다루는 운영 레시피다.
보존 기간 설정
binlog_expire_logs_seconds
MySQL 8.0부터 expire_logs_days는 폐기됐다. 초 단위로 표현하는 binlog_expire_logs_seconds를 쓴다.
-- 7일 보존 (604800초)
SET PERSIST binlog_expire_logs_seconds = 604800;자동 만료는 두 시점에 트리거된다.
- 서버 시작 시
- binlog가 로테이션될 때(새 파일로 전환될 때)
즉, 만료 설정을 줄여도 현재 쓰고 있는 파일이 로테이션되기 전까지는 삭제가 일어나지 않는다.
CDC 도구(Debezium 등)를 쓴다면: CDC 도구가 오프라인이던 사이에 binlog가 만료되면 재시작 시 전체 스냅샷을 다시 해야 한다. CDC 도구의 최대 예상 다운타임보다 넉넉하게 설정한다. 최소 14일 이상을 권장하는 이유가 여기에 있다.
클라우드 환경의 차이
AWS RDS/Aurora에서는 인스턴스 변수 대신 전용 프로시저를 사용한다.
-- RDS MySQL — 시간 단위
CALL mysql.rds_set_configuration('binlog retention hours', 168);
-- Aurora MySQL
CALL mysql.rds_set_configuration('binlog retention hours', 168);binlog_expire_logs_seconds를 직접 수정해도 RDS에서는 적용되지 않거나 재시작 후 초기화될 수 있다.
현재 binlog 파일 목록 확인
SHOW BINARY LOGS;출력 예:
+------------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+------------------+-----------+-----------+
| binlog.000087 | 107374182 | No |
| binlog.000088 | 107374182 | No |
| binlog.000089 | 45128341 | No |
+------------------+-----------+-----------+File_size 합계가 디스크 binlog 점유량이다. 현재 쓰고 있는 파일(마지막 항목)은 아직 닫히지 않아 파일 크기가 작게 보인다.
로테이션: 파일이 바뀌는 조건
binlog는 단일 파일에 계속 추가되다가 다음 조건 중 하나가 충족되면 새 파일로 전환된다.
max_binlog_size(기본 1 GB)에 도달- 서버 재시작
FLUSH BINARY LOGS실행
-- 현재 파일을 닫고 다음 번호 파일을 연다 (삭제 아님)
FLUSH BINARY LOGS;백업 직전에 FLUSH BINARY LOGS를 실행하면 "백업 완료 시점"과 "binlog 파일 경계"를 일치시켜 PITR(Point-in-Time Recovery) 처리를 단순하게 만들 수 있다.
안전한 수동 삭제
자동 만료 외에 수동으로 정리해야 할 때가 있다. 레플리카가 읽고 있는 파일을 삭제하면 복제가 깨진다.
레플리카 위치 확인 후 삭제
-- 1단계: 각 레플리카의 읽기 위치 확인
SHOW REPLICA STATUS\G
-- Read_Source_Log_Pos 와 Source_Log_File 필드 확인
-- 2단계: 모든 레플리카가 binlog.000088 이상을 읽고 있다면
PURGE BINARY LOGS TO 'binlog.000088';
-- 또는 날짜 기준
PURGE BINARY LOGS BEFORE '2026-06-01 00:00:00';PURGE BINARY LOGS는 MySQL이 내부적으로 레플리카 위치를 고려한다. 등록된 레플리카가 아직 읽고 있는 파일보다 이전 파일만 삭제한다. 그러나 레플리카가 연결 해제된 상태면 MySQL이 위치를 알 수 없어 잘못 삭제될 위험이 있다.
원칙: 수동 삭제 전에 반드시 SHOW REPLICA STATUS를 실행하고, 모든 레플리카가 삭제 대상보다 앞선 위치에 있음을 확인하라.
운영 흐름 다이어그램
PITR: binlog로 특정 시점 복구
풀 백업 직후 실수로 데이터를 삭제했다면 binlog를 재생해 복구할 수 있다.
# 특정 시간 범위의 binlog 이벤트를 추출해 적용
mysqlbinlog \
--start-datetime="2026-06-11 09:00:00" \
--stop-datetime="2026-06-11 09:14:00" \
/var/lib/mysql/binlog.000089 | mysql -u root -p주의: mysqlbinlog를 쓸 때 압축 binlog(binlog_transaction_compression = ON)는 도구가 자동으로 압축을 푼다. 특별한 옵션 없이 동일하게 사용할 수 있다.
시간 기반 복구는 클록 스큐(clock skew)로 오차가 생길 수 있다. 정밀하게 복구할 때는 --start-position / --stop-position으로 이벤트 오프셋을 직접 지정한다.
모니터링 지표 정리
복제 지연
SHOW REPLICA STATUS\G
-- Seconds_Behind_Source: 레플리카가 소스 대비 몇 초 뒤처지는지
-- Relay_Log_Space: relay log 누적 크기
-- Source_Log_File / Read_Source_Log_Pos: 현재 읽고 있는 파일/위치Seconds_Behind_Source가 NULL이면 I/O 스레드가 중단된 것이다. 0이라도 순간적으로 낮아 보일 수 있으므로 10초 이상 추이를 추적한다.
디스크 사용량 쿼리
SELECT
SUM(file_size) / 1024 / 1024 / 1024 AS binlog_gb
FROM information_schema.FILES
WHERE file_type = 'REDO LOG';
-- 단, FILES 뷰는 InnoDB redo log를 보여준다.
-- binlog 크기 합산은 SHOW BINARY LOGS를 파싱하거나
-- OS 레벨에서 du 를 사용한다.실제로는 셸 스크립트로 주기적으로 SHOW BINARY LOGS 결과를 파싱해 Prometheus/Grafana에 푸시하는 방식이 일반적이다.
알림 설정 가이드
| 지표 | 경고(Warning) 임계값 | 위험(Critical) 임계값 |
|---|---|---|
| binlog 디스크 점유율 | 60% | 80% |
Seconds_Behind_Source | 30초 | 300초 |
Relay_Log_Space | 20 GB | 50 GB |
| binlog 파일 수 | 보존 기간 × 2배 이상 | — |
보존 기간 × 2배를 넘는 파일 수는 자동 만료가 제대로 작동하지 않고 있다는 신호다.
운영 체크리스트
배포나 스키마 변경 전에 점검해야 할 사항:
binlog_expire_logs_seconds값이 CDC/레플리카 예상 다운타임보다 넉넉한가?SHOW REPLICA STATUS에서 모든 레플리카의Seconds_Behind_Source가 0에 가까운가?max_binlog_size가 디스크 여유 공간과 비교해 적절한가?- 수동
PURGE BINARY LOGS전에 레플리카 위치를 확인했는가? - PITR 복구 절차가 문서화되어 있고, 마지막으로 실제로 테스트한 날짜가 최근인가?
References
- https://dev.mysql.com/doc/refman/8.4/en/purge-binary-logs.html
- https://dev.mysql.com/doc/refman/8.4/en/point-in-time-recovery-binlog.html
- https://dev.mysql.com/doc/refman/8.4/en/replication-options-binary-log.html
- https://docs.upsolver.com/upsolver-1/connecting-data-sources/cdc-data-sources-debezium/mysql-cdc-data-source/binlog-retention-in-mysql
- https://www.mydbops.com/blog/maintenance-of-mysql-binary-logs
- https://repost.aws/knowledge-center/aurora-mysql-increase-binlog-retention
- https://www.percona.com/blog/mysql-replication-got-fatal-error-1236-causes-and-cures/