Skip to content

备份恢复

定期备份是保障数据安全的重要措施。本文档介绍 DNS-Go 的备份和恢复策略。

备份内容

DNS-Go 需要备份以下内容:

内容重要性备份频率说明
数据库⭐⭐⭐ 必需每天所有域名、记录、用户数据
配置文件⭐⭐⭐ 必需每次修改系统配置参数
日志文件⭐⭐ 推荐每周查询日志、操作日志

数据库备份

PostgreSQL 备份

使用 pg_dump:

bash
#!/bin/bash
# backup-postgres.sh

DB_NAME="dns_go"
DB_USER="dnsgo"
BACKUP_DIR="/backup/dns-go"
DATE=$(date +%Y%m%d_%H%M%S)

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

# 执行备份
pg_dump -h localhost -U ${DB_USER} -d ${DB_NAME} \
  -F custom -f ${BACKUP_DIR}/dns_go_${DATE}.dump

# 压缩
gzip ${BACKUP_DIR}/dns_go_${DATE}.dump

# 保留最近 30 天
find ${BACKUP_DIR} -name "dns_go_*.dump.gz" -mtime +30 -delete

echo "[$(date)] PostgreSQL backup completed"

定时任务:

bash
crontab -e

# 每天凌晨 2 点备份
0 2 * * * /opt/backup/backup-postgres.sh >> /var/log/backup.log 2>&1

MySQL 备份

使用 mysqldump:

bash
#!/bin/bash
# backup-mysql.sh

DB_NAME="dns_go"
DB_USER="dnsgo"
DB_PASS="your_password"
BACKUP_DIR="/backup/dns-go"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p ${BACKUP_DIR}

mysqldump -u ${DB_USER} -p${DB_PASS} ${DB_NAME} \
  --single-transaction > ${BACKUP_DIR}/dns_go_${DATE}.sql

gzip ${BACKUP_DIR}/dns_go_${DATE}.sql

find ${BACKUP_DIR} -name "dns_go_*.sql.gz" -mtime +30 -delete

echo "[$(date)] MySQL backup completed"

配置文件备份

自动备份配置文件

bash
#!/bin/bash
# backup-config.sh

CONFIG_DIR="/opt/dns-go/config"
BACKUP_DIR="/backup/dns-go/config"
DATE=$(date +%Y%m%d)

mkdir -p ${BACKUP_DIR}

# 打包配置文件
tar czf ${BACKUP_DIR}/config_${DATE}.tar.gz -C ${CONFIG_DIR} .

# 保留最近 10 个版本
ls -t ${BACKUP_DIR}/config_*.tar.gz | tail -n +11 | xargs rm -f

echo "[$(date)] Config backup completed"

完整备份脚本

一键备份脚本

bash
#!/bin/bash
# backup-dns-go.sh

# 配置
BACKUP_ROOT="/backup/dns-go"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30

# 数据库配置
DB_TYPE="postgres"  # 或 mysql
DB_NAME="dns_go"
DB_USER="dnsgo"
DB_PASS="your_password"

# DNS-Go 配置
DNS_GO_DIR="/opt/dns-go"

# 创建备份目录
BACKUP_DIR="${BACKUP_ROOT}/${DATE}"
mkdir -p ${BACKUP_DIR}

echo "[$(date)] Starting DNS-Go backup..."

# 1. 备份数据库
echo "Backing up database..."
if [ "$DB_TYPE" = "postgres" ]; then
    pg_dump -h localhost -U ${DB_USER} -d ${DB_NAME} \
      -F custom -f ${BACKUP_DIR}/database.dump
else
    mysqldump -u ${DB_USER} -p${DB_PASS} ${DB_NAME} \
      --single-transaction > ${BACKUP_DIR}/database.sql
fi

# 2. 备份配置文件
echo "Backing up config..."
cp -r ${DNS_GO_DIR}/config ${BACKUP_DIR}/

# 3. 备份数据目录
echo "Backing up data..."
cp -r ${DNS_GO_DIR}/data ${BACKUP_DIR}/

# 4. 打包备份
echo "Creating backup archive..."
tar czf ${BACKUP_ROOT}/dns-go-backup-${DATE}.tar.gz -C ${BACKUP_ROOT} ${DATE}

# 5. 清理临时文件
rm -rf ${BACKUP_DIR}

# 6. 清理旧备份
find ${BACKUP_ROOT} -name "dns-go-backup-*.tar.gz" -mtime +${RETENTION_DAYS} -delete

echo "[$(date)] Backup completed: dns-go-backup-${DATE}.tar.gz"

# 7. 可选:上传到远程存储
# aws s3 cp ${BACKUP_ROOT}/dns-go-backup-${DATE}.tar.gz s3://your-bucket/backups/
# scp ${BACKUP_ROOT}/dns-go-backup-${DATE}.tar.gz user@backup-server:/backups/

数据恢复

完整恢复流程

场景:服务器故障,需要在新服务器恢复

bash
#!/bin/bash
# restore-dns-go.sh

BACKUP_FILE="dns-go-backup-20250115_020000.tar.gz"
BACKUP_ROOT="/backup/dns-go"
DNS_GO_DIR="/opt/dns-go"

# 1. 停止 DNS-Go
sudo systemctl stop dns-go

# 2. 解压备份
cd ${BACKUP_ROOT}
tar xzf ${BACKUP_FILE}
BACKUP_DIR=$(tar tzf ${BACKUP_FILE} | head -1)

# 3. 恢复配置文件
rm -rf ${DNS_GO_DIR}/config
cp -r ${BACKUP_DIR}/config ${DNS_GO_DIR}/

# 4. 恢复数据目录
rm -rf ${DNS_GO_DIR}/data
cp -r ${BACKUP_DIR}/data ${DNS_GO_DIR}/

# 5. 恢复数据库
if [ -f "${BACKUP_DIR}/database.dump" ]; then
    # PostgreSQL
    dropdb -h localhost -U dnsgo dns_go
    createdb -h localhost -U dnsgo dns_go
    pg_restore -h localhost -U dnsgo -d dns_go ${BACKUP_DIR}/database.dump
else
    # MySQL
    mysql -u dnsgo -p -e "DROP DATABASE dns_go; CREATE DATABASE dns_go;"
    mysql -u dnsgo -p dns_go < ${BACKUP_DIR}/database.sql
fi

# 6. 设置权限
sudo chown -R dnsgo:dnsgo ${DNS_GO_DIR}

# 7. 清理临时文件
rm -rf ${BACKUP_DIR}

# 8. 启动 DNS-Go
sudo systemctl start dns-go

echo "Restore completed!"

单表恢复

恢复误删除的域名:

bash
# PostgreSQL
pg_restore -h localhost -U dnsgo -d dns_go \
  --table=domains \
  --data-only \
  backup.dump

# MySQL
# 从备份 SQL 中提取并执行相关 INSERT 语句

配置文件恢复

bash
# 恢复单个配置文件
cp /backup/dns-go/config/config.toml.20250115 /opt/dns-go/config/config.toml

# 重启服务
sudo systemctl restart dns-go

备份验证

定期测试恢复

bash
#!/bin/bash
# verify-backup.sh

BACKUP_FILE="/backup/dns-go/dns-go-backup-latest.tar.gz"
TEST_DIR="/tmp/dns-go-restore-test"

# 清理测试目录
rm -rf ${TEST_DIR}
mkdir -p ${TEST_DIR}

# 解压备份
tar xzf ${BACKUP_FILE} -C ${TEST_DIR}

# 检查备份完整性
if [ ! -f "${TEST_DIR}/database.dump" ] && [ ! -f "${TEST_DIR}/database.sql" ]; then
    echo "ERROR: Database backup missing!"
    exit 1
fi

if [ ! -d "${TEST_DIR}/config" ]; then
    echo "ERROR: Config backup missing!"
    exit 1
fi

# 可选:测试数据库恢复
# createdb -U dnsgo test_restore
# pg_restore -U dnsgo -d test_restore ${TEST_DIR}/database.dump
# dropdb -U dnsgo test_restore

# 清理
rm -rf ${TEST_DIR}

echo "Backup verification passed!"

远程备份

上传到 S3

bash
#!/bin/bash
# backup-to-s3.sh

BACKUP_FILE="/backup/dns-go/dns-go-backup-$(date +%Y%m%d).tar.gz"
BUCKET="your-backup-bucket"

# 创建备份
/opt/backup/backup-dns-go.sh

# 上传到 S3
aws s3 cp ${BACKUP_FILE} s3://${BUCKET}/dns-go/

# 清理本地旧备份(保留最近 7 天)
find /backup/dns-go -name "dns-go-backup-*.tar.gz" -mtime +7 -delete

# 清理 S3 旧备份(保留最近 30 天)
aws s3 ls s3://${BUCKET}/dns-go/ | \
  awk '{print $4}' | \
  while read file; do
    # 删除 30 天前的备份
    : # 实现删除逻辑
  done

使用 rsync 同步

bash
#!/bin/bash
# sync-to-remote.sh

BACKUP_DIR="/backup/dns-go"
REMOTE_SERVER="backup@backup-server.example.com"
REMOTE_DIR="/backups/dns-go"

# 同步到远程服务器
rsync -avz --delete ${BACKUP_DIR}/ ${REMOTE_SERVER}:${REMOTE_DIR}/

echo "[$(date)] Backup synced to remote server"

灾难恢复计划

RPO 和 RTO

指标目标值说明
RPO24 小时最多丢失 24 小时数据
RTO2 小时2 小时内恢复服务

恢复流程

灾难发生

评估影响范围

准备新服务器/环境

恢复数据库

恢复配置文件

启动 DNS-Go 服务

验证服务正常

切换 DNS 指向

监控运行状态

应急联系

角色联系人联系方式
系统管理员--
数据库管理员--
网络管理员--

最佳实践

备份策略

  1. 3-2-1 原则

    • 3 份数据副本
    • 2 种不同存储介质
    • 1 份异地备份
  2. 自动化备份

    • 使用 cron 定时任务
    • 监控备份任务执行
    • 及时告警备份失败
  3. 定期测试

    • 每月测试恢复流程
    • 验证备份数据完整性
    • 更新恢复文档

存储建议

存储位置用途保留时间
本地磁盘快速恢复7 天
网络存储故障恢复30 天
云存储灾难恢复90 天

相关文档

基于 MIT 许可发布