
장애의 시작은 단순했다.
크롤러 서버(1~5번) 중 4번 서버에서 logrotate 설정이 적용되어 있음에도 불구하고, 특정 커뮤니티의 JSON 파일이 19GB까지 비정상적으로 증가하며 디스크 사용량이 급격히 상승하는 문제가 발생했다.
반면 다른 서버의 동일 파일은 대부분 0.7GB ~ 1.8GB 수준이었다.
과거에도 동일한 이슈로 해당 파일을 rm으로 삭제한 적이 있었지만, 일주일 뒤 동일한 문제가 다시 발생했다.
여기서 바로 두 가지를 알 수 있었다.
초기에는 아래 네 가지를 의심했다.
이 가설들을 하나씩 검증하면서 원인을 좁혀갔다.
가장 먼저 확인한 것은 해당 파일이 코드에서 어떻게 다뤄지는지였다.
mode="a" (append 모드)로 열린다.write_to_file()은 file.write(data + "\n") 형태로 계속 append 한다.즉 이 파일은 구조적으로 누적형 파일이었다.
또한 해당 파일을 소비하거나 정리하는 로직은 보이지 않았다.
이 단계에서 이미 “rotate나 정리 작업이 실패하면 파일은 계속 커질 수밖에 없다”는 점은 분명해졌다.
게다가 이 커뮤니티는 글로벌 대상(119개 국가)으로 수집되고 있었고, 실시간성이 중요해 짧은 주기로 반복 수집되고 있었다.
따라서 데이터 증가 속도 자체도 빠른 상황이었다.
서버별 파일 상태를 비교해 보니 일정한 패턴이 보였다.
-YYYYMMDD, .gz)만 존재즉 “특정 서버만 이상하다”가 아니라
rotate가 어떤 날은 되고, 어떤 날은 안 되는 상태였다.
이 관찰은 매우 중요했다.
👉 따라서 문제는 애플리케이션 코드가 아니라 운영 계층의 실행 불안정성으로 방향이 이동했다.
/etc/logrotate.d/ 설정은 모든 서버에서 동일했고, 내용은 다음과 같았다.
daily
rotate 10
compress
delaycompress
copytruncate
설정 자체는 특별히 문제가 없어 보였다.
즉 “특정 서버 설정 오류” 가설은 여기서 배제되었다.
이제 확인해야 할 것은 설정이 아니라 실제 실행 결과였다.
systemctl status logrotate.service를 확인했을 때 다음 로그가 발견되었다.
error: state file /var/lib/logrotate/logrotate.status is already locked
logrotate does not support parallel execution on the same set of logfiles.
이 메시지는 매우 중요했다.
👉 자정에 실행되어야 할 메인 logrotate가 아예 실패하고 있었다.
그리고 실패 원인은 state file lock 충돌이었다.
이후 조사 방향은 “누가 동시에 logrotate를 실행하고 있는가”로 바뀌었다.
systemd 외에도 cron을 확인했고, /etc/cron에서 다음 설정을 발견했다.
0 */2 * * * root /usr/sbin/logrotate -f /etc/logrotate.d/send_json_to_s3
즉 2시간마다 cron에서 logrotate -f가 강제 실행되고 있었다.
문제는 이 작업이 메인 logrotate와 같은 시간대(자정)에 겹칠 수 있다는 점이었다.
핵심은 logrotate의 state file이다.
기본적으로 logrotate는 아래 파일을 사용한다.
/var/lib/logrotate/logrotate.status
이 파일은 단순 이력 파일이 아니라:
두 가지 역할을 동시에 수행한다.
👉 중요한 점
rotate 대상 파일이 달라도, 같은 state file을 사용하면 동시에 실행할 수 없다.
logrotate -f 실행 (state file lock 획득)already locked → 실행 실패즉 메인 rotate 작업이 통째로 스킵되는 구조였다.
이 상태가 반복되면:
또한 이후 rotate가 수행되는 시점에는:
copytruncate (복사 후 원본 truncate)delaycompress (다음 주기에 압축)과정이 겹치면서 디스크 I/O와 파일시스템 부담도 증가할 수 있다.
모든 서버가 동일한 설정을 사용했음에도 결과가 달랐던 이유는 다음과 같다.
즉 동일한 문제라도 비대칭적으로 나타날 수 있는 구조였다.
이번 문제는 다음 두 가지 방법으로 해결할 수 있다.
cron과 systemd의 실행 시간이 겹치지 않도록 조정
5 */2 * * * root /usr/sbin/logrotate -s /var/lib/logrotate/send_json_to_s3.status -f /etc/logrotate.d/send_json_to_s3
-s 옵션으로 별도 state file 사용이번 사례를 통해 확인한 것은 다음과 같다.
logrotate는 파일 단위가 아니라 state file 단위로 동시 실행을 제어한다.또한 단순히 rm으로 파일을 삭제하는 것은 근본 해결이 아니며, 왜 rotate가 실패했는지를 반드시 확인해야 재발을 막을 수 있다.