운영체제(OS)

[OS] FSCK and Journaling

서노리 2022. 12. 8. 22:13
반응형

Disk Crash Scenario

disk I/O 과정에서 crash가 발생하는 경우에 대해 살펴보자. 이미 존재하는 파일에 대해 새로운 데이터를 추가하는 경우에는 data bitmap, inodes, data block을 갱신해야한다. 위 세 가지 블록들에 대한 갱신은 원자적(atomic)으로 수행되어야하며, 이때 발생할 수 있는 crash 시나리오는 다음 6가지와 같다.

 

※ data bitmap과 inodes가 둘다 정상 갱신되거나 둘다 crash되면 consistent 상태로 다시 수행하면 문제를 해결할 수 있어 파일 시스템 상으로는 문제가 없지만 data bitmap과 inodes의 갱신 결과가 다른 경우 inconsistent한 상황이 되어 문제가 발생한다.

 

1. data block만 정상 갱신될 경우

consistent한 상황으로 파일 시스템에는 문제가 없지만 사용자는 data를 손실하게 된다.

 

 2. inodes만 정상 갱신될 경우

inconsistent한 상황으로 inodes는 이미 데이터 블록을 가리키지만 해당 데이터 블록에는 데이터가 쓰여있지 않다.

 

3. data bitmap만 정상 갱신될 경우

inconsistent한 상황으로 해당 데이터 블록에는 데이터가 없고, inodes에서도 해당 데이터 블록을 가리키지 않지만 data bitmap에는 used로 표시가 된다. 따라서 이후 해당 데이터 블록은 사용되지 못하고 낭비될 것이다.

 

4. data bitmap과 inodes만 정상 갱신될 경우

 

consistent한 상황으로 해당 데이터 블록을 읽으면 garbage data를 얻게 된다.

 

5. inodes와 data block만 정상 갱신될 경우

inconsistent한 상황으로 inode에서 정상적인 데이터 블록을 가리킴에도 불구하고 data bitmap에 unused로 표시되어 있기 때문에 언제든 덮어씌워질 수 있고, 다른 inode가 동일한 데이터 블록을 가리키게 될 수 도 있다.

 

6. data bitmap과 data block만 정상 갱신될 경우

inconsistent한 상황으로 data bitmap에서도 used로 표시되어 있으며 해당 데이터 블록도 정상적인 데이터가 쓰여져있지만 inode에서 해당 데이터 블록을 가리키지 않기 때문에 어떤 파일과도 연결되지 못하여 orphan data block이 된다.

 


FSCK (File System Checker)

FSCK는 Unix 파일 시스템에서 crash inconsistent state를 찾아내 해결하는 도구로 파일 시스템 메타 데이터들 간의 일관성을 유지하기 위한 목적으로 사용된다. 초기 파일 시스템은 crash inconsistent state가 발생해도 이를 무시하다가 재부팅시 해결하는 방법을 사용했다. FSCK는 재부팅 없이도 이를 해결하기 위해 개발되었다. FSCK 동작 중에는 파일 시스템이 어떠한 다른 동작도 수행하지 않는다고 가정한다.

 

FSCK는 inodes 정보를 기반으로 bitmap을 재갱신하며 간단하고 write overhead가 없다는 장점이 있지만, 수행 속도가 느리고 consistent한 경우에 대해서는 해결이 불가능하다는 단점이 있다.


Journaling (WAL: Write-Ahead Logging)

저널링은 write 요청 시에 이를 바로 갱신하지 않고 로그를 기록해 저장했다가 (write-ahead log) crash가 발생하면 해당 로그를 확인하여 재갱신(redo)하는 방법이다. 로그의 저장 단위는 트랜젝션(transaction) 단위이며 이러한 로그를 저장하기 위해 디스크에 journal block이 추가 된다. 저널링의 종류로는 데이터 저널링과 메타 데이터 저널링이 있다.

 

Data Journaling Scenario

inode와 bitmap, data block을 갱신하는 일반적인 파일 시스템 연산을 통해 데이터 저널링 과정을 알아보자

먼저 저널에 해당 데이터들을 쓴다. TxB는 트랜잭션의 시작 블록이며 TxE는 트랜잭션의 종료 블록이다. TxE가 저널에 기록되면 트랜잭션은 커밋(commit) 되었다고 한다. 이렇게 기록된 저널이 실제 위치에 반영되는 것을 체크포인팅이라고 부른다.

 

저널에 기록하는 도중 crash 발생 문제

한 번에 많은 양을 쓰고자 하는 경우에는 디스크가 스케줄링을 통해 작은 단위로 나누어 기록할 가능성이 존재한다. 쓰기 완료 순서는 디스크에 의해 결정되며 파일 시스템이 의도했던 순서와는 다를 수 있다. 따라서 위와 같이 TxE가 먼저 쓰여졌는데 Db가 아직 써지기 전에 디스크 전원이 차단되면 심각한 문제가 발생한다.

 

TxE의 기록은 트랜잭션의 성공적 종료를 의미하기 때문에 위와 같은 문제가 발생하더라도 성공적 종료로 판단한다. 이 상황에서 체크포인팅이 진행되면 ??라고 쓰여진 쓰레기 Db 블록을 실제 위치에 복사하게 된다.

 

이러한 문제를 방지하기 위해 파일 시스템은 트랜잭션을 두 단계로 나누어 기록한다. 먼저 TxE를 제외한 모든 블록을 한 번의 쓰기 요청으로 저널에 쓴다.

이후 TxE 블록에 대한 쓰기 요청으로 저널을 안전하게 만든다. 이러한 작업은 디스크 쓰기 연산의 원자성이 충족되어야 하며 TxE는 무조건 원자적으로 기록되어야 한다.

복구

crash가 발생하는 다양한 시점에서 복구하는 방법에 대해 알아보자

  • 트랜잭션이 커밋되기 전에 crash 발생된 경우
    - 아무것도 하지 않음

  • 트랜잭션이 체크포인트 되기 전에 crash 발생된 경우
    - 시스템이 부팅할 때 로그를 탐색
    - 있다면 원래 위치에 씀 (redo logging)

로그 공간 관리

로그 공간이 꽉 차면 로그 공간에 있는 모든 트랜잭션을 순서대로 재실행해야 하므로 복구 소요 시간이 길어진다. 더 심한 문제는 디스크에 더 이상의 트랜잭션을 커밋할 수 없다는 점이다.

 

이와 같은 문제를 해결하기 위해 저널링 파일 시스템은 환형 로그(Circular log)를 사용하여 로그 영역을 끝까지 다 쓰면 앞에서 부터 다시 쓸 수 있도록 한다.


메타 데이터 저널링

저널에 데이터 블록을 기록하지 않는다는 것 외에는 데이터 저널링과 동일하다. 메타 데이터 저널링에서는 추가적인 쓰기를 피하기 위해 파일 시스템의 원래 위치에 Db를 기록한다.


반응형

'운영체제(OS)' 카테고리의 다른 글

[OS] RAID  (0) 2022.12.08
[OS] Hard Disk, Disk Scheduling  (0) 2022.12.08
[OS] File System  (0) 2022.12.07
[OS] pthread  (0) 2022.12.06
[OS] Deadlock  (0) 2022.12.05