본문 바로가기
1. 개발/1.8. ActiveMQ

'tx.log' 파일의 비정상적 비대화 현상 원인과 해결책은?

by 엉짱 2026. 3. 28.
반응형

'tx.log' 파일의 비정상적 비대화 현상 원인과 해결책은?

엔터프라이즈 환경에서 메시지 브로커(ActiveMQ 등)와 관계형 데이터베이스(RDBMS) 간의 완벽한 데이터 정합성을 맞추기 위해 XA 트랜잭션(2PC, 2단계 커밋)을 도입하게 됩니다. 이 거대한 분산 트랜잭션을 지휘하는 오케스트라의 지휘자가 바로 트랜잭션 매니저(TM, Transaction Manager)입니다.

TM은 브로커와 DB 양쪽의 상태를 추적하고, 장애 발생 시 롤백이나 커밋을 결정하기 위해 자신의 로컬 디스크에 모든 트랜잭션의 상태 변화 이력을 꼼꼼하게 기록합니다. 이 파일이 바로 일반적으로 tx.log (또는 tmlog, btm.tlog 등)로 불리는 트랜잭션 복구 로그입니다.

정상적인 상황이라면 이 로그 파일은 트랜잭션이 종료됨과 동시에 내부의 기록들이 정리되어 일정한 크기를 유지해야 합니다. 하지만 운영 중 어느 순간 이 tx.log 파일이 수 기가바이트(GB) 단위로 무한정 팽창하며 디스크를 집어삼키는 '비정상적 비대화(Bloat)' 현상을 마주하게 됩니다. 이 가이드에서는 분산 시스템의 숨통을 조이는 트랜잭션 로그 비대화의 근본 원인과 이를 통제하기 위한 인프라 아키텍처 전략을 상세히 분석합니다.


1. 트랜잭션 로그(tx.log)의 정상적인 생명주기

문제를 파악하기 위해서는 먼저 TM이 로그를 어떻게 다루는지 이해해야 합니다.

  1. 트랜잭션 시작: 애플리케이션이 분산 트랜잭션을 시작하면 TM은 tx.log에 새로운 트랜잭션 ID(XID)와 참여자(ActiveMQ, DB) 목록을 기록합니다.
  2. Phase 1 (Prepare): TM이 브로커와 DB에 Prepare(준비) 명령을 내리고 성공 응답을 받으면, 로그에 'Prepared' 상태를 기록합니다.
  3. Phase 2 (Commit/Rollback): 최종적으로 커밋이나 롤백 명령이 성공적으로 수행되면, TM은 해당 트랜잭션이 완전히 종료되었음을 로그에 마킹합니다.
  4. 가비지 컬렉션 (Log Purge): 주기적으로 TM의 백그라운드 스레드가 동작하여, '완전히 종료된' 트랜잭션들의 기록을 파일에서 지우거나 컴팩션(Compaction)하여 파일 크기를 최적화합니다.

즉, 로그 파일이 계속 커진다는 것은 4번의 가비지 컬렉션이 정상적으로 동작하지 못하도록 막고 있는 '종료되지 못한 트랜잭션'들이 시스템 내부에 악성 종양처럼 쌓이고 있다는 뜻입니다.


2. 'tx.log' 비대화를 유발하는 3대 치명적 원인

그렇다면 무엇이 트랜잭션의 정상적인 종료를 가로막고 로그 파일의 팽창을 유발할까요?

A. 리소스 매니저(RM)의 영구적 단절 및 폐기
가장 흔하면서도 치명적인 원인입니다. 분산 트랜잭션 도중 DB 서버나 ActiveMQ 노드 하나가 죽어버렸습니다. TM은 끈질기게 해당 노드가 살아나길 기다리며 복구(Recovery)를 시도하기 위해 tx.log에 해당 트랜잭션 기록을 남겨둡니다.
문제는 인프라 팀이 죽어버린 DB나 브로커를 살리는 대신, 아예 새로운 IP의 서버로 교체해 버렸을 때 발생합니다. TM은 영원히 접속할 수 없는 과거의 유령 서버(RM)를 향해 끝없이 복구 접속을 시도하며, 해당 트랜잭션 기록은 tx.log에서 영원히 지워지지 않는 좀비 레코드가 됩니다.

B. 애플리케이션의 장기 실행 트랜잭션 (Long-Running Transaction)
개발자의 코드 실수로 트랜잭션을 시작한 뒤 commit()이나 rollback()을 명시적으로 호출하지 않고 스레드가 무한 루프나 외부 API 대기 상태(Deadlock)에 빠진 경우입니다. 트랜잭션이 닫히지 않았으므로 TM은 이 진행 중인 상태(In-flight)를 보존하기 위해 로그 파일의 컴팩션을 중단하게 되며, 이후에 발생하는 수백만 건의 정상적인 트랜잭션 로그들까지 모두 파일에 누적되어 순식간에 수 GB로 파일이 부풀어 오릅니다.

C. TM 로그 롤링(Rolling) 정책 설정 누락
Atomikos나 Bitronix 같은 트랜잭션 매니저들은 무한정 파일이 커지는 것을 막기 위해 날짜별로 파일을 쪼개는 롤링(Rolling) 기능이나 최대 크기 제한 기능을 제공합니다. 이 설정을 누락한 채 단일 파일로만 운영하게 되면, 물리적 디스크 한계에 도달할 때까지 파일이 무식하게 커지게 됩니다.


3. 비대화가 인프라 아키텍처에 미치는 파급 효과

tx.log 파일의 비대화는 단순한 용량 부족(Disk Full) 장애로 끝나지 않습니다.

가장 끔찍한 파급 효과는 TM 서버(또는 애플리케이션)의 재시작 지연입니다. 서버가 배포나 패치를 위해 재시작되면, TM은 무결성 검증을 위해 tx.log 파일을 메모리에 처음부터 끝까지 읽어 들여(Replay) 트랜잭션 트리를 복원해야 합니다.
파일 크기가 수 GB에 달한다면 이 스캔 작업에만 수십 분이 소요됩니다. 결국 애플리케이션 컨테이너는 기동 중 타임아웃으로 죽어버리고, 서비스는 기약 없는 다운타임(Downtime)의 늪에 빠지게 됩니다.


4. 문제 해결 및 사전 방어를 위한 모범 사례 (Best Practices)

이러한 로그 비대화의 악순환을 끊어내기 위해서는 다음과 같은 아키텍처적 조치와 설정 튜닝이 필수적입니다.

A. 강력한 트랜잭션 타임아웃(Transaction Timeout) 설정
비대화를 막는 가장 확실한 예방 주사입니다. TM 설정 및 애플리케이션의 @Transactional 어노테이션에 매우 타이트한 타임아웃(예: 30초~1분)을 강제해야 합니다. 지정된 시간이 지나면 TM이 자비 없이 해당 트랜잭션을 강제 롤백 상태로 마킹하고, 좀비가 되기 전에 로그에서 정리(Purge)할 수 있도록 시스템의 생태계를 구성해야 합니다.

B. 폐기된 RM에 대한 수동 휴리스틱(Heuristic) 개입
과거의 DB나 브로커 서버가 영구적으로 폐기되어 TM이 끝없는 복구를 시도하고 있다면, 관리자가 수동으로 개입해야 합니다. JMX 콘솔이나 TM이 제공하는 관리자 툴을 사용하여 보류 중인(In-doubt) 트랜잭션들을 강제로 forget(망각) 처리하거나 롤백시켜야 합니다. 이를 통해 TM에게 "저 서버는 죽었으니 더 이상 복구하려 애쓰지 말고 로그를 지워라"라고 명시적으로 알려주어야 합니다.

C. 로그 파일 순환(Rotation) 및 보관 정책 적용
엔터프라이즈 TM 라이브러리의 설정 파일(예: jta.properties)을 수정하여 로그 파일 아키텍처를 방어적으로 구축하십시오.

  • 단일 파일의 최대 크기(Max Size)를 수십 MB로 제한합니다.
  • 파일이 제한에 도달하면 날짜가 붙은 백업 파일(tx.log.1, tx.log.2)로 롤링되도록 설정합니다.
  • 며칠이 지난 오래된 백업 파일은 OS 레벨의 크론탭(Crontab)이나 TM 자체 기능을 통해 자동으로 삭제되도록 라이프사이클을 지정해야 합니다.

결론적으로 분산 시스템에서 tx.log는 트랜잭션의 생명줄이자, 잘못 관리되면 시스템의 목을 조르는 족쇄가 됩니다. 트랜잭션이 길어지는 것을 극도로 경계하고, TM의 로그 로테이션 설정을 꼼꼼히 점검하여 가볍고 빠른 복구 환경을 유지하시기 바랍니다.

반응형