파일의 메타데이터와 데이터 블록 위치를 담은 구조체.
무엇이 들어 있나
- inode 안 — inode 밖 (디렉터리에 있다)
- 파일 종류 · 권한 · 소유자 파일 이름 ← 여기 없다!
- 크기 · 링크 수
- 타임스탬프 (atime · mtime · ctime)
- 데이터 블록의 위치 (직접 · 간접 포인터)
디렉터리는 "이름 → inode 번호"의 표일 뿐이다. 이 구조에서 하드 링크가 자연스럽게 나온다.
ls -li file.txt
# 1234567 -rw-r--r-- 2 user user 100 ... file.txt
# ^^^^^^^ inode 번호 ^ 링크 수
ln file.txt hard.txt # 같은 inode 를 가리키는 이름을 하나 더 만든다 (링크 수 2)
ln -s file.txt soft.txt # 경로 문자열을 담은 별도 파일 (심볼릭 링크)
- 하드 링크 — 원본을 지워도 다른 이름으로 접근 가능 (링크 수가 0이 될 때 진짜 삭제)
-
파일 시스템을 넘을 수 없다 (inode 번호가 그 안에서만 유효) 심볼릭 링크 경로를 가리킬 뿐 — 원본이 사라지면 깨진다
-
파일 시스템을 넘을 수 있다
-
"용량은 남았는데 파일이 안 만들어진다"
df -h # 용량은 여유
df -i # inode 가 100% ← 이게 원인
inode 개수는 파일 시스템을 만들 때 정해진다. 작은 파일을 수백만 개 만들면 용량보다 inode가 먼저 고갈된다.
저널링 — 전원이 갑자기 나가면
파일 하나를 지우려면 여러 곳을 고쳐야 한다
-
① 디렉터리에서 항목 제거 ② inode 해제 ③ 데이터 블록 해제
-
② 만 하고 전원이 나가면?
- 어디에서도 참조되지 않는 블록이 남는다 (누수)
- 옛날에는 부팅 때 fsck 로 전체를 검사했다 — 대용량에서 몇 시간이 걸린다
저널링
- "이제 이 작업들을 하겠다" 를 저널에 먼저 적는다
- 크래시 후 저널만 보고 완료하거나 되돌린다 → 복구가 빠르다
모드 (ext4)
writeback 메타데이터만 저널링. 가장 빠르고 가장 약하다
ordered 메타데이터만 저널링하되 데이터를 먼저 쓴다 (기본값)
journal 데이터까지 저널링. 가장 안전하고 느리다 (두 번 쓴다)
페이지 캐시
디스크는 메모리보다 수만 배 느리다
- 읽은 블록을 메모리에 캐싱한다
- 쓰기도 일단 메모리에 하고 나중에 내린다 (write-back)
"free 명령의 free 가 적어 보인다" 는 대개 정상이다
- 남는 메모리를 캐시로 쓰고 있을 뿐, 필요하면 즉시 반납한다
- available 열을 봐야 한다
free -h
sync; echo 3 > /proc/sys/vm/drop_caches # 캐시 비우기 (벤치마크용. 운영에서 쓰지 않는다)
면접 함정
- ❌ "파일 이름은 inode에 있다" → 디렉터리에 있다. 그래서 하드 링크가 가능하다.
- ❌ "저널링하면 데이터가 안전하다" → 기본 모드는 메타데이터만 보호한다.
파일을 지웠는데 용량이 안 준다
df -h # 사용량 그대로
du -sh /var # 파일은 없다
lsof +L1 # 링크 수가 0인데 열려 있는 파일
# nginx 1234 ... /var/log/access.log (deleted)
inode 는 '링크 수 0 이고 아무도 안 열고 있을 때' 비로소 해제된다
→ 프로세스가 그 파일을 열어 두고 있으면 디스크 공간이 계속 잡혀 있다
→ 로그 파일을 rm 으로 지우고 프로세스를 재시작·시그널로 재오픈시키지 않으면 이렇게 된다
→ logrotate 가 copytruncate 나 시그널을 쓰는 이유
세 가지 시각
- atime — 마지막 접근 시각 — 읽기만 해도 쓰기가 발생해 성능에 나쁘다
- 요즘은 relatime(하루 한 번만 갱신)이 기본
- mtime — 내용이 마지막으로 바뀐 시각
- ctime — inode 가 마지막으로 바뀐 시각 (권한·소유자 변경 포함)
- 사용자가 임의로 바꾸기 어려워 포렌식에서 본다
stat file.txt
mount -o remount,noatime / # atime 갱신을 끄면 읽기 성능이 오른다