Comunidad MariaDB

备份工具横评

mariabackup / Percona XtraBackup / mydumper / clone plugin——吞吐、增量、恢复速度对比

选谁?快速决策

场景推荐
单机 MariaDB 11.xmariabackup(官方,免费)
多线程逻辑备份(小库)mydumper / myloader
MySQL 8 兼容(一份工具两边用)Percona XtraBackup(兼容性最好)
云上托管用云厂商内置 + 异地副本

mariabackup

MariaDB 官方物理备份工具,fork 自 Percona XtraBackup。

# 全量
mariabackup --backup \
  --target-dir=/data/backup/$(date +%F) \
  --user=backup --password=xxx \
  --parallel=4

# 增量(基于上次全量)
mariabackup --backup \
  --target-dir=/data/backup/inc1 \
  --incremental-basedir=/data/backup/2026-05-18 \
  --user=backup --password=xxx

# 准备(prepare)
mariabackup --prepare --target-dir=/data/backup/2026-05-18

# 应用增量
mariabackup --prepare --apply-log-only \
  --target-dir=/data/backup/2026-05-18 \
  --incremental-dir=/data/backup/inc1

# 恢复
systemctl stop mariadb
rm -rf /var/lib/mysql/*
mariabackup --copy-back --target-dir=/data/backup/2026-05-18
chown -R mysql:mysql /var/lib/mysql
systemctl start mariadb
mariadb-upgrade -uroot -p

性能

库大小全量备份耗时恢复耗时
10 GB~30s~30s
100 GB~5 min~5 min
1 TB~50 min~50 min
10 TB数小时数小时

线速度受 IO 限制——本地 NVMe ≈ 网络带宽峰值。

优劣

✅ 热备份不锁库 ✅ 物理拷贝速度快 ✅ 支持增量 ✅ 与 MariaDB 完全兼容

❌ 二进制格式只能 restore 到相同大版本(11.4 → 11.4,不能跨大版本) ❌ 需要服务端文件系统访问

Percona XtraBackup

MySQL 兼容版本。

xtrabackup --backup --target-dir=/data/bk
xtrabackup --prepare --target-dir=/data/bk
xtrabackup --copy-back --target-dir=/data/bk

跟 mariabackup 几乎一样。MariaDB 11+ 建议用 mariabackup——XtraBackup 对新版本兼容滞后。

mydumper / myloader

多线程逻辑备份。比 mariadb-dump 快 5–10 倍。

# 备份
mydumper -h host -u backup -p xxx \
  -B app \
  -o /data/dump \
  --threads 8 \
  --compress \
  --rows 1000000              # 大表自动拆段

# 恢复
myloader -h target -u root -p xxx \
  -B app \
  -d /data/dump \
  --threads 8

优劣

✅ 跨大版本可用(输出是 SQL) ✅ 跨平台、跨架构 ✅ 多线程 ✅ 支持单表 / 单库恢复

❌ 比物理备份慢 ❌ 大表恢复慢(要重建索引) ❌ 备份期间需要 consistent snapshot(短暂锁)

适合:跨版本迁移、小到中型库(< 500 GB)。

mariadb-dump(mysqldump)

mariadb-dump --single-transaction \
  --routines --triggers --events \
  --all-databases -uroot -p | gzip > full.sql.gz

✅ 简单、随处可用 ❌ 慢、单线程 ❌ 大库不实际

只用作快速 ad-hoc 备份或小库

clone plugin

MariaDB 没有官方 clone plugin(MySQL 8 有)。

MySQL 8 的 CLONE INSTANCE FROM ... 在 MariaDB 不存在。要用 mariabackup 或 mydumper。

备份策略实战

"三个一"原则

  • 1 份本地
  • 1 份异地
  • 1真实演练过的备份

典型策略

频率工具保留
每天 0 点全量mariabackup7 天
每小时增量mariabackup --incremental24 小时
Binlog 实时归档mysqlbinlog --read-from-remote-server --raw7 天
每周一次跨 regionrsync / aws s3 cp30 天
每月一次离线归档tar 到磁带 / Glacier1 年

PITR(时间点恢复)

                                 NOW
全量备份(T0) ---------- 增量(T1) ---- 增量(T2) ---- binlog ----
                                                              |
                                                       想恢复到这里

步骤:

# 1. 恢复最近的全量
mariabackup --copy-back --target-dir=T0
# 2. 应用增量
mariabackup --prepare --apply-log-only --target-dir=T0 --incremental-dir=T1
mariabackup --prepare --target-dir=T0 --incremental-dir=T2
# 3. 应用 binlog 到指定时间
mysqlbinlog --start-position=... --stop-datetime='2026-05-18 14:30:00' \
  binlog.000001 binlog.000002 | mariadb -uroot -p

备份验证

真演练才算有效

# 每周一次:恢复到独立环境,跑 checksum
mariabackup --prepare --target-dir=/restore
# 启动隔离实例
docker run -d --name verify -v /restore:/var/lib/mysql:ro mariadb:11.4
# 跑业务级 health check
mysql -h verify -e "SELECT COUNT(*) FROM users;"

云上托管:用云厂商提供的 restore 功能恢复到临时实例,跑 checksum。

备份的常见坑

  1. dump 时没加 --single-transaction → 数据不一致
  2. binlog 没归档 → PITR 失败
  3. 备份账号权限过大 → 安全风险
  4. 备份带在线上的 readonly 副本上做 → 反正最常踩坑:副本延迟使备份不是想要的时间点
  5. 不验证 restore → 事到临头才发现备份坏了
  6. 同实例同地保留所有备份 → 一着火全完
  7. 备份不加密 → 数据泄露
  8. 保留期没设上限 → S3 账单暴增

自动化备份脚本

#!/bin/bash
set -euo pipefail

BACKUP_DIR=/data/backup/$(date +%Y-%m-%d)
S3_BUCKET=s3://my-backups
RETENTION_DAYS=30

mkdir -p $BACKUP_DIR

mariabackup --backup \
  --target-dir=$BACKUP_DIR \
  --user=backup --password="$MYSQL_PWD" \
  --parallel=4

mariabackup --prepare --target-dir=$BACKUP_DIR

# 加密并上传
tar cz $BACKUP_DIR | openssl enc -aes-256-cbc -salt -k "$BACKUP_PASS" | \
  aws s3 cp - $S3_BUCKET/$(basename $BACKUP_DIR).tar.gz.enc

# 清理本地
find /data/backup -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf {} +

# 清理 S3
aws s3 ls $S3_BUCKET/ | awk '{print $4}' | while read key; do
  ts=$(echo $key | sed 's/\.tar.gz.enc//')
  if [[ $(date -d "$ts" +%s) -lt $(date -d "$RETENTION_DAYS days ago" +%s) ]]; then
    aws s3 rm $S3_BUCKET/$key
  fi
done

延伸

On this page