数据备份与恢复
问题
如何制定数据库备份策略?出现故障时如何恢复?
答案
备份类型
| 类型 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| 全量备份 | 备份整个数据库 | 恢复简单 | 耗时长、占空间 |
| 增量备份 | 仅备份自上次备份后的变更 | 快速、省空间 | 恢复需要依次应用 |
| 差异备份 | 备份自上次全量备份后的变更 | 恢复比增量简单 | 比增量占空间 |
备份策略
MySQL 备份
# 逻辑备份(mysqldump)
mysqldump -u root -p --single-transaction --routines \
--databases myapp > backup_$(date +%Y%m%d).sql
# 恢复
mysql -u root -p myapp < backup_20240101.sql
# 物理备份(大数据量推荐 xtrabackup)
xtrabackup --backup --target-dir=/backup/full
# 二进制日志(Point-in-Time Recovery)
mysqlbinlog --start-datetime="2024-01-01 10:00:00" \
--stop-datetime="2024-01-01 11:00:00" binlog.000001 | mysql -u root -p
自动化备份脚本
backup-script.ts
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
async function backupDatabase() {
const timestamp = new Date().toISOString().slice(0, 10);
const filename = `backup_${timestamp}.sql.gz`;
// 1. 导出并压缩
await execAsync(
`mysqldump -u ${process.env.DB_USER} -p${process.env.DB_PASS} \
--single-transaction ${process.env.DB_NAME} | gzip > /backups/${filename}`,
);
// 2. 上传到 S3
await execAsync(
`aws s3 cp /backups/${filename} s3://my-backups/mysql/${filename}`,
);
// 3. 清理 30 天前的本地备份
await execAsync('find /backups -name "*.sql.gz" -mtime +30 -delete');
// 4. 通知
console.log(`Backup completed: ${filename}`);
}
恢复验证
关键
备份不验证等于没备份!定期恢复到测试环境验证备份完整性。
常见面试问题
Q1: RPO 和 RTO 是什么?
答案:
- RPO(Recovery Point Objective):可容许的数据丢失量。RPO = 1 小时意味着最多丢 1 小时数据
- RTO(Recovery Time Objective):可容许的恢复时间。RTO = 30 分钟意味着 30 分钟内必须恢复
Q2: 逻辑备份和物理备份怎么选?
答案:
- 逻辑备份(mysqldump):SQL 可读、跨版本兼容,但慢,适合小数据量(< 50GB)
- 物理备份(xtrabackup):直接拷贝文件,速度快,适合大数据量
Q3: 如何防止误删数据?
答案:
- 使用软删除(
deleted_at字段) - 开启 Binlog(可按时间点恢复)
- 生产数据库禁止直接 DELETE/DROP 权限
- 重要操作前手动备份