!원문 캡처 · github.com

sqlite-multiwriter는 SQLite의 가상 파일 시스템(VFS) 확장으로, 여러 스레드나 프로세스가 하나의 데이터베이스에 동시에 쓰도록 한다. 제작자에 따르면 스키마와 SQL을 바꾸지 않고 사용할 수 있으며, 커밋은 로그에 기록된 뒤 데이터베이스 파일에 반영된다. 프로젝트는 GitHub 저장소에서 공개됐다.

제작자가 Apple M5 Pro에서 SQLite 3.53.4를 WAL 모드, synchronous=FULL로 실행해 비교한 결과, 16개 스레드가 각자 다른 행을 삽입할 때 초당 트랜잭션 수는 SQLite의 8,630건에서 sqlite-multiwriter의 49,277건으로 늘었다. 16개 프로세스에서는 8,636건에서 25,987건으로 늘었다. 이 조건에서 가장 느린 1,000건 중 한 건의 커밋 시간은 스레드 테스트에서 157ms에서 2.08ms로, 프로세스 테스트에서 233ms에서 1.54ms로 줄었다. 측정은 새 데이터베이스에서 8초간 진행했으며, 지연 시간에는 재시도도 포함됐다. 자세한 수치와 측정 방법은 저장소에 공개돼 있다.

확장 기능은 각 작성자에게 별도 WAL을 두고, 커밋 시 변경 페이지를 검증해 순서대로 게시한다. 서로 다른 페이지를 수정하는 쓰기는 서로 기다리지 않을 수 있다. 같은 페이지에서 충돌하면 먼저 커밋한 쪽이 이기며, 나중 트랜잭션은 SQLITE_BUSY_SNAPSHOT 오류를 받는다. 애플리케이션은 이때 트랜잭션 전체를 다시 실행해야 한다. 선택 사항인 mw_rebase=1은 서로 다른 행을 바꿨지만 같은 페이지를 수정한 경우 일부 트랜잭션을 최신 상태에 다시 적용한다. 같은 행을 바꾸는 실제 충돌은 해결하지 못한다.

사용하려면 확장 기능을 로드하고 SQLite 연결을 URI 모드로 열어야 한다. 스레드 간 공유는 vfs=multiwriter를 지정하고, 프로세스 간 공유에는 mw_mp=1을 추가한다. 프로세스 모드는 데이터베이스 옆에 공유 로그 파일을 만들며, 데이터베이스는 로컬 파일 시스템에 있어야 한다. 현재 버전과 플랫폼별 파일은 릴리스 페이지에서 확인할 수 있다.

제약도 있다. WAL 모드만 지원하며 네트워크 파일 시스템에서는 사용할 수 없다. 격리는 스냅샷 격리와 페이지 검증을 기반으로 하지만 직렬 가능성이 증명된 것은 아니다. 첨부 데이터베이스 간 트랜잭션은 원자적이지 않고, 읽기 검증을 끄면 쓰기 왜곡이 가능하다. 재베이스도 단순한 단일 행 INSERT·UPDATE·DELETE에 한정되며, 여러 조건에서는 적용되지 않아 재시도가 필요할 수 있다. 검증 항목에는 스레드 및 프로세스 테스트와 ext4에서의 전원 손실 테스트가 포함되지만, 다른 파일 시스템이나 하드웨어 전원 손실 상황은 검증되지 않았다고 프로젝트는 밝혔다. 데이터베이스 동기화 기능은 제공하지 않으며, 별도 프로젝트인 sqlite-sync를 안내한다.