线上大日志文件的删除

磁盘报警

线上磁盘报警,查看磁盘使用率:

[sage.wang@machine /home/www/web/logs]$ sudo df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/vda2             9.9G  1.5G  8.0G  16% /
tmpfs                 3.9G   12K  3.9G   1% /dev/shm
/dev/vda1             194M   54M  131M  29% /boot
/dev/vda6             985M  111M  824M  12% /home
/dev/vda7              60G   45G   13G  78% /home/q
/dev/vda5             4.0G  354M  3.4G  10% /var

登机器查看大文件:

[sage.wang@machine /home/www/web]$ sudo du -sh * |grep G
39G     logs


[sage.wang@machine /home/www/web/logs]$ sudo du -sh * |grep G    
7.4G    access..2018-08-12.log
4.5G    cache.log
1.2G    catalina.out
8.5G    qta.log

由于日志打印不当或者压缩策略设置不当,导致有比较大的日志文件

删除大文件

[sage.wang@machine /home/www/web/logs]$ sudo rm access..2018-08-12.log sudo rm access..2018-08-12.log

删除之后再查看磁盘使用率,其实还是没变:

[sage.wang@machine /home/www/web]$ sudo df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/vda2             9.9G  1.5G  8.0G  16% /
tmpfs                 3.9G   12K  3.9G   1% /dev/shm
/dev/vda1             194M   54M  131M  29% /boot
/dev/vda6             985M  111M  824M  12% /home
/dev/vda7              60G   45G   13G  79% /home/q
/dev/vda5             4.0G  354M  3.4G  10% /var

原因跟Linux下文件的存储机制和存储结构有关:

一个文件在文件系统中的存放分为两个部分:数据部分和指针(inode)部分,指针位于文件系统的meta-data中,数据被删除后,这个指针就从meta-data中清除了,而数据部分存储在磁盘中,数据对应的指针从meta-data中清除后,文件数据部分占用的空间就可以被覆盖并写入新的内容,之所以出现删除access_log文件后,空间还没释放,就是因为tomcat进程还在一直向这个文件写入内容,导致虽然删除了access_log文件,但文件对应的指针部分由于进程锁定,并未从meta-data中清除,而由于指针并未被删除,那么系统内核就认为文件并未被删除,因此通过df命令查询空间并未释放也就不足为奇了。

如何确认这一点呢?可以通过lsof -p pid的方式来查看文件传输的状态:

[sage.wang@machine /home/www/web]$ ps aux|grep java|grep Dcatalina
tomcat   18784 97.9 28.3 7733348 2283632 ?     Sl   Aug10 3381:52 /home/q/java/default/bin/java -Djava.util.logging.config.file=/home/www/web/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms3537216k -Xmx3537216k -XX:NewSize=1074560k -XX:TargetSurvivorRatio=65 -XX:SurvivorRatio=4 -server -XX:+TieredCompilation -XX:CICompilerCount=3 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSScavengeBeforeRemark -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:-UseBiasedLocking -XX:+PreserveFramePointer -XX:+DisableExplicitGC -XX:MaxMetaspaceSize=256m -XX:+TraceClassUnloading -XX:MaxTenuringThreshold=15 -XX:+PrintTenuringDistribution -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintPromotionFailure -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintClassHistogramBeforeFullGC -XX:+PrintClassHistogramAfterFullGC -XX:+PrintStringTableStatistics -XX:+PrintReferenceGC -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -Xloggc:/home/www/web/logs/gc-201808101121.log -Dqunar.logs=/home/www/web/logs -Dqunar.cache=/home/www/web/cache -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Djava.endorsed.dirs=/home/q/tomcat/endorsed -classpath /home/q/tomcat/bin/bootstrap.jar:/home/q/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/home/www/web -Dcatalina.home=/home/q/tomcat -Djava.io.tmpdir=/home/www/web/temp org.apache.catalina.startup.Bootstrap start




[sage.wang@machine /home/www/web]$ sudo lsof -p 18784|grep deleted
java    18784 tomcat    8w   REG              252,7     592867    1835029 /home/www/web/logs/catalina.2018-08-10.log (deleted)
java    18784 tomcat    9w   REG              252,7        773    1835037 /home/www/web/logs/localhost.2018-08-10.log (deleted)

当linux打开一个文件的时候,Linux内核会为每个进程在/proc/ 『/proc/nnnn/fd/文件夹(nnnn为pid)』建立一个以其pid为名的文件夹用来保存进程的相关信息,而其子文件夹fd保存的是该进程打开的全部文件的fd(fd:file descriptor)。

进去看一下内容:

[sage.wang@machine /home/www/web]$  sudo ls -alh  /proc/18784/fd/ |grep deleted
l-wx------ 1 tomcat tomcat 64 Aug 12 20:54 8 -> /home/www/web/logs/catalina.2018-08-10.log (deleted)
l-wx------ 1 tomcat tomcat 64 Aug 12 20:54 9 -> /home/www/web/logs/localhost.2018-08-10.log (deleted)

可以看到,这是被删除的文件,但实际上磁盘空间还是没有释放的

正确姿势

那么到底应该用什么姿势来解决问题呢?两种方式:

  • 重启应用,即可释放相应的空间
  • 在线清空这个文件的内容

重启应用很简单,若要在线清空文件,则不要使用rm命令,而是使用如下命令

cat /dev/null > file
#或者
echo > file
#或者
echo ' ' > file

再强调一遍,删除正在写的文件一般用 cat /dev/null > file或者echo > file,而不是直接rm(直接rm会造成文件删除空间不释放的问题)。

线上机器执行的时候会有权限的问题,比如:

[n-sage.wang@machine /home/www/web/logs]$ sudo echo > catalina.out
bash: catalina.out: Permission denied

这是因为重定向符号 “>” 也是 bash 的命令。sudo 只是让 echo 命令具有了 root 权限,但是没有让 “>” 命令也具有root 权限,所以 bash 会认为这个命令没有写入信息的权限。

解决方案有两种

当做一条命令执行:

sudo bash -c 'echo "hello" > f.txt'

或者使用tee命令:

echo "hello" | sudo tee f.txt  # add -a for append (>>)

实测第一条命令还是会有点问题,也是没权限。但是第二种方式是work的。

参考文章:

http://www.ywnds.com/?p=5186

https://blog.csdn.net/wangyage198801151103/article/details/51723759

https://www.cnblogs.com/mfryf/p/3334451.html

https://www.jb51.net/article/100462.htm

https://blog.csdn.net/tianyao_myc/article/details/52179668

http://blog.163.com/aprilthirty60@126/blog/static/88613578201282703952163/

https://blog.csdn.net/hejinjing_tom_com/article/details/7767127

https://askubuntu.com/questions/103643/cannot-echo-hello-x-txt-even-with-sudo

坚持原创技术分享,您的支持将鼓励我继续创作!
0%