---
title: "Percona XtraBackup 개요: 온라인 물리 백업의 동작 원리"
description: "Percona XtraBackup의 데이터 파일·redo 복사와 prepare 원리를 설명하고, 미커밋 변경이 있는 백업의 실제 복원과 운영 주의점을 확인한다."
tags: [ MySQL, 백업복구, InnoDB, 운영 ]
image: "mysql-report-bg.png"
published: "2026-09-26"
updated: "2026-09-26"
author: "MySQL 기술 노트"
source_url: ""
---

대용량 MySQL을 복구할 때 논리 백업은 테이블을 다시 만들고 행과 인덱스를 재구성하는 시간이 길어질 수 있다. Percona XtraBackup은 InnoDB 데이터 파일을 물리적으로 복사하므로 이러한 재구성 비용을 줄일 수 있다. 그러나 실행 중인 서버의 파일을 복사하는 것만으로 일관된 데이터베이스가 만들어지지는 않는다.

핵심은 **서로 다른 시점에 복사한 페이지를 redo로 복구하고, 복구 경계에서 미완료인 일반 트랜잭션을 undo로 되돌리는 것**이다. 따라서 백업 파일 생성, prepare, 파일 배치, 서버 기동, 업무 데이터 검증은 각각 별도의 성공 조건이다. `--backup`의 성공을 복구 완료로 해석해서는 안 된다.

이 글은 Community MySQL 8.0의 InnoDB 전체 백업을 중심으로 설명한다. 실제 실험에서는 MySQL **8.0.46**과 Percona XtraBackup **8.0.35-36**을 사용하여 백업부터 별도 데이터 디렉터리의 서버 기동까지 확인했다. 암호화 테이블스페이스, 증분 체인, binlog 재적용, Aurora 가져오기는 실험 범위에 포함하지 않는다.

## 1. 논리 백업과 다른 복구 단위

논리 백업은 테이블 정의와 행 값을 SQL 또는 별도 데이터 파일로 내보낸다. 물리 백업은 InnoDB가 이미 구성해 둔 페이지, 인덱스, 테이블스페이스와 복구에 필요한 파일을 보존한다. 두 방식의 차이는 파일 확장자가 아니라 **복원 시 무엇을 다시 만들어야 하는가**에 있다.

| 구분 | 논리 백업 | XtraBackup 물리 백업 |
|---|---|---|
| 주된 단위 | 객체 정의와 행 | 데이터 페이지와 복구용 파일 |
| 복원 비용 | 행 입력, 인덱스 재구성 등 | 파일 배치, prepare, 서버 복구 등 |
| 호환성의 중심 | SQL 문법·자료형·객체 기능 | 서버 계열·물리 형식·도구 버전 |
| 선택 복원 | 테이블·객체 단위로 다루기 상대적으로 쉬움 | 전체 인스턴스 복구가 기본이며 부분 복원은 별도 제약 존재 |
| 백업 시 서비스 영향 | 읽기 부하, 스냅샷·잠금 유지 비용 | 파일 읽기, redo 추적, 잠금·DDL 조정 비용 |

물리 백업이 언제나 더 빠르다는 뜻은 아니다. 원본 읽기 대역폭, 백업 저장소 쓰기 속도, 압축 CPU, 복원 경로와 저장소 성능에 따라 병목이 달라진다. 다만 대량의 행을 다시 입력하지 않는다는 점은 대용량 복구에서 중요한 이점이다.

또한 `--host`로 서버에 접속할 수 있다고 원격 데이터 파일까지 SQL 연결로 가져오는 것은 아니다. XtraBackup 실행 프로세스에는 **원본 데이터 파일에 대한 파일시스템 접근**이 필요하다. 컨테이너에서는 네트워크 연결과 데이터 볼륨 마운트를 별도로 설계해야 한다.

## 2. 실행 중인 데이터 파일 복사에 redo가 필요한 이유

### 2.1 파일 복사본에는 여러 시점이 섞인다

버퍼 풀의 페이지는 DML로 바뀌고, dirty page는 이후 디스크에 기록된다. 백업이 페이지 A를 읽은 뒤 페이지 B를 읽는 사이에도 트랜잭션은 계속 실행될 수 있다. 복사본의 각 페이지는 정상적인 개별 페이지일 수 있지만, 파일 전체가 동일한 트랜잭션 경계의 상태라는 보장은 없다.

이 문제를 해결하기 위해 XtraBackup은 시작 시 복구에 필요한 LSN 경계를 파악하고, 데이터 파일 복사와 동시에 redo를 추적·복사한다. LSN은 InnoDB 로그의 위치를 나타내며 시각, binlog 파일 위치, GTID와 같은 값이 아니다. 이들을 서로 치환하여 복구 위치를 계산하면 안 된다.

### 2.2 redo 수집은 파일 복사와 병행된다

redo는 계속 생성되며 오래된 영역은 재사용될 수 있다. 백업 측이 필요한 redo를 읽기 전에 원본이 해당 영역을 재사용하면 일관성을 복구할 재료가 사라진다. 따라서 데이터 파일을 모두 복사했더라도 redo 수집이 실패한 백업은 정상 백업으로 승격할 수 없다.

운영에서는 백업 크기뿐 아니라 redo 생성률, 원본과 백업 대상의 I/O 지연, 백업 진행 로그를 함께 관찰한다. redo 용량을 늘리는 것은 추적 여유를 줄 수 있지만, 지속적인 처리량 부족이나 백업 프로세스 정체를 해결하는 대책은 아니다. 지원되는 서버·도구 조합에서는 redo consumer 관련 기능도 검토할 수 있으나, 로그 보존이 원본 쓰기 진행에 미치는 영향을 함께 평가해야 한다.

```mermaid
flowchart TD
    A[실행 중인 MySQL] --> B[데이터 페이지 복사]
    A --> C[redo 변경 연속 수집]
    B --> D[시간이 섞인 물리 백업]
    C --> D
    D --> E[prepare: redo 적용]
    E --> F[미커밋 일반 트랜잭션 rollback]
    F --> G[복구 가능한 전체 백업]
    G --> H[중지된 별도 서버의 빈 datadir에 복사]
    H --> I[서버 기동과 업무 데이터 검증]
```

### 2.3 prepare는 백업 복사본에 대한 복구 작업이다

`xtrabackup --prepare`는 복사본을 대상으로 InnoDB 복구를 수행한다. redo 적용을 통해 페이지 상태를 전진시키고, 필요한 undo를 이용하여 미커밋 변경을 정리한다. redo가 커밋된 트랜잭션의 변경만 담는 것은 아니다. 미커밋 변경도 디스크와 redo에 존재할 수 있으므로, redo 적용과 트랜잭션 rollback을 구분해야 한다.

일반적인 전체 백업의 최종 prepare는 백업이 수집한 일관성 경계에 맞춘다. 백업 시작 시점으로 모든 데이터를 되돌리는 방식이 아니며, 사용자가 임의의 과거 시각을 지정하는 PITR도 아니다. 특정 사고 직전까지 복구하려면 적절한 기준 백업과 그 이후 binlog 보존·재적용 절차가 별도로 필요하다.

prepare는 원본 서버가 아닌 별도 작업 서버에서도 수행할 수 있다. 반면 prepare가 백업 파일 자체를 변경한다는 점은 중요하다. 원본 보관본과 복구 작업용 사본을 구분하고, 진행 중 강제 중단이나 저장 공간 고갈을 피한다. 증분 백업을 추가로 적용할 기반에는 최종 rollback을 일찍 수행하지 않도록 `--apply-log-only`를 사용하는 별도 절차가 필요하다.

## 3. hot backup은 무잠금·무영향을 뜻하지 않는다

InnoDB DML을 계속 허용하면서 백업할 수 있다는 것과 모든 DDL·엔진·옵션 조합에서 잠금이 없다는 것은 다르다. 테이블 삭제, 이름 변경, 테이블스페이스 변경처럼 복사 대상의 구조를 바꾸는 작업은 백업의 일관성과 충돌한다.

MySQL 8.0의 `LOCK INSTANCE FOR BACKUP`은 일반 DML을 허용하면서 백업에 위험한 파일 관련 작업을 제한하기 위한 인스턴스 수준 잠금이다. 이는 모든 문장을 멈추는 전역 읽기 잠금과 같지 않다. XtraBackup이 실제로 선택하는 잠금은 서버 종류, 테이블 엔진, DDL 관련 옵션, 복제 메타데이터 수집 옵션에 따라 달라진다. 따라서 “항상 FTWRL을 사용한다”와 “절대 잠그지 않는다”는 설명 모두 부정확하다.

이 글의 물리 백업 실험은 `--lock-ddl`을 지정했으며, 로그에서 `Executing LOCK INSTANCE FOR BACKUP ...`과 `Executing UNLOCK INSTANCE`를 확인했다. 혼합 엔진이나 복제본 백업에 이 관측 결과를 그대로 일반화하지 않는다.

다음은 폐기 가능한 테스트 DB에서 backup lock과 DML의 관계를 확인하는 예제다. `BACKUP_ADMIN`을 가진 계정으로 실행하며, 마지막 `UNLOCK INSTANCE`를 생략하지 않는다. **동시 DDL의 대기까지 재현하는 예제는 아니고, 잠금 보유 중 INSERT가 성공함을 확인하는 축소 실험**이다.

```sql
CREATE TABLE xb_lock_demo (
    id INT PRIMARY KEY,
    balance INT NOT NULL
) ENGINE=InnoDB;
LOCK INSTANCE FOR BACKUP;
INSERT INTO xb_lock_demo VALUES (1, 100), (2, 200);
SELECT id, balance FROM xb_lock_demo ORDER BY id;
SELECT OBJECT_TYPE, LOCK_TYPE, LOCK_STATUS
FROM performance_schema.metadata_locks
WHERE OBJECT_TYPE = 'BACKUP LOCK';
UNLOCK INSTANCE;
DROP TABLE xb_lock_demo;
```

실행 결과(MySQL 8.0.x):

```text
mysql> CREATE TABLE xb_lock_demo (
    ->     id INT PRIMARY KEY,
    ->     balance INT NOT NULL
    -> ) ENGINE=InnoDB;

Query OK, 0 rows affected (0.00 sec)

mysql> LOCK INSTANCE FOR BACKUP;

Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO xb_lock_demo VALUES (1, 100), (2, 200);

Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT id, balance FROM xb_lock_demo ORDER BY id;

+----+---------+
| id | balance |
+----+---------+
|  1 |     100 |
|  2 |     200 |
+----+---------+
2 rows in set (0.00 sec)

mysql> SELECT OBJECT_TYPE, LOCK_TYPE, LOCK_STATUS
    -> FROM performance_schema.metadata_locks
    -> WHERE OBJECT_TYPE = 'BACKUP LOCK';

+-------------+-----------+-------------+
| OBJECT_TYPE | LOCK_TYPE | LOCK_STATUS |
+-------------+-----------+-------------+
| BACKUP LOCK | SHARED    | GRANTED     |
+-------------+-----------+-------------+
1 row in set (0.00 sec)

mysql> UNLOCK INSTANCE;

Query OK, 0 rows affected (0.00 sec)

mysql> DROP TABLE xb_lock_demo;

Query OK, 0 rows affected (0.00 sec)
```

운영에서는 장기 DDL, 이미 쌓여 있는 메타데이터 잠금 대기, 비트랜잭션 테이블 크기를 백업 전에 확인한다. 잠금 대기 제한과 작업 중단 기준을 마련해야 하며, 백업 성공률을 높이겠다는 이유로 업무 세션을 자동 종료하는 정책을 무조건 적용해서는 안 된다.

## 4. 실제 실험: 미커밋 변경을 포함한 백업의 복원

### 4.1 실험에서 고정한 조건

네트워크와 데이터를 운영 환경에서 격리한 폐기용 컨테이너를 사용했다. 원본과 복원본은 서로 다른 데이터 디렉터리를 사용했으며, 백업 도구에는 원본 디렉터리를 읽기 전용으로 마운트했다. 원본은 백업 완료까지 실행 중이었고, 복원본은 원본 컨테이너 제거 후 기동했다.

시험 데이터는 `xb_demo.account`의 `(id, balance)` 세 행이다. 전체 기준 행은 다음과 같았다. 아래 행 목록은 `mysql -N -B`로 수집한 출력이며, mysql 대화형 표 형식으로 변환하지 않았다.

```text
1	100
2	200
3	300
```

검증 순서는 다음과 같다.

1. 위 세 행을 입력하고 커밋했다.
2. 별도 연결에서 트랜잭션을 시작하고 `id=2`의 `balance`를 `999`로 변경한 채 커밋하지 않았다.
3. 해당 연결을 유지하면서 전체 물리 백업을 수행했다.
4. 백업 완료 후 원본 연결을 rollback하고, 원본에서 `id=1` 행을 삭제·커밋했다.
5. 백업 복사본을 prepare하고 빈 복원 디렉터리에 copy-back했다.
6. 복원본 MySQL을 기동하여 전체 행을 기준 행과 대조했다.

이 순서는 서로 다른 두 조건을 검사한다. 미커밋 `999`가 복원본에 보이지 않아야 하며, 백업 완료 후 삭제한 `id=1`은 복원본에 남아 있어야 한다.

### 4.2 실행한 핵심 명령

다음은 격리 컨테이너 내부에서 실행한 핵심 명령이다. `root`는 이 폐기용 실험에만 사용한 계정이며 운영용 권한 구성 예제가 아니다. `/backup`, `/restore`, `/var/lib/mysql`은 각각 시험용 마운트 지점이다. 운영에서는 최소 권한 백업 계정, 보호된 옵션 파일, 실제 데이터·백업 경로를 준비해야 한다.

```bash
xtrabackup --backup --host=127.0.0.1 --user=root \
  --datadir=/var/lib/mysql --target-dir=/backup --lock-ddl

xtrabackup --prepare --target-dir=/backup --use-memory=128M

xtrabackup --copy-back --target-dir=/backup --datadir=/restore
```

각 단계의 종료 코드는 모두 `0`이었으며, 각 로그에 `completed OK!`가 있었다. `--use-memory=128M`는 작은 테스트의 prepare 메모리 설정일 뿐 운영 권장값이 아니다.

복원 대상은 **mysqld가 중지되어 있고 datadir가 비어 있는 별도 인스턴스**여야 한다. 운영 데이터 디렉터리에 위 명령을 덮어 실행해서는 안 된다. 파일 소유권과 접근 권한을 확인한 뒤, 해당 데이터 형식과 호환되는 서버·설정으로 기동한다. `--move-back`은 백업 원본을 이동시키므로 보관본을 유지해야 하는 복구 절차에서는 특히 주의한다.

### 4.3 prepare 전후 메타데이터와 rollback 증거

`xtrabackup_checkpoints`에서 다음 값을 확인했다. 출력은 핵심 필드만 발췌했으며, 숫자는 이번 실험의 관측값이지 고정 기준값이 아니다.

```text
prepare 전:
backup_type = full-backuped
from_lsn = 0
to_lsn = 29545581
last_lsn = 29637495

prepare 후:
backup_type = full-prepared
from_lsn = 0
to_lsn = 29545581
last_lsn = 29637495
```

`to_lsn`과 `last_lsn`이 서로 다를 수 있다. 전자는 백업의 체크포인트·증분 연결에 사용하는 경계이고, 후자는 마지막으로 수집한 redo 위치를 나타낸다. 값을 벽시계 시각이나 특정 업무 트랜잭션 번호로 읽지 않는다. 증분 연결 검사는 파일 이름 순서만이 아니라 앞 백업의 `to_lsn`과 뒤 백업의 `from_lsn` 관계를 확인하는 별도 작업이다.

prepare 로그에는 다음 메시지가 실제로 기록되었다. 시간·로그 접두부는 생략했다.

```text
Resurrected 1 transactions doing updates.
1 transaction(s) which must be rolled back or cleaned up in total 1 row operations to undo
Starting in background the rollback of uncommitted transactions
Rolling back trx with id 1820, 1 rows to undo
Rollback of non-prepared transactions completed
completed OK!
```

이 기록은 단순히 파일이 복사된 것이 아니라, 백업에 포함된 미커밋 변경의 rollback이 prepare 과정에서 수행되었음을 보여준다. XA prepared 트랜잭션의 처리는 별도 주제이며, 위 실험은 일반 미커밋 트랜잭션만 다룬다.

### 4.4 복원 후 전체 행 비교

백업 완료 후 삭제를 수행한 원본에서는 다음 행만 남았다.

```text
2	200
3	300
```

반면 복원본의 `SELECT id, balance FROM xb_demo.account ORDER BY id` 결과는 다음과 같았다.

```text
1	100
2	200
3	300
```

검증 프로그램은 복원본의 전체 행 문자열이 백업 전 기준 행과 동일하고, 삭제 후 원본의 행 목록과는 다르다는 것을 assertion으로 확인했다. 이에 따라 **미커밋 변경의 제거, 백업 이후 삭제와의 분리, 복원본 기동 후 실제 조회**를 확인했다.

다만 작은 테이블의 성공이 대용량 서버의 복구 시간이나 모든 객체의 복원 가능성을 보장하지는 않는다. 지속적인 대량 쓰기, redo 추적 지연, 동시 DDL, 암호화 키 손실, 파일 손상, 증분 체인 중간 누락은 이 실험에서 재현하지 않았다.

## 5. 버전·권한·복구 재료를 함께 관리한다

### 5.1 서버와 도구의 버전을 짝으로 기록한다

물리 백업은 “8 이상”이라는 조건만으로 호환성을 보장할 수 없다. 이 글에서 사용한 Percona XtraBackup 8.0.35-36의 공식 지원 문서는 MySQL 8.0.34 이상 및 이후 8.0.x 계열을 설명한다. MySQL 8.4에는 해당 서버를 지원하는 XtraBackup 8.4 계열의 문서와 제한을 확인해야 한다. 공식 8.4 문서는 MySQL 8.0 및 9.x 서버 백업을 지원하지 않는다고 명시한다.

버전 검사를 끄는 것은 데이터 형식 호환성을 만드는 방법이 아니다. 서버 패치 업그레이드 전후에는 실제 백업·prepare·복원 기동 시험을 수행한다. 다음 쿼리는 서버와 중요한 물리 형식 설정을 기록하는 출발점이다. 이 조회 자체가 도구 호환성을 판정하지는 않는다.

```sql
SELECT VERSION() AS mysql_version,
       @@version_comment AS distribution,
       @@innodb_page_size AS page_size,
       @@lower_case_table_names AS lower_case_table_names;
SELECT @@innodb_file_per_table AS file_per_table,
       @@innodb_redo_log_capacity AS redo_capacity_bytes,
       @@log_bin AS binary_logging;
```

실행 결과(MySQL 8.0.x):

```text
mysql> SELECT VERSION() AS mysql_version,
    ->        @@version_comment AS distribution,
    ->        @@innodb_page_size AS page_size,
    ->        @@lower_case_table_names AS lower_case_table_names;

+---------------+------------------------------+-----------+------------------------+
| mysql_version | distribution                 | page_size | lower_case_table_names |
+---------------+------------------------------+-----------+------------------------+
| 8.0.46        | MySQL Community Server - GPL |     16384 |                      0 |
+---------------+------------------------------+-----------+------------------------+
1 row in set (0.00 sec)

mysql> SELECT @@innodb_file_per_table AS file_per_table,
    ->        @@innodb_redo_log_capacity AS redo_capacity_bytes,
    ->        @@log_bin AS binary_logging;

+----------------+---------------------+----------------+
| file_per_table | redo_capacity_bytes | binary_logging |
+----------------+---------------------+----------------+
|              1 |           104857600 |              0 |
+----------------+---------------------+----------------+
1 row in set (0.00 sec)
```

위 SQL 실행 결과는 별도의 SQL 검증 인스턴스에서 얻은 값이다. 검증 인스턴스는 binlog를 꺼서 실행하므로 `binary_logging=0`이며, 앞 절의 실제 물리 백업 실험은 binlog를 켠 별도 인스턴스에서 수행했다. 서로 다른 시험 환경의 설정값을 하나의 결과로 섞지 않는다.

### 5.2 OS 권한과 SQL 권한은 서로 대체하지 않는다

OS 사용자는 데이터 파일 읽기와 디렉터리 탐색, 백업 대상 쓰기 권한이 필요하다. DB 사용자는 메타데이터 조회와 필요한 잠금·flush 작업 권한이 필요하다. 한쪽에서 `root`라고 다른 쪽의 권한까지 자동으로 생기지는 않는다.

공식 권한 문서는 일반 전체 백업에 `BACKUP_ADMIN`, `PROCESS`, `RELOAD`, `LOCK TABLES`, `REPLICATION CLIENT`와 관련 Performance Schema 테이블 조회 권한을 설명한다. 복제 제어, 백업 이력 기록, keyring 사용 여부에 따라 추가 요구가 달라지므로 사용하지 않는 기능의 권한까지 일괄 부여하지 않는다. 인증정보는 명령행·로그·공개 원고에 노출하지 않는다.

### 5.3 데이터 파일 외에 필요한 것을 분리한다

| 항목 | 운영상의 의미 |
|---|---|
| `xtrabackup_checkpoints` | 백업 유형과 LSN 범위를 확인하는 메타데이터 |
| `xtrabackup_info` | 도구·실행·백업 관련 정보를 검토하는 출발점 |
| `backup-my.cnf` | prepare에 필요한 일부 InnoDB 설정이며 전체 운영 구성 백업의 대체물이 아님 |
| `xtrabackup_binlog_info` | 복제·PITR 연결에 활용하는 좌표 정보이며 이후 binlog 전체의 보존을 보장하지 않음 |
| keyring·외부 키 관리 정보 | 암호화 테이블스페이스 복원에 필요한 별도 의존성 |
| 서버 설정·인증서·플러그인 | 데이터 파일만으로 완결되지 않는 실행 환경 |

실험에서는 `xtrabackup_binlog_info`에 `binlog.000003`의 위치 `157`이 기록되었다. 좌표 기록은 확인했지만 binlog를 재적용한 PITR은 수행하지 않았다. 실제 복구 정책은 로그 보존 기간, 보관본 무결성, 키 접근 가능 기간까지 함께 정의해야 한다.

## 6. 운영 실패를 판정하는 기준

| 증상·오해 | 해석과 조치 |
|---|---|
| 데이터 파일 복사가 끝났으니 성공이라고 판단 | redo 수집, 최종 메타데이터 기록, 종료 코드까지 확인한다 |
| `completed OK!` 하나만으로 복구 가능 판정 | 어느 단계의 메시지인지 구분하고 prepare·기동·업무 검증을 이어 간다 |
| 백업 중 원본 지연 증가 | 파일 읽기·압축·저장소 쓰기 병목과 잠금 대기를 분리한다 |
| prepare 중 공간 부족 또는 강제 종료 | 작업 사본의 유효성을 재판정하고 신뢰할 수 있는 보관본에서 다시 시작한다 |
| 백업 파일은 있으나 암호화 키 없음 | 파일 복사 성공과 복호화 가능성은 별개이므로 키 복구를 검증한다 |
| 같은 스토리지에 백업을 두고 재해 대비 완료로 판단 | 원본과 백업의 장애 범위를 분리하고 별도 보관·접근 통제를 적용한다 |
| 서버만 기동되면 업무 복구 완료로 판단 | 핵심 행·업무 불변식·계정·예약 작업·외부 연동을 확인한다 |

백업 작업 시간만 측정하면 복구 목표를 놓치기 쉽다. 복구 시간에는 백업 확보, 필요 시 전송·복호화·압축 해제, prepare, copy-back, 기동, 데이터 검증과 서비스 전환이 포함된다. 백업을 미리 prepare하는 정책은 장애 시 작업량을 줄일 수 있지만, 증분 체인 운영 및 보관본 관리와 함께 결정해야 한다.

## 7. Aurora MySQL에서는 사용 방향이 다르다

Aurora의 데이터 스토리지는 사용자가 일반 MySQL datadir처럼 직접 마운트하는 대상이 아니다. Aurora 자체의 백업·PITR은 관리형 백업 기능을 사용한다. Aurora reader에 연결해 XtraBackup을 실행하면 클러스터 물리 백업이 만들어진다고 해석해서는 안 된다.

반대로 **외부 MySQL에서 만든 호환 XtraBackup 백업을 S3에 올려 새로운 Aurora MySQL 클러스터로 가져오는 경로**는 AWS 공식 문서에 정의되어 있다. 이는 Aurora를 XtraBackup으로 백업하는 것과 방향이 반대다. 기존 Aurora 클러스터에 copy-back하는 작업도 아니다.

이 경로에는 원본과 목적지 버전, 지원 형식, IAM·S3 접근, 리전, 암호화 및 테이블스페이스 제한이 있다. Community MySQL에 복원 가능한 백업이라고 Aurora가 그대로 수용한다고 판단하지 않는다. 도입 시점의 AWS 지원 조건을 별도로 확인하며, 이 글의 로컬 실험은 Aurora 가져오기를 검증한 결과가 아니다.

## 8. 도입·운영 체크리스트

- [ ] 원본 서버·XtraBackup·복원 서버의 정확한 버전과 호환성 근거를 기록했다.
- [ ] 원본 파일 접근 권한과 DB 백업 계정 권한을 각각 검증했다.
- [ ] InnoDB 외 엔진, 진행 중 DDL, 잠금 대기 및 중단 정책을 점검했다.
- [ ] 데이터 파일 복사와 redo 수집의 성공을 모두 확인했다.
- [ ] 백업 로그와 메타데이터를 보존하고, 후속 binlog 보관을 별도 정책으로 관리한다.
- [ ] 암호화 키·플러그인·서버 설정 등 외부 의존성의 복구를 시험했다.
- [ ] 보관본과 prepare 작업 사본을 구분하며 저장 공간을 확보했다.
- [ ] 중지된 별도 서버의 빈 datadir에 복원하고 소유권을 확인했다.
- [ ] 서버 기동뿐 아니라 업무 데이터와 필요한 객체를 대조했다.
- [ ] 전체 복구 시간을 측정하고 원본과 백업의 장애 범위를 분리했다.
- [ ] Aurora로 가져올 경우 로컬 복원과 다른 AWS 지원 조건을 검토했다.

## 정리

Percona XtraBackup의 핵심은 온라인 파일 복사 자체가 아니라 **페이지 복사와 redo 수집을 결합하고 prepare로 복구 가능한 상태를 만드는 과정**이다. 실제 실험에서도 미커밋 변경은 prepare에서 rollback되었고, 백업 이후 원본 삭제는 복원본에 반영되지 않았다.

운영의 완료 기준은 백업 명령의 종료가 아니라, 독립된 복원본에서 확인한 데이터와 복구 시간이다. 이 원리를 바탕으로 증분 백업의 LSN 연결, 스트리밍·압축, binlog를 이용한 시점 복구를 확장해서 이해할 수 있다.

## 참고 문서

- [Percona: XtraBackup 동작 원리](https://docs.percona.com/percona-xtrabackup/8.0/how-xtrabackup-works.html)
- [Percona: 전체 백업 생성](https://docs.percona.com/percona-xtrabackup/8.0/create-full-backup.html)
- [Percona: 전체 백업 prepare](https://docs.percona.com/percona-xtrabackup/8.0/prepare-full-backup.html)
- [Percona: 백업 복원](https://docs.percona.com/percona-xtrabackup/8.0/restore-a-backup.html)
- [Percona: 지원 버전](https://docs.percona.com/percona-xtrabackup/8.0/supported-versions.html), [XtraBackup 8.4 지원 범위](https://docs.percona.com/percona-xtrabackup/8.4/)
- [Percona: 연결과 권한](https://docs.percona.com/percona-xtrabackup/8.0/privileges.html)
- [AWS: XtraBackup과 S3를 이용한 Aurora MySQL 물리 마이그레이션](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Migrating.ExtMySQL.S3.html)
