平原县网站建设,软件开发学院,浦东做网站公司,批量发布wordpress文章某天#xff0c;收到监控系统的告警信息#xff0c;说磁盘空间占用过高#xff0c;登上服务器#xff0c;使用 df -h 一看#xff0c;发现磁盘占用率已经 96%了#xff1a;
通过查看 /usr/local/nginx/conf/vhost/xxx.conf 找到 access_log 和 error_log 的路径#x…某天收到监控系统的告警信息说磁盘空间占用过高登上服务器使用 df -h 一看发现磁盘占用率已经 96%了
通过查看 /usr/local/nginx/conf/vhost/xxx.conf 找到 access_log 和 error_log 的路径进去后du -sh 查看了下总大小一共占用了 31GB二话不说直接 rm xxx_access.log 删除掉nginx的 access_log 文件然后兴冲冲的 df -h 一看磁盘空间并没有下降还是占用96%什么鬼
为什么文件被进程占用之后删除不会释放磁盘空间呢
因为在 Linux 中文件存储在硬盘上的最小存储单位是扇区Sector每个 sector 只有 512字节大小多个 sector 可以组成文件块 block 。当我们读取某个文件数据的时候操作系统就需要知道这个文件存储在哪个 block 上。文件的数据存放位置信息被存放到了 inode 索引节点上。也就是说在 Linux 下文件由指针部分inode和数据部分data组成。
因此执行 rm xxx 命令删除文件的时候只是删掉了inode数据而文件的实际数据部分在 inode 被清除掉之后会被覆盖并写入新的内容。但是如果文件在删除的时候是被打开的有一个进程正在使用该文件文件被进程锁定或者有进程一直在向这个文件写数据等状态那么进程依旧可以读取该文件系统就会认为该文件的磁盘空间一直被占用。
虽然删除了 access_log 文件但是由于 nginx 进程还在一直向这个文件写入内容文件的 inode 并没有清除掉系统内核认为文件并未删除这才出现空间不释放的情况。也就是说当一个进程持续的写入一个文件的时候直接删除这个文件磁盘空间并不会得到释放。
可以通过 lsof | grep deleted | grep access_log 命令查看是不是有进程一直还在写入这个文件 可以看到这个文件被进程 nginx 锁定而且 nginx 进程一直在往这个文件写数据最后一列的 deleted 状态表示这个文件已经被删除。由于进程还在一直往里面写数据导致磁盘空间并未释放。
解决方案
方法1写入一个空数据到这个文件中cat /dev/null /home/wwwlogs/access.log 或者 echo /home/wwwlogs/access.log方法2重启 nginx 进程让操作系统回收磁盘空间 /usr/local/nginx/sbin/nginx -s reload
这样操作后磁盘空间直接下降了 另外有一些查看文件相关的命令记录下来备用
# 查看当前磁盘占用
df -h# 查看当前目录大小
du -sh# 查看当前目录下第一层文件夹的大小按照由大到小排序
du -sh * | sort -rh (文件过多的话可以加 | less)# 同上但可以指定层级
du -lh --max-depth1 | sort -rh# 查看进程打开的文件
lsof | grep xxx (记得加上grep否则返回的数据会很多)后续工作 由于此前没有对nginx的日志进行切割导致nginx的日志文件越来越大因此需要写一个shell脚本通过定时任务按照每天或者其他自定义维度对日志文件切割存储并自动删除一段时间之前的日志文件。
shell脚本文件vim /root/cut_nginx_log.sh
#!/bin/bash
#日期参数
datedate -d yesterday %Y%m%d# 复制原来的日志文件
cp /home/wwwlogs/access.log /home/wwwlogs/backup/access_${date}.log# 清空原有的日志文件
cat /dev/null /home/wwwlogs/access.log# 删除7天前的日志文件
find /home/wwwlogs/backup -mtime 7 -type f -name \*.log | xargs rm -f增加执行权限 chmod x /root/cut_nginx_log.sh
定时任务crontab -e
0 0 * * * /root/cut_nginx_log.sh