서비스를 개발하고 운영하다 보면 데이터베이스 스키마를 변경해야 할 때가 생깁니다. 특히 애자일하게 개발하는 경우 DB 스키마를 변경할 일이 많습니다.
점검 공지를 한 뒤 서비스를 잠시 중단하고 할 수 있다면 별 문제가 없지만 그렇게 하기 어려운 경우도 있습니다. 제가 겪은 사례에서는 높은 가용성이 보장되어야 하는 IoT 서버가 DB에 의존하고 있었고 ‘서버 점검’을 통지하는 절차가 딱히 없었습니다. 행 개수가 수천만개에 달하는 거대한 테이블의 컬럼 데이터 타입을 바꿔야 했는데, 그냥 바꿔버리면 스키마가 변경되는 동안 다른 DML 쿼리들이 block되고 DB 서버의 부하가 폭증해서 서비스가 먹통이 될 우려가 있습니다.
그러면 다운타임 없이 DB 스키마를 운영 환경에서 변경하고자 하려면 어떻게 해야 할까요? MySQL 기준으로 알아보겠습니다.
내가 실행하고자 하는 DDL이 online DDL인지 먼저 확인
👉참고: InnoDB Online DDL Operations: MySQL 5.6, MySQL 5.7
MySQL이 내부적으로 테이블 스키마를 변경하는 전통적인 방법은 새 스키마가 반영된 테이블로 전체 데이터를 카피하고 인덱스를 리빌드하는 것입니다. 오래 걸리고 DML을 block하는 작업입니다.
하지만 MySQL 5.6, MariaDB 10.0부터는 online DDL을 지원합니다. 테이블 스키마를 수정하는 동안 DML(insert, update, delete)가 가능한 것입니다. 하지만 모든 DDL이 지원되는 것은 아닙니다. operation 마다 조금씩 다릅니다.
저는 컬럼 데이터 타입을 변경하려 했는데 이 작업은 online DDL이 지원되지 않습니다. In Place
가 No
이고, 테이블을 리빌드하며, 동시 DML을 허용하지 않는 동작입니다. 그냥 ALTER TABLE ...
쿼리를 실행해버리면 테이블 수정이 완료되기까지 억겁의 시간동안 기다려야 하고 그동안 그 테이블은 INSERT
, UPDATE
, DELETE
가 안 됩니다. 미친듯이 쏟아지는 에러 메시지를 받게 될 것입니다…
유의할 점들
- online DDL이 지원되는 DDL이라고 해서 운영에 전혀 영향을 안 미치지는 않습니다. alter 중에 높은 부하와 그에 따른 장애로 쿼리 타임아웃이 증가하거나 복제 지연(replication lag)이 커질 수 있습니다. 운영 환경에서 저지르기 전에 stage나 테스트 환경에서 먼저 해보는 것이 좋습니다.
- MySQL 5.7.23 버전 이전에서는 인덱스 걸린 VARCHAR 칼럼의 사이즈를 확장할 때 인덱스 리빌딩이 이루어집니다.
👉참고: Online Alter에도 헛점은 있더구나 - online DDL 중 사용하는 임시 로그파일이 지정된 innodb_online_alter_log_max_size 값을 초과한 경우 alter가 중단됩니다.
👉참고: mysql online ddl 시 유의할 점
고전적인 방법
다운타임이 예상된다면 고전적인 방법을 사용하는 수밖에 없습니다.
- dump & modify schema: 새 스키마로 빈 테이블을 생성하고 데이터를 새 테이블에 옮긴다. 또는 테이블을 복제한 후 스키마를 바꾼다.
- sync: 구 테이블의 데이터의 변경사항을 실시간으로 새 테이블에도 반영한다.
- replace: 두 테이블의 데이터가 완전히 동기화되면 새 테이블로 기존 테이블을 교체한다.
하지만 이걸 직접 하거나 이걸 수행하는 스크립팅하는 것은 매우 번거롭고 예상하기 어려운 문제도 많습니다. 다행히도 이런 절차를 자동화해주는 소프트웨어들이 있습니다.
pt-online-schema-change
percona의 percona-toolkit에 포함된 pt-online-schema-change입니다.
gh-ost
github/gh-ost (GitHub)
GitHub가 만들었으며 pt-online-schema-change 이후에 등장했으며 설계상 이점이 있습니다. AWS RDS에서 사용하는 경우 제한이 있기 때문에 관련 문서를 참고해야 합니다.
결론
- 스키마 변경은 비용이 많이 드는 작업이다.
- 그러나 online DDL 조건에 맞으면 그냥 alter 할 수 있다.
- 그렇지 않으면 pt-online-schema-change나 gh-ost를 사용한다.