Become a sponsor

生产环境必须备份
数据库和上传文件必须定期备份,建议每天自动备份。备份文件应存储在独立于服务器的安全位置。
# -----------------------------------------------------------------------------
# MySQL 全量备份(结构 + 数据)
# -----------------------------------------------------------------------------
# -u root → 数据库用户名
# -proot → 数据库密码(生产环境建议用 -p 后不跟密码,交互式输入)
# rxthinkcmf... → 要备份的数据库名
# > backup_*.sql → 输出到文件,$(date +%Y%m%d) 自动生成日期后缀
mysqldump -u root -proot rxthinkcmf.thinkphp6.elevue > backup_$(date +%Y%m%d).sql
# -----------------------------------------------------------------------------
# 压缩备份(推荐 — 可节省 70%+ 磁盘空间)
# -----------------------------------------------------------------------------
# | gzip → 将 mysqldump 输出通过管道传给 gzip 压缩
mysqldump -u root -proot rxthinkcmf.thinkphp6.elevue | gzip > backup_$(date +%Y%m%d).sql.gz
# -----------------------------------------------------------------------------
# 仅备份表结构(不含数据 — 用于对比表结构变更)
# -----------------------------------------------------------------------------
# --no-data → 只导出 CREATE TABLE 语句,不导出数据
mysqldump -u root -proot --no-data rxthinkcmf.thinkphp6.elevue > schema_$(date +%Y%m%d).sql
# -----------------------------------------------------------------------------
# 仅备份数据(不含表结构 — 用于数据迁移)
# -----------------------------------------------------------------------------
# --no-create-info → 只导出 INSERT 语句,不导出 CREATE TABLE
mysqldump -u root -proot --no-create-info rxthinkcmf.thinkphp6.elevue > data_$(date +%Y%m%d).sql#!/bin/bash
# =============================================================================
# backup_db.sh — 数据库自动备份脚本
# =============================================================================
# 用途:自动备份 MySQL 数据库,压缩存储,自动清理过期备份
# 用法:crontab 定时调用,或手动执行 bash backup_db.sh
# =============================================================================
# -----------------------------------------------------------------------------
# 配置参数(按实际环境修改)
# -----------------------------------------------------------------------------
BACKUP_DIR="/backup/mysql" # 备份文件存放目录
DB_NAME="rxthinkcmf.thinkphp6.elevue" # 要备份的数据库名
DB_USER="root" # 数据库用户名
DB_PASS="root" # 数据库密码
DATE=$(date +%Y%m%d_%H%M%S) # 当前时间戳(年月日_时分秒)
KEEP_DAYS=30 # 保留最近 N 天的备份
# -----------------------------------------------------------------------------
# 创建备份目录(-p 参数:目录不存在时自动创建)
# -----------------------------------------------------------------------------
mkdir -p $BACKUP_DIR
# -----------------------------------------------------------------------------
# 执行备份(mysqldump 输出通过管道传给 gzip 压缩)
# -----------------------------------------------------------------------------
mysqldump -u $DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/backup_$DATE.sql.gz
# -----------------------------------------------------------------------------
# 检查备份结果($? 为上一条命令的退出码,0=成功)
# -----------------------------------------------------------------------------
if [ $? -eq 0 ]; then
echo "[$(date)] 备份成功: backup_$DATE.sql.gz"
else
echo "[$(date)] 备份失败!"
exit 1 # 非零退出码表示失败,便于监控系统捕获
fi
# -----------------------------------------------------------------------------
# 清理过期备份
# -----------------------------------------------------------------------------
# find 参数说明:
# -name "backup_*.sql.gz" → 匹配备份文件名格式
# -mtime +$KEEP_DAYS → 修改时间超过 N 天的文件
# -delete → 删除匹配的文件
find $BACKUP_DIR -name "backup_*.sql.gz" -mtime +$KEEP_DAYS -delete
echo "[$(date)] 清理完成,保留最近 $KEEP_DAYS 天的备份"# 编辑当前用户的 crontab 定时任务
crontab -e
# -----------------------------------------------------------------------------
# 定时备份规则
# -----------------------------------------------------------------------------
# 格式:分 时 日 月 周 命令
# 0 3 * * * → 每天凌晨 3:00 执行
# 0 4 * * 0 → 每周日凌晨 4:00 执行(0=周日)
# >> /var/log/backup.log 2>&1 → 追加日志(2>&1 将错误也写入日志)
# -----------------------------------------------------------------------------
0 3 * * * /www/scripts/backup_db.sh >> /var/log/backup.log 2>&1
0 4 * * 0 /www/scripts/backup_db_full.sh >> /var/log/backup.log 2>&1# -----------------------------------------------------------------------------
# 备份上传目录为压缩包
# -----------------------------------------------------------------------------
# tar 参数说明:
# -c → 创建新归档
# -z → 用 gzip 压缩
# -f → 指定输出文件名
# $(date +%Y%m%d) → 自动生成日期后缀
tar -czf /backup/uploads_$(date +%Y%m%d).tar.gz /opt/data/uploads/
# -----------------------------------------------------------------------------
# 上传文件自动备份脚本
# -----------------------------------------------------------------------------
#!/bin/bash
BACKUP_DIR="/backup/uploads" # 备份存放目录
DATE=$(date +%Y%m%d) # 日期后缀
mkdir -p $BACKUP_DIR # 创建目录(如不存在)
tar -czf $BACKUP_DIR/uploads_$DATE.tar.gz /opt/data/uploads/ # 压缩打包
find $BACKUP_DIR -name "uploads_*.tar.gz" -mtime +30 -delete # 清理 30 天前的备份# -----------------------------------------------------------------------------
# 从 SQL 文件恢复(全量覆盖)
# -----------------------------------------------------------------------------
# < backup_*.sql → 将文件内容作为 mysql 命令的输入
mysql -u root -proot rxthinkcmf.thinkphp6.elevue < backup_20260920.sql
# -----------------------------------------------------------------------------
# 从压缩文件恢复(gunzip 解压后传给 mysql)
# -----------------------------------------------------------------------------
# gunzip < file.sql.gz → 解压并输出到标准输出
# | mysql → 通过管道传给 mysql 命令执行
gunzip < backup_20260920.sql.gz | mysql -u root -proot rxthinkcmf.thinkphp6.elevue
# -----------------------------------------------------------------------------
# 恢复到新数据库(安全起见 — 先验证再切换)
# -----------------------------------------------------------------------------
# 1. 创建临时验证数据库
mysql -u root -proot -e "CREATE DATABASE `rxthinkcmf.thinkphp6.elevue_restore`;"
# 2. 恢复备份到临时库
mysql -u root -proot rxthinkcmf.thinkphp6.elevue_restore < backup_20260920.sql
# 3. 验证数据无误后,重命名数据库(需停机操作)# -----------------------------------------------------------------------------
# 恢复上传目录到原始位置
# -----------------------------------------------------------------------------
# tar 参数说明:
# -x → 解压归档
# -z → 解压 gzip
# -f → 指定归档文件
# -C → 解压到指定目录(/ 表示按归档内的绝对路径还原)
tar -xzf /backup/uploads_20260920.tar.gz -C /
# -----------------------------------------------------------------------------
# 仅恢复特定子目录(如只恢复文章附件)
# -----------------------------------------------------------------------------
# 在归档文件名后追加要解压的路径前缀
tar -xzf /backup/uploads_20260920.tar.gz -C / www/uploads/article/必须定期验证备份
备份文件必须定期恢复验证,确保备份可用。建议每月进行一次恢复测试。
#!/bin/bash
# =============================================================================
# verify_backup.sh — 备份验证脚本
# =============================================================================
# 用途:将备份恢复到临时数据库,验证数据完整性后清理
# 用法:bash verify_backup.sh backup_20260920.sql.gz
# =============================================================================
BACKUP_FILE=$1 # 第一个参数:备份文件路径
VERIFY_DB="rxthinkcmf.thinkphp6.elevue_verify" # 临时验证数据库名
# -----------------------------------------------------------------------------
# 创建验证数据库(先删除旧的,再创建新的)
# -----------------------------------------------------------------------------
# DROP DATABASE IF EXISTS → 如果存在则删除(避免同名冲突)
mysql -u root -p -e "DROP DATABASE IF EXISTS $VERIFY_DB; CREATE DATABASE $VERIFY_DB;"
# -----------------------------------------------------------------------------
# 恢复备份到验证数据库
# -----------------------------------------------------------------------------
gunzip < $BACKUP_FILE | mysql -u root -p $VERIFY_DB
# -----------------------------------------------------------------------------
# 验证数据完整性
# -----------------------------------------------------------------------------
# -N → 不输出表头(只输出数据值)
# information_schema.tables → MySQL 系统表,存储所有表的元信息
TABLE_COUNT=$(mysql -u root -p -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$VERIFY_DB';")
echo "恢复的表数量: $TABLE_COUNT"
# 检查用户表数据量(验证核心数据是否完整)
USER_COUNT=$(mysql -u root -p -N -e "SELECT COUNT(*) FROM $VERIFY_DB.think_user;")
echo "用户数量: $USER_COUNT"
# -----------------------------------------------------------------------------
# 清理验证数据库(验证完毕后删除临时库)
# -----------------------------------------------------------------------------
mysql -u root -p -e "DROP DATABASE $VERIFY_DB;"
echo "备份验证完成"| 存储方式 | 优点 | 缺点 |
|---|---|---|
| 本地磁盘 | 速度快 | 服务器故障可能丢失 |
| NAS / 网络存储 | 独立于服务器 | 需要网络 |
| 云存储(OSS/S3) | 高可靠、异地 | 需要付费 |
| 异地服务器 | 灾难恢复 | 需要维护 |
最佳实践