接上篇,上次提到了排查是因为服务器的磁盘不够导致服务器没有写入的空间,进一步导致服务器宕机,下面是我清理磁盘日志的操作。

清理日志文件(*.log文件)

我们的Java的日志文件是根据日期分开成不同的log,所以我写了一个shell脚本用来每天定时清理三天之前的所有日志文件。

清理的Linux命令如下:

1
find log文件的文件路径 -mtime +3 -name "*.log" -exec rm -rf {} \;

shell脚本命令如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

# 指定日志目录路径
log_dir="*******/***/***"

# 计算三天前的日期
three_days_ago=$(date -d "3 days ago" +%Y%m%d)

# 删除三天前的日志文件
find "$log_dir" -mtime +3 -name "*.log" -exec rm -rf {} \;

echo "已删除 $log_dir 目录下 $three_days_ago 之前的日志文件。"

保存为一个shell脚本文件之后,赋予此文件执行权限:

1
chmod +x cleanup_logs.sh

然后写一个定时任务,让这个shell脚本文件每天早上八点执行一次

1
2
# 打开cron编辑器
crontab -e

然后在编辑器中添加以下行,以在每天的固定时间执行脚本(假设你希望在每天的凌晨8点执行):

1
2
0 8 * * * /path/to/cleanup_logs.sh
#文件路径:/path/to/cleanup_logs.sh

清理MySQL中request_log表的文件:

由于这个表已经非常大了、估计多少有个几千万条记录了、通过delete from tableName肯定是不现实了,那么因为需要MySQL会先查数据然后删相关数据,所以我想到了分段删除的思想,也就是分批次来删除半年前的数据,那么这时候就有一个问题了,难不成手动删?显然不现实,于是我想到了MySQL中的定时器PROCEDURE,先定义个PROCEDURE函数,具体函数实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
DELIMITER //
CREATE PROCEDURE DeleteOldRecords()
BEGIN
DECLARE batch_size INT DEFAULT 10000; -- 每批次删除的记录数
DECLARE total_records INT;
DECLARE deleted_records INT;
SET total_records = (SELECT COUNT(*) FROM tableName WHERE create_time <= DATE_SUB(NOW(), INTERVAL 6 MONTH));

WHILE total_records > 0 DO
DELETE FROM tableName
WHERE create_time <= DATE_SUB(NOW(), INTERVAL 6 MONTH)
LIMIT batch_size;

SET deleted_records = ROW_COUNT();
SET total_records = total_records - deleted_records;
END WHILE;
END //
DELIMITER ;

#create_time代表某条记录的创建时间字段
#tableName代表你要执行函数的表名

最后执行CALL DeleteOldRecords();的sql语句使以上函数开始删除相关记录

当然还需要等执行完此函数之后,删除此函数,sql命令如下:

1
DROP PROCEDURE IF EXISTS DeleteOldRecords;