Hold Off on Litestream 0.5.0

Michael Lynch

Litestream 0.5.0 업데이트는 일단 보류하세요

Litestream은 SQLite 데이터베이스를 클라우드 스토리지에 실시간으로 백업하는 오픈소스 도구입니다. 저는 Litestream을 정말 좋아해서 모든 프로젝트에 사용하고 있습니다.

Litestream은 Fly.io 소유이며, LiteFS라는 대체 프로젝트에 집중하느라 거의 2년 동안 개발이 중단된 상태였습니다. 2주 전, Litestream의 창시자이자 핵심 개발자인 Ben Johnson이 발표를 통해 다시 Litestream에 집중하겠다며 새 버전인 0.5.0을 공개했습니다.

저도 Litestream 0.5.0을 직접 사용해 봤는데, 다른 Litestream 사용자분들께는 프로덕션에 배포하기 전에 한두 번 더 릴리스가 나오고 좀 더 충분한 테스트를 거칠 때까지 기다리시라고 권하고 싶습니다. 새 버전으로 마이그레이션하는 과정이 순탄치 않았습니다.

업데이트: Litestream 0.5.1이 출시되었으며 제가 겪었던 문제 대부분(전부는 아니지만)이 수정되었습니다.

업데이트 2 (2025-10-17): Litestream 0.5.2에서 제가 겪었던 모든 버그가 해결되어, 이제 SQLite 기반 앱들에 적용할 예정입니다.

참고: Litestream에 대해 불평하려는 것이 아닙니다. 저는 Litestream을 좋아하고 개발이 재개된 것을 기쁘게 생각합니다. 다만 제가 겪은 것과 같은 버그를 다른 분들이 겪지 않기를 바라는 마음에서 이 글을 씁니다.

예상되는 마이그레이션 작업

이전 버전의 Litestream에서 v0.5.0 이상으로 업그레이드할 때 의도된 변경으로 인해 필요한 작업은 두 가지입니다:

  1. 백업 포맷이 변경되어, Litestream 0.5.0에서는 이전 버전에서 생성한 백업으로부터 복원할 수 없습니다.
  2. litestream.yml 설정 파일 포맷이 약간 변경되었습니다. 기존에는 replicas라는 배열 필드가 있었지만, 0.5.0에서는 replica(단수)라는 딕셔너리로 바뀌었습니다.

Litestream에서 더 자세한 내용을 담은 유용한 마이그레이션 가이드를 공개했습니다.

Litestream 0.5.0의 장점 중 하나는 이제 공식 litestream Docker 이미지가 제공된다는 점입니다. (수정: 독자 placardloop님이 지적해 주셨는데, Docker 이미지가 새로 나온 것은 아니고 제가 그동안 모르고 있었던 것이었습니다.) 이전에는 모든 Docker 컨테이너에서 올바른 버전의 Litestream을 다운로드해 컨테이너에서 사용할 수 있도록 상당한 보일러플레이트 코드가 필요했지만, 이제는 Dockerfile 한 줄로 줄어듭니다:

COPY --from=litestream/litestream:0.5.0 /usr/local/bin/litestream /app/litestream

Litestream 0.5.0 테스트 마이그레이션

Litestream 0.5.0을 테스트하기 위해 제 프로젝트인 What Got Done에 배포해 보았습니다. 이 프로젝트가 테스트에 적합한 이유는 다음과 같습니다:

  1. 이미 서비스 종료를 공지한 상태라 사용자들이 사이트 이용을 중단했습니다.
  2. Litestream 0.3.13의 버그 때문에 서버가 계속 장애를 겪고 있었는데, 이 버그가 0.5.0에서 수정되었습니다.

Backblaze 백엔드로의 업로드가 더 이상 동작하지 않음

마이그레이션을 시작하기 위해 Litestream 0.3.13으로 최신 데이터 사본을 다운로드한 뒤, Litestream 0.5.0으로 Litestream의 새로운 포맷으로 Backblaze 클라우드 스토리지에 다시 업로드해 보았습니다. 그런데 다음과 같은 오류가 발생했습니다:

error" db=store.db replica=s3 error="write ltx file: s3: upload to db/0000/0000000000000001-0000000000000001.ltx: operation error S3: PutObject, resolve auth scheme: resolve endpoint: endpoint rule error, Custom endpoint `s3.us-west-002.backblazeb2.com` was not a valid URI"

동일한 replica 정의가 이전 버전에서는 잘 동작했기 때문에 다소 의아했습니다.

access-key-id: ${LITESTREAM_ACCESS_KEY_ID}
secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY}
dbs:
  - path: ${DB_PATH}
    replica:
      url: s3://${LITESTREAM_BUCKET}/db
      endpoint: ${LITESTREAM_ENDPOINT}

Backblaze S3 엔드포인트를 지정하는 여러 다른 방법을 시도해 봤지만, Litestream은 백업을 시도하기도 전에 모두 설정 오류로 거부했습니다. 제가 사용한 설정은 Litestream이 유효한 설정으로 인정한 유일한 것이었지만, 정작 백업은 실패했습니다.

Backblaze replica가 “Custom endpoint … was not a valid URI” 오류와 함께 실패함 #789 이슈를 등록했고, Litestream 개발자인 Cory LaNou가 다음 날 수정했습니다.

이제 Litestream의 새로운 포맷으로 Backblaze에 데이터를 업로드할 수 있게 되면서, What Got Done에 Litestream 0.5.0을 통합하는 작업이 다시 진행 가능해졌습니다.

-if-replica-exists 플래그가 사라짐

What Got Done에 Litestream 0.5.0을 배포했지만, 서버가 다음 오류와 함께 부팅에 실패했습니다:

flag provided but not defined: -if-replica-exists

명령어 문서를 확인해 보니 -if-replica-exists가 여전히 지원된다고 나와 있었습니다:

$ litestream restore -help | grep if-replica-exists --after-context=1
        -if-replica-exists
            Returns exit code of 0 if no backups found.

알고 보니 해당 플래그는 실수로 제거된 것이었으며 0.5.1에서 다시 추가될 예정입니다.

복원이 transaction not available 오류와 함께 실패함

-if-replica-exists가 사라진 것에도 굴하지 않고 시작 스크립트에서 해당 플래그를 제거했습니다. 하지만 이번에는 서버가 새로운 오류와 함께 시작에 실패했습니다:

level=ERROR msg="failed to run" error="cannot calc restore plan: transaction not available"

이 오류는 현재 열려 있는 다음 Litestream 이슈와 일치하는데, 심각도가 “CRITICAL - 완전한 데이터 손실”로 상당히 심각합니다:

Litestream이 더 이상 디렉터리를 생성하지 않음

이 시점에서는 어떻게든 다시 서비스를 살리기 위해 무엇이든 시도해 볼 생각이었기 때문에, Docker 컨테이너에서 소스로부터 직접 빌드해 Litestream의 최신 개발 버전을 실행했습니다.

다행히 최신 버전에서는 제가 겪고 있던 transaction not available 문제를 우회했고, Litestream이 한 단계 더 진행되었습니다!

하지만 아직 넘어야 할 오류가 하나 남아 있었습니다:

level=ERROR msg="failed to run" error="create temp database path: open /app/data/store.db.tmp: no such file or directory"

이번 오류는 원인을 꽤 명확하게 짐작할 수 있을 정도로 단순했습니다. 이전 버전의 Litestream에서는 SQLite 데이터베이스를 /app/data/store.db에 복원하라고 하고 /app/data 경로가 존재하지 않으면, 파일을 쓰기 전에 해당 디렉터리를 생성하려 했습니다.

소스 코드를 확인해 보니 이 코드 흐름에서 폴더 생성 로직이 사라진 것을 알 수 있었고, 수정 자체는 간단했기 때문에 직접 수정했습니다:

성공!

최종 mkdir 수정을 적용한 제 Litestream 포크 덕분에 What Got Done이 다시 정상적으로 동작하기 시작했습니다!

되돌아보며

사전 릴리스 포크를 이용해 Litestream 0.5.x를 동작시키는 데는 성공했지만, 다른 프로젝트에는 한두 번 더 릴리스가 나올 때까지 배포를 미루려고 합니다. 0.5.0의 변경 사항은 Litestream 팀이 예상했던 것보다 더 큰 파장을 일으킨 것으로 보이며, 여전히 심각한 버그들과 씨름하고 있습니다:

그리고 개발 버전에서는 수정되었지만 아직 정식 릴리스에 반영되지 않은 (업데이트: 현재는 0.5.1에서 수정되었습니다) 다른 심각한 버그들도 몇 가지 있습니다:

참고: 다시 한 번 말씀드리지만, 이는 Litestream에 대한 비판이 아닙니다. 스트리밍 복제는 올바르게 구현하기가 매우 어렵고, Litestream 팀이 만들고 있는 것은 제가 만들 수 있는 것보다 훨씬 더 견고합니다. 버그 리포트에 빠르게 대응하고 문제를 신속히 수정해 준 Litestream 팀에 감사드립니다.

원문은 Michael Lynch님이 에 게재했습니다.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.