Blog >> Linux >> Whitepapers.
백업 스크립트 보강 – 통합 및 보고 메일 발송
/etc 디렉토리 백업을 확장해 /etc /host MariaDB 까지 백업하는 스크립트를 개별 작성하고,
시스템 타이머로 규칙적인 일일 백업을 진행하고, 결과를 postfix 로 Daum smtp를 연결해서 메일 발송하는 백업 보강 프로젝트 진행.
이전 작성된 systemd 기반의 자동화 백업 스크립트 참고
각 디렉토리 및 디비 전체 백업 스크립트는 개별 작성.
각 디렉토리 및 디비는 증분 방식으로 백업하고, – 디렉토리 일일 증분, 디비는 10일 주기.
백업 디스크는 USB 타입의 nvme 외장 디스크. systemd 서비스를 통한 백업 전 마운트 백업 후 언 마운트.
# 백업스크립트 3종
custom-backup_etc_snapshot.sh
custom-backup_host_snapshot.sh
custom-backup_mariabackup.sh
# 디비 전체 복구 스크립트는 따로 준비
custom-restore_fulldb.sh
# sytemd 서비스 파일
[Unit]
Description=Custom Professional Backup Service (etc, host and DB Dump)
After=network.target local-fs.target
[Service]
Type=oneshot
User=root
# 프로세스 보호 및 자원 관리
KillMode=process
MemoryMax=2G
# [보완 1] 타임아웃 해제 (대용량 DB 덤프 및 rsync 시 강제 킬 방지)
TimeoutSec=infinity
# 1. 백업 시작 전 1회 마운트 (이미 마운트되어 있으면 정상 통과)
ExecStartPre=/bin/sh -c 'mountpoint -q /mnt/usb || mount /dev/sda1 /mnt/usb'
ExecStartPre=/bin/sh -c 'rm -f /tmp/backup_summary.txt && touch /tmp/backup_summary.txt'
# 2. 본 백업 공정 순차 실행(- 기호를 붙여 실패하더라도 다음 명령을 무조건 실행)
ExecStart=-/usr/local/sbin/custom-backup_etc_snapshot.sh
ExecStart=-/usr/local/sbin/custom-backup_host_snapshot.sh
ExecStart=-/usr/local/sbin/custom-backup_mariabackup.sh
# 3. 종합 메일 1통 발송 및 최종 언마운트
ExecStopPost=/bin/sh -c 'if [ -s /tmp/backup_summary.txt ]; then \
mail -s "[통합보고] $(hostname) 일일 전체 백업 리포트 ($(date +%%Y-%%m-%%d))" phobe@gldigital.co.kr < /tmp/backup_summary.txt; \
rm -f /tmp/backup_summary.txt; \
fi'
# (- 기호로 마운트 해제 에러가 서비스 실패로 이어지지 않도록 방어)
ExecStopPost=-/bin/sh -c 'if mountpoint -q /mnt/usb; then sync && umount /mnt/usb; fi'
[Install]
WantedBy=multi-user.target
# systemd 타이머 파일
[Unit]
Description=Runs Custom Backup Service every day at 2am
[Timer]
# 매일 새벽 2시 정각에 실행
OnCalendar=*-*-* 02:00:00
# 서버가 꺼져 있어 실행 시간을 놓쳤을 경우, 부팅 후 즉시 실행
Persistent=true
# 3시 등 다른 작업과 겹치는 부하를 분산시키기 위한 5분 랜덤 지연 (선택 사항)
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
# 타이머 활성화 상태 및 다음 실행 시각 확인
systemctl list-timers custom-backup.timer
# 타이머 유닛의 활성(Active) 및 부팅 자동 실행(Enabled) 상태 확인
systemctl status custom-backup.timer
# 한 번에 모든 상태를 확인하는 통합 원라이너 명령어
echo "=== [1] 타이머 실행 기록 및 다음 일정 ===" && \
systemctl list-timers custom-backup.timer && \
echo "" && \
echo "=== [2] 서비스 종료 코드 및 systemd 저널 요약 ===" && \
journalctl -u custom-backup.service --since "today" -n 25 --no-pager && \
echo "" && \
echo "=== [3] 스토리지 안전 언마운트 여부 확인 ===" && \
(findmnt /mnt/usb && echo "경고: 아직 마운트되어 있음" || echo "정상: 안전하게 언마운트 완료됨") && \
echo "" && \
echo "=== [4] Postfix 메일 발송 로그 ===" && \
journalctl -u postfix --since "today" -n 15 --no-pager | grep -E "status=sent|to=<등록된메일>"
# 스크립트별 상세 파일 로그 확인 - 먼저 날짜 변수 TODAY 주고
TODAY=$(date +%Y-%m-%d)
[root@204 ~]# tail -n 10 /[스크립트내 로그저장위치]/custom-backup_mariabackup_${TODAY}.log정기 백업이 처음으로 실행된 후, 리포트 결과와 시스템 상태를 대조하여 즉시 점검 사항.
- 통합 메일 리포트 본문 무결성 점검
도착한 [통합보고] 메일을 열어 다음 항목의 값들이 정상 수집되었는지 확인.
소요 시간 및 용량 변수 : 각 섹션의 소요 시간, 이번 스냅샷/백업 디렉터리 크기, 백업 스토리지 여유 공간이 알수없음 으로 찍히지 않고 실제 수치(예: 45M, 234G 가용)로 계산되었는지 확인.
언마운트 상태 문구 일치 여부 : 메일 본문에는 연속 작업 대기 (시스템 일괄 해제 예정)으로 찍혀 있더라도, 백업 종료 후 실제 터미널에서findmnt /mnt/usb를 쳤을 때 마운트가 완전히 풀려 있는지 확인. - MariaDB 증분 백업 체인 및 LSN 연속성 점검
정기 백업을 통해 새로운 증분 디렉터리(inc_20xx-xx-xx 혹은 full_20xx-xx-xx)가 정상적으로 생성되었는지 검증.mountpoint -q /mnt/usb || mount /dev/sda1 /mnt/usbls -ld /mnt/usb/mariadb_phys/2026-10-10_cycle/inc_$(date +%Y-%m-%d)
증분 기준점(LSN) 일치 여부 검증:오늘 생성된 증분 폴더 내부의 xtrabackup_checkpoints 파일을 열어 확인.cat /mnt/usb/mariadb_phys/2026-10-10_cycle/inc_$(date +%Y-%m-%d)/xtrabackup_checkpoints
검증 기준:backup_type = incremental 로 표시되어야 함.
from_lsn 값이 직전 백업본(inc_2026-10-19)의 to_lsn 값과 정확히 일치해야 한다. (LSN 체인이 끊김 없이 연결되어야 향후 복구 스크립트 실행 시 에러가 나지 않는다.)확인 후 언마운트.umount /mnt/usb - I/O 부하 및 I/O 스케줄러 튜닝 점검 스크립트에 적용된 THROTTLE=”nice -n 19 ionice -c 3″ 설정이 새벽 시간대 서버 성능(웹 서비스 등)에 영향을 주지 않았는지 확인.
I/O 병목 여부 저널 점검:journalctl -u custom-backup.service --since "today" --no-pager | grep -iE "timeout|blocked|hung"만약 USB 외장 드라이브 쓰기 속도 저하로 인해 새벽 시간대 웹 응답이 지연되는 현상이 관찰된다면, rsync 옵션에 대역폭 제한(–bwlimit=30M)을 추가하여 버퍼 폭주를 완화하는 방안을 고려할 수 있다. - 오래된 백업 보존 주기(Retention) 자동 삭제 동작 점검.
백업 스크립트 하단의 정리 로직이 정상 작동했는지 확인.
로그 파일 정리 점검:/[로그 저장 지정 폴더]/ 경로에 7일 초과(.log, .log.gz)된 오래된 로그가 실제로 지워졌는지 확인.
스냅샷 디렉터리 보존 점검:/mnt/usb/*_ETC 및 *_HOST 디렉터리 중 보존 기간(7일/14일)을 넘긴 디렉터리가 깔끔하게 삭제되었는지 확인.
latest_etc, latest_host 심볼릭 링크 원본 폴더는 삭제 대상에서 안전하게 제외되었는지 로그 파일의 [과거 스냅샷 정리 완료] 섹션을 통해 점검.
# MariaDB LSN(Log Sequence Number) 체인 연속성 점검.
# 증분 백업 복구의 핵심은 직전 백업의 to_lsn과 오늘 백업의 from_lsn이 오차 없이 일치하는 것.
# 현재 주기의 모든 백업본 LSN 기록을 확인
# 1. 스토리지 임시 마운트 (마운트되어 있지 않은 경우)
mountpoint -q /mnt/usb || sudo mount /dev/sda1 /mnt/usb
# 2. 현재 주기(Cycle)의 모든 풀/증분 백업 LSN 값 확인
for cp in $(ls -d /mnt/usb/mariadb_phys/*_cycle/*/xtrabackup_checkpoints 2>/dev/null | sort); do
echo "=== 디렉터리: $(basename $(dirname $cp)) ==="
grep -E "backup_type|from_lsn|to_lsn" "$cp"
echo ""
done
# 3. 확인 후 스토리지 언마운트
umount /mnt/usb
# 2026-10-20 새벽 2시 백업 완료 후, 신규 증분 디렉터리의 LSN 연속성을 확인하고 판정하는 점검 절차.
# 스토리지 마운트 (마운트되어 있지 않은 경우)
mountpoint -q /mnt/usb || mount /dev/sda1 /mnt/usb
# 직전 백업(10-19)과 오늘 백업(10-20)의 LSN 체크포인트 비교
echo "=== [직전 백업] inc_2026-10-19 ==="
cat /mnt/usb/mariadb_phys/2026-10-10_cycle/inc_2026-10-19/xtrabackup_checkpoints 2>/dev/null
echo ""
echo "=== [오늘 백업] inc_2026-10-20 ==="
cat /mnt/usb/mariadb_phys/2026-10-10_cycle/inc_2026-10-20/xtrabackup_checkpoints 2>/dev/null
# 확인 후 안전 언마운트
umount /mnt/usb
# 정상 LSN 체인 판정 기준
# 두 파일의 출력 결과에서 다음 조건이 만족되어야 정상 연결된 상태이다.
# 사슬 연결 일치 (from_lsn == 직전 to_lsn):
# inc_2026-10-19의 to_lsn 값(현재 기준 2504988)과,
# inc_2026-10-20의 from_lsn 값이 정확히 동일한 숫자여야 한다.
# 백업 모드 확인:
# inc_2026-10-20의 backup_type이 incremental로 기록되어 있어야 한다.


