find -mtime +N 删除错误是因为 -mtime 基于距今完整24小时而非创建日,且 mtime 易被 touch 或 rsync 误改;应统一用 touch -d "$DATE" 对齐时间戳,或按文件名匹配清理。
find -mtime +N 清理为什么有时删错文件?
因为
看的是“距今多少个完整 24 小时”,不是“创建日期超过 n 天”。比如一个文件是昨天 23:59 创建的,今天 00:01 运行
,它不会被匹配——因为还没满 24 小时。
实际保留逻辑应按“最后修改时间”计算,而备份脚本中
生成的
文件,其
就是压缩完成时刻,一般可靠
但若备份后又用
或 rsync 同步过,
可能被意外更新,导致误删;此时应改用
按精确秒级时间过滤
更稳妥的做法:统一在备份脚本末尾加
,让文件时间戳对齐命名中的日期,后续清理可直接按名匹配(如
)
保留最新 N 个备份比按天数更安全吗?
不一定。按数量保留(如只留最近 5 个)在备份失败或漏跑时会掩盖问题——比如连续 3 天没成功备份,你仍剩 5 个“旧”文件,但实际已无有效新备份;而按天数(如
)能暴露中断,日志里会显示“未找到可删文件”,反而提醒你检查失败原因。
生产环境推荐“分层保留”:关键库(如用户账户库)用
,普通业务库用
,临时测试库用
若必须按数量,别直接
,要用
,避免文件名含空格或换行时报错
注意:MySQL 的
备份本身不保证跨实例一致性,若主从延迟大,单纯保留多个备份不能替代 GTID 或 binlog 位点定位
清理脚本加了 -delete 却没反应?常见权限与路径陷阱
要求对**父目录有写权限**,不是对文件本身。也就是说,即使你能
某个
,但若
目录属主是
、权限是
,而清理脚本以
用户运行,
就会静默失败。
先验证权限:
,确保运行脚本的用户对该目录有
权限
别用通配符路径如
,
不展开 shell 通配,应写死
上线前务必在测试机跑一次带
的预演命令:
,确认列出的全是预期文件
严禁在脚本里写
类操作——路径变量为空时会变成
,真发生过
跨版本恢复时,旧备份真的能用吗?
不能默认认为“能备份就能恢复”。MySQL 5.7 备份的
在 8.0 上可能因
→
默认变更、
移除等报错;PostgreSQL 12 的
输出在 15 上恢复也可能因权限模型调整失败。
每次数据库升级前,必须用旧备份在同版本测试库执行一次完整恢复流程,并校验表行数和关键字段值
备份脚本里加上版本标识:
,追加到压缩包开头,方便后续排查
不要只存
,对核心库额外存一份
生成的纯数据文件(
),它格式稳定、跨版本兼容性更好,只是恢复慢一点
最常被跳过的一步:清理策略生效前,没验证过恢复链是否完整。删掉的不是文件,是某次 RPO 时间点的唯一凭证。
-mtimefind -mtime +0mysqldump | gzip.sql.gzmtimetouchmtime-printf '%T@ %p\n' | awktouch -d "$DATE" "$BACKUP_FILE"find ... -name 'mydb_202[0-9][0-9][0-9][0-9]_*.sql.gz'RETENTION_DAYS=7RETENTION_DAYS=90307ls | head -n -5find -printf '%T@ %p\n' | sort -n | head -n -5 | cut -d' ' -f2- | xargs rm -fmysqldump --single-transactionfind ... -deleterm.sql.gz/data/backupsroot755mysql-deletels -ld $BACKUP_DIRw/data/backup/*findBACKUP_DIR="/data/backup/mysql"-printfind "$BACKUP_DIR" -name "*.sql.gz" -type f -mtime +7 -printrm -rf $BACKUP_DIR/*rm -rf /*.sqlutf8mb3utf8mb4NO_AUTO_CREATE_USERpg_dumpecho "# MYSQL_VERSION: $(mysql --version)" > "$BACKUP_FILE".sql.gzmysqldump --tab.txt