TECH 으로 돌아가기
TECH HACKER NEWS 2일 전 7분 읽기 31 READS

SQLite를 실서비스에 올릴 때 알아야 할 것들 — WAL 모드부터 백업까지

SQLite, 장난감 아니에요

개발 블로거로 유명한 줄리아 에번스(Julia Evans)가 SQLite를 실제로 운영하면서 배운 점들을 정리한 글을 올렸어요. SQLite라고 하면 '개발용이나 모바일 앱에나 쓰는 가벼운 DB 아니야?'라고 생각하는 분들이 많은데요, 최근 몇 년 사이 분위기가 많이 달라졌거든요. 작은 규모의 웹 서비스라면 PostgreSQL이나 MySQL 같은 별도 DB 서버 없이 SQLite 파일 하나로 운영하는 사례가 점점 늘고 있어요. 이 글을 계기로, SQLite를 프로덕션에서 쓸 때 꼭 알아야 하는 운영 포인트들을 정리해볼게요.

SQLite가 뭐냐면, 서버 프로세스 없이 라이브러리 형태로 앱에 내장되는 데이터베이스예요. PostgreSQL은 DB 서버를 따로 띄우고 네트워크로 접속하는 방식인데, SQLite는 그냥 내 프로그램이 디스크의 파일 하나를 직접 읽고 쓰는 방식이거든요. 네트워크 왕복이 없으니 단순 조회는 오히려 더 빠른 경우도 많아요.

첫 번째: WAL 모드는 무조건 켜세요

SQLite를 웹 서비스에 쓸 때 가장 먼저 해야 할 일이 WAL(Write-Ahead Logging) 모드 활성화예요. 기본 모드에서는 누군가 쓰기를 하는 동안 읽기가 막히는 구조라서, 여러 요청이 동시에 들어오는 웹 서비스에서는 금방 병목이 생기거든요. WAL 모드가 뭐냐면, 변경 사항을 원본 파일에 바로 쓰지 않고 별도의 로그 파일에 먼저 기록하는 방식이에요. 이렇게 하면 한쪽에서 쓰기가 진행되는 동안에도 다른 쪽에서는 읽기를 계속할 수 있어요. PRAGMA journal_mode=WAL 한 줄이면 켜져요. 이거 하나로 동시성 문제의 상당 부분이 해결되는데, 기본값이 아니라서 모르고 지나치는 분들이 정말 많아요.

두 번째: SQLITE_BUSY와 busy_timeout

SQLite 운영에서 제일 자주 마주치는 에러가 SQLITE_BUSY예요. SQLite는 쓰기를 한 번에 하나만 허용하거든요. 두 요청이 동시에 쓰기를 시도하면 한쪽은 기다려야 하는데, 기본 설정에서는 기다리지 않고 바로 에러를 던져버려요. 그래서 PRAGMA busy_timeout으로 '락이 풀릴 때까지 몇 초 기다려라'라고 설정해주는 게 필수예요. 보통 5초 정도로 잡는데, 이것만으로 산발적으로 터지던 에러 대부분이 사라져요.

한 가지 더 알아두면 좋은 게 트랜잭션 시작 방식이에요. 나중에 쓰기를 할 트랜잭션이라면 BEGIN 대신 BEGIN IMMEDIATE로 시작하는 게 안전해요. 읽기로 시작했다가 중간에 쓰기로 승격하려는 순간 다른 트랜잭션과 충돌하면, 기다려주지 않고 바로 실패하는 경우가 있거든요. 처음부터 '나 쓸 거야'라고 선언하고 시작하면 이 문제를 피할 수 있어요.

세 번째: 백업은 파일 복사로 하면 안 돼요

SQLite는 그냥 파일이니까 cp 명령으로 복사하면 백업이 될 것 같지만, 쓰기가 진행 중일 때 복사하면 깨진 백업이 만들어질 수 있어요. 안전한 방법은 SQLite가 제공하는 VACUUM INTO 명령이나 온라인 백업 API를 쓰는 거예요. 실시간 복제가 필요하면 Litestream 같은 도구도 있어요. 이게 뭐냐면, WAL 파일의 변경 사항을 지켜보고 있다가 S3 같은 오브젝트 스토리지로 계속 흘려보내주는 도구거든요. 서버가 통째로 날아가도 몇 초 전 시점으로 복구할 수 있게 해줘요.

업계 맥락: SQLite 재평가의 시대

요즘 SQLite를 프로덕션에 쓰는 흐름은 꽤 뚜렷해요. Litestream을 만든 개발자는 '대부분의 서비스는 SQLite로 충분하다'는 주장을 꾸준히 펼쳐왔고, Ruby on Rails는 프로덕션에서 SQLite를 제대로 쓸 수 있도록 기본 설정을 다듬는 방향으로 움직여왔어요. 엣지 컴퓨팅 쪽에서는 Turso나 Cloudflare D1처럼 SQLite를 기반으로 한 분산 서비스도 나왔고요. 배경에는 '요즘 서버 한 대가 생각보다 강력하다'는 재발견이 있어요. NVMe SSD에 수십 기가 메모리면 어지간한 서비스 트래픽은 한 대로 감당이 되거든요. 그렇다면 DB 서버를 따로 두고 네트워크로 통신하는 복잡함이 정말 필요한가, 라는 질문이 나오는 거죠.

물론 만능은 아니에요. 여러 서버가 하나의 DB에 써야 하는 구조, 쓰기가 아주 많은 서비스, 무거운 분석 쿼리가 수시로 도는 환경이라면 여전히 PostgreSQL 같은 서버형 DB가 맞아요.

한국 개발자에게 주는 시사점

사이드 프로젝트나 사내 도구, 초기 스타트업 서비스라면 SQLite를 진지하게 고려해볼 만해요. DB 서버 관리 비용이 사라지고, 배포도 파일 하나 챙기면 끝이니까요. 다만 위에서 말한 세 가지, WAL 모드와 busy_timeout과 안전한 백업은 시작할 때 꼭 세팅해두세요. 이 세 개를 모르고 시작하면 '역시 SQLite는 장난감이네'라는 잘못된 결론에 도달하기 쉽거든요.

마무리

한 줄로 정리하면, 'SQLite는 설정 몇 줄만 제대로 하면 훌륭한 프로덕션 DB가 된다'예요. 여러분은 실서비스에 SQLite 써본 경험 있으신가요? 어느 규모까지 버티던가요? 경험담을 댓글로 공유해주세요.


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://jvns.ca/blog/2026/07/17/learning-about-running-sqlit...
SHARE
처리 중...