清理日志表前须先确认表结构与数据增长模式,检查时间字段、主键及业务依赖;使用分批带条件的DELETE语句并确保时间字段有索引;通过宝塔定时执行Shell脚本,配合权限控制、日志统计与防误删机制保障安全。

清理日志表前先确认表结构和数据增长模式
直接删数据前,得先搞清日志表是不是带时间字段、有没有主键、是否被其他业务逻辑依赖。常见如 wp_options(WordPress 的 _transient_ 类临时数据)、dede_sys_log(织梦后台操作日志)、phpwind_log 或自定义的 user_login_log、api_request_log 等。用 phpMyAdmin 或命令行连上数据库,执行:
DESCRIBE `user_login_log`;
重点看是否有 create_time、log_time、addtime 这类字段;再查下最近 30 天有多少数据:
SELECT COUNT(*) FROM `user_login_log` WHERE `create_time` <p>如果返回值很大,且业务上确实不需要保留这么久,就可以继续。别一上来就 <code>TRUNCATE</code> —— 那会锁表、重置自增 ID,还可能破坏外键约束。</p><h3>写安全可回溯的 DELETE SQL 脚本</h3><p>推荐用带条件、分批次的 <code>DELETE</code>,避免单次操作卡死或触发 MySQL 的 <code>max_allowed_packet</code> 或事务日志爆满。例如清理 90 天前的请求日志:</p><pre class="brush:php;toolbar:false;">DELETE FROM `api_request_log` WHERE `created_at`
-
ORDER BY id ASC+LIMIT是为了控制每次只删固定行数,降低锁表时间 - 务必加
WHERE时间条件,且字段要有索引(没索引的话先建:ALTER TABLE `api_request_log` ADD INDEX idx_created_at (`created_at`);) - 别用
SELECT * FROM ... INTO OUTFILE做备份再删——宝塔计划任务不支持多语句,也不方便自动归档 - 如果表没有时间字段,但有自增
id,可按 ID 范围删(需先估算 ID 增长速率)
在宝塔面板中创建定时 SQL 任务
宝塔不支持直接执行 SQL 文件,但能调用 mysql 命令行工具执行语句。你需要把 SQL 写成 shell 脚本,再加进计划任务:
第一步:新建脚本文件,比如 /www/server/panel/script/clean_api_log.sh,内容如下:
#!/bin/bash DB_NAME="your_db_name" DB_USER="your_db_user" DB_PASS="your_db_pass" DB_HOST="127.0.0.1" DB_PORT="3306" <p>mysql -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASS $DB_NAME -e " DELETE FROM `api_request_log` WHERE `created_at` </p>
第二步:给脚本加执行权限:chmod +x /www/server/panel/script/clean_api_log.sh
第三步:在宝塔「计划任务」→「Shell 脚本」中添加,执行周期设为每天凌晨 2 点,脚本内容填:/www/server/panel/script/clean_api_log.sh
- 密码明文写在脚本里有风险,生产环境建议改用
~/.my.cnf配置文件免密登录 - 务必先手动运行一次脚本,检查输出是否报错(比如
Access denied或Unknown column) - 宝塔默认以
www用户运行脚本,确保该用户对脚本文件有读取权限、对数据库有 DELETE 权限
验证效果与防误删兜底措施
脚本跑完不能光看“执行成功”,要查实际删了多少行。可以在脚本末尾加一行统计:
echo "$(date): $(mysql -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASS $DB_NAME -Nse "SELECT COUNT(*) FROM \`api_request_log\` WHERE \`created_at\` > /var/log/clean_api_log.log
同时建议加个简单保护机制:
- 首次上线时,把
LIMIT 10000改成LIMIT 100,观察三天 - 在 SQL 前加判断:只有当待删数据 > 5000 行时才执行(避免空跑或误触)
- 所有日志表清理任务,都单独建一个数据库用户,只授予对应表的
DELETE权限,不给DROP或ALTER
真正麻烦的不是写 SQL,而是某天发现订单日志表被当成行为日志一起清了——因为两个表名都叫 xxx_log,而脚本里用的是模糊匹配或通配符。这种细节,宝塔面板不会提醒你。











