데이터베이스를 바꾸는 일은 테이블과 데이터를 옮기는 작업으로 끝나지 않아. lobste.rs의 MariaDB→SQLite 전환은 첫 배포에서 CPU가 100%까지 치솟으며 롤백했고, 쿼리 병목을 고친 뒤에야 월요일 트래픽 급증까지 버텼어.1
오래된 이슈가 배포로 이어지기까지
논의는 2019년 이슈 539에서 시작됐어. 처음에는 MariaDB와 호환되는 MySQL이나 PostgreSQL이 대안으로 거론됐지만, 2025년부터 SQLite 전환 작업이 본격화됐고, 기존 변환 스크립트로는 요구를 맞출 수 없어 별도 스크립트를 작성했지.1
첫 번째 PR은 작업이 멈춘 뒤 오래된 PR로 닫혔어. 두 번째 PR에는 성능 테스트와 데이터 무결성 확인이 들어갔고, 세 번째이자 최종 PR에서는 검색 문제를 고치고 실제 데이터의 절반 크기를 만드는 생성 스크립트를 추가했어. 현실적인 크기의 데이터를 준비하는 데만 일주일이 걸렸다는 점이 눈에 들어와.1
첫 배포에서 CPU가 100%가 됐어
2월 21일 첫 배포는 체크리스트를 준비하고 진행했지만, 읽기 전용 트래픽만으로 모든 CPU가 100%에 도달했어. 원인을 바로 재현할 수 있는 프로덕션 데이터베이스가 없어서 롤백부터 해야 했지.1
병목은 대형 테이블에서 발생한 두 건의 전체 테이블 스캔과 별도의 N+1 문제였어. 이 문제들을 고친 뒤에는 느린 쿼리 로그도 추가해서, 다음 배포에서 성능 문제를 더 빨리 찾을 수 있게 했어.1
7월 11일 두 번째 배포에서는 사이트가 정상적으로 운영됐고 CPU와 메모리 사용량도 안정적이었어. 월요일 트래픽이 급증했을 때도 문제가 없었고, 체감 응답 속도는 더 빨라졌다고 해. MariaDB VPS를 내리면 VPS 비용은 절반으로 줄어들어.1
SQLite의 가벼움에는 조건이 붙어
전환 과정에서 SQLite에 없던 regexp, if, stddev는 사용자 정의 함수로 보완했어. 반면 unsigned bigint는 지원되지 않아 bigint로 바꿨고, MariaDB의 utf8mb4_general_ci 대신 적용한 NOCASE는 ASCII 문자만 대소문자를 접어 준다는 차이도 남았지.1
이런 타입과 정렬 규칙의 차이는 SQLite STRICT 테이블의 타입 검사를 이해할 때도 같이 봐야 해. 데이터베이스 이름만 바꾸면 같은 애플리케이션이 그대로 움직일 거라는 기대는, 실제 쿼리와 데이터가 들어간 뒤에야 시험대에 올라가거든.
그래서 이 사례에서 확인된 성공 조건은 단순해. 테스트 스위트만으로는 충분하지 않고, 실제와 비슷한 크기의 데이터와 배포·롤백 체크리스트가 함께 있어야 해. 테스트에서 전체 테이블 스캔이 나오면 실패하도록 만들 수 있었다면 첫 배포의 병목을 더 일찍 발견했을 거라는 회고도 남았어.1
댓글