MySQL 8.0 물리 백업 완전 가이드: Percona XtraBackup 8.x와 InnoDB Hot Backup 구조

MySQL 8.0은 내부 구조(redo/undo, data dictionary, transactional DDL 등)가 5.7과 완전히 달라졌다.
따라서 예전처럼 XtraBackup 2.4로는 백업이 불가능하다.
MySQL 8.0 → XtraBackup 8.x,
MySQL 5.7 이하 → XtraBackup 2.4.x
이 조합만이 호환된다.

이 글은 MySQL 8.0 환경에서 **Percona XtraBackup 8.x(PXB 8.x)**을 이용한 무중단(Hot) 물리 백업을 구축하는 전 과정을 다룬다.
설치, 계정 권한, 스크립트, 로그 회전, 크론 스케줄링, 복구, 검증까지 모두 포함한다.


1. XtraBackup 8.x가 필요한 이유

✅ 호환성

MySQL 8.0은 **데이터 딕셔너리(DD tables)**가 InnoDB 내부로 통합되었고 redo/undo 포맷도 변경됐다.
이 구조를 읽을 수 있는 건 XtraBackup 8.x뿐이다.
PXB 2.4.x는 MySQL 5.7 이하까지만 호환된다.

MySQL 버전지원 XtraBackup 버전
MySQL 5.7 이하Percona XtraBackup 2.4.x
MySQL 8.0Percona XtraBackup 8.x

✅ InnoDB Hot Backup 구조

PXB는 InnoDB의 **MVCC(다중 버전 동시성 제어)**와 **redo 로그 재적용(prepare 단계)**을 이용한다.
백업 중에도 데이터 변경이 일어나지만, redo 로그를 읽어 그 시점까지의 변경을 적용하여 Crash-Consistent Snapshot을 만든다.

즉, MySQL 서비스를 중단하지 않고(Hot), 읽기/쓰기 트랜잭션이 진행 중인 상태에서도 일관된 스냅샷을 확보할 수 있다.


✅ FTWRL 최소화와 백업 락(LOCK INSTANCE FOR BACKUP)

MySQL 8.0은 FTWRL(FLUSH TABLES WITH READ LOCK)을 대체할 LOCK INSTANCE FOR BACKUP 명령을 도입했다.
PXB 8.x는 이를 활용해 짧은 순간만 잠금하고 대부분의 백업 구간은 락 없이 진행한다.

  • InnoDB만 사용하는 경우: 거의 완전한 무중단 백업.
  • MyISAM/CSV 혼합 사용: 여전히 락이 필요하므로 --no-lock을 쓰면 안 된다.

2. 설치 (Ubuntu 22.04 기준)

① Percona 레포 추가

wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb

② MySQL 8용 레포 활성화

sudo percona-release setup ps80
sudo apt-get update

③ XtraBackup 8 설치

sudo apt-get install -y percona-xtrabackup-80

④ GPG 오류 제거 (MySQL 레포 비활성화)

MySQL이 이미 설치되어 있다면, 굳이 레포를 유지할 필요가 없다.

sudo mv /etc/apt/sources.list.d/mysql.list /etc/apt/sources.list.d/mysql.list.disabled 2>/dev/null || true
sudo apt-get update

⑤ 의존성 오류 해결

sudo apt --fix-broken install -y
sudo apt install -y libdbd-mysql-perl libcurl4-openssl-dev libev4
sudo apt install -y percona-xtrabackup-80

3. 버전 및 설정 확인

xtrabackup --version
# xtrabackup version 8.0.35-31 based on MySQL server 8.0.35 ...

PXB는 MySQL 설정 파일(my.cnf)을 자동으로 읽어 --datadir, --log_bin, --innodb_buffer_pool_size 등을 인식한다.
설정 파일을 수정하면, 다음 백업 실행부터 자동으로 반영된다.

명시적으로 지정할 수도 있다:

xtrabackup --defaults-file=/etc/mysql/my.cnf --backup --target-dir=/backup/mysql

4. 백업 계정 생성 (MySQL 8.0 권장 방식)

✅ MySQL 8.0 권장 — 단일 권한

CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_pw';
GRANT BACKUP_ADMIN ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;

BACKUP_ADMINLOCK INSTANCE FOR BACKUP, RELOAD, PROCESS, REPLICATION CLIENT 등의 하위 권한을 모두 포함한다.

✅ 구버전 호환 방식 (5.7 이전)

CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_pw';
GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT, PROCESS ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;

5. 풀 백업 스크립트 (날짜별 로그 포함)

/usr/local/bin/mysql_full_backup.sh

#!/bin/bash
set -euo pipefail

# === 기본 설정 ===
BACKUP_ROOT="/backup/mysql"
FULL_DIR="${BACKUP_ROOT}/full/$(date +%F_%H-%M-%S)"
LOG_DIR="${BACKUP_ROOT}/logs"
LOG_FILE="${LOG_DIR}/full_backup_$(date +%F).log"
PARALLEL=4
NOLOCK="--no-lock"   # InnoDB-only 환경일 때만 사용. 혼합 환경이면 주석처리.
XB_USER="backup_user"
XB_PASS="strong_pw"
# ==================

mkdir -p "$FULL_DIR" "$LOG_DIR"

{
  echo "[$(date +%F_%T)] START Full backup -> $FULL_DIR"

  xtrabackup --backup \
    --target-dir="$FULL_DIR" \
    --user="$XB_USER" \
    --password="$XB_PASS" \
    --parallel="$PARALLEL" \
    $NOLOCK

  echo "[$(date +%F_%T)] PREPARE start"
  xtrabackup --prepare --target-dir="$FULL_DIR" --use-memory=4G
  echo "[$(date +%F_%T)] PREPARE done"

  cp -a /etc/mysql/my.cnf "$FULL_DIR"/my.cnf 2>/dev/null || true

  echo "[$(date +%F_%T)] SUCCESS"
} >> "$LOG_FILE" 2>&1

💡 --use-memory는 redo 재적용 시 사용할 메모리 크기.
일반적으로 서버 RAM의 10~20%, 최소 4GB 이상 권장.

권한 설정:

chmod +x /usr/local/bin/mysql_full_backup.sh

6. 크론 자동화

서버가 한국 시간대(KST, UTC+9)면 단순히 03시로 스케줄링하면 된다.
만약 서버 타임존이 UTC라면, KST 03시 = 전날 18:00 UTC로 맞춰야 한다.

crontab -e
# KST 서버
0 3 * * * /usr/local/bin/mysql_full_backup.sh
# UTC 서버에서 KST 03:00 실행
# 0 18 * * * /usr/local/bin/mysql_full_backup.sh

7. 백업 보존 및 로그 정리

/usr/local/bin/cleanup_mysql_backups.sh

#!/bin/bash
set -euo pipefail
find /backup/mysql/full/ -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;
find /backup/mysql/logs/ -type f -name "full_backup_*.log" -mtime +30 -delete
chmod +x /usr/local/bin/cleanup_mysql_backups.sh
crontab -e
0 4 * * * /usr/local/bin/cleanup_mysql_backups.sh

8. 복구 (Restore) 절차

1️⃣ 백업 준비(prepare)
이미 스크립트에서 prepare까지 수행하지만, 미수행된 경우:

xtrabackup --prepare --target-dir=/backup/mysql/full/2025-10-08_03-00-02 --use-memory=4G

2️⃣ MySQL 서비스 중단

sudo systemctl stop mysql
sudo mv /var/lib/mysql /var/lib/mysql.bak.$(date +%s)

3️⃣ 복사 및 권한 복원

xtrabackup --copy-back --target-dir=/backup/mysql/full/2025-10-08_03-00-02
sudo chown -R mysql:mysql /var/lib/mysql

4️⃣ 무결성 점검 및 재시작

sudo systemctl start mysql

5️⃣ 마무리

SET GLOBAL innodb_fast_shutdown=0;

→ 복구된 서버가 클린 상태로 종료되도록 보장한다.


9. InnoDB Hot Backup 개념 요약

항목설명
백업 중 일관성InnoDB는 MVCC로 트랜잭션 간 스냅샷을 유지, redo 로그로 변경분을 재적용
Hot Backup 가능 이유백업 중에도 쓰기 작업 허용, redo/undo 재적용으로 Crash-Consistent 복구
백업 락MySQL 8.0의 LOCK INSTANCE FOR BACKUP으로 FTWRL 없이 메타데이터 보호
–no-lock 사용 기준InnoDB-only 환경에서만 사용 가능, MyISAM이 섞이면 데이터 불일치 위험
prepare 단계redo 재적용 및 checkpoint 정리로 복구 시간 단축
복구 후 innodb_fast_shutdown=0재시작 시 crash recovery 스킵, 안정적 clean start

10. 운영 실무 팁

  • I/O 제어: --parallel, --throttle로 디스크 부하 조절
  • 저장소 분리: 백업은 MySQL 데이터 디스크와 물리적으로 분리된 NFS/SAN 권장
  • 압축: --compress=zstd 또는 OS 레벨 압축 가능
  • 증분 백업: 풀 + 증분 구조 (--incremental)로 용량 절감
  • 모니터링: Zabbix, Prometheus로 백업 성공률/소요시간 트래킹
  • 복구 리허설: 주기적 테스트가 진짜 복구력을 만든다

✅ 요약 체크리스트

항목상태
PXB 8.x 설치 (percona-xtrabackup-80)
백업 계정 (BACKUP_ADMIN) 생성
풀 백업 스크립트 + 로그 회전
prepare 단계 포함 여부 확인
크론 스케줄 (KST/UTC 확인)
7일 보존 / 로그 30일 보존
복구 테스트 및 무결성 검증

이 구성은 MySQL 8.0의 구조적 특성을 정확히 반영한 실무용 무중단 백업 체계다.
PXB 8.x의 Hot Backup 메커니즘과 MySQL 8.0의 BACKUP_ADMIN 권한, prepare 단계 최적화를 조합하면
운영 트래픽에 영향을 거의 주지 않으면서도 완전한 일관성 백업을 확보할 수 있다.

ⓒ 2025 엉뚱한 녀석의 블로그 [quirky guy's Blog]. 본문 및 이미지를 무단 복제·배포할 수 없습니다. 공유 시 반드시 원문 링크를 명시해 주세요.
ⓒ 2025 엉뚱한 녀석의 블로그 [quirky guy's Blog]. All rights reserved. Unauthorized copying or redistribution of the text and images is prohibited. When sharing, please include the original source link.

🛠 마지막 수정일: 2025.10.08