개요

저널링 파일 시스템(영어: Journaling file system)은 주 파일 시스템에 변경사항을 반영(commit)하기 전에, 저널(주로 파일 시스템의 지정된 영역 안의 원형 로그)안에 생성되는 변경사항을 추적하는 파일 시스템이다. 시스템 충돌이나 전원 문제가 발생하면, 이러한 파일 시스템은 더 빠르게 online 상태로 돌아오며 손상될 가능성이 낮다. FSCK로 대변되는 offline 파일 시스템 체킹과 비교하여, 실시간으로 사용할 수 있기에 시스템을 halting시키지 않아도 된다는 장점이 있다. 그러나 저널은 하나의 write에 대해서 저널과 대상 블럭에 대한 최소 두번의 write가 필요가게 된다. 따라서 저널링 시스템을 효과적으로 사용하기 위해선 buffering을 효과적으로 사용하여 이러한 overhead를 줄여야 한다.

저널링 방식 말고도 파일 시스템의 일관성을 유지하는 방법으로 File system COW, Backpointer-based consistency, Soft update와 같은 다양한 방식들이 있다.

저널은 기본적으로 Fixed-size의 circular array이다. 저널은 hard-coded inode넘버를 가지는 (보통 8)특별한 파일에 작성하게 된다. 각각의 저널은 begin, log 그리고 end 마커를 가진다.

Begin, Data for block123, data for block 765, end ... 

저널링 작동의 기본 원리

기본적으로 저널링은 파일 시스템에 transaction을 기록하고, 그후 저널링에 기록된 내용을 다시 원래 위치에 적는 과정을 통해서 이루어 진다. 이때 디스크는 최소 블럭 단위 (보통 512바이트에서 4킬로바이트)의 access는 atomic하게 보장한다. 따라서 이러한 성질을 살려서 데이터 작성은 저널에 transaction 작성후, CKPT END를 한 블럭 크기로 삽입 (commit), 그리고 실제 데이터 작성 (checkpointing) 순으로 이루어 지게 된다.

Journal write -> Journal commit -> Checkpoint

많약 파일 시스템이 commit 없이 fault난 경우에는 간단히 저널에 있는 내용을 무시하고, 그 외의 경우에는 저널의 내용을 redo하여서 파일 시스템을 복구하게 된다. (어떤 저널 시스템은 파일 메타데이터를 모두 적고 commit을 작성하는 경우도 있다. 이런 경우는 undo logging으로 저널의 데이터를 복구한다. 이러한 방식에서는 commit 이 있으면 commit 된 시점까지 데이터를 복구하고 commit 되지 않은 것은 무시한다. - 데이터 베이스 복구의 한 방법으로 파일 시스템 복구에서는 redo 로깅을 주로 사용 -)

Crash Scenarios

  1. Data block만이 작성됨: 이경우 데이터 블럭 할당과 그에 따른 연관된 메타데이터가 업데이트 되지 못한다. 그러나 이러한 경우는 저널링 할 필요가 없다. # Inode Block만이 작성됨: 이 경우, 아이노드 블럭이 잘못된 (garbage)데이터를 가르키거나, 아니면 할당 되지 않은 블럭을 가르키는 치명적인 문제가 생길 수 있다.
  2. Bitmap만이 작성됨: 이 경우, space leak현상이 발생할 수 있다. 이러한 경우 할당된 블럭을 다시는 사용하지 못하게 되는 경우가 발생할 수 있다.
  3. Data block만 작성되지 않음: 이 경우, 데이터 블럭은 쓰레기 값을 가지게 된다.
  4. Inode block만이 작성되지 않음: 블럭과 데이터에 정보가 할당되어 있지라도, 아이노드가 이 블럭을 가르키지 않아서 블럭이 어떠한 구조로 저장된지를 모르게 된다.
  5. Bitmap만이 작성되지 않음: 이 경우, 아이노드가 잘못된 블럭을 가르킬 수도 있으며, 데이터 블럭과 아이노드 정보의 불일치를 가져오게 된다.

Journaling Log

저널링 시스템에서 로그는 Full 되는 경우는 없어야 된다. 저널이 Full 되었다는 것은 더이상 저널링 시스템을 사용하지 못한다는 말과 같은 말이기 때문이다. 따라서 저널은 Circular log을 이용하여 구현하게 된다. 저널은 계속해서 재 사용되면서 파일 시스템을 저널링 하게 된다.

Metadata Journaling

저널링을 할때 전체 데이터를 모두 저널링 하는 것을 Data Journaling이라고 부른다. 저널링에서 데이터를 읽고 쓸때 write access를 두번 발생시켜서 total bandwidth가 반으로 줄어드는 문제가 있다. 이러한 문제를 극복하기 위해서 저널에 전체 데이터를 저장하는 것이 아니라 일부 메타데이터만을 저장시키게 된다. 이러한 방법을 Ordered Journaling혹은 Metadata Journaling이라고 한다. ext3는 이 방식을 사용하며, 거의 대다수 저널링 기법의 기본이 된다. 이 방식에서 각각의 블럭들을 적는 순서는 매우 중요한 역활을 한다. 만약 데이터가 메타데이터 이후에 적히거나 하면, garbage data를 가르키는 등의 문제가 생길 수도 있기 때문이다. (이떄 indirect pointer와 같은 block device pointer, dentry와 같은 디렉토리 정보는 data가 아니라 metadata로 간주된다.)

Data write -> journal matadata write -> Journal commit -> Checkpoint metadata -> Free log

이떄 메타데이터 저널링에서 데이터 블럭과 메타데이터 블럭의 경계가 모호한 경우도 있는데 이러한 경우는 따로 처리해 주어야 한다. 예를 들어서 디렉토리 엔트리가 모두 삭제되어 free된 블럭을 다른 아이노드가 가르키게 되었다고 해보자. 이러한 경우, 많약 메타데이터 저널링을 사용하게 되면 덴트리는 로깅되어 복구 되는데 블럭은 그렇지 않아, 나중에 복구가 완료된뒤 파일을 열어 보면 파일 내용에 덴트리가 적히게 되는 당혹스러운 에러가 발생하게 된다. 이러한 에러를 막기 위해서 만약 블럭이 삭제되면, 그 블럭이 저널에서 삭제 될때까지 reuse하지 않거나 revoke라는 특수한 log를 이용하여, 만약 이러한 특수한 경우가 생기면 revoke를 저장하고 revoke라는 로그가 있는 해당 블럭은 redo를 하지 않아 이러한 특수한 경우를 방지한다.

명령어

저널링 끄는 법

$tune4fs -O ^has_journal /dev/?
$e4fsck –f /dev/sda2