파일 시스템
보조 기억 장치에 파일과 디렉터리를 할당하는 시스템
🎈 파티셔닝, 포맷팅
보조 기억 장치를 처음 사용하기 위해서는 파티션을 나누고, 포맷 작업을 해야 한다.
- 파티셔닝 : 저장 장치를 여러개의 파티션으로 나누는 과정
- 포맷팅 : 파일 시스템 종류를 설정하고, 새로운 데이터를 쓸 준비를 하는 작업
파티션마다 다른 파일 시스템을 사용할 수도 있다.
🎈 파일 할당 방법
운영체제는 하드디스크를 블록 단위로 나눠서 파일과 디렉터리를 읽고 쓴다.
(하드디스크의 가장 작은 저장 단위인 섹터를 여러개 묶어 블록이라는 단위로 관리한다.)
파일을 저장하기 위해 파일에 블록을 할당해야 하는데, 할당 방법은 여러가지가 있다.
- 연속 할당
- 연속적으로 블록을 할당하는 방식
- 연속 메모리 할당 처럼 외부 단편화 문제가 있다.
- 연결 할당
- 블록에 다음 블록의 주소를 저장해 연결 리스트로 관리한다.
- 무조건 처음부터 탐색해야 하므로 중간 부분부터 접근할 수 없다.
- 한 블록이 삑나면 그다음 블록부터 탐색할 수 없다.
- 색인 할당
- 파일의 모든 블록 주소를 색인 블록이라는 하나의 블록에 모아 관리한다.
- 색인 블록 주소만 알면 해당 파일의 데이터에 접근할 수 있다.
🎈 파일 시스템
- FAT 파일 시스템
- 연결 할당의 단점을 보완, 각 블록의 다음 블록 주소를 한 곳에 모아 테이블로 관리한다.
- 이 테이블을 파일 할당 테이블 이라고 한다.
- 유닉스 파일 시스템
- 색인 할당 기반으로, 색인 블록을 i-node 라고 부른다.
- i-node에 파일 속성 정보와 최대 15개의 블록 주소가 저장된다.
- 파일 크기가 커서 블록이 15개 넘게 필요한 경우, 색인 블록을 하나 더 만들고 i-node에 이 색인 블록을 저장한다. (필요한 만큼 계층적으로 구성한다.)
- i-node는 파일 이름을 저장하지 않는다. i-node는 번호로 식별되고, 디렉터리가 이름 → i-node 번호 매핑을 담고 있다. (디렉터리도 파일들의 매핑 정보를 저장하는 특수한 파일)
🔰 저널링
파일을 변경하는 도중 컴퓨터가 꺼지면 파일 시스템이 훼손될 수 있다.
작업 로그를 이용해서 이 문제를 해결할 수 있다.
- 작업 직전, 수행할 변경 작업을 로그로 남긴다.
- 작업을 수행한다.
- 수행이 끝나면 로그를 삭제한다
- 재부팅 시 로그를 확인하고 완료하지 못한 일이 있다면 진행한다.
🎈 페이지 캐시
파일에 직접 접근 하는것은 성능을 소모한다.
이를 완화하기 위해, 메모리(RAM)의 남는 공간을 활용하여 파일을 캐싱한다.
- 읽기: 파일 블록을 처음 읽으면 디스크에서 가져와 페이지 캐시에 캐싱하고, 다음에 같은 블록을 읽으면 메모리에서 바로 읽음
- 쓰기: 일단 페이지 캐시에만 쓰고, dirty page로 표시한 후, 나중에 몰아서 디스크로 flush (write-back)
리눅스는 남는 RAM을 전부 페이지 캐시로 사용한다. 메모리가 부족해지면 깨끗한 페이지는 즉시 버리고 dirty page는 flush 후 버린다.
🔰 mmap (메모리 매핑 파일)
파일을 페이지 캐시에 캐싱하고, 페이지 캐시 주소와 프로그램 내부 가상주소를 연결하여 사용한다
패이지 캐시에 접근하는 방법은 두 가지가 있다. read()/write() 와 mmap
- read() 방식 : 파일을 읽으면, 커널이 디스크에서 페이지 캐시로 데이터를 올린 뒤, 그걸 다시 내 프로그램의 버퍼로 복사해준다.
- mmap 방식 : 파일을 내 프로그램의 주소 공간에 매핑한다. 그러면 그 주소를 메모리처럼 읽고 쓰면 그게 곧 파일 접근이 된다.
- 접근할 때마다 시스템 콜을 안 불러도 되고, 캐시에서 내 버퍼로 복사하는 과정이 없어서 큰 파일의 랜덤·반복 접근에 유리하다.
- 하지만 실제로는 디스크 I/O(페이지 폴트)가 숨어 있어서 지연이 예측 불가능하고, 오류가 SIGBUS 같은 형태로 튀어 다루기 까다롭다. 또 데이터가 디스크로 언제 반영될지(flush 시점)를 프로그램이 세밀하게 통제하기 어려워서, 이 통제가 생명인 데이터베이스는 오히려 mmap을 피하는 경우가 많다.

