那是个周六的凌晨,我正窝在沙发里刷剧,手机突然像抽风一样震个不停——五个站点的监控同时报警,全部指向“数据库连接失败”,我揉着眼睛爬上服务器,打开宝塔面板,手一抖差点把咖啡洒在键盘上:操作日志里,一串诡异的执行记录像幽灵一样排在那里——凌晨2点15分到2点17分,三个不同的数据库备份任务被依次执行,紧接着,对应的数据库目录被“自动清理”,可我根本没设置过任何定时清理脚本。
先别急着说“你肯定得罪人了”,我第一反应是查面板的登录记录——IP正常、账号正常、登录方式还是密钥,那问题就出在面板自身,我点开【计划任务】的列表,果然,一个我从未见过的任务规则静静躺在那里:每个周六凌晨2点,执行 find /www/wwwroot/*/database -mtime +0 -exec rm -rf {} \;,这个命令的恶毒之处在于,它把所有当天修改过的库文件全都删了,而宝塔的自动备份恰恰是凌晨2点跑的——备份完立刻被自己人干掉。
当时屏幕上的报错截图我现在还记得:一片深红底色,顶部是“Nginx 502”,中间是MySQL的“Can't connect to local MySQL server”,最下面那个小箭头指着 /www/wwwroot/site_a/database/backup_2025-01-13.sql.gz 已不存在的提示,那绝对是我见过最刺眼的“502”。
排查思路要稳,我先停掉面板的【计划任务】服务,再把Nginx和MySQL日志拉出来对比——时间戳完全吻合,说明不是外部入侵,接着我用 stat 命令去查那个备份文件的inode修改时间,发现文件居然是在2点14分被创建的,而删除动作发生在2点16分——这10秒间隔里,恰好有个“清理临时文件”任务错杀了新备份,原来,我上个月为了调一个DedeCMS的伪静态规则,手滑把默认的计划任务模板改了一笔,保存时没注意“执行周期”里的通配符冲突,导致这个清理任务被“继承”到了所有站点。
宝塔面板操作日志里的幽灵删除事件,一场与默认规则的赛跑
怎么救?我没法恢复已经物理删除的文件,但好在宝塔的【数据库】页签里,有个“定时备份”的额外副本存储到了阿里云OSS,我立刻手动触发一次全量备份,然后重建三个库的物理文件,再用网盘上的备份导入,整个过程花了两个小时,比重新配置环境快得多——但这破事本可以避免。
现在说预防建议,这比什么都值钱。第一,任何对宝塔【计划任务】的修改,必须截图存证并写进运维文档;第二,所有备份任务和“清理”任务,执行周期错开至少6小时,别让它们在同一个窗口期碰面;第三,数据库备份默认不要放在项目目录下,改成 /www/backup 这种独立路径,即使被误删,也不影响站点入口文件;第四,宝塔面板自带的【操作日志】和【系统日志】要定期导出,别全靠人脑记——我这次就是靠翻日志才定位到任务错配,否则得从入侵方向排查,白白浪费半天。
那个凌晨,我喝着凉透的咖啡,在键盘上敲下这篇文章时,面板右上角又弹出一条“新的计划任务已创建”——我默默点开,把执行周期改成了“每月1号”,并在备注里写了三个大字:“别手贱”,你踩过的坑,往往不是技术多高深,而是默认规则里藏着的那把隐形镰刀。



发表评论