TL;DR

  • sqlite3_rsync는 로컬 또는 원격의 SQLite 데이터베이스 한 개를 동기화해 REPLICA를 ORIGIN의 일관된 시점 스냅샷으로 만드는 도구임.
  • 동기화 중에도 양쪽 데이터베이스를 사용할 수 있으며, ORIGIN은 읽고 쓸 수 있고 REPLICA는 읽기 전용임.
  • ssh를 통신에 사용하고, 양쪽 데이터베이스가 비슷할 때 500MB 데이터베이스의 일반적인 네트워크 트래픽은 약 20KB임.
  • SQLite 3.50.0부터 WAL 모드 및 동일 페이지 크기 제한이 해제됐으며, 이 버전 이상의 양쪽 도구를 사용하면 동기화 트래픽이 크게 줄어듦.
  • 일반 rsync와 달리 SQLite 트랜잭션을 고려해 항상 일관된 복사본을 생성하지만, 한 번에 데이터베이스 하나만 동기화함.

1. 개요

  • sqlite3_rsync ORIGIN REPLICA ?OPTIONS? 명령은 REPLICA를 ORIGIN의 복사본으로 만듦.
  • 전체 옵션 목록은 --help 또는 -? 플래그로 확인할 수 있으며, 옵션 플래그는 ORIGIN과 REPLICA 앞이나 뒤, 또는 두 인자 사이에 둘 수 있음.
  • -v 옵션을 추가하면 rsync와 비슷한 형식으로 더 많은 출력이 표시됨.

2. 기능

  • ORIGIN 또는 REPLICA 중 하나는 USER@HOST:PATH 형식일 수 있고, 다른 하나는 일반 PATH일 수 있음. REPLICA가 없으면 새로 생성됨.
  • 통신에는 ssh를 사용하므로 USER@HOST에 SSH 별칭을 사용할 수 있음. ORIGIN과 REPLICA가 모두 로컬에 있어도 작동함.
  • 동기화 중에도 양쪽 데이터베이스를 사용하는 다른 프로그램의 연결이 유지될 수 있음. 다른 프로그램은 ORIGIN에 쓸 수 있고 REPLICA에서 읽을 수 있음.
  • REPLICA는 sqlite3_rsync 명령이 시작된 시점의 ORIGIN 스냅샷이 됨. 명령 실행 중 ORIGIN의 내용이 바뀌면 변경 사항은 ORIGIN에 반영되지만 REPLICA로 전송되지는 않으므로, REPLICA는 특정 시점의 일관된 ORIGIN 스냅샷이 됨.
  • 동기화에는 이름의 유래인 rsync와 유사한 대역폭 효율적 프로토콜을 사용함.

3. 제한 사항

  • SQLite 3.50.0(2025-05-29) 이전에는 두 데이터베이스 파일이 모두 WAL 모드여야 하고 페이지 크기도 같아야 했음. 이 제한은 3.50.0에서 해제됨.
  • sqlite3_rsync 실행 중 REPLICA는 읽기 전용임. 쿼리는 실행할 수 있지만 쓰기 트랜잭션은 실행할 수 없음.
  • 실행 한 번에 데이터베이스 하나만 동기화함. 표준 rsync처럼 와일드카드로 여러 데이터베이스를 동기화하는 기능은 아직 없음.
  • ORIGIN과 REPLICA 중 적어도 하나는 로컬 머신에 있어야 함. 두 데이터베이스가 모두 다른 머신에 있는 경우는 지원하지 않음.
  • 원격 시스템에서는 이 도구가 SSH의 기본 $PATH에 포함된 디렉터리에 설치돼야 함. /usr/local/bin이 적절한 위치인 경우가 많으며, --exe NAME 플래그로 /opt/bin/sqlite3_rsync 같은 원격 실행 파일 경로를 지정할 수도 있음.
  • REPLICA는 ORIGIN과 매우 비슷하지만 완전히 동일한 복사본은 아님. 모든 테이블과 인덱스 내용은 바이트 단위로 동일하지만 데이터베이스 헤더는 일부 달라질 수 있음.
  • 데이터베이스 헤더의 24~27바이트에 있는 변경 카운터는 REPLICA에서 증가할 수 있음.
  • 헤더의 96~99바이트에 있는 버전 유효성 번호는 ORIGIN 데이터베이스의 마지막 기록자 버전이 아니라 복사에 사용한 sqlite3_rsync 프로그램의 SQLite 버전 번호임.
  • Windows에서는 USER@ 접두사가 없는 한 글자 HOST가 호스트 이름이 아니라 Windows 드라이브 문자로 해석됨.

4. 설치 방법

  • 실행 파일을 $PATH에 있는 위치에 두면 sqlite3_rsync를 설치할 수 있음. 원격 시스템과 동기화한다면 로컬과 원격 양쪽에 실행 파일을 설치해야 하며, 원격 실행 파일은 SSH에서 사용하는 $PATH에 있어야 함. /usr/local/bin이 적절한 위치인 경우가 많음.
  • MacOS에서 SSH의 기본 PATH는 /usr/bin:/bin:/usr/sbin:/sbin이며, 이 디렉터리에는 새 프로그램을 추가할 수 없음. 이를 우회하기 위해 sqlite3_rsync는 PATH를 다음과 같이 확장하려고 시도함: $HOME/bin:/usr/local/bin:/opt/homebrew/bin:$PATH.
  • 원격 Mac과 동기화할 때는 sqlite3_rsync 실행 파일을 $HOME/bin, /usr/local/bin, /opt/homebrew/bin 중 한 곳에 설치하면 됨.
  • 원격 머신의 비표준 위치에 설치해야 한다면 명령줄에서 --exe 옵션으로 정확한 경로를 지정할 수 있음. 예를 들어 sqlite3_rsync sample.db mac:sample.db --exe /some/weird/place/sqlite3_rsync와 같이 사용함.
  • Windows에서 SSHD를 실행하는 데 성공한 적이 없어 원격 Windows 머신과의 데이터베이스 동기화 안내는 제공되지 않음. 향후 릴리스에서 해결될 가능성이 있음.

4.1. 이전 버전과의 호환성 문제

  • sqlite3_rsync는 시작 시 ORIGIN과 REPLICA 사이에서 동기화 알고리즘의 세부 사항을 협의하고, 양쪽에서 사용할 수 있는 가장 발전된 알고리즘을 사용하도록 설계됨.
  • 알고리즘 협상 로직에 fflush() 호출이 누락된 버그가 있어, 로컬에서 3.50.0 이상을 사용하고 원격에서 3.49.1 이하를 사용할 경우 프로그램이 멈출 수 있음.
  • 가장 좋은 해결책은 양쪽에 최신 sqlite3_rsync를 설치하는 것임. 이것이 불가능하면 명령줄에 --protocol 1 옵션을 추가해 우회할 수 있음.

5. 네트워크 대역폭

  • 프로토콜의 핵심은 REPLICA가 페이지 또는 페이지 그룹의 암호화 해시를 ORIGIN으로 보내는 방식임. ORIGIN은 다른 페이지 내용을 반환하거나, 여러 페이지의 해시가 일치하지 않으면 더 세밀한 해시를 요청함.
  • 두 데이터베이스의 차이가 매우 크면 해시 교환 오버헤드 때문에 전체 네트워크 트래픽이 데이터베이스 전체 크기를 넘을 수 있지만, 추가 트래픽은 최대 몇 퍼센트 수준임.
  • 두 데이터베이스가 매우 비슷한 일반적인 경우 전체 트래픽은 데이터베이스 크기의 0.01% 미만인 경우가 많음. 테스트에서는 500MB 데이터베이스가 보통 약 20KB의 네트워크 트래픽으로 동기화됨.
  • 3.50.0(2025-05-29) 이전 프로토콜은 페이지 그룹이 아니라 개별 페이지의 해시만 전송했음. 따라서 양쪽 데이터가 동일하게 시작해도 필요한 대역폭은 대개 데이터베이스 크기의 약 0.5% 이상이었음.
  • 3.50.0 이상은 ORIGIN과 REPLICA의 차이가 적을 때 대역폭 효율이 더 높음. 다만 양쪽 모두 3.50.0 이상을 설치하지 않으면 이전의 대역폭 효율이 낮은 알고리즘으로 되돌아감.

6. 일반 `rsync`를 사용하면 안 되는 이유

  • 일반 rsync는 SQLite 트랜잭션을 이해하지 못함. ORIGIN을 REPLICA로 복사할 수는 있지만, 복사본의 일부는 한 트랜잭션에서, 다른 일부는 다른 트랜잭션에서 가져온 내용일 수 있어 데이터베이스가 손상될 수 있음.
  • rsync 실행 시간 내내 데이터베이스에 연결된 다른 프로세스가 없고 핫 저널도 없다면 일관된 복사본을 만들 수 있음. 두 조건을 모두 보장할 수 없다면 rsync가 손상된 복사본을 만들 수 있음.
  • 반면 sqlite3_rsync는 항상 일관된 복사본을 생성함.
  • 이 페이지의 마지막 업데이트 시각은 2025-11-13 07:12:58Z임.