0%

MySQL 备份恢复方案

一、前言

数据是企业的核心资产,数据库备份是保障数据安全的最重要措施。根据 Verizon 2026 年数据泄露调查报告,28% 的数据丢失事件是由于备份失败或恢复失败导致的

MySQL 作为全球最流行的开源数据库,提供了多种备份恢复方案:

  • 逻辑备份:mysqldump、mysqlpump
  • 物理备份:XtraBackup、MySQL Enterprise Backup
  • 二进制日志:binlog 增量备份
  • 快照备份:LVM、云存储快照
  • 主从复制:实时数据冗余

本文将详细介绍各种 MySQL 备份恢复方案,提供完整的操作步骤和可运行的自动化脚本,帮助你构建可靠的数据保护体系。


二、备份策略设计

2.1 备份类型对比

1
2
3
4
5
6
7
8
9
10
graph TB
A[MySQL 备份] --> B[逻辑备份]
A --> C[物理备份]
A --> D[增量备份]
A --> E[快照备份]

B --> B1[mysqldump<br/>跨版本<br/>速度慢]
C --> C1[XtraBackup<br/>热备份<br/>速度快]
D --> D1[binlog<br/>PITR 恢复<br/>需配合全量]
E --> E1[LVM/云快照<br/>秒级<br/>平台依赖]
备份类型 优点 缺点 适用场景
逻辑备份 跨版本、可编辑、选择性强 速度慢、恢复慢 小数据量、迁移
物理备份 速度快、支持热备 同版本、文件大 大数据量、生产
增量备份 节省空间、恢复灵活 依赖全量、复杂 频繁备份
快照备份 秒级、一致性 平台依赖 云环境

2.2 备份策略建议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
gantt
title 备份策略示例(周)
dateFormat HH:mm
axisFormat %H:%M

section 全量备份
周日全量 :crit, 01:00, 2h

section 增量备份
周一增量 :01:00, 30m
周二增量 :01:00, 30m
周三增量 :01:00, 30m
周四增量 :01:00, 30m
周五增量 :01:00, 30m
周六增量 :01:00, 30m

section Binlog
实时备份 :active, 00:00, 24h

推荐策略

  • 全量备份:每周日凌晨 1 点
  • 增量备份:每天凌晨 1 点(除周日)
  • Binlog 备份:实时备份,每小时切割
  • 保留策略:全量保留 4 周,增量保留 1 周,binlog 保留 1 周

三、逻辑备份(mysqldump)

3.1 基础用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 备份单个数据库
mysqldump -u root -p mydb > mydb.sql

# 备份多个数据库
mysqldump -u root -p --databases db1 db2 > backup.sql

# 备份所有数据库
mysqldump -u root -p --all-databases > all.sql

# 只备份表结构
mysqldump -u root -p --no-data mydb > structure.sql

# 只备份数据
mysqldump -u root -p --no-create-info mydb > data.sql

# 备份特定表
mysqldump -u root -p mydb table1 table2 > tables.sql

3.2 推荐参数

1
2
3
4
5
6
7
8
9
10
11
12
# 生产环境推荐配置
mysqldump -u root -p \
--single-transaction \ # 事务一致性(InnoDB)
--quick \ # 快速导出
--lock-tables=false \ # 不锁表
--set-gtid-purged=OFF \ # 不包含 GTID
--triggers \ # 包含触发器
--routines \ # 包含存储过程
--events \ # 包含事件
--hex-blob \ # 二进制字段十六进制
--default-character-set=utf8mb4 \
mydb > mydb.sql

3.3 压缩备份

1
2
3
4
5
6
7
8
# 备份并压缩
mysqldump -u root -p mydb | gzip > mydb.sql.gz

# 备份并加密
mysqldump -u root -p mydb | gpg -c > mydb.sql.gpg

# 备份压缩加密
mysqldump -u root -p mydb | gzip | gpg -c > mydb.sql.gz.gpg

3.4 恢复数据

1
2
3
4
5
6
7
8
9
10
11
# 恢复普通 SQL 文件
mysql -u root -p mydb < mydb.sql

# 恢复压缩文件
gunzip < mydb.sql.gz | mysql -u root -p mydb

# 恢复加密文件
gpg -d mydb.sql.gpg | mysql -u root -p mydb

# 在 MySQL 命令行中恢复
mysql> source /path/to/backup.sql;

四、物理备份(XtraBackup)

4.1 安装 XtraBackup

1
2
3
4
5
6
7
8
9
# Ubuntu/Debian
wget https://repo.percona.com/apt/percona-release_latest.generic_all.deb
sudo dpkg -i percona-release_latest.generic_all.deb
sudo apt update
sudo apt install percona-xtrabackup-80

# CentOS/RHEL
sudo yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
sudo yum install percona-xtrabackup-80

4.2 全量备份

1
2
3
4
5
6
7
8
9
10
11
# 创建备份目录
mkdir -p /backup/mysql/full

# 执行全量备份
xtrabackup --backup \
--target-dir=/backup/mysql/full \
--user=root \
--password=your_password

# 备份完成后准备(apply log)
xtrabackup --prepare --target-dir=/backup/mysql/full

4.3 增量备份

1
2
3
4
5
6
7
8
9
10
11
12
13
# 周一增量备份(基于周日全量)
xtrabackup --backup \
--target-dir=/backup/mysql/incr-mon \
--incremental-basedir=/backup/mysql/full \
--user=root \
--password=your_password

# 周二增量备份(基于周一增量)
xtrabackup --backup \
--target-dir=/backup/mysql/incr-tue \
--incremental-basedir=/backup/mysql/incr-mon \
--user=root \
--password=your_password

4.4 恢复全量备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1. 停止 MySQL
sudo systemctl stop mysql

# 2. 清空数据目录
sudo rm -rf /var/lib/mysql/*

# 3. 准备备份(apply log)
xtrabackup --prepare --target-dir=/backup/mysql/full

# 4. 合并增量备份(如果有)
xtrabackup --prepare --target-dir=/backup/mysql/full \
--incremental-dir=/backup/mysql/incr-mon

xtrabackup --prepare --target-dir=/backup/mysql/full \
--incremental-dir=/backup/mysql/incr-tue

# 5. 恢复数据
xtrabackup --copy-back --target-dir=/backup/mysql/full

# 6. 修改权限
sudo chown -R mysql:mysql /var/lib/mysql

# 7. 启动 MySQL
sudo systemctl start mysql

五、Binlog 增量备份

5.1 配置 Binlog

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# 启用 binlog
log_bin = /var/log/mysql/mysql-bin.log

# binlog 格式(推荐 ROW)
binlog_format = ROW

# 保留天数
binlog_expire_logs_seconds = 604800 # 7 天

# 最大文件大小
max_binlog_size = 100M

# 排除的数据库
binlog_ignore_db = mysql
binlog_ignore_db = information_schema
binlog_ignore_db = performance_schema

# GTID 模式(MySQL 5.7.6+)
gtid_mode = ON
enforce_gtid_consistency = ON

5.2 查看 Binlog

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看 binlog 文件列表
mysql -u root -p -e "SHOW BINARY LOGS;"

# 查看当前 binlog 文件
mysql -u root -p -e "SHOW MASTER STATUS;"

# 查看 binlog 内容
mysqlbinlog /var/log/mysql/mysql-bin.000001

# 查看特定时间的 binlog
mysqlbinlog --start-datetime="2026-03-12 10:00:00" \
--stop-datetime="2026-03-12 11:00:00" \
/var/log/mysql/mysql-bin.000001

5.3 Binlog 备份脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash
# backup-binlog.sh

BACKUP_DIR="/backup/mysql/binlog"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7

# 创建备份目录
mkdir -p $BACKUP_DIR

# 刷新 binlog
mysql -u root -p$MYSQL_PASSWORD -e "FLUSH BINARY LOGS;"

# 获取最新的 binlog 文件名
LATEST_BINLOG=$(mysql -u root -p$MYSQL_PASSWORD -e "SHOW BINARY LOGS;" | tail -n +2 | head -n 1 | awk '{print $1}')

# 备份除最新外的所有 binlog
for binlog in $(mysql -u root -p$MYSQL_PASSWORD -e "SHOW BINARY LOGS;" | tail -n +2 | awk '{print $1}' | grep -v "$LATEST_BINLOG"); do
if [ ! -f "$BACKUP_DIR/$binlog.gz" ]; then
echo "Backing up $binlog..."
gzip -c /var/log/mysql/$binlog > $BACKUP_DIR/$binlog.gz
fi
done

# 删除旧的备份
find $BACKUP_DIR -name "*.gz" -mtime +$RETENTION_DAYS -delete

echo "Binlog backup completed at $(date)"

5.4 PITR 恢复(Point-in-Time Recovery)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 恢复最近的全量备份
mysql -u root -p < /backup/mysql/full-20260310.sql

# 2. 恢复 binlog 到指定时间
mysqlbinlog /backup/mysql/binlog/mysql-bin.000001.gz | mysql -u root -p
mysqlbinlog /backup/mysql/binlog/mysql-bin.000002.gz | mysql -u root -p

# 3. 恢复到特定时间点(误操作前)
mysqlbinlog --stop-datetime="2026-03-12 10:59:00" \
/var/log/mysql/mysql-bin.000003 | mysql -u root -p

# 4. 恢复到特定位置
mysqlbinlog --start-position=107 --stop-position=928 \
/var/log/mysql/mysql-bin.000003 | mysql -u root -p

六、自动化备份脚本

6.1 完整备份脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/bin/bash
# mysql-backup.sh - MySQL 自动化备份脚本

set -e

# 配置
MYSQL_USER="backup"
MYSQL_PASSWORD="your_secure_password"
MYSQL_HOST="localhost"
BACKUP_DIR="/backup/mysql"
RETENTION_DAYS=30
LOG_FILE="/var/log/mysql-backup.log"
DATE=$(date +%Y%m%d_%H%M%S)
DAY_OF_WEEK=$(date +%u) # 1=Monday, 7=Sunday

# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# 错误处理
error_exit() {
log "ERROR: $1"
exit 1
}

# 创建备份目录
mkdir -p $BACKUP_DIR/{full,incremental,binlog}

log "Starting MySQL backup..."

# 判断是全量还是增量备份
if [ $DAY_OF_WEEK -eq 7 ]; then
# 周日:全量备份
log "Performing full backup..."
BACKUP_TYPE="full"
BACKUP_PATH="$BACKUP_DIR/full/full-$DATE"

# 使用 mysqldump 进行逻辑备份
mysqldump -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST \
--single-transaction \
--quick \
--lock-tables=false \
--routines \
--triggers \
--events \
--all-databases | gzip > $BACKUP_PATH.sql.gz

if [ $? -eq 0 ]; then
log "Full backup completed: $BACKUP_PATH.sql.gz"
BACKUP_SIZE=$(du -h $BACKUP_PATH.sql.gz | cut -f1)
log "Backup size: $BACKUP_SIZE"
else
error_exit "Full backup failed"
fi
else
# 其他日期:binlog 备份
log "Performing binlog backup..."
BACKUP_TYPE="binlog"

# 刷新 binlog
mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST -e "FLUSH BINARY LOGS;"

# 备份 binlog
LATEST_BINLOG=$(mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST \
-e "SHOW BINARY LOGS;" | tail -n +2 | head -n 1 | awk '{print $1}')

for binlog in $(mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -h$MYSQL_HOST \
-e "SHOW BINARY LOGS;" | tail -n +2 | awk '{print $1}' | grep -v "$LATEST_BINLOG"); do
if [ ! -f "$BACKUP_DIR/binlog/$binlog.gz" ]; then
gzip -c /var/log/mysql/$binlog > $BACKUP_DIR/binlog/$binlog.gz
log "Backed up $binlog"
fi
done
fi

# 清理旧备份
log "Cleaning up backups older than $RETENTION_DAYS days..."
find $BACKUP_DIR/full -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR/incremental -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
find $BACKUP_DIR/binlog -name "*.gz" -mtime +$RETENTION_DAYS -delete

# 验证备份
log "Verifying backup..."
if [ $BACKUP_TYPE = "full" ]; then
if gzip -t $BACKUP_PATH.sql.gz 2>/dev/null; then
log "Backup verification passed"
else
error_exit "Backup verification failed"
fi
fi

log "MySQL backup completed successfully"

# 发送通知(可选)
# curl -X POST -H 'Content-type: application/json' \
# --data "{\"text\":\"MySQL backup completed: $BACKUP_PATH.sql.gz\"}" \
# https://hooks.slack.com/services/YOUR/WEBHOOK/URL

exit 0

6.2 恢复脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/bin/bash
# mysql-restore.sh - MySQL 恢复脚本

set -e

# 配置
MYSQL_USER="root"
MYSQL_PASSWORD="your_password"
BACKUP_DIR="/backup/mysql"

# 显示可用备份
echo "Available backups:"
ls -lh $BACKUP_DIR/full/*.sql.gz

# 选择要恢复的备份
read -p "Enter backup file to restore: " BACKUP_FILE

if [ ! -f "$BACKUP_FILE" ]; then
echo "Backup file not found!"
exit 1
fi

# 确认恢复
read -p "WARNING: This will overwrite existing data. Continue? (yes/no): " CONFIRM
if [ "$CONFIRM" != "yes" ]; then
echo "Restore cancelled"
exit 0
fi

# 停止应用(可选)
# systemctl stop your-app

# 停止 MySQL
echo "Stopping MySQL..."
systemctl stop mysql

# 清空数据目录
echo "Clearing data directory..."
rm -rf /var/lib/mysql/*

# 恢复数据
echo "Restoring from $BACKUP_FILE..."
gunzip -c $BACKUP_FILE | mysql -u$MYSQL_USER -p$MYSQL_PASSWORD

if [ $? -eq 0 ]; then
echo "Data restored successfully"
else
echo "Restore failed!"
exit 1
fi

# 启动 MySQL
echo "Starting MySQL..."
systemctl start mysql

# 验证
echo "Verifying restoration..."
mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "SHOW DATABASES;"

# 启动应用(可选)
# systemctl start your-app

echo "Restore completed successfully"

6.3 配置定时任务

1
2
3
4
5
6
7
8
9
# 编辑 crontab
crontab -e

# 添加定时任务
# 每天凌晨 1 点备份
0 1 * * * /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1

# 每周日凌晨 1 点全量备份(覆盖每日备份)
0 1 * * 0 /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1

七、主从复制备份

7.1 配置主从复制

主库配置

1
2
3
4
5
6
7
8
9
10
11
12
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON

# 创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'secure_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

从库配置

1
2
3
4
5
6
7
8
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
server-id = 2
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
read_only = ON

配置复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 主库查看状态
mysql -u root -p -e "SHOW MASTER STATUS;"

# 从库配置复制
mysql -u root -p -e "
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='secure_password',
MASTER_AUTO_POSITION=1;
"

# 启动复制
mysql -u root -p -e "START SLAVE;"

# 查看复制状态
mysql -u root -p -e "SHOW SLAVE STATUS\G"

7.2 从库备份优势

1
2
3
4
5
6
7
8
9
graph TB
A[主库] -->|复制 | B[从库 1]
A -->|复制 | C[从库 2]

B --> D[备份任务]
C --> E[查询负载]

D --> F[不影响主库性能]
E --> G[读写分离]

在从库执行备份

1
2
3
4
5
# 在从库执行备份,不影响主库
ssh slave-server "mysqldump -u root -p --all-databases > backup.sql"

# 或使用 XtraBackup 热备
ssh slave-server "xtrabackup --backup --target-dir=/backup"

八、云环境备份

8.1 AWS RDS 备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 创建手动快照
aws rds create-db-snapshot \
--db-instance-identifier mydb \
--db-snapshot-identifier mydb-snapshot-20260312

# 列出快照
aws rds describe-db-snapshots \
--db-instance-identifier mydb

# 恢复快照
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier mydb-restored \
--db-snapshot-identifier mydb-snapshot-20260312

# 配置自动备份
aws rds modify-db-instance \
--db-instance-identifier mydb \
--backup-retention-period 7 \
--preferred-backup-window 01:00-02:00

8.2 阿里云 RDS 备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建备份
aliyun rds CreateBackup \
--DBInstanceId rm-xxx \
--BackupStrategy Manual

# 查询备份列表
aliyun rds DescribeBackups \
--DBInstanceId rm-xxx

# 恢复数据
aliyun rds CloneDBInstance \
--DBInstanceId rm-xxx \
--BackupId 12345 \
--DBInstanceClass mysql.n2.medium.2

九、备份验证与演练

9.1 自动化验证脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/bash
# mysql-verify-backup.sh - 备份验证脚本

set -e

BACKUP_FILE=$1
TEST_DB="backup_verify_test_$$"

if [ -z "$BACKUP_FILE" ]; then
echo "Usage: $0 <backup_file>"
exit 1
fi

echo "Verifying backup: $BACKUP_FILE"

# 创建测试数据库
mysql -u root -p -e "CREATE DATABASE $TEST_DB;"

# 恢复备份到测试数据库
gunzip -c $BACKUP_FILE | mysql -u root -p $TEST_DB

if [ $? -ne 0 ]; then
echo "Restore failed!"
mysql -u root -p -e "DROP DATABASE $TEST_DB;"
exit 1
fi

# 验证表数量
TABLE_COUNT=$(mysql -u root -p -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$TEST_DB';" $TEST_DB)
echo "Tables restored: $TABLE_COUNT"

# 验证记录数
RECORD_COUNT=$(mysql -u root -p -N -e "SELECT SUM(table_rows) FROM information_schema.tables WHERE table_schema='$TEST_DB';" $TEST_DB)
echo "Records restored: $RECORD_COUNT"

# 运行检查查询
mysql -u root -p -e "SELECT COUNT(*) FROM $TEST_DB.users;" > /dev/null
mysql -u root -p -e "SELECT COUNT(*) FROM $TEST_DB.orders;" > /dev/null

# 清理测试数据库
mysql -u root -p -e "DROP DATABASE $TEST_DB;"

echo "Backup verification passed!"

9.2 恢复演练计划

1
2
3
4
5
6
7
8
9
10
11
gantt
title 季度恢复演练计划
dateFormat YYYY-MM-DD
section Q1
1 月演练 :done, 2026-01-15, 1d
2 月演练 :done, 2026-02-15, 1d
3 月演练 :active, 2026-03-15, 1d
section Q2
4 月演练 :2026-04-15, 1d
5 月演练 :2026-05-15, 1d
6 月演练 :2026-06-15, 1d

演练步骤

  1. 选择最近的备份文件
  2. 在测试环境恢复
  3. 验证数据完整性
  4. 记录恢复时间(RTO)
  5. 记录数据丢失量(RPO)
  6. 编写演练报告
  7. 优化备份策略

十、监控与告警

10.1 备份监控脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/bash
# mysql-backup-monitor.sh - 备份监控脚本

BACKUP_DIR="/backup/mysql"
MAX_AGE_HOURS=26 # 超过 26 小时未备份则告警
SLACK_WEBHOOK="https://hooks.slack.com/services/XXX"

# 检查最新备份时间
LATEST_BACKUP=$(find $BACKUP_DIR -name "*.sql.gz" -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)

if [ -z "$LATEST_BACKUP" ]; then
MESSAGE="🚨 CRITICAL: No MySQL backup found!"
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$MESSAGE\"}" \
$SLACK_WEBHOOK
exit 1
fi

# 计算备份年龄
BACKUP_TIME=$(stat -c %Y $LATEST_BACKUP)
CURRENT_TIME=$(date +%s)
AGE_HOURS=$(( (CURRENT_TIME - BACKUP_TIME) / 3600 ))

if [ $AGE_HOURS -gt $MAX_AGE_HOURS ]; then
MESSAGE="⚠️ WARNING: MySQL backup is $AGE_HOURS hours old (last: $LATEST_BACKUP)"
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$MESSAGE\"}" \
$SLACK_WEBHOOK
exit 1
fi

# 检查备份大小
BACKUP_SIZE=$(du -m $LATEST_BACKUP | cut -f1)
if [ $BACKUP_SIZE -lt 10 ]; then
MESSAGE="⚠️ WARNING: MySQL backup is suspiciously small (${BACKUP_SIZE}MB)"
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$MESSAGE\"}" \
$SLACK_WEBHOOK
exit 1
fi

echo "✅ MySQL backup is healthy (age: ${AGE_HOURS}h, size: ${BACKUP_SIZE}MB)"
exit 0

10.2 Prometheus 监控指标

1
2
3
4
5
6
7
8
# prometheus.yml
scrape_configs:
- job_name: 'mysql-backup'
static_configs:
- targets: ['localhost:9104']
metrics_path: /probe
params:
module: [mysql_backup]
1
2
3
4
5
# 关键指标
mysql_backup_age_seconds # 备份年龄
mysql_backup_size_bytes # 备份大小
mysql_backup_status # 备份状态(1=成功,0=失败)
mysql_binlog_age_seconds # binlog 年龄

十一、总结

备份策略检查清单

  • 全量备份:每周至少一次
  • 增量备份:每天执行
  • Binlog 备份:实时开启
  • 备份验证:定期恢复测试
  • 异地备份:至少一份离线
  • 加密备份:敏感数据加密
  • 监控告警:失败及时通知
  • 文档记录:恢复流程文档化

RTO/RPO 目标

数据级别 RPO(数据丢失) RTO(恢复时间) 备份方案
核心数据 < 5 分钟 < 30 分钟 主从 + binlog
重要数据 < 1 小时 < 2 小时 每日增量 + binlog
一般数据 < 24 小时 < 4 小时 每日全量

最后更新: 2026-03-12

标签: #MySQL #备份 #恢复 #数据库运维 #数据安全

分类: 数据库/运维

参考资料: