不能直接在web请求里做数据库清理,因web请求有30–120秒超时限制,而清理任务可能耗时数分钟;php-fpm/apache子进程不保证长期存活,set_time_limit(0)在部分sapi下无效,且并发触发会导致重复执行或锁表冲突。

为什么不能直接在Web请求里做数据库清理
Web请求有超时限制(通常30–120秒),而清理旧日志、归档表或批量删除可能耗时数分钟甚至更久;一旦超时,任务中断且无重试机制。更关键的是,PHP-FPM 或 Apache 的子进程不保证长期存活,set_time_limit(0) 在某些 SAPI 下无效,且并发请求触发多次清理会导致重复执行或锁表冲突。
如何用CLI脚本安全地编写清理逻辑
CLI模式无超时、可访问完整PHP配置、支持事务与信号处理。重点注意三点:
- 始终用
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,避免静默失败 - 对大表删除务必分批操作,例如每次删
1000行,配合WHERE created_at 和 <code>LIMIT(MySQL)或FETCH FIRST 1000 ROWS ONLY(PostgreSQL) - 加锁防止Cron重复启动:用
flock包裹主逻辑,或写临时锁文件并检查file_exists()+filemtime()防陈旧锁 - 日志必须写入文件(如
/var/log/myapp/cleanup.log),别依赖error_log()—— Cron 默认不捕获 stderr
示例片段:
#!/usr/bin/env php
<?php $pdo = new PDO('mysql:host=localhost;dbname=myapp', $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$lock = fopen('/tmp/cleanup.lock', 'c');
if (!flock($lock, LOCK_EX | LOCK_NB)) {
exit("Another cleanup is running\n");
}
try {
$stmt = $pdo->prepare("DELETE FROM logs WHERE created_at execute() && $stmt->rowCount() === 1000) {
usleep(10000); // 避免锁表太久
}
} finally {
flock($lock, LOCK_UN);
fclose($lock);
}
Cron条目怎么写才可靠
Cron环境变量极简(PATH常为 /usr/bin:/bin),不加载用户shell配置,容易因找不到 php 或扩展而失败。
- 绝对路径写死:用
which php查到真实路径,比如/usr/bin/php,别用php - 显式指定INI文件:加
-c /etc/php/8.2/cli/php.ini,确保pdo_mysql等扩展已启用 - 重定向输出:用
> /dev/null 2>&1屏蔽正常输出,但调试期建议写入日志,如> /var/log/myapp/cleanup-cron.log 2>&1 - 避免高频调度:清理任务设为每天一次(
0 2 * * *),而非每分钟 —— 错误的* * * * *可能瞬间堆积数十个进程
正确写法示例:
0 2 * * * /usr/bin/php -c /etc/php/8.2/cli/php.ini /var/www/myapp/cli/cleanup.php >> /var/log/myapp/cleanup-cron.log 2>&1
清理失败后如何快速定位问题
Cron失败几乎不报错,得靠三处排查:
- 查系统级Cron日志:
/var/log/syslog或journalctl -u cron -n 50,找 “CRON” 关键字,看是否因权限、路径不存在被拒绝 - 检查脚本权限:
chmod +x /var/www/myapp/cli/cleanup.php,且运行用户(如www-data)对数据库有DELETE权限,对日志目录有写权限 - 手动模拟Cron环境执行:
env -i PATH=/usr/bin:/bin /usr/bin/php -c /etc/php/8.2/cli/php.ini /var/www/myapp/cli/cleanup.php—— 这比直接敲php xxx.php更接近真实场景
特别注意:如果清理涉及外键约束或触发器,SET FOREIGN_KEY_CHECKS=0 要谨慎使用,优先用 ON DELETE CASCADE 或先删子表再删主表。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











