🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

DB·Application 일관성 백업 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 10. · 10 Views

DB·Application 일관성 백업 완벽 가이드

데이터베이스와 애플리케이션의 일관성을 보장하는 백업 전략을 다룹니다. pg_dump 옵션부터 pre/post 훅 설정, S3 백업 자동화까지 실무에서 바로 적용할 수 있는 백업 시스템 구축 방법을 배웁니다.


목차

  1. pg_dump 옵션과 포맷 선택
  2. pre-backup hook: 서비스 정지/잠금
  3. post-backup hook: 서비스 재개
  4. S3 lifecycle 정책 설정
  5. 백업 메타데이터 관리
  6. post-backup-hook.yml 완성

1. pg dump 옵션과 포맷 선택

어느 날 김개발 씨가 서버 장애를 겪었습니다. 다행히 백업이 있었지만, 복원하려니 파일 형식이 맞지 않아 당황했습니다.

"이 백업 파일, 어떻게 복원하죠?"

pg_dump는 PostgreSQL 데이터베이스를 백업하는 핵심 도구입니다. 포맷 선택에 따라 복원 방식과 압축률이 달라집니다.

custom 포맷은 압축과 선택적 복원을 지원하여 실무에서 가장 많이 사용됩니다.

다음 코드를 살펴봅시다.

# custom 포맷: 압축 + 선택적 복원 가능
pg_dump -h localhost -U postgres -d mydb \
  -F c \
  -f backup.dump

# plain SQL 포맷: 사람이 읽을 수 있음
pg_dump -h localhost -U postgres -d mydb \
  -F p \
  -f backup.sql

# directory 포맷: 병렬 백업/복원 지원
pg_dump -h localhost -U postgres -d mydb \
  -F d \
  -j 4 \
  -f backup_dir/

김개발 씨는 입사 6개월 차 백엔드 개발자입니다. 오늘 아침 긴급 회의가 소집되었습니다.

어젯밤 서버 장애로 데이터베이스 일부가 손상되었고, 백업을 복원해야 하는 상황이 발생했습니다. 다행히 백업 파일은 있었습니다.

하지만 문제가 생겼습니다. 백업 파일을 열어보려 하니 이상한 바이너리 형식이었습니다.

"이거 어떻게 복원하죠?" 김개발 씨는 당황했습니다. 선배 개발자 박시니어 씨가 다가와 파일을 확인했습니다.

"아, 이건 custom 포맷이네요. pg_restore로 복원해야 해요." pg_dump의 세 가지 얼굴 그렇다면 pg_dump의 포맷이란 정확히 무엇일까요?

쉽게 비유하자면, 포맷은 마치 책을 저장하는 방식과 같습니다. 일반 텍스트로 저장할 수도 있고, PDF로 압축할 수도 있고, 챕터별로 나눠 저장할 수도 있습니다.

각 방식마다 장단점이 있듯이, pg_dump의 포맷도 상황에 따라 선택해야 합니다. 왜 포맷 선택이 중요한가 포맷을 잘못 선택하면 어떤 문제가 생길까요?

실제로 많은 초보 개발자들이 기본 설정으로 백업을 받습니다. 그런데 데이터베이스가 100GB가 넘어가면 백업 파일도 똑같이 100GB가 됩니다.

디스크 공간도 문제지만, 네트워크로 전송할 때 시간이 너무 오래 걸립니다. 더 큰 문제는 복원 시점입니다.

전체 데이터베이스를 복원할 필요 없이 특정 테이블만 복원하고 싶은데, plain SQL 포맷으로는 쉽지 않습니다. 수백 줄의 SQL 파일에서 원하는 부분만 찾아야 하기 때문입니다.

custom 포맷의 등장 바로 이런 문제를 해결하기 위해 custom 포맷이 등장했습니다. custom 포맷을 사용하면 자동으로 압축이 적용됩니다.

100GB 데이터베이스가 20GB로 줄어듭니다. 또한 pg_restore를 사용해 특정 테이블만 선택적으로 복원할 수 있습니다.

무엇보다 메타데이터가 함께 저장되어 복원 순서를 자동으로 관리해줍니다. plain SQL 포맷은 언제 쓸까 그렇다면 plain SQL 포맷은 쓸모가 없을까요?

그렇지 않습니다. plain SQL 포맷은 사람이 직접 읽고 수정할 수 있다는 장점이 있습니다.

백업 파일을 열어서 특정 데이터를 확인하거나, 일부 SQL 문을 수정해야 할 때 유용합니다. 또한 psql 명령으로 바로 실행할 수 있어 간단한 백업에는 오히려 더 편리합니다.

directory 포맷의 강력함 대용량 데이터베이스를 다루는 회사라면 directory 포맷을 주목해야 합니다. directory 포맷은 백업을 여러 파일로 나눠 저장합니다.

이렇게 하면 병렬 처리가 가능해집니다. 4개의 CPU 코어를 활용해 동시에 백업하면 속도가 4배 빨라집니다.

복원할 때도 마찬가지입니다. 실무 시나리오 실제 현업에서는 어떻게 활용할까요?

스타트업 A사는 매일 밤 자동 백업을 실행합니다. 데이터베이스 크기가 50GB 정도 됩니다.

처음에는 plain SQL로 백업했는데, 파일 크기가 너무 커서 S3 업로드에 30분이 걸렸습니다. custom 포맷으로 변경하니 압축되어 10GB로 줄었고, 업로드 시간도 8분으로 단축되었습니다.

대기업 B사는 500GB 데이터베이스를 운영합니다. directory 포맷으로 8개 코어를 활용해 병렬 백업을 실행합니다.

기존에 3시간 걸리던 백업이 40분으로 줄어들었습니다. 코드 분석 위의 코드를 자세히 살펴보겠습니다.

첫 번째 예제에서 -F c 옵션이 custom 포맷을 지정합니다. 이 포맷은 자동으로 압축되고, pg_restore로 복원할 수 있습니다.

두 번째 예제의 -F p는 plain SQL 포맷으로, 일반 텍스트 파일이 생성됩니다. 세 번째 예제의 -F d는 directory 포맷이며, -j 4 옵션으로 4개 작업을 병렬 실행합니다.

backup_dir 디렉토리에 여러 파일이 생성됩니다. 선택 기준 그렇다면 어떤 포맷을 선택해야 할까요?

데이터베이스가 10GB 미만이고 간단한 프로젝트라면 plain SQL이 편합니다. 10GB 이상이고 선택적 복원이 필요하다면 custom 포맷이 최선입니다.

100GB 이상의 대용량이고 빠른 백업이 필수라면 directory 포맷을 고려해야 합니다. 마무리 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 설명을 들은 김개발 씨는 pg_restore 명령으로 백업을 성공적으로 복원했습니다. "앞으로는 포맷을 신중하게 선택해야겠어요." 여러분도 백업 전략을 세울 때 포맷 선택을 먼저 고민해 보세요.

작은 선택이 큰 차이를 만들어냅니다.

실전 팁

💡 - custom 포맷은 범용적이고 안전한 선택입니다

  • 백업 파일명에 날짜와 포맷 정보를 포함하세요 (예: backup_20250101_custom.dump)
  • 복원 테스트는 필수입니다. 백업만 하고 복원을 안 해보면 무용지물입니다

2. pre-backup hook: 서비스 정지/잠금

백업 중에 데이터가 변경되면 어떻게 될까요? 김개발 씨는 백업을 받는 동안 사용자가 주문을 계속하는 상황을 목격했습니다.

"이 백업, 정확한 건가요?"

pre-backup hook은 백업 시작 전에 실행되는 스크립트입니다. 애플리케이션 트래픽을 차단하거나 데이터베이스를 읽기 전용으로 전환하여 일관성 있는 백업을 보장합니다.

다음 코드를 살펴봅시다.

#!/bin/bash
# pre-backup-hook.sh

echo "=== Pre-backup: 서비스 정지 시작 ==="

# 1. 애플리케이션 헬스체크 엔드포인트 비활성화
curl -X POST http://localhost:3000/api/admin/maintenance \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -d '{"enabled": true}'

# 2. 진행 중인 요청 완료 대기 (30초)
echo "진행 중인 요청 완료 대기..."
sleep 30

# 3. PostgreSQL 읽기 전용 모드 설정
psql -U postgres -d mydb -c \
  "ALTER DATABASE mydb SET default_transaction_read_only = on;"

echo "=== Pre-backup: 준비 완료 ==="

김개발 씨는 밤 11시, 자동 백업 스크립트를 실행했습니다. 모니터링 대시보드를 보니 백업이 진행되는 동안에도 사용자들이 계속 주문을 하고 있었습니다.

"이렇게 되면 백업 파일이 정확한 시점의 데이터를 담고 있지 않은 거 아닌가요?" 박시니어 씨가 고개를 끄덕였습니다. "맞아요.

백업 중에 데이터가 변경되면 일관성이 깨질 수 있어요. 그래서 pre-backup hook이 필요합니다." 일관성 문제란 무엇인가 쉽게 비유하자면, 백업은 마치 사진을 찍는 것과 같습니다.

사진을 찍는 동안 사람들이 계속 움직이면 흐릿한 사진이 나옵니다. 마찬가지로 백업하는 동안 데이터가 계속 변경되면 정확한 스냅샷을 얻을 수 없습니다.

특히 문제가 되는 경우는 트랜잭션이 진행 중일 때입니다. 주문 테이블은 백업되었는데 결제 테이블은 아직 백업 전이라면, 복원 후 데이터 불일치가 발생합니다.

왜 서비스를 정지해야 할까 그렇다면 왜 서비스를 정지해야 할까요? 백업은 백그라운드에서 조용히 하면 안 될까요?

PostgreSQL의 pg_dump는 MVCC 덕분에 일관된 스냅샷을 제공합니다. 하지만 애플리케이션 레벨의 일관성은 보장하지 못합니다.

예를 들어 Redis 캐시와 DB 사이의 일관성, 파일 시스템에 저장된 이미지와 DB 메타데이터의 일관성은 별개의 문제입니다. 또한 장시간 실행되는 트랜잭션이 있으면 백업이 느려집니다.

백업 중에 락이 발생하면 서비스 전체가 느려질 수 있습니다. pre-backup hook의 역할 바로 이런 문제를 해결하기 위해 pre-backup hook을 사용합니다.

pre-backup hook은 백업 시작 전에 자동으로 실행되는 스크립트입니다. 이 스크립트에서 애플리케이션을 점진적으로 정지시키고, 데이터베이스를 안전한 상태로 만듭니다.

단계별 정지 프로세스 급작스러운 서비스 정지는 사용자 경험을 해칩니다. 따라서 단계적으로 접근해야 합니다.

첫 번째 단계는 신규 요청 차단입니다. 로드 밸런서나 헬스체크 엔드포인트를 비활성화하여 새로운 트래픽이 들어오지 못하게 합니다.

두 번째 단계는 진행 중인 요청 완료 대기입니다. 보통 30초에서 1분 정도면 충분합니다.

세 번째 단계는 데이터베이스 읽기 전용 전환입니다. ALTER DATABASE 명령으로 모든 쓰기 작업을 차단합니다.

이제 안전하게 백업을 시작할 수 있습니다. 코드 분석 위의 스크립트를 자세히 살펴보겠습니다.

첫 번째 curl 명령은 애플리케이션의 관리자 API를 호출합니다. maintenance 모드를 활성화하면 헬스체크가 실패하고, 로드 밸런서가 해당 인스턴스로 트래픽을 보내지 않습니다.

sleep 30 명령은 진행 중인 요청이 완료될 시간을 줍니다. 마지막 psql 명령은 데이터베이스를 읽기 전용으로 전환합니다.

이제 SELECT는 가능하지만 INSERT, UPDATE, DELETE는 실패합니다. 실무에서의 고민 하지만 실무에서는 완전한 서비스 정지가 불가능한 경우가 많습니다.

24시간 운영되는 글로벌 서비스라면 어떻게 할까요? 이런 경우 리드 레플리카를 활용합니다.

프라이머리 DB는 계속 서비스하고, 레플리카에서 백업을 받습니다. 약간의 복제 지연은 있지만, 서비스 중단 없이 백업할 수 있습니다.

또 다른 방법은 백업 시간대를 신중하게 선택하는 것입니다. 새벽 3시처럼 트래픽이 가장 적은 시간대를 선택하면, 짧은 정지 시간도 사용자에게 거의 영향을 주지 않습니다.

모니터링과 알림 pre-backup hook이 실패하면 어떻게 될까요? 스크립트에 에러 핸들링을 추가해야 합니다.

헬스체크 비활성화가 실패하면 백업을 중단하고 알림을 보냅니다. DB 읽기 전용 전환이 실패해도 마찬가지입니다.

백업은 성공했지만 일관성이 보장되지 않는 것보다, 백업 실패를 명확히 아는 것이 낫습니다. 정리 김개발 씨는 pre-backup hook을 추가한 후 안심하고 백업을 실행할 수 있게 되었습니다.

"이제 백업 파일을 신뢰할 수 있어요." 여러분도 백업 스크립트를 작성할 때 pre-backup hook을 꼭 포함하세요. 일관성은 백업의 생명입니다.

실전 팁

💡 - 스크립트는 멱등성을 갖도록 작성하세요 (여러 번 실행해도 같은 결과)

  • 타임아웃을 반드시 설정하세요 (무한 대기 방지)
  • 로그를 상세하게 남겨 문제 발생 시 디버깅이 쉽도록 하세요

3. post-backup hook: 서비스 재개

백업이 끝났는데 서비스가 계속 정지 상태였습니다. 사용자들이 접속 오류를 겪고 있었습니다.

"백업은 성공했는데, 서비스는 왜 안 돌아오죠?"

post-backup hook은 백업 완료 후 자동으로 실행되는 스크립트입니다. 데이터베이스를 쓰기 가능 상태로 복구하고, 애플리케이션 트래픽을 재개하여 서비스를 정상화합니다.

다음 코드를 살펴봅시다.

#!/bin/bash
# post-backup-hook.sh

echo "=== Post-backup: 서비스 재개 시작 ==="

# 1. PostgreSQL 쓰기 모드 복구
psql -U postgres -d mydb -c \
  "ALTER DATABASE mydb SET default_transaction_read_only = off;"

# 2. 커넥션 풀 재시작 (stale connection 제거)
curl -X POST http://localhost:3000/api/admin/pool/restart \
  -H "Authorization: Bearer $ADMIN_TOKEN"

# 3. 헬스체크 엔드포인트 활성화
curl -X POST http://localhost:3000/api/admin/maintenance \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -d '{"enabled": false}'

# 4. 백업 성공 알림 전송
echo "백업 완료: $(date)" | \
  mail -s "DB Backup Success" admin@company.com

echo "=== Post-backup: 서비스 재개 완료 ==="

김개발 씨는 새벽 2시, 백업 완료 메시지를 확인했습니다. "백업 성공!

이제 자도 되겠네." 그런데 5분 후 슬랙에 긴급 메시지가 쏟아졌습니다. "사이트가 안 열려요!" "주문이 안 돼요!" 모니터링 대시보드를 확인하니 애플리케이션은 여전히 maintenance 모드였습니다.

백업은 끝났지만 서비스가 재개되지 않았던 것입니다. 박시니어 씨가 새벽에 전화를 받고 말했습니다.

"post-backup hook을 안 만들었구나. 수동으로 복구해야겠어요." 복구의 중요성 쉽게 비유하자면, pre-backup hook은 공사 시작 전 도로를 통제하는 것이고, post-backup hook은 공사 후 도로를 다시 개방하는 것입니다.

공사는 끝났지만 통제를 해제하지 않으면 차들이 지나갈 수 없습니다. 마찬가지로 백업이 끝났지만 데이터베이스가 여전히 읽기 전용이라면, 애플리케이션은 모든 쓰기 작업에서 에러를 발생시킵니다.

자동화의 필요성 왜 post-backup hook을 자동화해야 할까요? 수동으로 복구하면 안 될까요?

사람은 실수합니다. 특히 새벽 시간대에는 더욱 그렇습니다.

백업 스크립트를 실행하고 복구를 깜빡하면, 서비스 장애가 발생합니다. 또한 백업이 실패했을 때 부분적으로 복구된 상태로 남을 수 있습니다.

자동화하면 이런 휴먼 에러를 방지할 수 있습니다. 백업 성공 여부와 관계없이 항상 복구 절차가 실행됩니다.

복구 순서의 중요성 post-backup hook에서 순서는 매우 중요합니다. 먼저 데이터베이스를 쓰기 가능 상태로 복구해야 합니다.

그다음 커넥션 풀을 재시작합니다. 읽기 전용 모드에서 생성된 커넥션은 여전히 쓰기를 시도하다 실패할 수 있기 때문입니다.

커넥션 풀이 재시작되면 헬스체크를 활성화합니다. 로드 밸런서가 다시 트래픽을 보내기 시작합니다.

마지막으로 백업 성공을 알립니다. 코드 분석 위의 스크립트를 단계별로 살펴보겠습니다.

첫 번째 psql 명령은 데이터베이스를 쓰기 가능 상태로 되돌립니다. default_transaction_read_only를 off로 설정하면 모든 트랜잭션이 다시 쓰기를 할 수 있습니다.

두 번째 curl 명령은 애플리케이션의 커넥션 풀을 재시작합니다. 이렇게 하면 오래된 커넥션이 제거되고 새로운 커넥션이 생성됩니다.

세 번째 curl 명령은 maintenance 모드를 해제하여 헬스체크가 다시 성공하도록 합니다. 마지막으로 mail 명령으로 관리자에게 백업 완료를 알립니다.

슬랙이나 SMS로 보낼 수도 있습니다. 실패 처리 백업이 실패했을 때는 어떻게 해야 할까요?

post-backup hook은 백업 성공 여부와 관계없이 항상 실행되어야 합니다. 백업이 실패했더라도 서비스는 복구되어야 하기 때문입니다.

따라서 백업 스크립트는 다음과 같은 구조를 가져야 합니다. trap post_backup_hook EXIT pre_backup_hook backup_database trap 명령을 사용하면 스크립트가 어떻게 종료되든 post_backup_hook이 실행됩니다.

실무 시나리오 스타트업 C사는 매일 새벽 3시에 백업을 실행합니다. 백업 시간은 약 10분입니다.

pre-backup hook으로 신규 트래픽을 차단하고, post-backup hook으로 자동 복구합니다. 어느 날 백업이 디스크 부족으로 실패했습니다.

하지만 post-backup hook 덕분에 서비스는 자동으로 재개되었고, 관리자는 아침에 알림을 받고 디스크를 확장했습니다. 서비스 중단 없이 문제를 해결한 것입니다.

모니터링 포인트 post-backup hook이 제대로 실행되었는지 어떻게 확인할까요? 스크립트에 로그를 상세히 남기고, 각 단계의 성공/실패를 기록해야 합니다.

또한 헬스체크 엔드포인트가 정상적으로 응답하는지 자동으로 검증하는 것이 좋습니다. 만약 5분 내에 헬스체크가 복구되지 않으면 긴급 알림을 보내야 합니다.

이렇게 하면 수동 개입이 필요한 상황을 빠르게 파악할 수 있습니다. 정리 김개발 씨는 그날 이후 post-backup hook을 추가했습니다.

이제 백업이 자동으로 실행되고, 서비스도 자동으로 재개됩니다. "이제 안심하고 잘 수 있어요." 백업은 정지와 복구가 한 쌍입니다.

pre-backup hook과 post-backup hook을 함께 구성해야 완전한 백업 시스템이 됩니다.

실전 팁

💡 - trap 명령으로 스크립트 종료 시 항상 복구되도록 보장하세요

  • 각 단계마다 성공 여부를 확인하고 로그를 남기세요
  • 복구 후 실제 쓰기 작업이 가능한지 테스트 쿼리를 실행해 보세요

4. S3 lifecycle 정책 설정

백업 파일이 계속 쌓이더니 어느새 S3 비용이 급증했습니다. 김개발 씨는 청구서를 보고 놀랐습니다.

"백업 파일 보관에 이렇게 돈이 들다니!"

S3 lifecycle 정책은 백업 파일의 보관 기간과 스토리지 클래스를 자동으로 관리합니다. 오래된 백업은 저비용 스토리지로 이동하거나 삭제하여 비용을 최적화합니다.

다음 코드를 살펴봅시다.

{
  "Rules": [
    {
      "Id": "backup-lifecycle-policy",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "backups/"
      },
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER"
        }
      ],
      "Expiration": {
        "Days": 365
      }
    }
  ]
}

김개발 씨는 회사 이메일을 확인하다 깜짝 놀랐습니다. AWS 청구서에 S3 비용이 지난달보다 3배 늘어나 있었습니다.

"뭐지? 트래픽이 늘어난 것도 아닌데?" 원인을 파악하기 위해 S3 버킷을 열어보니 backups 폴더에 수백 개의 파일이 쌓여 있었습니다.

매일 백업을 하다 보니 1년 치 백업 파일이 모두 Standard 스토리지에 저장되어 있었습니다. 박시니어 씨가 말했습니다.

"lifecycle 정책을 설정하지 않았구나. 오래된 백업은 저렴한 스토리지로 옮겨야 해요." S3 스토리지 클래스의 세계 S3에는 여러 스토리지 클래스가 있습니다.

쉽게 비유하자면 창고의 선반 위치와 같습니다. Standard 클래스는 1층 정면 선반입니다.

언제든 빠르게 꺼낼 수 있지만 임대료가 비쌉니다. Standard-IA는 2층 선반입니다.

가격은 저렴하지만 꺼낼 때 비용이 조금 듭니다. Glacier는 지하 창고입니다.

가격은 매우 저렴하지만 꺼내는 데 몇 시간이 걸립니다. 백업 파일의 생명주기 백업 파일은 시간이 지날수록 접근 빈도가 줄어듭니다.

최근 7일 이내의 백업은 자주 조회됩니다. 장애가 발생하면 가장 먼저 찾는 파일들입니다.

하지만 30일이 지나면 거의 접근하지 않습니다. 1년이 지나면 규정상 보관해야 하지만 실제로는 거의 쓸 일이 없습니다.

따라서 백업 파일의 생명주기에 맞춰 스토리지 클래스를 변경하면 비용을 크게 절감할 수 있습니다. lifecycle 정책의 마법 바로 이런 작업을 자동화하는 것이 lifecycle 정책입니다.

위의 JSON 설정을 S3 버킷에 적용하면, S3가 알아서 파일을 관리합니다. 30일이 지나면 Standard-IA로 이동하고, 90일이 지나면 Glacier로 이동합니다.

365일이 지나면 자동으로 삭제됩니다. 개발자는 아무것도 할 필요가 없습니다.

S3가 매일 밤 정책을 확인하고 조건에 맞는 파일을 자동으로 이동하거나 삭제합니다. 정책 설정 분석 위의 JSON 코드를 자세히 살펴보겠습니다.

Filter의 Prefix는 정책을 적용할 대상을 지정합니다. "backups/" 폴더의 파일만 관리합니다.

다른 폴더의 파일은 영향을 받지 않습니다. Transitions 배열은 스토리지 클래스 변경 규칙입니다.

30일 후 Standard-IA로, 90일 후 Glacier로 이동합니다. Expiration은 365일 후 파일을 삭제합니다.

비용 절감 효과 실제로 얼마나 절감될까요? Standard 스토리지는 GB당 월 0.023달러입니다.

Standard-IA는 0.0125달러, Glacier는 0.004달러입니다. 매일 10GB 백업을 1년간 보관한다고 가정해봅시다.

lifecycle 정책 없이 모두 Standard에 보관하면 연간 약 1,000달러가 듭니다. 하지만 정책을 적용하면 최근 30일만 Standard에, 나머지는 저렴한 스토리지에 보관하여 연간 약 300달러로 줄어듭니다.

70% 비용 절감입니다. 실무 시나리오 스타트업 D사는 매일 50GB 백업을 생성합니다.

처음에는 아무 정책 없이 보관했다가 월 S3 비용이 500달러를 넘었습니다. lifecycle 정책을 적용한 후 비용이 150달러로 줄었습니다.

더 나아가 7일 이내의 백업만 Standard에 두고, 나머지는 바로 Standard-IA로 이동하도록 정책을 수정했습니다. 월 비용이 100달러까지 내려갔습니다.

보관 기간 전략 얼마나 오래 백업을 보관해야 할까요? 법적 규정이 있는 산업이라면 그 기간을 따라야 합니다.

금융권은 보통 7년, 의료는 10년입니다. 일반 서비스라면 1년 정도면 충분합니다.

실무에서는 3-2-1 백업 규칙을 따르는 것이 좋습니다. 3개의 복사본을 2개의 다른 매체에 보관하고, 1개는 오프사이트에 둡니다.

S3 Glacier는 오프사이트 장기 보관용으로 완벽합니다. 주의사항 lifecycle 정책을 설정할 때 주의할 점이 있습니다.

Glacier로 이동한 파일을 복원하려면 시간이 걸립니다. Expedited 옵션은 1-5분, Standard는 3-5시간, Bulk는 5-12시간입니다.

긴급 복구가 필요한 백업은 최소 30일은 Standard-IA에 두는 것이 좋습니다. 또한 Glacier와 Deep Archive는 최소 보관 기간이 있습니다.

90일 이전에 삭제하면 남은 기간만큼 비용이 청구됩니다. 정책 설계 시 이를 고려해야 합니다.

정리 김개발 씨는 lifecycle 정책을 설정한 후 S3 비용이 정상화되었습니다. "이제 백업을 마음 놓고 쌓을 수 있어요." 백업 파일은 자동으로 관리되어야 합니다.

lifecycle 정책은 비용 절감과 관리 효율을 동시에 가져다줍니다.

실전 팁

💡 - 처음 30일은 Standard-IA, 90일 이후 Glacier가 일반적인 전략입니다

  • 정책 적용 전 비용 계산기로 시뮬레이션해 보세요
  • 백업 복원 테스트 시 Glacier 복원 시간도 고려하세요

5. 백업 메타데이터 관리

백업 파일은 많은데, 어떤 파일이 언제 생성되었고 무엇을 담고 있는지 알 수가 없었습니다. "이 파일, 복원해도 되는 건가요?"

백업 메타데이터는 백업의 생성 시각, 크기, 데이터베이스 버전, 일관성 검증 결과 등을 기록합니다. 이를 통해 복원 시점 선택백업 품질 관리가 가능해집니다.

다음 코드를 살펴봅시다.

#!/bin/bash
# backup-with-metadata.sh

BACKUP_ID=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="backup_${BACKUP_ID}.dump"
METADATA_FILE="backup_${BACKUP_ID}.json"

# 백업 실행
pg_dump -h localhost -U postgres -d mydb -F c -f $BACKUP_FILE

# 메타데이터 수집
DB_VERSION=$(psql -U postgres -d mydb -t -c "SELECT version();")
DB_SIZE=$(psql -U postgres -d mydb -t -c "SELECT pg_database_size('mydb');")
FILE_SIZE=$(stat -f%z $BACKUP_FILE)
CHECKSUM=$(sha256sum $BACKUP_FILE | awk '{print $1}')

# JSON 메타데이터 생성
cat > $METADATA_FILE <<EOF
{
  "backup_id": "$BACKUP_ID",
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "database": "mydb",
  "db_version": "$DB_VERSION",
  "db_size_bytes": $DB_SIZE,
  "file_size_bytes": $FILE_SIZE,
  "checksum": "$CHECKSUM",
  "format": "custom",
  "compression": true
}
EOF

# S3 업로드 (메타데이터도 함께)
aws s3 cp $BACKUP_FILE s3://my-bucket/backups/
aws s3 cp $METADATA_FILE s3://my-bucket/backups/metadata/

김개발 씨는 장애 복구 중이었습니다. S3 버킷에 수백 개의 백업 파일이 있었습니다.

"어떤 파일로 복원해야 하지? 이 파일은 정상적으로 백업된 건가?" 파일 이름만으로는 알 수 없었습니다.

파일을 다운로드해서 pg_restore로 검증해야 했습니다. 10GB 파일을 다운로드하는 데만 5분이 걸렸습니다.

그런데 복원을 시도하니 파일이 손상되었다는 에러가 발생했습니다. 박시니어 씨가 한숨을 쉬었습니다.

"메타데이터를 기록했어야 하는데. 백업 파일만 있어서는 관리가 안 돼요." 메타데이터란 무엇인가 쉽게 비유하자면, 메타데이터는 책의 목차와 같습니다.

책 내용은 백업 파일이고, 목차는 메타데이터입니다. 목차를 보면 책을 펼치지 않아도 무엇이 담겨 있는지, 언제 출판되었는지, 몇 페이지인지 알 수 있습니다.

마찬가지로 메타데이터를 보면 백업 파일을 열지 않아도 필요한 정보를 파악할 수 있습니다. 왜 메타데이터가 필요한가 백업 파일만 있으면 안 될까요?

복원할 때 열어보면 되지 않을까요? 문제는 백업 파일이 클수록 이 과정이 느리다는 것입니다.

100GB 파일을 다운로드해서 검증하는 데 한 시간이 걸립니다. 장애 상황에서는 1분 1초가 중요한데, 이런 시간 낭비는 치명적입니다.

또한 백업의 무결성 검증도 중요합니다. 백업 파일이 전송 중 손상되었을 수 있습니다.

메타데이터에 체크섬을 기록하면 파일을 열지 않아도 무결성을 확인할 수 있습니다. 메타데이터에 담아야 할 정보 그렇다면 어떤 정보를 기록해야 할까요?

필수 항목은 백업 ID, 생성 시각, 데이터베이스 이름입니다. 이것만 있어도 어떤 백업인지 식별할 수 있습니다.

추가로 데이터베이스 버전, 원본 크기, 백업 파일 크기를 기록하면 호환성과 압축률을 파악할 수 있습니다. 체크섬은 무결성 검증에 필수입니다.

백업 포맷압축 여부도 복원 방법을 결정하는 데 도움이 됩니다. 코드 분석 위의 스크립트를 자세히 살펴보겠습니다.

먼저 BACKUP_ID를 타임스탬프로 생성합니다. 이것은 백업의 고유 식별자가 됩니다.

pg_dump로 백업을 생성한 후, psql 명령으로 데이터베이스 버전과 크기를 조회합니다. stat 명령으로 백업 파일 크기를 얻고, sha256sum으로 체크섬을 계산합니다.

이 모든 정보를 JSON 파일로 저장합니다. JSON 형식은 사람이 읽기 쉽고 프로그램으로 파싱하기도 편합니다.

마지막으로 백업 파일과 메타데이터 파일을 모두 S3에 업로드합니다. 메타데이터는 별도 폴더에 저장하여 빠르게 조회할 수 있도록 합니다.

메타데이터 활용 메타데이터가 있으면 무엇이 좋아질까요? 복원할 백업을 선택할 때, 메타데이터만 다운로드해서 확인할 수 있습니다.

몇 KB의 JSON 파일을 조회하는 것이 GB 단위 백업 파일을 다운로드하는 것보다 훨씬 빠릅니다. 또한 백업 통계를 쉽게 생성할 수 있습니다.

최근 30일간 백업 크기 추이, 압축률 변화, 백업 성공률 등을 시각화할 수 있습니다. 이런 정보는 용량 계획과 정책 개선에 유용합니다.

무결성 검증 체크섬은 어떻게 활용할까요? S3에서 백업 파일을 다운로드한 후, 즉시 체크섬을 계산하여 메타데이터의 값과 비교합니다.

일치하지 않으면 파일이 손상된 것이므로 다른 백업을 선택해야 합니다. 또한 정기적으로 백업 파일의 무결성을 검증하는 스크립트를 실행할 수 있습니다.

월 1회 모든 백업의 체크섬을 확인하여 조용히 손상된 파일을 미리 발견할 수 있습니다. 실무 시나리오 스타트업 E사는 메타데이터 관리 시스템을 구축했습니다.

PostgreSQL 테이블에 백업 메타데이터를 저장하고, 웹 대시보드에서 조회할 수 있도록 만들었습니다. 장애 발생 시 대시보드에서 "장애 시점 이전의 정상 백업"을 필터링하여 즉시 찾을 수 있습니다.

파일 크기와 복원 예상 시간도 표시되어 의사결정이 빠릅니다. 복구 시간이 2시간에서 20분으로 단축되었습니다.

메타데이터 저장소 메타데이터를 어디에 저장할까요? 간단한 방법은 백업 파일과 함께 S3에 JSON 파일로 저장하는 것입니다.

하지만 검색과 통계 생성을 위해서는 데이터베이스에 저장하는 것이 좋습니다. PostgreSQL 테이블을 만들어 백업 메타데이터를 저장하면 SQL로 쿼리할 수 있습니다.

"최근 7일간 성공한 백업 중 크기가 가장 작은 것"같은 복잡한 조건도 쉽게 검색할 수 있습니다. 정리 김개발 씨는 메타데이터 시스템을 구축한 후 백업 관리가 한결 쉬워졌습니다.

"이제 어떤 백업이 좋은지 한눈에 알 수 있어요." 백업 파일만큼 메타데이터도 중요합니다. 작은 투자로 큰 효율을 얻을 수 있습니다.

실전 팁

💡 - 메타데이터는 JSON 형식으로 저장하면 확장이 쉽습니다

  • 체크섬 계산은 백업 직후 즉시 하세요 (나중에 하면 의미 없음)
  • 메타데이터도 백업하세요 (S3 버전 관리 활성화)

6. post-backup-hook.yml 완성

백업 스크립트의 모든 조각이 준비되었습니다. 이제 이것들을 하나로 묶어야 합니다.

"어떻게 통합하면 좋을까요?"

post-backup-hook.yml은 백업 완료 후 실행되는 모든 작업을 정의하는 설정 파일입니다. 서비스 복구, S3 업로드, 메타데이터 기록, 알림 전송을 자동화합니다.

다음 코드를 살펴봅시다.

# post-backup-hook.yml
version: '1.0'

steps:
  - name: "서비스 복구"
    type: script
    script: |
      psql -U postgres -d mydb -c \
        "ALTER DATABASE mydb SET default_transaction_read_only = off;"
      curl -X POST http://localhost:3000/api/admin/pool/restart
      curl -X POST http://localhost:3000/api/admin/maintenance -d '{"enabled": false}'

  - name: "백업 파일 압축 및 암호화"
    type: script
    script: |
      gzip -9 ${BACKUP_FILE}
      openssl enc -aes-256-cbc -salt -in ${BACKUP_FILE}.gz \
        -out ${BACKUP_FILE}.gz.enc -pass pass:${ENCRYPTION_KEY}

  - name: "S3 업로드"
    type: s3
    source: "${BACKUP_FILE}.gz.enc"
    destination: "s3://my-bucket/backups/${BACKUP_ID}/"
    metadata:
      backup-id: "${BACKUP_ID}"
      timestamp: "${TIMESTAMP}"

  - name: "메타데이터 저장"
    type: database
    query: |
      INSERT INTO backup_logs (backup_id, timestamp, file_size, checksum, status)
      VALUES ('${BACKUP_ID}', NOW(), ${FILE_SIZE}, '${CHECKSUM}', 'success');

  - name: "알림 전송"
    type: notification
    slack:
      webhook: "${SLACK_WEBHOOK}"
      message: "백업 완료: ${BACKUP_ID} (${FILE_SIZE_MB}MB)"

김개발 씨는 지금까지 배운 모든 것을 정리하고 있었습니다. pre-backup hook으로 서비스를 안전하게 정지하고, pg_dump로 백업을 생성하고, 메타데이터를 기록하고, S3에 업로드하고, post-backup hook으로 서비스를 복구하는 전체 과정이 머릿속에 그려졌습니다.

"이 모든 것을 하나의 설정 파일로 관리할 수 있다면 좋을 텐데." 박시니어 씨가 웃으며 말했습니다. "그게 바로 post-backup-hook.yml이에요." 설정 파일 기반 자동화 쉽게 비유하자면, post-backup-hook.yml은 마치 요리 레시피와 같습니다.

재료(백업 파일)와 조리 과정(각 단계)이 명확히 정의되어 있어, 누가 실행하든 같은 결과를 얻을 수 있습니다. 코드로 하드코딩하는 대신 YAML 설정 파일로 관리하면 유지보수가 쉽습니다.

순서를 바꾸거나 단계를 추가하는 것이 간단합니다. 선언적 설정의 힘 왜 YAML 형식을 사용할까요?

YAML은 선언적입니다. "어떻게 할지"가 아니라 "무엇을 할지"를 선언합니다.

"서비스 복구"라는 이름의 단계가 있고, 그 단계에서 실행할 스크립트가 명시되어 있습니다. 이렇게 하면 백업 프로세스를 한눈에 파악할 수 있습니다.

또한 각 단계가 독립적이므로 테스트와 디버깅이 쉽습니다. 단계별 분석 위의 YAML 파일을 단계별로 살펴보겠습니다.

첫 번째 단계는 서비스 복구입니다. 데이터베이스를 쓰기 가능 상태로 되돌리고, 커넥션 풀을 재시작하고, maintenance 모드를 해제합니다.

이것은 post-backup hook의 핵심입니다. 두 번째 단계는 압축 및 암호화입니다.

gzip으로 백업 파일을 압축하여 크기를 줄이고, openssl로 암호화하여 보안을 강화합니다. 민감한 데이터가 포함된 백업은 반드시 암호화해야 합니다.

S3 업로드 단계 세 번째 단계는 S3 업로드입니다. 압축되고 암호화된 파일을 S3에 업로드합니다.

destination에는 백업 ID를 포함한 경로를 지정하여 파일을 체계적으로 관리합니다. metadata 섹션에서 S3 객체 메타데이터를 설정하면, S3 콘솔에서 파일을 클릭했을 때 백업 정보를 즉시 확인할 수 있습니다.

메타데이터 저장 네 번째 단계는 메타데이터 저장입니다. 백업 정보를 PostgreSQL 테이블에 기록합니다.

backup_logs 테이블에 백업 ID, 생성 시각, 파일 크기, 체크섬, 상태를 저장합니다. 이 데이터는 나중에 백업 이력 조회와 통계 생성에 활용됩니다.

알림 전송 다섯 번째 단계는 알림 전송입니다. 슬랙 웹훅으로 백업 완료 메시지를 보냅니다.

팀원들이 백업 상태를 실시간으로 파악할 수 있습니다. 백업 크기도 함께 표시하여 용량 추이를 모니터링할 수 있습니다.

에러 핸들링 각 단계가 실패하면 어떻게 될까요? YAML 파일에는 보이지 않지만, 백업 스크립트는 각 단계의 종료 코드를 확인합니다.

단계가 실패하면 즉시 중단하고 에러 알림을 보냅니다. 예를 들어 S3 업로드가 실패하면, 메타데이터 저장과 알림 전송은 실행되지 않습니다.

또한 각 단계는 타임아웃을 가집니다. S3 업로드가 10분 이상 걸리면 네트워크 문제로 판단하고 재시도합니다.

실무 시나리오 대기업 F사는 수십 개의 데이터베이스를 운영합니다. 각 데이터베이스마다 백업 정책이 다릅니다.

중요한 DB는 매일, 덜 중요한 DB는 주 1회 백업합니다. 처음에는 각 DB마다 별도 스크립트를 관리했습니다.

그러다 post-backup-hook.yml 형식을 도입하면서 설정만 다르고 로직은 동일한 구조로 통일했습니다. 새로운 DB를 추가할 때 YAML 파일만 복사하고 수정하면 됩니다.

템플릿 변수 YAML 파일에 ${BACKUP_ID}, ${TIMESTAMP} 같은 변수가 보입니다. 이것은 어떻게 채워질까요?

백업 스크립트가 실행될 때 환경 변수로 제공됩니다. BACKUP_ID는 스크립트 시작 시 생성되고, TIMESTAMP는 현재 시각입니다.

이렇게 하면 YAML 파일을 수정하지 않고도 매번 다른 값을 사용할 수 있습니다. 확장 가능한 구조 post-backup-hook.yml은 쉽게 확장할 수 있습니다.

새로운 단계를 추가하고 싶다면 steps 배열에 항목을 추가하면 됩니다. 예를 들어 백업 파일을 여러 클라우드에 중복 저장하고 싶다면, "GCS 업로드" 단계를 추가할 수 있습니다.

또한 조건부 실행도 가능합니다. 백업 크기가 일정 이상일 때만 Glacier로 바로 업로드하는 식으로 분기할 수 있습니다.

정리 김개발 씨는 post-backup-hook.yml을 작성하고 나서 뿌듯했습니다. "이제 백업 시스템이 완벽해졌어요.

설정 파일만 보면 전체 흐름을 이해할 수 있어요." 백업은 단순히 pg_dump를 실행하는 것이 아닙니다. 일관성 보장, 압축, 암호화, 업로드, 메타데이터 관리, 알림까지 고려해야 합니다.

post-backup-hook.yml은 이 모든 것을 하나로 통합합니다. 여러분도 백업 시스템을 구축할 때 설정 파일 기반으로 접근해 보세요.

유지보수하기 쉽고 확장 가능한 시스템을 만들 수 있습니다.

실전 팁

💡 - YAML 파일은 버전 관리 시스템에 커밋하세요 (변경 이력 추적)

  • 민감한 정보(비밀번호, API 키)는 환경 변수로 주입하세요
  • 각 단계에 설명을 상세히 작성하여 6개월 후에도 이해할 수 있도록 하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#PostgreSQL#pg_dump#backup#S3#automation#DevOps,백업,PostgreSQL

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

S3 이벤트 트리거 완벽 가이드

AWS S3에 파일이 업로드되면 자동으로 Lambda가 실행되는 이벤트 트리거의 원리와 실전 활용법을 배웁니다. 이미지 리사이징, 파일 처리 자동화 등 실무에 바로 적용할 수 있는 패턴을 소개합니다.

AWS 웹 서버 배포 완벽 가이드

EC2 인스턴스에 웹 서버를 구축하고 실제 서비스를 배포하는 과정을 단계별로 배웁니다. Nginx 설정부터 도메인 연결까지, 실무에서 바로 활용할 수 있는 배포 노하우를 담았습니다.

AWS CLI 완벽 가이드 - 설치부터 실전까지

AWS CLI를 처음 접하는 개발자를 위한 완벽 가이드입니다. 설치 방법부터 자격 증명 설정, 실전에서 자주 사용하는 S3와 EC2 명령어까지 실무에 바로 적용할 수 있는 내용을 담았습니다. 베스트셀러 프로그래밍 입문서처럼 술술 읽히는 스타일로 작성되었습니다.

AWS RDS 데이터베이스 생성 완벽 가이드

AWS RDS를 처음 접하는 개발자를 위한 안내서입니다. 데이터베이스 인스턴스 생성부터 서브넷 그룹, 파라미터 그룹 설정까지 실무에 필요한 모든 것을 다룹니다. 초급 개발자도 쉽게 따라할 수 있도록 단계별로 설명합니다.

S3 권한과 정책 완벽 가이드

AWS S3의 권한 모델부터 버킷 정책, ACL, 퍼블릭 접근 차단, 정적 웹 호스팅, CORS 설정까지 실무에서 꼭 필요한 S3 보안과 권한 관리를 초급 개발자도 쉽게 이해할 수 있도록 스토리텔링으로 풀어냅니다.