본문 바로가기
WIKI 기술 지식 베이스

다중 프로세스 접근

원문 보기 위키 갱신

다중 프로세스 접근 (Multi-Process Access)

Turso 데이터베이스 파일을 여러 OS 프로세스가 함께 열 수 있어요. 실험적인 다중 프로세스 WAL 코디네이터가 프로세스들 사이의 읽기·쓰기·체크포인트를 조율해 줘요.

출처: 문서

본문

다중 프로세스 접근은 **실험적**이에요. 디스크상의 조율 형식과 공개 API는 릴리스 사이에서 바뀔 수 있어요. Turso 버전을 넘나드는 장기 저장용으로 이 형식에 의존하지 마세요.

기본적으로 Turso 데이터베이스 파일은 하나의 OS 프로세스만 열 수 있어요. 그 프로세스 안의 여러 스레드와 연결은 데이터베이스를 안전하게 공유할 수 있지만, 두 번째 프로세스에서 같은 파일을 열면 잠금 오류로 거절돼요.

다중 프로세스 접근은 이 제한을 없애줘요. multiprocess_wal 기능이 활성화되면, 여러 프로세스가 같은 .db 파일을 동시에 열고 공유 메모리 파일을 통해 WAL 읽기·쓰기·체크포인트를 조율할 수 있어요.

언제 쓰면 좋아요

다음이 필요할 때 다중 프로세스 접근을 활성화하세요:

  • 여러 개의 독립 OS 프로세스(워커, 사이드카, CLI + 임베디드 앱)가 서버 계층 없이 같은 데이터베이스 파일을 읽고 쓰고 싶을 때
  • 기존 프로세스와 새 프로세스가 잠깐 겹치는 무중단 배포를 할 때
  • 스레드보다 강한 격리가 필요한 프로세스당 연결(process-per-connection) 배포를 할 때

단일 프로세스 애플리케이션 — 연결 풀을 쓰는 멀티스레드 서버 포함 — 에서는 기본 모드가 더 빠르고 설정도 필요 없어요.

동작 방식

다중 프로세스 접근이 활성화되면 Turso는 데이터베이스 옆에 추가 형제 파일을 만들어요:

파일 용도
mydb.db 데이터베이스 파일 (변화 없음).
mydb.db-wal 쓰기 선행 로그 (변화 없음).
mydb.db-tshm Turso 공유 메모리. WAL 상태, 활성 writer, 활성 checkpointer, 리더 슬롯, 공유 page-to-frame 인덱스를 추적하는 메모리 매핑 코디네이터예요.

참여하는 모든 프로세스는 .tshm 파일을 mmap하고 다음을 통해 조율해요:

  • 단일 writer 슬롯. 언제나 클러스터 전체에서 최대 한 프로세스만 writer 잠금을 잡고 있어요.
  • 단일 checkpointer 슬롯. 체크포인팅은 프로세스들 사이에서 직렬화돼요.
  • 유한한 개수의 리더 슬롯. 활성 읽기 트랜잭션은 각자 WAL 프레임을 고정(pin)해서, 동시 writer가 덮어쓰거나 checkpointer가 회수하지 못하게 해요.
  • 공유 프레임 인덱스. 어떤 프로세스의 리더든 페이지 번호를 최신 WAL 프레임으로 해석할 수 있고, WAL을 처음부터 훑을 필요가 없어요.

.tshm 파일 위의 프로세스 간 바이트 범위 잠금(Linux는 OFD 잠금, macOS는 fcntl)이 소유권 전환을 통제하고, mmap 영역이 메타데이터 조회의 빠른 경로를 제공해요.

요구 사항

다중 프로세스 WAL은 다음 조건이 모두 충족될 때만 사용할 수 있어요:

  • 플랫폼: 64비트 Unix 계열 OS (Linux, macOS, Android, 기타 지원되는 Unix). Windows, WASM, 32비트 대상에서는 플래그가 받아들여지지만 효과가 없고, 데이터베이스는 단일 프로세스 모드로 열려요.

  • IO 백엔드: 활성 IO 백엔드가 공유 WAL 조율을 구현해야 해요. 기본 파일 기반 백엔드는 그렇고, 메모리 전용과 일부 커스텀 VFS는 그렇지 않아요.

  • 파일시스템: 데이터베이스는 POSIX 바이트 범위 잠금과 mmap을 올바르게 구현하는 로컬 파일시스템에 있어야 해요. 다음 파일시스템은 공유 mmap 조율이 안전하지 않기 때문에 명시적으로 거절돼요:

    파일시스템 이유
    NFS 클라이언트마다 어드바이저리 잠금 의미가 달라요
    CIFS / SMB2 위와 동일; mmap 일관성이 보장되지 않아요
    CephFS 분산 캐시 의미 체계
    GFS2 클러스터 파일시스템; 검증되지 않았어요
    Lustre 분산형; 검증되지 않았어요
    OCFS2 클러스터 파일시스템; 검증되지 않았어요
    AFS, CODA, NCP, 9P (v9fs) mmap+잠금 의미가 불안정한 네트워크/레거시 파일시스템

    이 파일시스템 중 하나에서 multiprocess_wal을 켠 채 데이터베이스를 열면 InvalidArgument를 반환해요.

  • 인메모리 불가: :memory:와 file::memory: 경로는 거절돼요 — 공유 조율은 영속적인 파일이 필요해요.

다중 프로세스 접근 활성화하기

CLI

--experimental-multiprocess-wal을 넘기세요:

tursodb --experimental-multiprocess-wal mydb.db

같은 시점에 mydb.db를 여는 모든 tursodb(또는 SDK) 프로세스는 반드시 이 플래그를 넘겨야 해요. 모드를 섞어 쓰면 거절돼요 — 모드 혼합을 참고하세요.

Rust SDK

use turso::Builder;

let db = Builder::new_local("mydb.db")
    .experimental_multiprocess_wal(true)
    .build()?;

JavaScript / Node.js SDK

import { Database } from "@tursodatabase/libsql";

const db = new Database("file:mydb.db", {
    experimental: ["multiprocess_wal"],
});

Python SDK

import turso

conn = turso.connect(
    "mydb.db",
    experimental_features="multiprocess_wal",
)

Go SDK

db, err := turso.NewDatabase(turso.TursoDatabaseConfig{
    Path:                 "mydb.db",
    ExperimentalFeatures: "multiprocess_wal",
})

DSN으로도 할 수 있어요:

db, err := sql.Open("turso", "mydb.db?experimental=multiprocess_wal")

동시성 모델

다중 프로세스 접근은 Turso의 WAL 동시성 보장을 프로세스 사이에서도 그대로 지켜줘요:

  • Writer는 프로세스들 사이에서 직렬화돼요. 어느 순간이든 최대 한 프로세스(그 프로세스 안의 한 연결)만 writer 슬롯을 잡고 있어요. 다른 프로세스의 writer는 풀릴 때까지 기다려요.
  • 리더는 절대 writer를 막지 않아요. 활성 읽기 트랜잭션은 각자 리더 슬롯에 등록해서 자기 스냅샷의 max-frame을 고정해요. 한 프로세스의 리더는 다른 프로세스의 writer에 의해 무효화되지 않아요.
  • 체크포인팅은 프로세스들 사이에서 직렬화돼요. 단일 checkpointer가 WAL을 잘라내고, 예전 프레임을 고정한 리더가 있으면 어느 프로세스가 소유하든 조기 회수가 막혀요.
  • 스냅샷은 안정적이에요. 동시에 다른 프로세스가 새 프레임을 커밋하더라도, 각 읽기 트랜잭션은 일관된 스냅샷을 봐요.

한 프로세스에서 일어난 스키마 변경(DDL)은 기존 스키마 갱신 경로를 통해 다른 프로세스가 다음 문장을 실행할 때 반영돼요 — 형제 프로세스의 준비된 문(prepared statement)은 SchemaUpdated를 반환하고 다시 준비할 수 있어요. 단일 프로세스 안의 연결들 사이에서 그러듯이요.

모드 혼합

한 프로세스가 단일 프로세스 모드로, 다른 프로세스가 다중 프로세스 모드로 데이터베이스를 동시에 열 수는 없어요. 열기 경로는 호환되지 않는 살아있는 오프너를 탐지해서 즉시 실패해요:

  • multiprocess_wal 없이 열려는데 다른 프로세스가 살아있는 .tshm 권한을 잡고 있으면 다음 오류로 실패해요:

    Database is already open with experimental multiprocess WAL in another process

  • multiprocess_wal을 켜서 열려는데 다른 프로세스가 레거시 배타적 DB 파일 잠금을 잡고 있으면 다음 오류로 실패해요:

    Database is already open without experimental multiprocess WAL in another process

모드를 바꾸려면, 데이터베이스에 대한 기존 연결을 모두 닫은 뒤 원하는 설정으로 다시 여세요. .tshm 파일이 남아 있어도 괜찮아요 — Turso는 다음 다중 프로세스 열기에서 그 파일을 재사용하고, 필요하면 WAL에서 상태를 다시 만들어요.

읽기 전용 열기는 어드바이저리예요: 읽기 전용 열기에서 multiprocess_wal을 요청했는데 .tshm 파일이 없으면, Turso는 실패하는 대신 레거시 읽기 전용 WAL 경로로 폴백해요. 덕분에 단일 프로세스 writer가 깨끗하게 닫은 데이터베이스에 읽기 전용 도구를 붙일 수 있어요.

제한 사항

  • .tshm 파일 형식은 버전이 매겨져 있고, 이후 릴리스에서 바뀔 수 있어요. 형식이 바뀌면 기존 .tshm 파일은 무효화돼요 — Turso는 열 때 다시 만들고, 버전 간 마이그레이션을 시도하지 않아요.
  • ATTACH DATABASE로 붙인 데이터베이스는 메인 연결의 다중 프로세스 설정을 물려받아요.
  • 이 기능은 아직 MVCC(BEGIN CONCURRENT) 아래에서는 지원되지 않아요. 단일 프로세스 안에서의 MVCC 또는 기본 격리 모델의 다중 프로세스 WAL, 둘 중 하나만 쓰세요.
  • 다중 프로세스 모드의 동시성 시뮬레이터와 스트레스 테스트는 64비트 Unix 대상에서만 돌아가요. Windows, WASM, 32비트 빌드는 플래그를 조용히 무시해요.

더 알아보기 (Learn more)