문제해결: CentOS에서 로그 파일 삭제하기

하드디스크가 로그 때문에 여러 번 다 찬 적이 있는데 이 이슈를 분석하고 해결한 과정을 공유합니다.

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으로 만들었습니다.

참고 문헌

Advertisements

최 재훈

블로그, 페이스북, 트위터 고성능 서버 엔진, 데이터베이스, 지속적인 통합 등 다양한 주제에 관심이 많다.
Close Menu