
벡터 DB 백업은 스냅샷을 찍는 순간이 아니라 그 스냅샷으로 실제 서비스를 되살릴 수 있는지 확인하는 순간에 완성됩니다. 스냅샷 파일이 스토리지에 잘 쌓여 있어도, 복구 절차를 한 번도 실행해 본 적이 없다면 그건 백업이 아니라 그냥 파일일 뿐입니다. 이 글에서는 Milvus·Qdrant·Weaviate·pgvector 네 가지 도구를 기준으로, 스냅샷과 실제 복구 사이에 벌어지는 구체적인 간극과 이를 좁히는 복구 테스트 설계를 정리해 보겠습니다.
스냅샷은 정말 백업의 전부일까요?
스냅샷은 특정 시점의 데이터 상태를 통째로 떠낸 파일입니다. 벡터 DB에서는 여기에 벡터 값뿐 아니라 페이로드(메타데이터), 인덱스 구조, 세그먼트 정보까지 함께 담기는 경우가 많습니다.
문제는 이 파일이 ‘떠졌다’는 사실과 ‘복원해서 원래대로 서비스가 돌아간다’는 사실이 서로 다른 명제라는 점입니다. 스냅샷 생성 시점에 인덱싱이 진행 중이었거나, 임베딩을 만든 원본 문서 DB와 벡터 DB의 시점이 어긋나 있으면, 파일 자체는 정상이어도 복구된 결과가 서비스 요구 수준에 못 미칠 수 있습니다. 이런 정합성 문제는 파일 크기나 체크섬만 봐서는 드러나지 않고, 실제로 컬렉션을 열어 쿼리를 던져봐야 알 수 있습니다.
Milvus·Qdrant·Weaviate·pgvector, 백업 방식부터 다릅니다
네 도구는 벡터를 저장한다는 점은 같지만 백업이 이뤄지는 계층이 서로 다릅니다. Milvus는 별도 오픈소스 도구인 milvus-backup을 통해 컬렉션 단위로 데이터와 인덱스 메타데이터를 오브젝트 스토리지에 백업하는 구조입니다. 공식 저장소는 GitHub의 zilliztech/milvus-backup에서 확인할 수 있습니다.
Qdrant는 컬렉션 스냅샷을 API 호출 한 번으로 생성하고, 이 파일을 S3 호환 스토리지에 올리거나 다른 노드로 옮겨 복구하는 방식을 씁니다. 공식 문서는 Qdrant Snapshots에 정리돼 있습니다. Weaviate는 backup-s3, backup-gcs, backup-filesystem 같은 백업 모듈을 통해 클래스(샤드 전체) 단위로 비동기 백업을 수행합니다.
pgvector는 별도의 벡터 DB가 아니라 PostgreSQL 확장이기 때문에, 백업도 PostgreSQL의 표준 도구를 그대로 씁니다. pg_dump로 뜨는 논리 백업과, pg_basebackup과 WAL 아카이빙을 조합한 물리 백업 두 갈래로 나뉘는데, 이 차이가 뒤에서 다룰 인덱스 재빌드 문제와 바로 연결됩니다.

스냅샷만 있으면 복구에서 왜 막힐까요?
가장 흔한 문제는 버전 불일치입니다. 스냅샷을 뜬 Milvus나 Qdrant의 버전과 복구할 인스턴스의 버전이 다르면, 내부 스토리지 포맷이 바뀌어 있어 복구 자체가 거부되거나 일부 인덱스만 깨진 채로 올라오는 경우가 있습니다.
두 번째는 분산 환경에서의 부분 실패입니다. Weaviate처럼 클래스가 여러 샤드로 나뉘어 있으면, 백업 도중 일부 노드의 스냅샷만 실패해도 전체 백업이 불완전한 상태로 저장소에 남을 수 있습니다. 이 상태는 백업 작업 로그의 성공/실패 여부만으로는 눈에 잘 띄지 않고, 실제로 복구를 시도해야 드러납니다.
세 번째는 외부 시스템과의 참조 깨짐입니다. 벡터 DB만 특정 시점으로 되돌리고, 벡터의 원본 텍스트나 ID를 관리하는 관계형 DB는 그보다 늦은 시점 그대로 남아 있으면, 복구된 벡터가 가리키는 문서가 이미 삭제됐거나 수정된 상태일 수 있습니다.
복구 테스트, 이렇게 설계해 보세요
복구 테스트의 핵심은 운영 환경과 분리된 테스트 인스턴스에 실제로 스냅샷을 얹어 보고, 숫자로 비교하는 것입니다. Qdrant 1.x 기준으로 스냅샷 생성부터 복구, 검증까지의 흐름은 아래와 같은 형태로 자동화할 수 있습니다. (정확한 파라미터명은 사용 중인 버전의 공식 문서를 함께 확인하시기 바랍니다.)
# 1. 현재 컬렉션 스냅샷 생성
curl -X POST "http://localhost:6333/collections/articles/snapshots"
# 2. 생성된 스냅샷 목록 확인
curl "http://localhost:6333/collections/articles/snapshots"
# 3. 별도 테스트 인스턴스에 스냅샷 복구
curl -X PUT \
"http://localhost:6334/collections/articles/snapshots/recover" \
-H "Content-Type: application/json" \
-d '{"location": "http://localhost:6333/collections/articles/snapshots/articles-2026-09-15.snapshot"}'
# 4. 포인트 개수 비교 (원본 vs 복구본)
ORIG=$(curl -s http://localhost:6333/collections/articles | jq '.result.points_count')
REST=$(curl -s http://localhost:6334/collections/articles | jq '.result.points_count')
echo "원본: $ORIG / 복구본: $REST"
[ "$ORIG" = "$REST" ] || echo "개수 불일치 - 복구 실패 가능성"
Milvus 환경이라면 milvus-backup CLI로도 비슷한 절차를 구성할 수 있습니다.
# 백업 생성
milvus-backup create -n backup_20260915
# 백업 목록 확인
milvus-backup list
# 별도 컬렉션명으로 복구해 원본과 병행 검증
milvus-backup restore -n backup_20260915 -s articles_restore_test

개수만 맞춰보는 것으로는 부족합니다. 같은 쿼리 벡터로 원본과 복구본에 검색을 걸어 상위 결과의 ID가 얼마나 겹치는지까지 비교해야, 인덱스가 손상 없이 살아났는지 확인할 수 있습니다. 이 절차를 월 1회 이상 정기적으로 돌리는 것이 스냅샷만 쌓아두는 것과 실질적인 차이를 만듭니다.
인덱스 재빌드 시간이 RTO를 갉아먹는 경우
pgvector에서 pg_dump로 논리 백업을 뜨면 스키마와 데이터만 텍스트/바이너리 형태로 저장되고, HNSW나 IVFFlat 인덱스는 복구 시점에 처음부터 다시 만들어집니다. 수백만 건 이상 규모의 벡터 컬렉션에서는 이 재생성 작업만으로 복구 시간이 크게 늘어날 수 있어, 목표로 잡은 복구 시간(RTO)을 넘겨버리는 원인이 됩니다.
반면 pg_basebackup과 WAL 아카이빙을 조합한 물리 백업은 디스크 파일을 그대로 복사하는 방식이라 인덱스도 파일 상태 그대로 복구되고, 특정 시점으로 되돌리는 포인트인타임 복구도 가능합니다. 다만 WAL을 계속 저장해야 하니 스토리지 비용과 운영 복잡도가 올라가는 트레이드오프가 있습니다. Milvus나 Qdrant의 스냅샷 방식도 세그먼트를 그대로 복구해 재빌드 부담이 적은 편이지만, 스냅샷과 스냅샷 사이의 변경분은 복구 대상에서 빠지기 때문에 스냅샷 주기가 곧 데이터 손실 허용 범위(RPO)가 됩니다.
이런 목표 수치를 정하고 정기적으로 검증하는 절차는 미국 국립표준기술연구소(NIST)가 발간한 재해복구계획 관련 가이드라인에서도 핵심 항목으로 다루고 있으며, 분산 시스템에서는 샤딩 구조 때문에 노드별 백업 시점이 어긋나지 않도록 조율하는 절차가 특히 중요합니다.
도구별 백업·복구 특성, 표로 정리해 보세요
| 도구 | 백업 방식 | 복구 단위 | PITR 지원 | 복구 시 인덱스 처리 |
|---|---|---|---|---|
| Milvus (milvus-backup) | 컬렉션 단위 풀 백업, 오브젝트 스토리지 저장 | 컬렉션 | 미지원 | 인덱스 메타 포함, 재빌드 최소화 |
| Qdrant | 컬렉션/스토리지 스냅샷 파일 | 컬렉션 | 미지원 | 세그먼트 그대로 복구, 재빌드 불필요 |
| Weaviate | 백업 모듈(backup-s3 등)로 샤드 단위 백업 | 클래스(전체 샤드) | 미지원 | 샤드 파일 그대로 복구 |
| pgvector (PostgreSQL) | pg_dump(논리) 또는 pg_basebackup+WAL(물리) | 논리: DB/테이블, 물리: 클러스터 전체 | 물리 백업 시 지원 | 논리는 재생성 필요, 물리는 불필요 |
표에서 보듯 PITR을 지원하는 조합은 사실상 pgvector의 물리 백업뿐입니다. Milvus·Qdrant·Weaviate는 스냅샷 시점 단위로만 복구가 가능하므로, 스냅샷 주기를 서비스가 감당할 수 있는 데이터 손실 범위에 맞춰 설계해야 합니다.
벡터 DB 백업을 스냅샷 생성 자동화까지만 해두고 안심하는 경우가 많은데, 실제 장애는 복구 단계에서 버전 불일치나 부분 실패, 참조 깨짐 같은 형태로 나타납니다. 지금 쓰고 있는 도구의 백업이 마지막으로 실제 복구까지 검증된 게 언제인지부터 확인해 보시고, 다음 백업 주기가 오기 전에 별도 테스트 인스턴스로 복구 드릴을 한 번 돌려보시기 바랍니다.
