WAS 업로드 실패: No space left on device 원인 분석과 디스크 용량 장애 대응
- 카테고리: Troubleshooting
- 태그: Linux, JEUS, WAS, Disk, Filesystem, Troubleshooting
- 주제: WAS에서 발생한 파일 업로드 오류를 리눅스 파일시스템 관점에서 분석하는 방법
1. 장애 발생 상황
WAS에서 파일 업로드를 처리하던 중 임시 파일 생성에 실패하는 오류가 발생했다. 오류 메시지에는 /tmp 아래의 업로드 임시 파일 경로와 함께 No space left on device가 표시됐다.
Caused by: java.nio.file.FileSystemException:
/tmp/upload_....tmp: No space left on device
오류가 발생한 경로는 /tmp였지만, 원인은 해당 디렉터리 자체의 설정 문제라고 단정할 수 없었다. 먼저 서버의 파일시스템 사용량을 확인하고 /tmp가 어느 파일시스템을 사용하는지 조사할 필요가 있었다.
2. 오류 메시지 분석
오류 메시지에서 확인할 수 있는 정보는 다음과 같다.
FileSystemException: 파일시스템과 관련된 작업에서 예외가 발생했다는 의미다./tmp/upload_....tmp: 생성하거나 쓰려고 한 임시 파일의 경로다.No space left on device: 파일시스템에 필요한 저장 자원이 부족하다는 의미다.
이 메시지는 디스크 블록 부족을 의심하게 하는 대표적인 오류다. 다만 inode 고갈 등 다른 원인도 가능하므로, 오류 문구만으로 원인을 확정하지 않고 관련 정보를 함께 확인해야 한다.
3. 파일시스템 사용량 확인: df -h
먼저 다음 명령어로 파일시스템별 전체 용량과 사용량을 확인한다.
df -h
df는 파일시스템의 디스크 사용량을 표시하며, -h 옵션은 사람이 읽기 쉬운 단위로 용량을 출력한다.
이번 서버에서 확인한 df -h 결과 중 장애 분석에 필요한 부분은 다음과 같다.
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 44G 44G 20K 100% /
/dev/sdd1 100G 2.5G 97G 3% /app
/dev/sdb1 100G 30G 71G 30% /loggin
/dev/sdc1 150G 150G 0 100% /share_old
/dev/mapper/sharevg-sharelv 700G 451G 250G 65% /share
루트 파일시스템(/)은 전체 44G 중 사실상 전부를 사용해 100%였고, 남은 공간은 20K에 불과했다.
반면 /loggin, /app, /share_old은 별도 파일시스템(/dev/sdb1, /dev/sdb1, /dev/sdc1)으로 마운트되어 있다./share_old도 사용률 100%로 표시되지만, 이것이 이번 업로드 오류의 직접 원인인지는 해당 경로와 오류 경로의 파일시스템 관계를 확인해야 판단할 수 있다.
특정 경로가 사용하는 파일시스템은 다음과 같이 확인한다.
df -h /tmp
결과
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 44G 44G 20K 100% /
df -h /tmp 결과가 /dev/mapper/rhel-root 이므로 /tmp는 루트 파일시스템의 공간을 사용한다.
이 경우 루트 파일시스템이 가득 차면 /tmp에 임시 파일을 생성하는 작업도 실패할 수 있다.
4. inode 사용량 확인: df -i /tmp
디스크 용량뿐 아니라 inode 사용량도 확인해야 한다. inode는 파일과 디렉터리의 메타데이터를 관리하는 자료 구조로, 파일이나 디렉터리를 생성할 때 필요하다.
디스크 공간이 남아 있더라도 inode가 부족하면 새 파일을 생성하지 못할 수 있다.
df -i /tmp
실행 결과는 다음과 같다.
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/rhel-root 220008 219608 400 100% /
-i 옵션은 디스크 용량 대신 inode의 전체 개수(Inodes), 사용 개수(IUsed), 남은 개수(IFree), 사용률(IUse%)을 표시한다.
이번 서버는 전체 inode 220,008개 중 219,608개를 사용했고, 남은 inode는 400개뿐이었다. 사용률이 반올림되어 100%로 표시됐다.
** 디스크 용량과 inode는 서로 다른 자원이다 **
- 디스크 용량 부족: 파일의 데이터를 저장할 공간이 부족한 상태다.
- inode 부족: 새로운 파일이나 디렉터리를 생성하는 데 필요한 inode가 부족한 상태다.
예를 들어 용량이 큰 로그 파일은 디스크 공간을 많이 차지한다. 반면 크기가 작은 임시 파일이 수십만 개 생성되면 전체 데이터 용량이 충분하더라도 inode가 부족해질 수 있다.
이번 결과에서는 디스크 사용률이 100%이고 inode 사용률도 100%로 표시된다. 따라서 저장 공간뿐 아니라 파일 생성에 필요한 inode도 거의 소진된 상태임을 확인할 수 있다.
디스크 장애를 진단할 때는 다음 두 명령어를 함께 확인하는 것이 좋다.
df -h /tmp # 디스크 용량 확인
df -i /tmp # inode 사용량 확인
5. 원인 분석: WAS 로그 경로 설정 문제
JEUS 설치 디렉터리에서 du -sh *를 실행한 결과, logs 디렉터리가 약 34G를 차지하고 있었다. 다른 주요 항목은 상대적으로 작았다.
6.0M bin
5.3M derby
5.7M docs
125M domains
60K JEUS9.1.1_security_patchfile.zip
388M lib
4.0K license
34G logs
8.0K nodemanager
36M setup
100K templates
4.0K ThirdPartyLicenses.txt
8.8M UninstallerData
이는 로그 파일이 디스크 부족에 크게 기여했을 가능성을 뒷받침한다.
다만 du -sh *는 명령을 실행한 현재 디렉터리의 하위 항목별 사용량을 보여준다.
따라서 해당 JEUS 디렉터리가 실제로 / 파일시스템에 위치하는지, 그리고 /tmp도 같은 파일시스템을 사용하는지는 별도로 확인해야 한다.df -h /tmp, df -h <JEUS 로그 디렉터리 경로>, findmnt /tmp 등의 결과로 파일시스템 관계를 검증한다.
확인된 내용을 바탕으로 가능한 장애 흐름은 다음과 같다.
- JEUS의
logs디렉터리에 로그 파일이 누적되어 약 34G를 차지한다. - 로그가 위치한 파일시스템의 여유 공간이 줄어든다.
- 루트 파일시스템(
/dev/mapper/rhel-root)은 100% 사용 상태가 되고, 남은 공간이 20K 수준으로 떨어진다. /tmp가 루트 파일시스템을 공유한다면 업로드 임시 파일을 생성하거나 쓰는 작업에도 영향을 준다.- 파일 생성 또는 쓰기 작업이 실패하면서
No space left on device오류가 발생한다.
6. 조치 방향과 검증
확인 결과, JEUS 로그 경로가 잘못 설정되어 있었으며 로그는 /loggin 경로에 기록되도록 조치할 필요가 있음을 확인했다.
또한 고객 측에서는 기존 로그 백업 솔루션을 통해 로그를 백업하고 있었으나, 백업 후 원본 로그를 삭제하는 작업은 수행하지 않고 있었다.
로그 경로 변경과 백업 후 원본 로그 삭제 정책은 고객사에서 자체적으로 WAS 고객센터에 문의 및 crontab 배치 추가하여 처리하기로 했다.
7. 트러블슈팅을 통해 배운 점
이번 장애에서 중요한 점은 오류가 발생한 파일 경로와 실제 디스크 공간을 관리하는 단위가 다를 수 있다는 사실이다.
/tmp에서 오류가 발생했더라도 원인은 같은 파일시스템을 공유하는 다른 디렉터리의 로그 파일일 수 있다.
따라서 No space left on device 오류가 발생하면 오류 경로만 살펴보는 것이 아니라, 파일시스템 사용량과 마운트 관계를 확인하고 실제 공간을 점유하는 원인을 조사해야 한다.
참고 명령어
# 파일시스템 사용량
df -h
# 오류 경로가 사용하는 파일시스템
df -h /tmp
findmnt /tmp
# 로그 경로가 사용하는 파일시스템
df -h /loggin
findmnt /loggin
# 실제 JEUS 로그 경로가 사용하는 파일시스템
# 아래 <JEUS 로그 디렉터리 경로>를 실제 경로로 바꿔 실행한다.
df -h <JEUS 로그 디렉터리 경로>
# 루트 파일시스템 내부의 디렉터리별 사용량
# 루트 파일시스템에 한정해 하위 디렉터리별 용량을 조사한다.
du -xhd1 / 2>/dev/null | sort -h
# inode 사용량
df -i
# 삭제됐지만 프로세스가 열고 있는 파일 확인
sudo lsof +L1
du -xhd1은 GNU du에서 사용할 수 있는 옵션 조합이다. 배포판이나 명령어 구현에 따라 옵션 지원 여부가 다를 수 있으므로, 지원되지 않는 경우 du -x -d 1 / 등의 형식을 확인한다.
운영 서버에서는 대규모 디렉터리 조사가 I/O에 부담을 줄 수 있으므로 실행 범위를 고려한다.
운영 주의: 공간을 확보하기 위해 로그 파일을 무작정 삭제하거나
truncate하지 않는다.
실행 중인 프로세스가 파일을 열고 있을 수 있으며, 장애 분석에 필요한 로그가 사라질 수 있다. 먼저 파일을 사용하는 프로세스와 로그 관리 방식을 확인한다.
'error 트러블슈팅' 카테고리의 다른 글
| 브라우저 캐시 트러블슈팅 (Spring Boot) (0) | 2026.10.30 |
|---|---|
| 업로드 임시파일이 `/tmp`에 쌓이는 문제: 멀티파트 파싱 구조 개선 (0) | 2026.10.27 |
| java.net.SocketException:A system call received a parameter that is not valid. (0) | 2025.12.18 |
| [error] ORA-01461: LONG 값은 LONG 열에 삽입할 때만 바인드할 수 있습니다 (0) | 2025.09.01 |
| [error] ORA-06502: PL/SQL: 수치 또는 값 오류: 원시 변수 길이가 너무 깁니다 (For Select & Insert) (0) | 2025.08.09 |