MySQL Replication 환경에서 발생하는 문제

MySQL Replication 환경에서 발생하는 문제

Tags
데이터베이스
MySQL
Published
Aug 13, 2024
Property

개요

데이터베이스 부하 분산을 위해서 사용하는 slave DB 는 막연히 더 좋은 것이라고 생각하기 쉽다.
데이터베이스 조회 시의 트래픽을 분산할 수 있고, CQRS라는 멋진 아키텍처도 쓸 수 있는 것 같다.
그러나 은총알은 없듯이, 실제로는 운영 과정에서 어려움들이 있다.
MySQL 5.6 기준으로 알아보려고 한다. 현재 MySQL 8.0에서는 아래 이슈들이 많이 개선되어 있다.
 

작동 원리

💡
데이터 변경 시 master는 slave에 Binary Log를 전달하여 데이터를 동기화한다.
위의 작동 원리를 생각하면 아래와 같은 기본적인 특징이 있다.
  • master는 쓰기 및 읽기, slave는 읽기 용도로 사용할 수 있다.
  • slave와 master 간의 데이터 동기화 과정에서 문제가 발생하면 장애가 발생할 수 있다. (Replication Delay)
 

사례 1: 대량 업데이트 수행 시

UPDATE partner SET publish_yn = true WHERE created_at <= "2023-01-01"
예시 쿼리
한 컬럼에 대한 기본값 설정을 변경해야할 일이 생겼다.
해당 쿼리 수행 시 테이블의 대부분의 값들이 업데이트 되며, 대량의 데이터가 있는 테이블이므로 기본적으로 수행시간이 길어지는 상황이다.
Master DB만 사용하는 경우, 락이 발생하면서 다소 응답 시간의 지연이 발생할 수는 있을 것이다.
그러나 Replication 환경일 경우 응답 시간이 문제가 아니라, slave 들이 master 데이터를 복제하는 복제 시간에서 문제가 발생한다.
 

slave DB의 옵티마이저가 고장날 수 있다.

테이블의 행의 10% 이상만 변경되어도(innodb_stats_auto_recalc 옵션) 통계는 자동으로 계산된다.
Replication 환경에서 위의 쿼리를 수행했다면, 통계 재계산 작업이 진행되면서, DB 서버가 다운될 수 있다.
문제는 DB 재시작 이후에도, 옵티마이저 테이블이 올바르게 구성되지 않아서 일부 쿼리의 경우 응답이 불가하는 등의 문제가 발생하기도 한다.
해결책은 옵티마이저 테이블의 초기화이다.
테이블의 통계 정보는 테이블로 영구 관리되기 때문에, 서버 재시작만으로는 해결할 수 없다.
(MySQL 기본 설정들이 궁금하다면 innodb_stats_persistent 옵션을 참고하자.)
 

개선방안

  • 데이터베이스 튜닝
    • innodb_stats_persistent, innodb_stats_auto_recalc , innodb_stats_persistent_sample_pages 등의 값을 조정하여 master-slave 간 DB통계 최적화를 시도해볼 수도 있다.
  • slaveDB 장애 시 failover 처리
    • slave DB가 장애 상황이라면, 서비스 레이어에서 master DB를 사용하도록 처리할 수 있다.
 

사례2: 신규 컬럼 추가 시

신규 컬럼 추가 시 replicaiton 중단이 발생하는 문제가 있다.
해당 문제는 MySQL 8에서 Instant 알고리즘을 통해 일부 개선되었다.
 

MySQL 5.7 vs 8 replication

  • Instant 알고리즘
테이블 리네임, 컬럼 Default 설정 등에서도 사용 가능하다.
단, 테이블의 맨 끝에 추가해야하는 등의 제약이 있다. (AFTER 사용 불가)
 

마무리

MySQL Replication은 대부분의 웹 서비스 환경에서 발생하는 DB 병목을 완화하는 데 매우 효과적이다.
다만, 모든 서비스가 꼭 DB Replication 이 필요한 것은 아니다.
대부분의 문제들은 서버 확장, 캐싱, 또는 비즈니스로직 개선으로도 해결이 가능하다.
본질적인 문제가 무엇인지 확인하고, 꼭 필요한 경우에 Trade-Off를 잘 계산해서 Replication을 도입하면 좋을 것 같다.
 

참고 자료