빙응의 공부 블로그

[OSTEP 영속성(persistence)]로그 기반 파일 시스템(LFS) 본문

CS/운영체제

[OSTEP 영속성(persistence)]로그 기반 파일 시스템(LFS)

빙응이 2025. 7. 17. 21:38

 

📝서론 

저번 포스팅에서 우리는 크래시 방지를 위해서 저널링을 하였다.

시간이 지나 컴퓨터의 성능이 좋아지며 저널링에서 더 나아가 로그 기반 파일 시스템(LFS)이 등장하였다.

해당 파일 시스템 설계 배경은 다음과 같다.

메모리 크기 증가 대부분의 읽기는 메모리 캐시에서 처리됨 → 디스크는 주로 쓰기 위주 I/O 발생
순차 I/O 성능 향상 > 랜덤 I/O 디스크는 순차적으로 쓸 때 훨씬 빠름 → 랜덤 I/O는 탐색/회전 지연으로 매우 느림
기존 파일 시스템의 비효율성 FFS 같은 기존 파일 시스템은 쓰기마다 여러 I/O → 블럭 그룹 최적화로도 한계
RAID 환경의 쓰기 병목 RAID는 작은 쓰기(small write)에서 읽기-수정-쓰기 반복 필요 → 기존 FS들은 고려하지 않음

 

이상적인 파일 시스템은 쓰기 성능에 초점을 둔다. 디스크의 순차 대역폭 성능을 최대한 활용하는 방향으로 설계된다.

 

핵심 질문 : 모든 쓰기를 어떻게 순차 쓰기로 변형시킬까??

 

 

📝디스크에 순차적으로 쓰기

파일 시스템을 변경하는 모든 쓰기 작업을 어떻게 순차 쓰기로 디스크에 보낼까?

 

LFS의 핵심은 모든 갱신을 디스크에 순차적으로 기록한다는 것이다. 

그렇다면 어떻게 순차적이면서 효율적인 쓰기를 할까?

 

순차적이면서 효율적으로 쓰기

쓰기 버퍼링으로 메모리에 갱신 내용을 모아 두었다가 일괄적으로 세그멘트 단위로 디스크에 커밋하는 것이다.

  • 쓰기 버퍼링 
    1. 쓰기 버퍼링은 디스크에 쓰기 전에 LFS는 갱신 내용을 메모리에 보관한다.
    2. 갱신된 내용이 메모리에 충분히 쌓였다면 한꺼번에 순차적으로 갱신한다.

이러한 쓰기 버퍼링의 단위를 세그먼트라고 부른다. (LFS에서는 그저 집합 쓰기 단위의 의미이다)

 

적절한 세그먼트의 크기는?

여기서 다음 질문이 나온다. 적절한 세그먼트의 크기는?

  • 고려해야할 것
    • 탐색 시간
    • 회전 지연 시간
    • 예: Tposition=10ms, Rpeak=100MB/s, F=0.9 → D ≈ 9MB

 

문제 1: 아이노드 위치 관리

LFS가 쉬워보이지만 문제점이 몇가지 있다.

대표적인 것으로는 LFS는 데이터가 덮어쓰기 되지 않고 계속 새로운 위치에 순차적으로 기록된다는 것이다.

이로인해 아이노드의 위치가 계속 바뀐다.

  • 해결책 : imap
    • 디스크에 아이노드가 기록될 때 imap은 새로운 위치를 가리키도록 갱신하는 것이다.
    • 계속적으로 이동하는 아이노드의 위치를 파악하기 위한 자료 구조이다.

 

문제 2: 아이노드 맵 저장 위치

아이노드 맵도 역시 블럭을 저장하여 디스크 상에서 흩어지게 된다. 이것은 어떻게 해결할까?

그것은 아이노드 맵을 지정된 위치에 저장하는 것이다. 즉 검색 시작 위치에 고정적으로 저장하는 것

이것을 체크포인트 영역이라고 부른다. 

  • 체크포인트 영역
    • 디스크의 고정된 위치에 위치
    • 최신 imap 조각들의 위치를 가리키는 포인터들 저장

 

📝디렉터리 관리 방법은?

지금까지 설명은 간단하게 파일에 대해 말하였다. 하지만 파일을 접근하려면 디렉터리들을 읽어야한다.

LFS는 디렉터리를 어떻게 처리할까?

 

 

초창기 방식

 

디렉터리 항목은 다음 정보를 가졌습니다.

[파일 이름] + [아이노드 번호]
  • 이 당시에는 아이노드 번호 자체가 물리적 위치를 의미했습니다.
  • 문제점 : 아이노드의 위치가 고정되어 있기 때문에, 아이노드를 옮길 수 없음(스냅샷 및 로그 구조 사용 불가)
    • 아이노드를 옮길려면 디렉터리도 같이 갱신해줘야함(재귀 갱신 문제)
LFS 방식

디렉터리 항목은 초창기와 동일합니다.

[파일 이름] + [아이노드 번호]
  • LFS 방식은 아이노드 번호의 위치를 알려주는 imap을 사용합니다. 그렇기에 실제 위치 추적이 가능합니다.
  • 그 말은 디렉터리를 바꾸지 않고 아이노드 번호의 위치인 imap만 갱신하면 끝나기에 재귀 갱신 문제가 해결됩니다.

 

📝LFS 디렉터리 관리의 문제점

LFS의 다른 문제점도 있습니다. 갱신된 파일의 예전 값들이 디스크에 그대로 남아있게 되는 문제입니다.

즉, 사용되지는 않지만 디스크의 공간에 그대로 차지하는 문제가 발생합니다.

 

가비지 컬렉션

사용되지 않는 디스크 공간을 가비지(garbage, 쓰레기)라고 부릅니다.

가비지 컬렉션 전략

  • 세그멘트 단위로 수행
    • 유효 블록만 모아서 새로운 세그멘트로 이동 (compact)
    • 이후 원래 세그멘트는 제거 → 디스크 공간 회수
  • 블록의 유효성 판단 방법
    • 각 블록에는 (아이노드 번호 N, 파일 오프셋 T) 정보가 포함됨
    • imap[N]을 통해 아이노드를 찾고, inode[T]의 주소가 현재 블록 주소와 같으면 → 유효 블록

 

📝LFS 크래시로부터의 복구와 로그

 

 

LFS에서 디스크에 쓰는 도중에 시스템이 크래시되면 어떻게 되는가?

 

문제 상황: 크래시 발생 시 어떻게 복구할 것인가?
  • 로그 구조 파일 시스템(LFS)은 모든 쓰기를 순차적으로 로그처럼 기록합니다
  • 하지만 쓰기 중간, 또는 체크포인트 업데이트 중에 크래시가 발생할 경우, 데이터 일관성이 깨질 위험이 있습니다.
첫 번째 경우 : 체크포인트 갱신 도중 크래시
  • LFS는 체크포인트를 교대 방식으로 갱신합니다.(디스크 앞과 맨 뒤에 체크포인트가 존재합니다.)
  • 복구 시에는 두 체크포인트 영역을 비교 :
    • 헤드 시간값 > 마지막 블록 시간 값 -> 쓰는 도중 크래시 발생
    • 시간값이 일치 -> 이 체크포인트는 유효
  • 크래시 중에도 일관된 체크포인트 선택이 가능합니다.
두 번째 경우 : 세그먼트 쓰는 도중 크래시(로그 유실 위험)
  • 체크포인트는 30초 간격으로만 저장됩니다.
  • 크래시 직전의 몇 초 동안의 쓰기 내역은 유실이 가능합니다. 
  • 이를 위해 복구 기법 Roll Forward가 도입되었습니다.
Roll Forward??
  • 데이터베이스에서 온 개념으로 체크포인트 이후의 로그 기록을 읽어 복원하는 방식입니다.
  • 작동방식 :
    1. 체크포인트가 가리키는 마지막 세그먼트부터 시작
    2. 세그먼트 안의 포인터를 따라 다음 세그먼트를 계속 따라갑니다.(세그먼트 안에는 다음 세그먼트 주소가 들어있습니다.)
    3. 세그먼트들의 로그를 순차적으로 읽어, imap, 아이노드, 파일 데이터를 복원합니다.