하드디스크가 로그 때문에 여러 번 다 찬 적이 있는데 이 이슈를 분석하고 해결한 과정을 공유합니다.
JBoss 노드이므로 일반적으로 /var/log/jboss-as/server.log
파일이 문제가 됩니다. 보통은 rotated 된 파일, 예를 들어 server.log.2014-11-30.gz
등을 지워서 공간을 확보합니다. 하지만 이때는 server.log
가 수십 기가를 차지해서 해당 파일을 삭제했습니다.
그런데 리눅스 파일시스템은 inode 개념이 있어서(Mac OS X도 마찬가지죠) 이렇게 삭제하더라도 실제로 디스크에서 완전히 지워진다는 보장이 없습니다. 예를 들어 Mac OS X에서 미생.mkv
를 재생해서 보는 와중에 해당 파일을 삭제하더라도 동영상 프로그램에서는 미생이 계속해서 재생됩니다. 이런 일이 발생하지 않게 하는 제일 손 쉬운 방법은 해당 파일을 사용하는 프로세스를 죽이는 것입니다. 하지만 Production 서비스를 중지시킬 수는 없는 일이라 간단하게 rm
으로 로그 파일을 지우려 시도했습니다.
그러니까 당시 팀원 중 한 명이 최초로 발견한 것처럼
[production: root@webservices var]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/xvde 32G 20G 11G 66% /
tmpfs 7.3G 0 7.3G 0% /dev/shm
/dev/xvdk 99G 91G 2.9G 97% /var/log
로그를 다 지웠음에도 99G의 로그용 볼륨 중 91G가 사용 중인 상황이 벌어진 것입니다. 문제를 처리하기 위해 우선 dangled된 파일 목록부터 가져왔습니다.
# check with lsof if there are files held open, space will not be freed until they are closed
/usr/sbin/lsof | grep deleted
lsof
라는 프로그램은yum install isof
로 설치했습니다.
이렇게 확인하니 총 세 개의 로그 파일이 dangled된 상태였습니다(반복해서 로그 파일을 삭제했으니).
# 예제입니다
su 14895 root 1w REG 202,160 100014384953 5242885 /var/log/jboss-as/server.log (deleted)
su 14895 root 2u CHR 136,0 0t0 3 /dev/pts/0 (deleted)
standalon 14898 jboss-as 1w REG 202,160 100014386438 5242885 /var/log/jboss-as/server.log (deleted)
standalon 14898 jboss-as 10u CHR 136,0 0t0 3 /dev/pts/0 (deleted)
java 14963 jboss-as 1w REG 202,160 100014388887 5242885 /var/log/jboss-as/server.log (deleted)
java 14963 jboss-as 2u CHR 136,0 0t0 3 /dev/pts/0 (deleted)
tail 17900 root 3r REG 202,160 0 5242935 /var/log/jboss-as/server.log.2014-11-16 (deleted)
그나마 다행인 건 JBoss가 신규 로그를 dangled된 파일이 아닌 새 로그 파일에 남기고 있었습니다. 결국 dangled된 파일만 처리하면 문제가 해결됩니다. 기본적으로는 jboss 프로세스를 죽여야 파일을 삭제할 수 있습니다만 이를 우회하는 방법이 있습니다. 바로 dangled된 로그 파일을 덮어씌워서 파일 크기를 0으로 만드는 겁니다. lsof
로 inode 번호를 알아냈으니 간단한 스크립트만 있으면 됩니다.
# or output nothing to each file, setting them to empty.
lsof | grep "(deleted)$" | sed -re 's/^S+s+(S+)s+S+s+([0-9]+).*/1/fd/2/' | while read file; do sudo bash -c ": > /proc/$file"; done
이런 코드면 되는데 어차피 문제가 된 파일이 셋에 불과하므로 하나하나 따로 수작업해서 파일 크기를 0으로 만들었습니다.
참고 문헌
- Find and remove large files that are open but have been deleted
- Tell fs to free space from deleted files NOW