在Linux系统上跑任务会遇到系统磁盘空间爆满的情况,表现出来的现象是程序运行报错,或执行缓慢。记录下Linux磁盘空间占用的查看方法和文件清理脚本定时触发配置的实现。
一、Linux磁盘空间占用分析
这边用df和du命令配合来查找占用磁盘空间的大头,找到文件目录之后,再根据文件类型决定是删除还是对磁盘扩容。
首先使用df -h命令查看磁盘整体的占用百分比和占用大小情况,先确定是哪个文件夹占用较多,如果文件较多命令执行可能很慢,这边df命令如果没加-h参数,输出的容量、已用和可用数据就是没转化的字节大小。
~$ df -h 文件系统 容量 已用 可用 已用% 挂载点 udev 16G 0 16G 0% /dev tmpfs 3.2G 11M 3.2G 1% /run /dev/nvme0n1p2 234G 182G 40G 83% / tmpfs 16G 0 16G 0% /dev/shm tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 16G 0 16G 0% /sys/fs/cgroup
可以看到当前根目录占用83%,接着使用du命令继续查找占用大头的文件夹,du的–max-depth=1表示只展示第一个层级的目录和文件,sort的-h选项和du的-h选项一样,-r表示倒叙,默认升序。
~$ du -h / --max-depth=1 | sort -hr | head -n 10
186G /
161G /home
6.3G /usr
5.9G /var
4.3G /lib
4.0G /tmp
3.8G /snap
418M /opt
375M /boot
288M /bin
可以看出/home目录占用大头,接着继续查看/home目录下的文件占用:
~$ du -h /home --max-depth=1 | sort -hr | head -n 10 161G /home 150G /home/arc 4.0K /home/Systemback
~$ du -h /home/arc --max-depth=1 | sort -hr | head -n 10 150G /home/arc 90G /home/arc/lizr 27G /home/arc/WebstormProjects 8.7G /home/arc/arc-log 7.5G /home/arc/arc-resources 5.1G /home/arc/autoPressureLog 4.0G /home/arc/atf_runner 1.3G /home/arc/AtfCaseServer 524M /home/arc/.local 522M /home/arc/ArcCaseServer
~$ du -h /home/arc/lizr --max-depth=1 | sort -hr | head -n 10 90G /home/arc/lizr/master 90G /home/arc/lizr 4.0K /home/arc/lizr/protocol
~$ du -h /home/arc/lizr/master --max-depth=1 | sort -hr | head -n 10 90G /home/arc/lizr/master 45G /home/arc/lizr/master/atf_runner 44G /home/arc/lizr/master/atf_report 1.1G /home/arc/lizr/master/atf 108K /home/arc/lizr/master/atf_pre 20K /home/arc/lizr/master/atf_apk
现在可以知道是atf_runner和atf_report占用最多,接着可以用ls -l查看这两个文件夹下面有哪些文件
~$ ls -l /home/arc/lizr/master/atf_report/
总用量 24772 drwxrwxr-x 4 arc arc 4096 3月 7 01:45 20210307_014457514410 drwxrwxr-x 4 arc arc 4096 3月 7 01:47 20210307_014601203246 drwxrwxr-x 4 arc arc 4096 3月 7 01:48 20210307_014736618057 drwxrwxr-x 4 arc arc 4096 3月 7 01:50 20210307_014900881721 ....
~$ ls -l /home/arc/lizr/master/atf_runner/
比如这边查看在atf_report目录下有6193个报告文件,都是以日期命名的文件夹,有如下三种方式批量删除文件
1)用日期前缀删除较早的文件;例如把20210307开头的文件夹都删除:
rm -rf /home/arc/lizr/master/atf_report/20210307*
2)保留最近5天的文件,5天之前的文件都清除;例如保留atf_report目录下最近5天的文件,超过5天的都删除,要保留不同的天数,配置不同的-mtime参数就行,也可以同时对删除的文件名做一个匹配过滤,这边配置‘*’不做过滤:
find /home/arc/lizr/master/atf_report/ -mtime +5 -name '*' -exec rm -rf {} \;
3)限制文件夹大小批量清除;例如在一天之内跑的任务过多,定时清理文件操作删除不及时还是容易导致存储空间不足,可以限制监控的文件夹大小为固定阈值,逐天删除文件夹下的文件直到文件夹大小小于安全阈值。以下是供参考的脚本实现,clear_path_array配置监控的文件夹参数,limitSize配置安全阈值大小,同时定时触发的周期可配置成半天或几个小时触发检测一次。
#!/bin/bash
#每个文件夹限制2GB大小
limitSize=$[ 2 * 1024 * 1024 * 1024 ]
clear_path_array[0]="/home/arc/lizr/master/atf_runner/apk_package/"
clear_path_array[1]="/home/arc/lizr/master/atf_runner/log/amap_log/"
clear_path_array[2]="/home/arc/lizr/master/atf_runner/log/info_log/"
clear_path_array[3]="/home/arc/lizr/master/atf/temp/"
clear_path_array[4]="/home/arc/lizr/master/atf/log/"
clear_path_array[5]="/home/arc/lizr/master/atf_report/"
clear_path_array[6]="/home/arc/lizr/master/atf_apk/"
clear_path_array[7]="/home/arc/atf_runner/atf/apk_package/"
clear_path_array[8]="/home/arc/atf_runner/atf/log/"
clear_path_array[9]="/home/arc/atf_runner/atf_report/"
for path in ${clear_path_array[@]}
do
#echo ">>>>>>${path}"
#判断文件夹是否存在并具有权限
if [ -x "${path}" ]
then
# 查看文件夹大小,以字节大小形式输出
folderSize=$(du -b ${path} --max-depth=0 | tr -cd "[0-9]")
echo ">>>>>>>${path} size is ${folderSize}"
day=5
# 逐天删除直到文件夹大小小于2GB
while [ $folderSize -ge $limitSize ]
do
echo ">>>>>>>day=$day"
find $path -mtime +$day -name '*' -exec rm -rf {} \;
if [ -x "${path}" ]
then
day=$[day-1]
folderSize=$(du -b ${path} --max-depth=0 | tr -cd "[0-9]")
echo ">>>>>>>${path} size is ${folderSize}"
else
folderSize=0
fi
done
fi
done
4)根据系统磁盘空间确定一个安全阈值,指定几个目录做清除处理,比如超过85%的时候,遍历指定的文件路径逐天删除文件直到磁盘空间占用降低到安全阈值内。
~$ df -h 文件系统 容量 已用 可用 已用% 挂载点 udev 16G 0 16G 0% /dev tmpfs 3.2G 2.6M 3.2G 1% /run /dev/nvme0n1p2 234G 164G 58G 74% / tmpfs 16G 54M 16G 1% /dev/shm
比如这边通过df -h命令查看主要的磁盘占用在/dev/nvme0n1p2,就通过这边的已用百分比来判断,对应的处理脚本逻辑如下:
#!/bin/bash #5天有效期 clear_path_five[0]="/home/arc/lizr/master/atf_report/" clear_path_five[1]="/home/arc/lizr/master/atf_runner/log/amap_log/" clear_path_five[2]="/home/arc/lizr/master/atf_runner/log/info_log/" clear_path_five[3]="/home/arc/atf_runner/atf/log/" clear_path_five[4]="/home/arc/atf_runner/atf_report/" #检查磁盘占用百分比,超过85%则逐天清理直到小于安全阈值,这边从第五列第四行截取数据 memUsedPercent=`df -h | awk '{print $5}' | sed -n '4p'` percent=${memUsedPercent%"%"} threshold=85 dayFive=5 if [ $percent -lt $threshold ] then echo "无需清理!" else # 至少保留两天的文件 while [[ $percent -gt $threshold && $dayFive -gt 2 ]] do dayFive=$[dayFive-1] echo ">>>>>>>dayFive clean day before=$dayFive" for path in ${clear_path_five[@]} do if [ -x "${path}" ] then find $path -mtime +$dayFive -name '*' -exec rm -rf {} \; fi done memUsedPercent=`df -h | awk '{print $5}' | sed -n '4p'` percent=${memUsedPercent%"%"} done fi
如果是在Ubuntu环境下用sh命令执行脚本,不注意的话会报出数组初始化的异常:
clear_path_five[0]=/home/arc/lizr/master/atf_report/: not found clear_path_five[1]=/home/arc/lizr/master/atf_runner/log/amap_log/: not found clear_path_five[2]=/home/arc/lizr/master/atf_runner/log/info_log/: not found clear_path_five[3]=/home/arc/atf_runner/atf/log/: not found
这个是因为Ubuntu中默认的shell是dash,不支持数组。执行 ls -l /bin/sh 命令可以看到sh是个指向dash的链接,虽然在脚本开头声明了#!/bin/sh,其实还是用的dash。所以在执行的时候用完整路径去执行sh脚本。
dash,是Ubuntu里默认的shell。shell有好多种,除支持默认的POSIX标准外还支持不同的扩展语法,目前最常用的是bash,很多shell学习的教程都是针对bash的。dash除了不支持数组外,其实和bash差别也不大。ubuntu里可以将默认shell由dash改为bash。
二、定时文件清理脚本配置实现
1、Jenkins配置定时触发
比较简便的方式是配置Jenkins,在项目里面加上清理文件的脚本,Jenkins执行流水线上加上脚本的执行,定时任务配置见:Jenkins时区配置及定时构建。
2、Linux cron配置周期性触发
cron进程是Linux中的一个守护进程,一般用来执行系统中的周期性任务,首先查看cron进程,/usr/sbin/cron 就是当前运行的cron进程。
~$ ps -ef | grep cron
arc 2533299 2533276 0 00:23 pts/1 00:00:00 grep –color=auto cron
root 2591934 1 0 2月07 ? 00:00:05 /usr/sbin/cron -f
如果cron进程不存在,用以下命令开启或停止。
# 开启服务 sudo service cron start # 停止服务 sudo service cron stop
接着编辑crontab文件,crontab是UNIX系统下定期执行任务的触发器,要定期执行的任务都可以在这个文件里面配置,用以下命令打开文件,第一次使用这个命令会让你选择编辑器,选择vim比较方便
sudo crontab -e
加入要执行的脚本参数配置:
# Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any'). # # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command 0 0 * * * /home/script/timer_cache_clean.sh
这边定时配置的语法和Jenkins定时触发构建是一样的,只是在5个时间参数后面加上要执行的命令。
* * * * * <command>
之后保存修改,退出文件编辑,重启cron就配置完成了。
sudo service cron restart
关于sh脚本里面清理文件的配置可以参考上面find -exec操作。
转载请注明出处:陈文管的博客 – Linux磁盘空间查看及定时清理配置
扫码或搜索:文呓
微信公众号 扫一扫关注