본문으로 건너뛰기

중단 없는 업그레이드

중단 없이 셀프호스트 Quire를 업그레이드하기.

Markdown으로 보기

규칙은 docs/architecture/23-ops.md 7절과 docs/architecture/07-data.md 4.1절에 있습니다. 이것은 절차입니다.

안전하게 만드는 보장

릴리스 R은 스키마 R과 스키마 R 마이너스 하나에 대해 올바르게 실행됩니다. 모든 스키마 변경은 확장, 전환, 축소로 나뉩니다.

  1. 확장: 새 컬럼, 테이블, 인덱스를 추가합니다. 이전 코드는 무시합니다.
  2. 전환: 최소 한 릴리스 동안 새 코드는 두 형태 모두에 쓰고 새 것을 읽으며, 재개 가능한 작업이 이전 행을 채웁니다.
  3. 축소: 이후 릴리스에서, 이전 형태를 그 자체로 제거합니다.

따라서 롤링 업그레이드의 어느 순간에도 이전과 새 프로세스는 하나의 데이터베이스를 공유할 수 있습니다. 다운 마이그레이션은 없습니다. 한 시간 전에 컬럼을 삭제한 마이그레이션이 그 한 시간 동안 쓰인 행을 되돌려줄 수 없기 때문입니다.

schema-compat CI 작업은 이전 릴리스의 테스트를 새 스키마에 대해 실행하여 매 릴리스마다 이 보장을 점검합니다.

시작하기 전에

  1. 릴리스 노트를 읽으세요. 유지보수 창이 필요한 릴리스는 추정 시간과 함께 그렇게 밝힙니다. 릴리스당 최대 한 번입니다.
  2. 복구 훈련을 실행하거나, 이번 릴리스에서 초록으로 통과했는지 확인하세요 (backup-restore.md). 실패한 훈련은 업그레이드를 막습니다.
  3. 기준 백업을 준비하세요: docker compose -f docker/compose.yaml --profile backup run --rm backup.

Docker Compose, 단일 호스트

export QUIRE_RELEASE=2026.10.0            # or set it in docker/.env
docker compose -f docker/compose.yaml pull   # or build
docker compose -f docker/compose.yaml run --rm migrate
docker compose -f docker/compose.yaml up -d --no-deps web content collab
docker compose -f docker/compose.yaml up -d --no-deps worker scheduler

순서는 의도적입니다.

  1. 마이그레이션 먼저, 이전 릴리스가 트래픽을 처리하는 동안에. 확장 마이그레이션은 그 릴리스에게 보이지 않습니다.
  2. 다음은 웹 계층. SIGTERM을 받으면 각 웹 프로세스는 /readyz를 draining으로 바꾸고, 진행 중인 요청을 30초 안에 마치고, 재연결 힌트와 함께 스트림을 닫고 종료합니다. stop_grace_period는 40초여서 Compose가 건강한 드레이닝을 끊지 않습니다.
  3. 마지막은 워커. 가장 새로운 이벤트 형태가 가장 새로운 소비자가 기대하기 전에 만들어지도록 하기 위함입니다. 워커는 즉시 가져오기를 멈추고 120초를 받습니다. 끝내지 못한 작업은 다른 곳에서 다시 가져오는데, 모든 작업이 멱등하므로 안전합니다. 스케줄러는 다음 틱에서 리더십을 넘깁니다.

한 호스트에서는 Compose가 컨테이너를 하나씩 교체하므로 서비스마다 짧은 빈틈이 있습니다. 빈틈을 없애려면 웹 계층을 자체 프록시 뒤의 두 컨테이너로 실행하고(게시된 포트 없이 두 번째 web 서비스를 추가하는 오버라이드 파일), 한 번에 하나씩 재생성하면서 각각이 다음에 들어가기 전에 건강을 보고할 때까지 기다리세요.

여러 호스트 또는 오케스트레이터

같은 순서를 사용하세요. 단일 작업에서 한 번 마이그레이션한 뒤, surge는 1, unavailable는 0으로 웹 계층을 굴리고, 그 다음 워커입니다. 준비성 점사는 /readyz, 생존성 점사는 /healthz를 가리키세요.

전용 테넌트 데이터베이스가 있으면 migrate 단계가 둘 다 합니다. 제어 데이터베이스를 먼저 마이그레이션한 뒤, ops.tenant_database에 나열된 모든 데이터베이스를 각각 자기 잠금 아래에서 하나씩 처리합니다. 한 테넌트 데이터베이스의 실패가 다른 것을 멈추지 않습니다. 모든 데이터베이스가 끝나면 마이그레이션 원장을 비교하고, 모든 데이터베이스가 제어 데이터베이스가 적용한 마이그레이션과 정확히 일치하지 않으면 각각 뒤처지거나 앞서 있는 것을 명시하며 0이 아닌 코드로 종료합니다. 같은 명령이 각 데이터베이스에 큐 테이블을 설치합니다. 워커가 고정된 테넌트의 작업을 쓰인 곳에서 소비하기 때문입니다.

bun apps/worker/src/migrate.ts   # what the Compose step runs
bun run db:migrate:all                            # the same, from a checkout

일반 마이그레이션과 최초 설정은 ops.platform_policy_version에 Quire 운영자의 표준 영어 법률 문서도 설치합니다. 설치 프로그램은 멱등합니다. 누락된 영어 본문과 마이그레이션이 시드한 정확한 플레이스홀더 본문만 교체됩니다. 시드는 보관되고 새 게시 버전이 삽입됩니다. 과거 수락 참조와 본문은 유지됩니다. 초안을 포함하여 운영자가 실제로 작성한 모든 버전은 보존되며 플랫폼 정책 콘솔을 통해 관리해야 합니다. 테넌트 정책 문서, 버전 및 동의는 이번 전환으로 절대 변경되지 않습니다. 이는 운영자 텍스트의 게시이지, 법적 인증이나 약속의 자동 이행이 아닙니다.

각 전용 데이터베이스는 등록된 이름으로 접근합니다. env:QUIRE_DB_NORTHWIND_URL로 등록된 데이터베이스에는 다음이 필요합니다.

변수 용도
QUIRE_DB_NORTHWIND_URL 애플리케이션 역할, 웹 계층과 워커용
QUIRE_DB_NORTHWIND_URL_MIGRATOR 마이그레이터 역할, 이 명령과 이동용
QUIRE_DB_NORTHWIND_URL_SUPERUSER 선택 사항: 마이그레이션 전에 부트스트랩(역할, 스키마, 헬퍼)을 다시 적용

_MIGRATOR 연결이 없는 등록된 데이터베이스는 건너뛰지 않고 실패로 보고됩니다. 제어 데이터베이스가 끝나면 웹 계층은 한 번 굴릴 수 있습니다. 한 시간 뒤처진 테넌트 데이터베이스는 경고하고, 하루 뒤처지면 페이지를 보냅니다.

pgvector

마이그레이션 0264부터 근거 코퍼스는 서버에 확장이 있는 경우 pgvector HNSW 인덱스를 사용하며, Compose의 postgres 서비스는 그것을 가지고 빌드됩니다 (docker/postgres.Dockerfile). 이미지를 바꾼 뒤의 첫 migrate는 슈퍼유저 부트스트랩을 통해 확장을 만들고, 0264는 생성된 벡터 컬럼을 추가하며 인덱스를 만듭니다. 컬럼 추가는 배타적 잠금 아래에서 app.ai_chunk를 한 번 다시 쓰므로 근거 요청은 기다려야 합니다. 다른 것은 그 테이블을 건드리지 않습니다.

pgvector가 없는 서버에서는 0264가 알림을 기록하고 아무것도 바꾸지 않으며 검색은 정확 그대로입니다. 0.8보다 오래된 pgvector에서는 컬럼과 인덱스는 만들지만, 확장이 업그레이드되기(alter extension vector update) 전까지 검색은 정확 그대로입니다. 필터링된 HNSW 스캔에는 0.8의 반복 스캔이 필요하기 때문입니다. 나중에 없는 서버에서 켜려면 확장을 설치하고 부트스트랩을 다시 실행한 뒤(또는 슈퍼유저로 create extension vector), 이어서 quire_migrator로:

set maintenance_work_mem = '1GB';  -- the HNSW build is much faster in memory
select ops.ai_chunk_enable_vector_index();

이 명령은 멱등하며 enabled 또는 unavailable를 반환합니다. 각 전용 테넌트 데이터베이스에서도 실행하세요.

롤백

코드 롤백은 항상 가능합니다. QUIRE_RELEASE를 이전 태그로 바꾸고 up -d를 다시 실행하면 됩니다. 릴리스 안에서 스키마가 양방향으로 호환되기 때문에 동작합니다.

스키마 롤백은 제공되지 않습니다. 되돌릴 수 없는 것과 그 회복 방법:

되돌릴 수 없는 것 회복
컬럼을 삭제한 축소 마이그레이션 삭제 이전으로의 지점 복원을 새 데이터베이스로, 추출 후 병합
제자리 데이터 변경 같은 방법, 이후의 쓰기부터 조정
보낸 웹훅과 이벤트 보상 이벤트, 삭제는 절대 금지
보낸 이메일 사람이 후속 조치를 작성
감사 해시 체인 절대 다시 쓰지 않음; 정정 항목을 덧붙임

그래서 축소 마이그레이션은 따로 릴리스됩니다. 복원 시 경계가 깨끗하기 때문입니다.

업그레이드 확인

docker compose -f docker/compose.yaml ps           # every service healthy
curl -fsS http://localhost:8080/readyz             # ready, and what is configured
docker compose -f docker/compose.yaml logs migrate # the migrations applied
탐색

검색어를 입력하세요…

↑↓ 이동↵ 선택Esc 닫기