首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Linux XtraBackup 安裝與實戰:從二進制部署到自動化備份腳本

     編輯:MySQL 資料庫相關知識

環境準備

  • OS: CentOS 7.x
  • MySQL: 5.7+ (已安裝並運行,datadir=/var/lib/mysql)
  • 目標: 安裝 XtraBackup 2.4/8.0 並實現壓縮備份/自動恢復

快速安裝 (二進制包解壓即用)

# 1. 下載對應版本 (Percona 官網)
cd /opt
wget https://downloads.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.28/binary/redhat/7/x86_64/percona-xtrabackup-2.4.28-1.el7.x86_64.rpm

# 2. 解壓 RPM (不安裝,直接提取二進制)
rpm2cpio percona-xtrabackup-2.4.28-1.el7.x86_64.rpm | cpio -idmv

# 3. 複製核心工具到 PATH
cp usr/bin/innobackupex /usr/local/bin/
cp usr/bin/xtrabackup /usr/local/bin/
cp usr/bin/xtrabackup_55 /usr/local/bin/  # MySQL 5.5
cp usr/bin/xtrabackup_56 /usr/local/bin/  # MySQL 5.6
cp usr/bin/xtrabackup_57 /usr/local/bin/  # MySQL 5.7

# 4. 驗證
innobackupex --version
xtrabackup --version

核心參數速查表

參數說明典型值
--user資料庫用戶backup_user
--password密碼 (建議用 --defaults-file)xxx
--defaults-filemy.cnf 路徑/etc/my.cnf
--database指定庫 (不加 = 全庫)mydb
--stream=tar串流輸出 tar 格式配合管道壓縮
--compress快速壓縮 (需 qpress)節省空間
--parallel=N並行複製線程數4-8
--no-timestamp不生成時間戳目錄固定路徑便於腳本
--slave-info記錄主庫 binlog 位置從庫備份必加
--apply-log準備階段 (redo log 重放)恢復前必執行
--copy-back複製回 datadir恢復最後步驟

實戰:壓縮備份腳本 (生產就緒)

#!/bin/bash
# /usr/local/bin/xtrabackup_full.sh
# 功能:每日全量壓縮備份,保留 7 天

set -euo pipefail

# ===== 配置區 =====
MY_CNF="/etc/my.cnf"
DB_USER="backup_user"
DB_PASS="your_strong_password"
BACKUP_ROOT="/data/backup/mysql"
RETENTION_DAYS=7
PARALLEL=4
COMPRESS_THREADS=4
LOG_FILE="/var/log/xtrabackup_full.log"
# ==================

DATE=$(date +%F_%H-%M)
BACKUP_DIR="$BACKUP_ROOT/full_$DATE"
LOG_DIR="$BACKUP_ROOT/logs"
mkdir -p "$BACKUP_DIR" "$LOG_DIR"

exec > >(tee -a "$LOG_FILE") 2>&1

echo "[$(date)] ===== 開始全量備份 ====="
echo "目標目錄: $BACKUP_DIR"

# 執行備份
innobackupex \
  --defaults-file="$MY_CNF" \
  --user="$DB_USER" \
  --password="$DB_PASS" \
  --no-timestamp \
  --parallel=$PARALLEL \
  --compress \
  --compress-threads=$COMPRESS_THREADS \
  --slave-info \
  "$BACKUP_DIR" 2>&1 | tee -a "$LOG_DIR/full_$DATE.log"

EXIT_CODE=${PIPESTATUS[0]}

if [ $EXIT_CODE -eq 0 ]; then
    echo "[$(date)] ✅ 備份成功: $BACKUP_DIR"
    # 記錄備份元信息
    echo "$DATE|full|$BACKUP_DIR|$(du -sh $BACKUP_DIR | cut -f1)" >> "$BACKUP_ROOT/backup_index.log"
else
    echo "[$(date)] ❌ 備份失敗,退出碼: $EXIT_CODE"
    rm -rf "$BACKUP_DIR"
    exit 1
fi

# 清理舊備份
echo "[$(date)] 清理 $RETENTION_DAYS 天前備份..."
find "$BACKUP_ROOT" -maxdepth 1 -type d -name 'full_*' -mtime +$RETENTION_DAYS -exec rm -rf {} \;
find "$LOG_DIR" -type f -mtime +$RETENTION_DAYS -delete

echo "[$(date)] ===== 備份任務結束 ====="

實戰:恢復操作標準流程

#!/bin/bash
# /usr/local/bin/xtrabackup_restore.sh
# 用法: ./xtrabackup_restore.sh /data/backup/mysql/full_2024-01-15_02-00

set -euo pipefail

BACKUP_DIR="${1:-}"
if [ -z "$BACKUP_DIR" ] || [ ! -d "$BACKUP_DIR" ]; then
    echo "用法: $0 <備份目錄路徑>"
    exit 1
fi

MY_CNF="/etc/my.cnf"
DB_USER="root"
DB_PASS="your_password"
DATADIR="/var/lib/mysql"

echo "[$(date)] 開始恢復: $BACKUP_DIR"

# 1. 停止 MySQL
systemctl stop mysqld
echo "MySQL 已停止"

# 2. 備份當前數據 (安全網)
mv "$DATADIR" "${DATADIR}_bak_$(date +%s)"
mkdir -p "$DATADIR"
echo "原數據目錄已備份"

# 3. 解壓 (若為壓縮備份)
if ls "$BACKUP_DIR"/*.qp 2>/dev/null; then
    echo "檢測到壓縮備份,正在解壓..."
    xtrabackup --decompress --target-dir="$BACKUP_DIR" --parallel=4
    find "$BACKUP_DIR" -name "*.qp" -delete
fi

# 4. 準備備份 (核心步驟)
echo "執行 --apply-log..."
innobackupex --defaults-file="$MY_CNF" --apply-log "$BACKUP_DIR"

# 5. 複製回數據目錄
echo "執行 --copy-back..."
innobackupex --defaults-file="$MY_CNF" --copy-back "$BACKUP_DIR"

# 6. 修正權限
chown -R mysql:mysql "$DATADIR"

# 7. 清理殘留 xtrabackup 文件
rm -f "$DATADIR"/xtrabackup_*

# 8. 啟動 MySQL
systemctl start mysqld
sleep 3

# 9. 驗證
if mysql -u"$DB_USER" -p"$DB_PASS" -e "SELECT 1;" >/dev/null 2>&1; then
    echo "[$(date)] ✅ 恢復成功並驗證通過"
else
    echo "[$(date)] ❌ 恢復後連線失敗,請檢查日誌"
    exit 1
fi

增量備份策略 (配合全量)

#!/bin/bash
# /usr/local/bin/xtrabackup_inc.sh
# 每 4 小時執行一次增量

MY_CNF="/etc/my.cnf"
DB_USER="backup_user"
DB_PASS="xxx"
BACKUP_ROOT="/data/backup/mysql"

# 找到最新的基準目錄 (優先增量,其次全量)
LATEST_BASE=$(ls -1dt "$BACKUP_ROOT"/inc_* "$BACKUP_ROOT"/full_* 2>/dev/null | head -1)

if [ -z "$LATEST_BASE" ]; then
    echo "無基準備份,請先執行全量備份"
    exit 1
fi

DATE=$(date +%F_%H-%M)
INC_DIR="$BACKUP_ROOT/inc_$DATE"

innobackupex \
  --defaults-file="$MY_CNF" \
  --user="$DB_USER" \
  --password="$DB_PASS" \
  --no-timestamp \
  --incremental "$INC_DIR" \
  --incremental-basedir="$LATEST_BASE"

echo "增量備份完成: $INC_DIR (基於 $LATEST_BASE)"

定時任務配置

# crontab -e (root 用戶)

# 每日 02:00 全量備份
0 2 * * * /usr/local/bin/xtrabackup_full.sh

# 每 4 小時增量備份
0 */4 * * * /usr/local/bin/xtrabackup_inc.sh

# 每週日 04:00 執行恢復演練 (測試環境)
0 4 * * 0 /usr/local/bin/xtrabackup_restore.sh /data/backup/mysql/full_$(date -d 'yesterday' +%F)_02-00

常見問題排查

問題原因解決
innobackupex: command not found未加入 PATHcp 到 /usr/local/bin 或 export PATH
Error: unknown option --compress版本不支援升級 XtraBackup 或用管道 gzip
備份卡住無響應MyISAM 表加鎖評估業務窗口或遷移至 InnoDB
恢復後表不存在.frm 文件缺失xtrabackup 不備份 .frm,確認使用 innobackupex
權限拒絕datadir 權限錯誤chown -R mysql:mysql /var/lib/mysql

生產環境核心建議

  1. 專用備份賬號:最小權限原則,禁止使用 root
  2. 異地備份:備份完成後同步至異地存儲 (S3/OSS/NFS)
  3. 加密傳輸:rsync over SSH 或加密壓縮包
  4. 監控告警:備份耗時、大小、成功率納入監控體系
  5. 文檔化恢復流程:壓力測試環境每月演練,記錄 RTO
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved