저는 파일 변경 사항이 디스크에 직접 저장된다고 생각했습니다. 즉, 파일을 닫고 저장을 클릭/선택하기로 결정한 후에 말입니다. 그러나 최근 대화에서 내 친구는 이것이 일반적으로 사실이 아니라고 말했습니다. 운영 체제(특히 Linux 시스템에 대해 이야기하고 있음)는 메모리의 변경 사항을 유지하며 실제로 메모리 내용을 디스크에 쓰는 데몬을 가지고 있습니다.
그는 외부 플래시 드라이브의 예도 제시했습니다. 이러한 드라이브는 시스템에 마운트되고(메모리에 복사됨) 때로는 데몬이 내용을 플래시 메모리에 저장하지 않았기 때문에 데이터 손실이 발생합니다. 이것이 바로 우리가 플래시 드라이브를 마운트 해제하는 이유입니다.
나는 운영 체제 기능에 대해 아무것도 모르기 때문에 이것이 사실인지, 어떤 상황에서 이런 일이 발생하는지 전혀 모릅니다. 내 주요 질문은 다음과 같습니다. Linux/Unix 시스템(및 다른 운영 체제)에서 설명된 대로 이것이 발생합니까? 예를 들어, 이것은 내가 컴퓨터를 끄는 것을 의미합니까?곧파일을 편집하고 저장한 후 변경 사항이 손실될 수 있나요? 아마도 디스크 유형(기존 HDD와 SSD)에 따라 달라질 수 있을까요?
이 질문은 구체적으로 정보를 저장할 디스크가 있는 파일 시스템에 관한 것이지만, 명확한 설명이나 비교가 필요합니다.
답변1
파일을 편집하고 저장한 후 즉시 컴퓨터를 끄면 변경 사항이 손실될 수 있나요?
아마도 그럴 것입니다. "가능성이 가장 높다"고는 말할 수 없지만 가능성은 여러 요인에 따라 달라집니다.
파일 쓰기 성능을 향상시키는 간단한 방법은 운영 체제가 데이터를 캐시하고 응용 프로그램에 쓰기 프로세스를 알려주고 나중에 실제로 쓰기를 수행하는 것입니다. 이는 다른 디스크 활동이 동시에 발생하는 경우 특히 유용합니다. 운영 체제는 나중에 읽기 및 쓰기의 우선 순위를 지정할 수 있습니다. 또한, 예를 들어 나중에 임시 파일을 빠르게 삭제하는 경우와 같이 실제 쓰기 작업이 전혀 필요하지 않습니다.
캐싱 문제는 스토리지 속도가 느린 경우 더욱 분명해집니다. 빠른 SSD에서 느린 USB 스틱으로 파일을 복사하는 경우 USB 스틱이 따라잡을 수 없기 때문에 많은 쓰기 캐싱이 필요할 수 있습니다. 그러나 cp
명령이 더 빨리 반환되므로 작업을 계속할 수 있으며 방금 복사한 파일을 편집할 수도 있습니다.
물론 이와 같은 캐싱에는 단점이 있습니다. 일부 데이터는 실제로 저장되기 전에 손실될 수 있습니다. 편집자가 쓰기가 성공했지만 파일이 실제로 디스크에 없다고 말하면 사용자는 화를 낼 것입니다. 그렇기 때문에fsync()
시스템 호출, 파일이 실제로 디스크에 도달한 후에만 반환되어야 합니다. 편집자는 이를 사용하여 사용자에게 성공적인 쓰기를 보고하기 전에 데이터가 올바른지 확인할 수 있습니다.
"해야 한다"고 말한 이유는 파일이 실제로 드라이브 내의 휘발성 쓰기 캐시에만 존재하는 경우 드라이브 자체가 운영 체제에 동일한 거짓말을 하고 쓰기가 완료되었다고 말할 수 있기 때문입니다. 드라이브에 따라 이 문제를 해결할 수 있는 방법이 없을 수도 있습니다.
또한 모든 시스템 전체 쓰기 또는 특정 파일 시스템의 모든 쓰기가 디스크에 도달했는지 확인하도록 시스템에 요청하는 시스템 호출이 있습니다 fsync()
. 이 유틸리티를 사용하여 이를 호출할 수 있습니다.sync()
syncfs()
sync
그리고 거기에는O_DIRECT
다음으로 표시open()
, "파일에 대한 I/O의 캐시 영향을 최소화하도록 노력"해야 합니다. 캐시를 제거하면 성능이 저하되므로, 스스로 캐시하고 이를 제어하려는 애플리케이션(데이터베이스)에서 주로 사용됩니다. ( O_DIRECT
문제가 없는 것은 아니지만 매뉴얼 페이지에는 이에 대한 다소 흥미로운 설명이 있습니다.)
전원이 끊겼을 때 발생하는 상황은 파일 시스템에 따라 다릅니다. 주의해야 할 것은 파일 데이터뿐만 아니라 파일 시스템 메타데이터도 마찬가지입니다. 파일 데이터를 디스크에 저장해도 찾을 수 없으면 아무 소용이 없습니다. 단순히 파일을 더 큰 크기로 확장하려면 새로운 데이터 블록을 할당해야 하며 어딘가에 표시해야 합니다.
파일 시스템이 메타데이터 변경 사항을 처리하는 방법과 메타데이터와 데이터 쓰기 간의 순서는 매우 다양합니다. 예를 들어 ext4
, 마운트 플래그를 설정하면 data=journal
모든 쓰기(데이터 쓰기 포함)가 로그를 통과하므로 상당히 안전해야 합니다. 이는 또한 두 번 작성되므로 성능이 저하된다는 것을 의미합니다. 기본 옵션은 메타데이터가 업데이트되기 전에 데이터가 디스크에 있도록 쓰기 순서를 지정합니다. 다른 옵션이나 다른 파일 시스템이 더 좋을 수도 있고 나쁠 수도 있습니다. 포괄적인 연구는 시도하지 않겠습니다.
실제로 로드가 적은 시스템에서는 파일이 몇 초 내에 디스크에 도착해야 합니다. 이동식 저장소를 다루는 경우 미디어를 가져오기 전에 파일 시스템을 마운트 해제하여 데이터가 실제로 드라이브로 전송되고 더 이상 활동이 없는지 확인하세요. (또는 GUI 환경에서 이를 수행하도록 하십시오.)
답변2
하나 있다극도로증명하는 쉬운 방법할 수 없다실제로 파일 편집 내용은 항상 디스크에 직접 저장됩니다. 즉, 다음과 같은 파일 시스템이 존재합니다.처음부터 디스크 지원 없음. 파일 시스템에 없는 경우가지다먼저 디스크, 그다음불가능한변경 사항을 디스크에 기록하고,한 번.
몇 가지 예는 다음과 같습니다:
tmpfs
, RAM(더 정확하게는 버퍼 캐시)에만 존재하는 파일 시스템입니다.ramfs
, RAM에만 존재하는 파일 시스템- 어느네트워크 파일 시스템(NFS, CIFS/SMB, AFS, AFP...)
- 어느가상 파일 시스템(
sysfs
,procfs
,devfs
,shmfs
, ...)
그러나 디스크 백업 파일 시스템의 경우에도 일반적으로 그렇지 않습니다. 이 페이지SQLite 데이터베이스를 손상시키는 방법라는 챕터가 있습니다.동기화 실패쓰기(이 경우 SQLite 데이터베이스에 커밋됨)가 디스크에 도달하지 못할 수 있는 다양한 방법을 설명합니다. SQLite에는 보장을 위해 뛰어넘어야 하는 많은 어려움을 설명하는 백서도 있습니다.SQLite의 원자적 커밋. (알아채다원자 쓰기문제보다 더 어렵다쓰다, 그러나 물론 디스크에 쓰는 것은 원자 쓰기의 하위 문제이며 이 기사에서도 해당 문제에 대해 많은 것을 배울 수 있습니다. ) 이 기사에는 소개하는 섹션이 있습니다.잘못될 수 있는 일약 포함불완전한 디스크 플러시쓰기가 디스크에 도달하지 못하게 할 수 있는 미묘한 복잡성의 몇 가지 예를 제공합니다(예: HDD 컨트롤러가 디스크에 기록했지만 실제로 디스크에 기록하지 않았다고 보고합니다. 예, 일부 HDD 제조업체에서는 이 작업을 수행하며 그럴 수도 있습니다). 이와 관련하여 표현이 모호하므로 ATA 사양에 따라서도 합법적입니다.
답변3
실제로 Unix, Linux, Windows를 포함한 대부분의 운영 체제는 작업 속도를 높이기 위해 쓰기 캐싱을 사용합니다. 이는 컴퓨터를 끄지 않고 종료하는 것은 좋지 않은 생각이며 데이터가 손실될 수 있음을 의미합니다. USB 저장 장치를 제거할 준비가 되기 전에 제거하는 경우에도 동일한 상황이 발생합니다.
대부분의 시스템은 동기식 쓰기 옵션도 제공합니다. 즉, 애플리케이션이 성공 승인을 받을 때까지 데이터가 디스크에 저장되지만 속도가 느려집니다.
즉, 컴퓨터를 올바르게 종료하고 USB 저장소 제거를 적절하게 준비해야 하는 이유가 있습니다.
답변4
로드가 적은 시스템에서 커널은 새로 작성된 파일 데이터를 페이지 캐시에 약 30초 동안 보관한 write()
후 디스크에 플러시하여 곧 다시 삭제되거나 수정되지 않도록 최적화합니다.
Linux의 기본값 dirty_expire_centisecs
은 3000(30초)입니다., 새로 작성된 데이터가 "만료"되기 전까지의 시간을 제어합니다. (바라보다https://lwn.net/Articles/322823/).
바라보다https://www.kernel.org/doc/Documentation/sysctl/vm.txt더 많은 관련 조정 가능 매개변수를 보려면 Google에서 자세한 내용을 확인하세요. (예: Google에서 dirty_writeback_centisecs
)
Linux 기본값은 /proc/sys/vm/dirty_writeback_centisecs
500(5초) 입니다., PowerTop에서는 전력 소비를 줄이기 위해 1500(15초)으로 설정할 것을 권장합니다.
또한 지연된 쓰기 저장은 디스크에 쓰기를 시작하기 전에 파일의 크기를 확인할 수 있는 커널 시간을 제공합니다. 지연 할당을 사용하는 파일 시스템(예: XFS 및 현재 다른 파일 시스템)은 inode 자체에 공간을 할당하는 대신 필요할 때 파일에 새로 작성된 데이터를 저장할 디스크 위치를 선택하지도 않습니다. 예를 들어, 이를 통해 다른 파일 사이의 1MB 간격에 대용량 파일의 시작 부분을 배치하는 것을 방지하여 조각화를 줄일 수 있습니다.
많은 양의 데이터가 기록되는 경우 페이지 캐시에 있는 더티 데이터(아직 디스크에 동기화되지 않음)의 양에 대한 임계값에 따라 디스크에 다시 쓰기가 트리거될 수 있습니다.
하지만 별다른 조치를 취하지 않으면 작은 파일에서 "저장"을 클릭한 후 5초(또는 15)초 동안 하드 드라이브 활동 표시등이 켜지지 않습니다.
파일을 작성한 후 편집기를 fsync()
사용하면 커널은 파일을 즉시 디스크에 씁니다. (그리고 fsync
데이터가 실제로 디스크로 전송될 때까지 반환되지 않습니다).
캐시 쓰기이내에디스크도 중요할 수 있지만 디스크는 일반적으로 Linux의 페이지 캐시 알고리즘과 달리 쓰기 캐시를 가능한 한 빨리 영구 저장소에 커밋하려고 합니다. 디스크 쓰기 캐시는 소량의 쓰기 버스트를 흡수하는 스토리지 버퍼와 비슷하지만 읽기를 위해 쓰기를 지연하고 탐색 패턴을 최적화할 수 있는 디스크 펌웨어 공간을 제공할 수도 있습니다(예: 두 번 쓰기 또는 읽기를 수행하는 대신 두 번에 가까운 쓰기 또는 읽기 작업 수행). 한 번) 그런 다음 멀리 찾고 다시 찾아보세요. )
회전(자기) 디스크에서 쓰기 전에 보류 중인 읽기/쓰기 작업이 있는 경우 SATA 쓰기 명령의 데이터가 실제로 밀리초 단위로 중단되기 전까지 약 7~10초가 소요될 수 있습니다. (이 질문에 대한 다른 대답은 저널링 파일 시스템이 손상을 방지하는 데 사용할 수 있는 디스크 쓰기 캐싱 및 쓰기 장벽에 대해 자세히 설명합니다.)