백업과 복구#

그래프는 PostgreSQL 스키마와 테이블로 저장되므로, 모든 PostgreSQL 백업 방법이 그래프를 담으며, 관계형 데이터와 같은 시점으로 담습니다. 따로 받아야 할 그래프 백업도, 따로 맞춰야 할 복원도 없습니다.

그러므로 PostgreSQL의 백업 장이 레퍼런스이고, 이 페이지는 선택지와 그래프에만 해당하는 세부를 다룹니다.

어느 방법을 쓸 것인가#

방법

얻는 것

언제 쓰는가

pg_dump / pg_dumpall

논리적 사본입니다. SQL 문장 또는 아카이브이며, 메이저 버전과 플랫폼을 넘어 이식됩니다.

데이터베이스를 옮길 때, 그래프 하나를 복사할 때, 버전에 매이지 않는 사본을 둘 때.

pg_basebackup

클러스터 전체의 물리적 사본입니다.

시점 복구 구성의 기반, 그리고 복제본을 처음 채울 때.

연속 아카이빙

베이스 백업에 그 뒤의 모든 WAL 세그먼트를 더한 것이며, 어느 순간으로든 복구할 수 있습니다.

운영 환경. 한 시간 치 쓰기를 잃는 것이 용납되지 않는 곳.

파일시스템 스냅샷

스토리지 계층이 뜨는 물리적 사본입니다.

클러스터가 쓰는 모든 파일시스템에 걸쳐 스냅샷이 원자적일 때만.

서버가 도는 중에 cp로 데이터 디렉터리를 복사하는 것은 백업이 아닙니다. 테이블 파일을 하나씩 복사하는 것은 결코 백업이 아닙니다. 커밋 로그는 클러스터 전체의 것이므로, 홀로 떠 온 파일은 자기 행 중 무엇이 커밋됐는지 말할 방법이 없습니다.

논리 백업#

pg_dump -d mydb -Fc -f mydb.dump          # one database, archive format
pg_dumpall -f cluster.sql                  # every database plus roles
pg_dump -d mydb --schema=moviekb -f g.sql  # one graph

복원:

pg_restore --exit-on-error -d mydb mydb.dump
psql -d postgres -f cluster.sql

경고

두 도구 모두 기본값이 오류를 만나도 계속 진행하는 것이고, psql 은 그러고도 종료 코드 0 을 냅니다. 그래서 객체가 빠진 채로 복원이 «성공» 이라고 보고될 수 있습니다 — 서버가 거부한 제약이 있으면 그 테이블은 제약 없이 만들어지고, 그다음부터 아무것도 참조하지 않는 행이 들어갑니다. --exit-on-error 를 주면 pg_restore 가 첫 오류에서 멈춥니다.

psql 에는 ON_ERROR_STOP 이 있지만 pg_dumpall 산출물에는 쓸 수 없습니다. 그 파일은 이미 존재하는 부트스트랩 슈퍼유저를 다시 만들기 때문에, 14행에서 멈추고 아무것도 적재하지 않습니다. 그 경우에는 출력을 직접 읽거나, 데이터베이스마다 pg_dump -Fc 로 따로 덤프해서 pg_restore --exit-on-error 로 복원하십시오.

그래프가 곧 스키마이므로, 그래프 하나를 덤프하는 방법은 그 스키마를 지정하는 것입니다. 덤프에는 데이터와 함께 CREATE GRAPH·CREATE VLABEL·CREATE ELABEL 문장이 담기므로, 복원하면 그래프 구조가 다시 만들어집니다.

그래프에만 해당하는 것 네 가지이며, 자세한 내용은 모두 서버 측 도구에 있습니다:

  • 두 도구 모두 AgensGraph 버전을 검사하지 않고 PostgreSQL 버전만 검사합니다.

  • 평범한 컬럼을 지닌 레이블의 덤프는 복원할 때 enable_graph_ddl이 필요하며, 덤프가 자기 문장을 그것으로 감쌉니다.

  • 어떤 그래프든 승격된 컬럼을 쓰고 있으면 2.18 덤프는 2.17에 복원되지 않습니다.

  • Cypher 쿼리로 만든 뷰는 그 Cypher가 컴파일된 SQL로 덤프됩니다.

어떤 복원이든 끝난 뒤에는 그래프 메타데이터와 통계를 다시 만드십시오:

SET graph_path = <your graph>;
SELECT regather_graphmeta();
vacuumdb -d mydb --analyze-in-stages

물리 백업과 시점 복구#

동작 방식은 PostgreSQL의 것 그대로입니다. 요약하면:

서버를 아카이빙하도록 설정하고 재기동합니다:

wal_level = replica
archive_mode = on
archive_command = 'test ! -f /mnt/archive/%f && cp %p /mnt/archive/%f'

wal_level = minimal은 아카이브에서 복구할 만큼을 기록하지 않으므로, 이 방법을 쓸 수 없게 만듭니다.

베이스 백업을 받습니다:

pg_basebackup -D /mnt/backup/base -Ft -z -P -X stream

복구하려면 베이스 백업을 빈 데이터 디렉터리에 풀고, 아카이브된 WAL을 어디서 가져올지 서버에 알려 줍니다:

restore_command = 'cp /mnt/archive/%f %p'
recovery_target_time = '2026-09-02 14:30:00'

이 값들은 postgresql.conf에 넣고, 데이터 디렉터리에 둔 recovery.signal이라는 빈 파일이 서버를 복구 모드로 들어가게 합니다. 복구가 끝나면 서버는 그 신호 파일을 지우고 접속을 받기 시작합니다.

참고

예전 AgensGraph나 PostgreSQL 문서를 보고 작업한다면 자리를 옮긴 것이 셋 있습니다. 복구 설정은 recovery.conf가 아니라 recovery.signal 파일과 함께 postgresql.conf에 있습니다. 그 파일은 PostgreSQL 12에서 없어졌고, 서버는 그것을 발견하면 기동을 거부합니다. WAL 디렉터리는 pg_xlog가 아니라 pg_wal이고, 커밋 로그는 pg_clog가 아니라 pg_xact입니다. 둘 다 PostgreSQL 10에서 이름이 바뀌었습니다.

베이스 백업에 기대기 전에 그것을 검증하십시오:

pg_verifybackup /mnt/backup/base

더 높은 수준의 도구#

pgBackRest와 Barman은 보관 기간·병렬 압축·증분 백업·복원 절차를 관리하며, 둘 다 그래프에만 해당하는 설정 없이 AgensGraph 클러스터에서 동작합니다. 서버를 둘 이상 운영한다면 손으로 쓴 archive_command보다 어느 쪽이든 더 나은 답입니다.

무엇을 확인할 것인가#

복원해 보지 않은 백업은 백업이 아니라 바람입니다. 특히 그래프라면, 복원 시험은 서버가 뜬다는 것 이상을 확인해야 합니다:

SET graph_path = <your graph>;
MATCH (n) RETURN label(n) AS label, count(*) ORDER BY label;
MATCH ()-[e]->() RETURN label(e) AS label, count(*) ORDER BY label;
SELECT graphname, graphmeta_valid FROM pg_catalog.ag_graph;
SELECT * FROM pg_catalog.ag_property_indexes;

원본과 일치하는 개수, 그리고 인덱스와 제약이 제자리에 있다는 것이 그래프가 온전히 돌아왔음을 말해 줍니다.