일관성
- DRAM vs 스토리지
- 스토리지 : 용량 크다 . 속도 낮다. 메모리 계층구조를 만든다.
- DRAM : 바이트 단위, 스토리지 : 섹터단위, 블럭단위
- 스토리지 : 비휘발성
- 비휘발성
- 전원이 공급되지 않더라도 데이터가 영속적
- 일관성을 유지해야한다.
Consistency(일관성의 정의)
- 파일 시스템이 valid한 상태를 유지하는 것
- invalid state => 비트맵과 파일이 사용되는것이 불일치한 경우
- 사용 가능하다고 했는데 사용중인 경우(일관성이 깨진 상태)
- valid에서 또다른 valid로 바뀌는 것을 보장하는 것
- 일관성은 power loss에 많이 깨진다.
비일관성은 언제 발생하는가?
- 비트맵 , 아이노드(8개) , 데이터블럭(8개)
- 회색 : 사용중
- 4KB의 새로운 파일을 만드려한다.=> 디스크블럭 4번 할당받음 , 아이노드 2번
- 아이노드 비트맵 => 2번 회색 , 4번 데이터블럭 비트맵 => 회색
-
기존 4K => 8K
-
새로운 디스크 블럭 할당
-
아이노드 수정 , 비트맵 수정 , 데이터 써짐
-
3개의 쓰기 발생 // 모두 잘 써지면 문제가 없다
-
Seek distance때문에 항상 쓰기 순서가 보장되지 않는다.
-
지연쓰기 => 쓸 때마다 쓰는게 아니라 DRAM상에 미리 써놓았다가 이후에 스토리지에 쓴다.
- 전원결함 발생시 어떤 write는 써지고 어떤건 쓰이지 않을수도 있다.
-
데이터만 쓰인다면 ? 문제 x
-
비트맵만 쓰인다면 ? 공간 손실
-
아이노드만 쓰인다면 ? 비일관성(inode vs bitmap) , garbage read(아이노드만 쓰임)
-
데이터 + 비트맵 => 비일관성
-
데이터 + 아이노드 => 비일관성
-
아이노드 + 비트맵 => Garbage Read
==> 일관성 : All or Nothing (락에서의 Atomic과 유사)
비일관성 해결법
- fsck : 문제탐지 , 해결 => 사건 해결
- 저널링 : 파일시스템에 어떤작업을 할거라고 log 를 기록 , 로그를 보고 다시 수행해도 괜찮으면 redo or undo => 사건 예방
- CoW : 데이터에 대해 수정이 요청될 때 다른 공간에 갱신
- integrity를 보장하여 일관성을 보장 => 성능 향상 (ext4) ex)checksum
- soft update : 항상 일관된 상태를 유지하도록 순서를 잘 정리.
fsck (file system checker)
- 파일시스템이 일관성을 유지하는지 보고 고치는 도구
- 슈퍼블럭이 일관성을 가지고 있나 체크. sanity check
- 모든 아이노드를 찾고 비트맵을 보며 프리블럭인지 확인
- 아이노드 링크수가 제대로 되어있는지 중복되는 데이터블럭을 동시에 가리키지 않는지
- 디렉토리 체크 - 첫번째 디렉토리가 ..이 맞는지
==> 너무 느리다. 전체를 검사해야한다.
CoW (Copy on Write)
- Out of place update
- 데이터블럭의 1을 2로 바꾸고싶다. 다른 블럭을 하나 할당받아서 2를 입력하고 inode가 다른쪽을 가리키게 만든다.
- commit => 갱신 이후
- undo => 롤백
저널링
- WAL (Write Ahead logging)
- 디스크를 업데이트하기 전에 어떤 일을 할 지 미리 노트에 남겨놓음
- 액션을 취하기전에 저널링하여 문제가 발생하면 redo or undo를 함
- 그룹마다 슈퍼블록을 가지고 있음
- Ext3 = Ext2 + 저널링
-
저널링은 쓰기 요청이 발생하면 쓰기를 저널공간에 씀(커밋) => 원래 위치에 쓴다(체크포인팅)
if) 3개의 write 발생, 4K => 8K
-
Commiting : 3개의 write부터 저널링 함
-
원자성을 보장하기 위해 TxB , TxE를 씌운다.
-
T : Transaction
-
Transaction까지 고려하면 5개의 write가 발생
-
체크포인팅 : 원래 위치에 데이터를 업데이트
-
리커버리(fault handling) : redo or undo
- redo : 결함이 저널링이 완료가 되고 체크포인팅(저널은 valid)라면 다시 저널
- undo : 저널이 invalid하면 , 저널링중 fail하면 지운다. 이전의 일관된 상태로 유지가능
저널 이슈
유효성 체크를 어떻게 하나?
- transaction : begin , and 도입 => 제대로 쓰여있는지 확인
- 이것은 caching/i/o스케줄러를 통해 순서가 바뀔 수 있음
- read는 읽을때까지 기다려야하기에 우선순위를 높이는 경우가 많다.
5개의 write를 한번에? 순차적으로?
TxE만 분리한다면
TxE 전에만 sync한다. 보장 정책을 이용한 것(Ext3에서 사용)
- 한번에 모두 쓴다. 대신 checksum을 도입한다면?
무엇을 저널링 할것인가?
1. 둘 다 저널링
2. 메타데이터만 저널링
- 데이터와 메타데이터 모두 저널링 : 일관성이 나아짐. write twice(비용이 많이 든다.)
- 메타데이터만 저널링 : 오버헤드 줄어듦
순서관계를 지켜야하는가?
- 데이터 저널링 : 항상 저널링 먼저하고 원래 위치에 쓰면 된다.
- 메타데이터 저널링 : 저널 공간에 써야할 내용과 데이터 공간에 쓸 내용이 다르다.
- 항상 데이터 부분을 먼저 쓰고 저널을 써야한다.
- 데이터 부분은 일관성에 문제가 없기 때문.
- 아이노드가 쓰였는데 데이터가 안쓰이면 garbage read가 생길 수 있다.
- 그림에서 점선은 오더링을 지키기 위함
- issue => issue complete(데이터 유효성 검사) // 커밋이 끝남
- 원래 위치에 데이터와 메타데이터를 쓴다. // 체크포인트
- 위는 데이터와 메타데이터 저널링의 병렬적으로 이루어짐(writeback모드)
- 데이터 쓰기 이후 저널링 => 커밋 => 체크포인팅
저널 valid but cannot redo
- 푸가 1000, 푸바도 1000, redo를 하면 foo가 덮어쓰게 됨. 메타데이터는 있지만 데이터는 없어서 푸바가 손실됨.
==> revoke record 도입 : 다시 저널을 만든다.
Ext3
- 3개의 저널모드
- 저널 모드(데이터 저널)
- 메타데이터 저널 (순서 지킴)
- writeback (순서 x)
- 데이터 저널 : 저널을 먼저 씀 => 커밋 => 오리지널 위치에 쓴다.
- 메타데이터 저널 : 데이터 쓰고 => 저널링 => 커밋 => 저널 safe => 원래 위치에 메타데이터 업데이트 (디폴트)
- 순서관계 x : 저널 => 커밋 => 실제데이터는 저널 전/후 아무데나 상관없음 (성능최적화)
Ext3 파일 시스템의 구현
- jbd 소프트웨어 컴포넌트 사용 : 저널링을 제공하는 블록디바이스 레이어
- jdb2 : Ext4 (64bit지원)