예약 백업 및 복구

LinuxBeginner
지금 연습하기

소개

유용한 백업은 단순히 아카이브 명령을 실행하는 것만으로 완성되지 않습니다. 무엇이 포함되어 있는지 확인하고, 읽을 수 있는 상태인지 검증하며, 필요한 파일을 복구하고, 사람이 개입하지 않는 실행도 추적할 수 있어야 합니다.

이 실습에서는 매니페스트를 사용해 작은 애플리케이션 작업 공간을 백업하고, 선택한 파일 하나를 복구합니다. 그런 다음 이 작업을 타임스탬프 기반 스크립트로 만들고 Cron 일정을 등록합니다. 자동화에 사용되는 모든 경로는 절대 경로이므로 작업이 대화형 셸의 현재 디렉터리에 의존하지 않습니다.

매니페스트로 백업 범위 정의하기

이 단계에서는 백업 범위를 명확하게 확인하고 검토할 수 있도록 경로 목록을 일반 텍스트로 작성한 매니페스트를 만듭니다.

작업 공간으로 이동합니다.

cd /home/labex/project/backup-lab

data 디렉터리를 기준으로 하는 상대 경로를 매니페스트에 기록합니다.

cat > backup-manifest.txt <<'EOF'
config/app.conf
documents/runbook.txt
EOF

검토하기 쉽도록 항목에 번호를 붙입니다.

nl -ba backup-manifest.txt

while 루프를 사용해 목록에 있는 모든 원본 파일이 실제로 존재하는지 확인합니다. 실행하기 전에 구조를 살펴보세요.

  • IFS=는 셸이 줄의 시작이나 끝에 있는 공백을 제거하지 않도록 합니다.
  • read -r item은 백슬래시를 특별히 처리하지 않고 한 줄 전체를 item에 읽어 들입니다.
  • do ... done은 각 줄마다 반복해서 실행할 명령을 감쌉니다.
  • < backup-manifest.txt는 매니페스트를 루프의 입력으로 제공합니다.
  • test -f는 해당 경로가 일반 파일인지 확인하며, &&는 검사가 성공한 경우에만 ready를 출력합니다.
while IFS= read -r item; do
  test -f "data/$item" && echo "ready: $item"
done < backup-manifest.txt

목록에 없는 documents/scratch.txt 파일은 의도적으로 이 관리 대상 백업에서 제외되어 있습니다.

매니페스트로 아카이브 만들기

이 단계에서는 tar -T를 사용해 매니페스트에서 파일 이름을 읽습니다. -C data 옵션을 지정하면 아카이브 내부에 짧은 상대 경로가 사용됩니다.

tar -czf backups/manual-backup.tar.gz -C data -T backup-manifest.txt

각 옵션의 의미는 다음과 같습니다.

  • -c: 아카이브를 생성합니다.
  • -z: gzip 으로 압축합니다.
  • -f: 뒤에 지정된 아카이브 파일 이름을 사용합니다.
  • -C data: data를 기준 경로로 작업합니다.
  • -T backup-manifest.txt: 매니페스트에서 백업할 아카이브 구성원을 읽습니다.

생성된 파일을 확인합니다.

ls -lh backups/manual-backup.tar.gz

원본 파일과 타임스탬프 및 크기를 비교합니다.

stat -c '%n size=%s modified=%y' backups/manual-backup.tar.gz data/config/app.conf data/documents/runbook.txt

압축을 풀지 않고 아카이브 검증하기

이 단계에서는 아카이브를 실제로 사용하기 전에 정상 상태인지 테스트합니다. 먼저 gzip 스트림을 검사합니다.

gzip -t backups/manual-backup.tar.gz

출력이 없으면 압축 스트림의 무결성 검사가 통과한 것입니다. 이제 압축을 풀지 않고 tar 구성원 목록을 확인합니다.

tar -tzf backups/manual-backup.tar.gz | tee archive-contents.txt

저장한 목록을 매니페스트와 비교합니다.

diff -u backup-manifest.txt archive-contents.txt

차이가 없어야 합니다. 관리 대상이 아닌 스크래치 파일이 포함되지 않았는지도 확인합니다.

if tar -tzf backups/manual-backup.tar.gz | grep -qx 'documents/scratch.txt'; then
  echo "Unexpected scratch file found"
else
  echo "Archive scope is correct"
fi

선택한 파일 하나 복구하기

이 단계에서는 관련 없는 데이터가 덮어쓰이지 않도록 선택한 파일 하나만 복구합니다. 설정 파일이 실수로 삭제된 상황을 시뮬레이션합니다.

rm data/config/app.conf
test -e data/config/app.conf || echo "app.conf is missing"

별도의 복구 디렉터리에 config/app.conf만 압축 해제합니다.

rm -rf restore/*
tar -xzf backups/manual-backup.tar.gz -C restore config/app.conf

복구된 파일을 확인한 다음 작업 위치로 다시 복사합니다.

cat restore/config/app.conf
cp restore/config/app.conf data/config/app.conf
cmp -s restore/config/app.conf data/config/app.conf && echo "Configuration restored"

요청한 아카이브 구성원만 압축 해제되었습니다.

타임스탬프 기반 백업 스크립트 만들기

이 단계에서는 타임스탬프가 포함된 백업 스크립트를 작성합니다. Cron 은 제한된 환경에서 작업을 시작하므로, 사람이 개입하지 않는 스크립트에서는 절대 경로를 사용해야 합니다.

backup.sh를 생성합니다.

cat > backup.sh <<'EOF'
#!/bin/bash

source_dir=/home/labex/project/backup-lab/data
manifest=/home/labex/project/backup-lab/backup-manifest.txt
backup_dir=/home/labex/project/backup-lab/backups
timestamp=$(date +%Y%m%d-%H%M%S)
archive="$backup_dir/backup-$timestamp.tar.gz"

mkdir -p "$backup_dir"

if [ ! -d "$source_dir" ] || [ ! -f "$manifest" ]; then
  echo "Backup source or manifest is missing" >&2
  exit 1
fi

/bin/tar -czf "$archive" -C "$source_dir" -T "$manifest" || exit 1
/bin/tar -tzf "$archive" > "$archive.contents" || exit 1

echo "Created $archive"
exit 0
EOF

스크립트를 실행 가능하게 만든 뒤 Cron 을 기다리지 말고 지금 바로 테스트합니다.

chmod u+x backup.sh
./backup.sh | tee last-backup.txt
ls -1 backups

타임스탬프 덕분에 실행할 때마다 고유한 파일 이름이 생성됩니다. 함께 생성되는 .contents 파일에는 아카이브에 실제로 포함된 항목이 정확히 기록됩니다.

Cron 일정 등록 및 확인하기

이 단계에서는 개인 Cron 일정을 등록하고 확인합니다. crontab 한 줄은 다섯 개의 일정 필드와 그 뒤에 실행할 명령으로 구성됩니다.

위치 필드 일반적인 범위
1 059
2 023
3 131
4 112
5 요일 07, 일요일은 0 또는 7

별표 *는 허용되는 모든 값을 의미합니다. */5와 같은 단계 표현은 해당 필드에서 5 단위마다 실행한다는 뜻입니다.

minute hour day-of-month month day-of-week command

예를 들어 */5 * * * *는 5 분마다 실행한다는 뜻입니다. 0 2 * * *는 매일 02:00 에 실행한다는 의미입니다.

crontab -e는 편집기에서 개인 crontab 을 엽니다. 신뢰할 수 있는 흐름은 먼저 올바른 항목을 준비해 등록한 다음 작은 대화형 수정을 수행하는 것입니다. 절대 경로를 사용하고 표준 출력과 표준 오류를 모두 기록하는 항목을 만듭니다.

cat > backup.crontab <<'EOF'
*/5 * * * * /home/labex/project/backup-lab/backup.sh >> /home/labex/project/backup-lab/logs/backup.log 2>&1
EOF

내용을 검토하고 등록합니다.

cat backup.crontab
crontab backup.crontab

이제 등록된 crontab 을 Nano 로 엽니다.

EDITOR=nano crontab -e

일정 항목 바로 위 줄에 다음 주석을 추가합니다.

## LabEx managed backup schedule

Ctrl+O를 누른 다음 Enter를 눌러 저장합니다. Ctrl+X를 눌러 Nano 를 종료하고 셸로 돌아갑니다. crontab -l로 Cron 이 실제로 읽을 내용을 확인하고 출력을 저장합니다.

crontab -l | tee installed-crontab.txt

출력에는 주석이 먼저 나오고 그 다음에 5분마다 실행되는 항목이 있어야 합니다. 등록된 결과를 확인하면 일정에 의존하기 전에 편집 실수를 발견할 수 있습니다.

로깅 테스트 및 퍼센트 기호 이스케이프 이해하기

이 단계에서는 백업 로깅을 테스트하고 Cron 에서 퍼센트 기호를 특별하게 처리하는 방식을 알아봅니다. 먼저 예약된 명령을 수동으로 실행합니다.

/home/labex/project/backup-lab/backup.sh >> /home/labex/project/backup-lab/logs/backup.log 2>&1
tail -n 5 logs/backup.log
find backups -maxdepth 1 -type f -name 'backup-*.tar.gz' -printf '%f\n' | sort

타임스탬프는 backup.sh 내부에서 생성되므로 일반적인 % 문자를 그대로 사용해도 안전합니다. 하지만 Cron 은 crontab 명령에 포함된 이스케이프되지 않은 %를 특별하게 처리합니다. 따라서 crontab 한 줄에 date를 직접 넣을 경우 각 퍼센트 기호 앞에 백슬래시를 붙여야 합니다.

나중에 참고할 수 있도록 올바르게 이스케이프한 예제를 저장합니다.

cat > cron-date-example.txt <<'EOF'
0 2 * * * /bin/echo "backup-$(/bin/date +\%Y\%m\%d-\%H\%M\%S)" >> /home/labex/project/backup-lab/logs/date-example.log 2>&1
EOF
cat cron-date-example.txt

현재 등록된 작업은 더 단순한 스크립트 기반 항목으로 유지됩니다. 절대 경로를 사용하고, 각 아카이브에 타임스탬프를 붙이며, 사람이 개입하지 않는 실행 후 확인할 수 있는 로그를 남깁니다.

요약

매니페스트로 백업 범위를 정의하고 tar -T로 아카이브를 만들었으며, 압축을 풀지 않고 아카이브를 검증하고 선택한 파일 하나를 복구했습니다. 이어서 절대 경로를 사용하는 타임스탬프 기반 백업 스크립트를 작성하고 Cron 일정을 등록 및 확인했습니다. 또한 자동 실행의 출력을 로그로 리디렉션하고, date가 crontab 명령에 직접 포함될 때 퍼센트 기호를 이스케이프해야 하는 이유를 배웠습니다.