Database/Mysql

[Real MySQL] 16-3. 복제: 데이터 포맷

noahkim_ 2024. 9. 7. 20:15

백은빈, 이성욱 님의 "Real MySQL" 책을 정리한 포스팅 입니다.

 

  • 이벤트들이 바이너리 로그에 어떤 형태로 저장되는지에 대한 구분

 

1. Statement 기반 바이너리 로그 포맷

  • 이벤트를 발생시킨 SQL문을 바이너리 로그에 기록하는 방식

 

장점
  • 저장 공간 용량에 대한 부담이 적어짐
  • 백업 및 복제 작업이 빠르게 처리됨

 

단점
  • 비확정적인 쿼리 사용시, 동기화가 정확히 이루어지지 않을 수 있음
    • RAND(), VERSION()
    • SELECT FOR UPDATE / SHARE에서 NOWAIT이나 SKIP LOCKED 옵션 사용
    • 사용자 정의 함수 or 스토어드 프로시저 사용
  • 데이터에 락을 많이 검
  • 풀 테이블 스캔이 발생할 가능성 있음
  • 트랜잭션 격리 수준이 "READABLE-READ" 이상이어야 함

 

2. Row 기반 바이너리 로그 포맷

  • 데이터 변경이 발생했을 때, 변경된 값 자체가 바이너리 로그에 기록되는 방식

 

장점
  • 동기화 하기에 가장 안전한 방식 
    • 비확정적 함수를 사용하더라도 안전하게 복제 가능

 

단점
  • 실행된 쿼리가 많은 데이터를 변경한 경우 전부 기록되므로 바이너리 로그 크기가 매우 커짐
  • 복제 중에, 레플리카 서버에서 현재 복제중인 이벤트가 무엇인지 육안으로 확인하기 어려움

 

 

3. Mixed 포맷

  • 두 가지 바이너리 로그 포맷을 혼합해서 사용하는 방식
  • binlog_format 시스템 변수를 MIXED로 지정

 

4. Row 포맷의 용량 최적화

바이너리 로그 Row 이미지

  • 각 바이너리 로그에는 변경 데이터마다 변경 전 레코드와 변경 후 레코드가 함께 저장됨
  • 저장되는 변경 데이터의 칼럼 구성을 제어할 수 있음

 

binlog_row_image 시스템 변수
  • full
    • 변경이 발생한 모든 컬럼값을 바이너리 로그에 기록
  • minimal
    • 변경 데이터에 대해 꼭 필요한 컬럼들의 값만 기록됨
  • noblob
    • 기본적으로 full 옵션과 동일하게 동작
    • blob or text 칼럼에 대해, 변경이 발생하지 않으면 기록하지 않음

 

바이너리 로그 트랜잭션 압축

  • 트랜잭션에서 변경한 데이터를 압축해서 바이너리 로그에 기록하여 보관 주기를 유지하면서 디스크 용량을 절약할 수 있음
    • 바이너리 로그는 백업과 PITR을 목적으로 생성됨
    • 보관되기 때문에 디스크 저장 공간을 많이 점유하게 됨
  • Transaction_payload_event라는 하나의 이벤트로 하나의 바이너리 로그에 기록함
  • 레플리카 서버로 복제될 때도 압축된 상태를 유지
    • 레플리케이션 I/O 스레드도 압축된 상태로 읽고 릴레이 로그에 기록함
    • 반드시 레플리카 서버도 바이너리 로그 압축을 지원해야 함 (MySQL 8.0.20~)

 

zstd 알고리즘
  • 트랜잭션 데이터 압축 알고리즘

 

시스템 변수
  • binlog_transaction_compression: 압축 기능 활성화
  • binlog_transaction_compression_level_zstd: zstd 알고리즘 압축 레벨 지정

 

압축이 적용되지 않는 이벤트
  • GTID 관련 이벤트
  • View Change 이벤트 (그룹 복제에서 발생)
  • Heartbeat 이벤트 (레플리카 서버가 살아있음을 알리는 이벤트)
  • Incident 타입의 이벤트 (복제 실패 or 소스 서버와 레플리카 서버 간 데이터 불일치 발생)
  • Statement 포맷으로 기록되는 이벤트

 

통계 정보 확인
select * from information_schema.binary_log_transaction_compression_stats;
  • 로그 종류, 압축 여부 등 확인 가능