SQLite를 여러 곳에 두기 전에 정해야 할 장애의 모양

연결이 갈라진 저장 상자와 보관 서랍을 배치한 일러스트

데이터를 한 대에만 두는 것이 불안해지면 복제부터 떠올리기 쉽다. 여러 곳에 같은 자료가 있으면 더 안전할 것 같다. 하지만 안전하다는 말에는 잃지 않는 것, 기다리지 않는 것, 서로 다른 결과를 보여주지 않는 것이 섞여 있다. 이 셋을 모두 같은 방식으로 얻을 수 있다고 생각하면 제품 이름을 비교하는 동안에도 정작 필요한 조건은 흐려진다.

rqlite를 만든 Philip O’Toole은 분산 SQLite의 열두 해를 돌아보는 글에서 합의를 통한 복제, 복구를 위한 스트리밍, 여러 작성자의 변경을 나중에 합치는 접근을 구분한다. 2026년 10월 23일의 이 회고는 각 방식이 다른 질문에서 출발했다는 점을 보여준다. 특정 서비스의 성능이나 현재 상품을 검증한 글로 읽기보다, 먼저 장애의 모양을 적는 데 활용해볼 수 있다.

같은 일정 앱에서도 답이 달라진다

가상의 상담 예약 서비스를 생각해보자. 같은 시간대에 한 사람만 예약할 수 있다. 서버 두 곳이 서로 연락하지 못하는 동안 각각 같은 자리를 팔면, 나중에 자료를 합쳐도 두 사람의 약속을 동시에 지킬 수 없다. 이 경우에는 잠시 예약을 받지 않는 불편과 중복 예약의 비용을 비교해야 한다. 둘 다 쓰기를 계속하는 것이 항상 더 좋은 가용성은 아니다.

반면 개인 메모 앱이라면 다른 선택이 가능하다. 휴대전화와 노트북이 잠시 떨어져 있어도 각자 새 메모를 적게 하고, 연결된 뒤 내용을 합칠 수 있다. 그래도 같은 문장의 수정이 충돌하면 무엇을 보여줄지 정해야 한다. 여러 곳에서 쓸 수 있다는 설명만으로 사용자가 본 마지막 문장이 보존되는 것은 아니다.

이번에는 읽기 전용 자료실을 떠올려보자. 원본 서버가 고장 났을 때 잠깐 기다렸다가 복구해도 되는 서비스라면, 즉시 다른 서버가 쓰기를 이어받는 구조가 꼭 필요하지 않을 수 있다. 어느 시점의 자료까지 되살릴 수 있는지, 실제로 복구하는 데 얼마나 걸리는지를 확인하는 것이 더 가까운 질문이다. 여러 복사본의 존재만 세어서는 이 시간을 알 수 없다.

세 예시는 모두 설명을 위한 가정이다. 실제 사업의 요구와 데이터 양, 장애 비용을 측정한 결과가 아니다. 다만 같은 데이터베이스를 사용해도 지켜야 할 약속은 다를 수 있다는 점을 드러낸다. 예약의 자리를 지키는 문제와 메모를 계속 적게 하는 문제를 하나의 추천 목록으로 해결하려 하면 중요한 차이를 놓친다.

고장 난 날의 문장을 먼저 쓰기

설계를 고르기 전에 장애 상황을 짧은 문장으로 적어볼 수 있다. 한 대가 멈췄을 때 읽기는 계속 가능한가. 쓰기는 언제까지 기다릴 수 있는가. 연결이 끊긴 두 곳이 각각 받아들인 변경을 어떻게 다룰 것인가. 사용자에게 성공이라고 알린 요청이 이후에도 남아 있어야 하는가. 구현 용어보다 이런 문장이 먼저 있어야 선택의 이유를 설명할 수 있다.

가상의 예약 서비스라면 성공 화면을 보여준 예약이 사라져서는 안 된다는 약속이 중심이 된다. 이를 지키기 위해 어떤 장애에서는 새 예약을 거절할 수 있다고 정할 수 있다. 그때 사용자가 보는 안내도 설계의 일부다. 다시 시도하라는 말만 남기면 중복 요청과 실제 예약 상태를 확인할 방법이 함께 필요해진다.

복구 시간도 숫자 하나로 적고 끝낼 항목은 아니다. 백업을 가져오는 시간, 새 환경에서 여는 시간, 애플리케이션이 올바른 자료를 읽는지 확인하는 시간이 다를 수 있다. 약속한 시간 안에 돌아온다고 말하려면 실제 조건에서 확인한 근거가 있어야 한다. 이 글에서는 그런 시험을 수행하지 않았으므로 특정 시간을 제시하지 않는다.

오래된 자료를 읽어도 되는 범위 역시 나눠볼 만하다. 소개 문구가 조금 늦게 바뀌는 것은 괜찮을 수 있지만 예약 잔여 수량은 다를 수 있다. 모든 조회가 같은 신선도를 요구하는 것은 아니다. 반대로 아무 화면이나 오래된 복사본으로 보내도 된다고 가정하면 쓰기 쪽의 약속을 읽기 쪽에서 깨뜨릴 수 있다.

단순한 구조를 고르는 근거

처음부터 가장 복잡한 구성을 고를 필요는 없다. 장애가 나면 잠깐 멈춰도 되고 복구 절차를 실제로 확인할 수 있다면, 그 조건에 맞는 작은 구조를 선택할 수 있다. 중요한 것은 단순해서 좋다는 취향보다 어떤 요구를 충족하고 어떤 요구는 아직 다루지 않는지 적는 일이다. 작은 구조도 약속이 분명하면 설명할 수 있다.

나중에 요구가 달라졌을 때에도 이 기록이 도움이 된다. 자료실이 예약 서비스로 바뀌었다면 이전 구성이 틀렸다기보다 지켜야 할 약속이 달라진 것이다. 서버가 느려졌다는 이유만으로 복제를 더하는 경우에도, 읽기 부하를 나누려는 것인지 고장에 대비하려는 것인지 구분하면 다음 확인이 선명해진다. 이름이 같은 복제라도 목적이 다르다.

도구를 비교하는 표에는 장애 시 쓰기, 읽기 자료의 신선도, 충돌 처리, 복구 확인 여부를 열로 넣어볼 수 있다. 아직 모르는 값은 빈칸이나 미확인으로 남긴다. 제품 소개에서 찾지 못한 항목을 좋은 쪽으로 추정하지 않는 것이 중요하다. 이 표는 추천 순위를 만드는 점수판보다, 다음에 물어볼 질문을 고르는 종이에 가깝다.

데이터를 여러 곳에 두려는 마음에는 잃고 싶지 않은 무언가가 있다. 그것이 자료인지, 기다리지 않는 경험인지, 약속한 예약 자리인지 먼저 알아야 한다. SQLite를 어디에 복제할지 고민하기 전에 고장 난 날 사용자가 보게 될 장면부터 적어보면 어떨까. 필요한 구조는 그 장면을 지키는 쪽에서 조금 더 분명해질 수 있다.

관련 글은 Database에서 이어 읽을 수 있습니다.

공개 원문을 참고해 AI의 도움으로 구성·작성한 글입니다. 본문의 가상 예시는 실제 수행 결과와 구분했으며, 표지는 Google Gemini로 만든 개념 일러스트입니다.