Сохраняются ли правки файлов в Linux напрямую на диск?


57

Раньше я думал, что изменения файла сохраняются непосредственно на диск, то есть, как только я закрываю файл и решаю нажать / выбрать сохранить. Однако в недавнем разговоре мой друг сказал мне, что обычно это не так; ОС (в частности, мы говорили о системах Linux) хранит изменения в памяти, и у нее есть демон, который фактически записывает содержимое из памяти на диск.

Он даже привел пример внешних флэш-накопителей: они монтируются в систему (копируются в память), и иногда происходит потеря данных, потому что демон еще не сохранял содержимое во флэш-памяти; именно поэтому мы размонтируем флешки.

У меня нет знаний о функционировании операционных систем, и поэтому я абсолютно не знаю, так ли это и при каких обстоятельствах. Мой главный вопрос: происходит ли это так, как описано в системах Linux / Unix (и, возможно, в других ОС)? Например, означает ли это, что если я выключу компьютер сразу после редактирования и сохранения файла, мои изменения, скорее всего, будут потеряны? Возможно, это зависит от типа диска - традиционные жесткие диски или твердотельные диски?

Этот вопрос относится конкретно к файловым системам, которые имеют диск для хранения информации, даже если любые разъяснения или сравнения хорошо приняты.


8
ФАО: Закрыть рецензентов очереди голосования. Это не запрос на учебные материалы. См. Unix.meta.stackexchange.com/q/3892/22812
Энтони Дж - правосудие для Моники

2
Кэш является непрозрачным для пользователя, в лучшем случае вы должны sync, и приложения должны flushгарантировать, что кэши будут записаны обратно, но даже успешное выполнение syncне гарантирует обратной записи только на физический диск, поскольку кэши ядра сбрасываются на диск, что может иметь задержку в драйвере или оборудовании диска (например, кэш-память на диске, которую вы теряете)
сбой

1
Хотя я не согласен с тем, что это запрос на учебные материалы, я думаю, что вопрос в его нынешнем виде является немного более широким. Ограничьте область применения дистрибутивами Linux (или какой-либо конкретной ОС) и, возможно, ограничьте ее определенными технологиями хранения и файловыми системами.
Джефф Шаллер

3
Как отметил @AnthonyGeoghegan, я не считаю этот вопрос запросом учебных материалов. Я думаю, что это довольно специфично; Я не просил длинного и глубокого объяснения или руководства по файловым системам Linux; только о краткой идее, которую я хотел прояснить.
JuanRocamonde

3
Это правда, что это может быть немного шире, @JeffSchaller; Я попытаюсь немного его отредактировать; однако, если честно, если сайт не предназначен для такого типа вопросов, которые напрямую касаются работы Linux, то для чего он нужен?
JuanRocamonde

Ответы:


70

если я немедленно выключу компьютер после редактирования и сохранения файла, мои изменения, скорее всего, будут потеряны?

Они могут быть. Я бы не сказал «скорее всего», но вероятность зависит от многих вещей.


Простой способ повысить производительность записи в файл - для ОС просто кэшировать данные, сказать (лгать) приложению, через которое прошла запись, а затем фактически выполнить запись позже. Это особенно полезно, если одновременно происходит другая активность на диске: ОС может назначать приоритеты чтению и делать записи позже. Это также может полностью устранить необходимость в реальной записи, например, в случае, когда временный файл удаляется быстро после этого.

Проблема с кэшированием становится более заметной, если хранилище работает медленно. Копирование файлов с быстрого SSD на медленный USB-накопитель, вероятно, потребует большого объема кэширования при записи, поскольку USB-накопитель просто не справляется. Но ваша cpкоманда возвращается быстрее, поэтому вы можете продолжать работать, возможно, даже редактируя только что скопированные файлы.


Конечно, у такого кеширования есть и обратная сторона: некоторые данные могут быть потеряны до того, как они действительно будут сохранены. Пользователь будет недоволен, если его редактор скажет им, что запись прошла успешно, но на самом деле файл не был на диске. Вот почему существует fsync()системный вызов , который должен возвращаться только после того, как файл действительно попал на диск. Ваш редактор может использовать это, чтобы убедиться, что данные в порядке, прежде чем сообщать пользователю, что запись прошла успешно.

Я сказал: «Предполагается», поскольку сам накопитель может сказать ту же ложь ОС и сказать, что запись завершена, в то время как файл действительно существует только в энергозависимом кеше записи внутри накопителя. В зависимости от диска, может не быть никакого пути к этому.

Кроме того fsync(), существуют также sync()и syncfs()системные вызовы , которые запрашивают систему , чтобы убедиться , что все общесистемные записи или все записи на конкретной файловой ударяли диск. Утилита syncможет быть использована для вызова тех.

Кроме того, есть O_DIRECTфлаг toopen() , который должен «попытаться минимизировать эффекты кэширования ввода-вывода в этот файл и из него». Удаление кэширования снижает производительность, так что в основном оно используется приложениями (базами данных), которые выполняют свое собственное кэширование и хотят контролировать его. ( O_DIRECTне без проблем, комментарии об этом на странице руководства несколько забавны.)


То, что происходит при отключении питания, также зависит от файловой системы. Вы должны быть обеспокоены не только данными файла, но и метаданными файловой системы. Наличие данных на диске не очень полезно, если вы не можете их найти. Простое расширение файла до большего размера потребует выделения новых блоков данных, и они должны быть где-то отмечены.

То, как файловая система справляется с изменениями метаданных, и порядок между метаданными и записью данных сильно различается. Например, с помощью ext4, если вы установите флаг монтирования data=journal, тогда все записи - даже записи данных - проходят через журнал и должны быть достаточно безопасными. Это также означает, что они пишутся дважды, поэтому производительность снижается. Параметры по умолчанию пытаются упорядочить записи так, чтобы данные находились на диске до обновления метаданных. Другие параметры или другие файловые системы могут быть лучше или хуже; Я даже не буду пытаться всесторонне изучить.


На практике в слегка загруженной системе файл должен попасть на диск в течение нескольких секунд. Если вы имеете дело со съемным хранилищем, размонтируйте файловую систему перед извлечением носителя, чтобы убедиться, что данные действительно отправлены на диск, и больше никаких действий нет. (Или ваша среда графического интерфейса сделает это за вас.)


some cases whereПохоже, ваша ссылка не говорит ни о каких подобных случаях - вместо этого говорится, что были проблемы, когда приложения не использовались fsync. Или я должен посмотреть в комментариях, чтобы найти эти случаи, на которые вы указываете?
Руслан

1
Вы также можете использовать syncнепосредственно как команду системной оболочки, чтобы запустить ядро ​​для очистки всех кешей.
авария

3
На практике в слегка загруженной системе файл попадает на диск через мгновение. Только если ваш редактор использует fsync()после записи файла. По умолчанию для Linux установлено значение /proc/sys/vm/dirty_writeback_centisecs500 (5 секунд), и PowerTop рекомендует установить значение 1500 (15 секунд). ( kernel.org/doc/Documentation/sysctl/vm.txt ). В слегка загруженной системе ядро ​​просто оставит грязным в кеше страницы задолго write()до того, как записать его на диск, чтобы оптимизировать его для случая, когда оно вскоре будет удалено или изменено снова.
Питер Кордес

2
+1, поскольку сам накопитель может быть таким же обманом для ОС . Насколько я понимаю, накопители, выполняющие такого рода кэширование, также имеют достаточную емкость, чтобы их кэши могли быть сохранены даже при катастрофической потере мощности. Это не зависит от ОС; В Windows есть механизм «Безопасного удаления USB», который выполняет очистку кэша перед отключением пользователя.
Студог

1
@ Studog, я бы не был так уверен, особенно на потребительском оборудовании. Но это может быть просто паранойя. Было бы интересно проверить, хотя.
ilkkachu

14

Существует чрезвычайно простой способ доказать, что не может быть правдой, что изменения файлов всегда сохраняются непосредственно на диск, а именно тот факт, что существуют файловые системы, которые в первую очередь не поддерживаются диском . Если файловая система не имеет диска, то она никогда не сможет записать изменения на диск .

Вот некоторые примеры:

  • tmpfsфайловая система, которая существует только в ОЗУ (или, точнее, в буферном кеше)
  • ramfsфайловая система, которая существует только в оперативной памяти
  • любая сетевая файловая система (NFS, CIFS / SMB, AFS, AFP,…)
  • любая виртуальная файловая система ( sysfs, procfs, devfs, shmfs, ...)

Но даже для дисковых файловых систем это обычно не так. Страница Как повредить базу данных SQLite содержит главу под названием « Невозможность синхронизации», в которой описываются различные способы, с помощью которых записи (в этом случае фиксируются в базе данных SQLite) могут не поступать на диск. В SQLite также есть технический документ, объясняющий множество циклов, через которые вы должны перейти, чтобы гарантировать атомарную фиксацию в SQLite . (Обратите внимание, что атомарная запись гораздо сложнее, чем просто запись , но, конечно, запись на диск является подзадачей атомарной записи, и вы также можете многое узнать об этой проблеме из этой статьи.) раздел о том, что может пойти не так, который включает в себя подраздел оНеполные сбросы диска, которые приводят некоторые примеры тонких хитростей, которые могут помешать записи достигнуть диска (например, сообщение контроллера жесткого диска о том, что оно записано на диск, когда на самом деле его нет - да, есть производители жестких дисков, которые делают это, и это может быть даже законно в соответствии со спецификацией ATA, потому что это неоднозначно сформулировано в этом отношении).


10
Первая часть этого ответа просто недооценивает точное использованное слово. Я не понимаю, как это служит какой-либо цели, кроме насмешек над пользователем. Очевидно, что сетевая файловая система не будет записывать на локальный диск, но вопрос все еще остается там.
труба

3
Как указал @pipe, тот факт, что существуют файловые системы, которые не сохраняют данные на диск, потому что они не используют диск для хранения данных, не решает, могут ли те, у кого они есть, сохранять их напрямую или нет. Тем не менее, ответ выглядит интересно
JuanRocamonde

1
@pipe Я уверен, что использование термина "besserwissering" - это бессмысленно! Сказать это как немецкий Besserwisser с властью.
Фолькер Сигел

11

Это правда, что большинство операционных систем, включая Unix, Linux и Windows, используют кэш записи для ускорения операций. Это означает, что выключение компьютера без его выключения является плохой идеей и может привести к потере данных. То же самое верно, если вы извлекаете USB-накопитель до того, как он будет готов к удалению.

Большинство систем также предлагают возможность делать записи синхронно. Это означает, что данные будут на диске до того, как приложение получит подтверждение успеха, за счет того, что оно будет медленнее.

Короче говоря, есть причина, по которой вы должны правильно выключить компьютер и правильно подготовить USB-накопитель для удаления.


Спасибо за ваш ответ! Есть ли способ принудительно записать на диск определенный файл в Linux? Может быть, ссылка на учебник или страницу документации, даже вопрос SE будет хорошо :)
JuanRocamonde

4
Вы можете принудительно записать файл с помощью fsync()системного вызова из программы. Из оболочки просто используйте syncкоманду.
Ральф Фридл

2
В некоторых версиях Linux есть (или, по крайней мере, были) некоторые файловые системы, которые syncбыли реализованы как неактивные. И даже для файловых систем , которые бы правильно реализовать sync, есть еще проблема , что некоторые диски прошивки реализовать FLUSH CACHEкак не-оп или немедленно вернуться из него и выполнять его в фоновом режиме.
Йорг Миттаг

9

1. Flash-хранилище

Зависит ли это от типа диска (традиционные жесткие диски или твердотельные диски) или от какой-либо другой переменной, о которой я не знаю? Это происходит (если это происходит) только в Linux или присутствует в других ОС?

Когда у вас есть выбор, вы не должны позволять флэш-хранилищам терять энергию без чистого выключения.

В недорогом хранилище, таком как SD-карты, вы можете ожидать потери целых блоков стирания (в несколько раз превышающих 4 КБ), потери данных, которые могут принадлежать разным файлам или основным структурам файловой системы.

Некоторые дорогие твердотельные накопители могут утверждать, что предлагают лучшие гарантии в случае сбоя питания. Однако стороннее тестирование показывает, что многие дорогие твердотельные накопители этого не делают. Слой, который перераспределяет блоки для «выравнивания износа», является сложным и запатентованным. Возможные сбои включают в себя потерю всех данных на диске.

Применяя нашу среду тестирования, мы тестируем 17 стандартных SSD от шести разных поставщиков, используя в общей сложности более трех тысяч циклов ввода ошибок. Наши экспериментальные результаты показывают, что 14 из 17 протестированных SSD-устройств демонстрируют неожиданное поведение при сбоях при сбоях питания, в том числе повреждение битов, урезанные записи, несериализуемые записи, повреждение метаданных и полный отказ устройства.

2017: https://dl.acm.org/citation.cfm?id=2992782&preflayout=flat

2013: https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf?wptouch_preview_theme=enabled

2. Вращающиеся жесткие диски

Вращающиеся жесткие диски имеют разные характеристики. В целях безопасности и простоты я рекомендую предположить, что они имеют ту же практическую неопределенность, что и хранилище на основе флэш-памяти.

Если у вас нет конкретных доказательств, которых у вас явно нет. У меня нет сравнительных данных по вращению жестких дисков.

Жесткий диск может оставить один не полностью записанный сектор с неверной контрольной суммой, что впоследствии даст нам хороший сбой при чтении. Вообще говоря, этот режим отказа жестких дисков вполне ожидаем; родные файловые системы Linux разработаны с учетом этого. Они стремятся сохранить договор fsync()перед лицом этого типа потери питания. (Мы бы очень хотели, чтобы это было гарантировано на SSD).

Однако я не уверен, что файловые системы Linux достигают этого во всех случаях, или это вообще возможно.

Следующая загрузка после этого типа ошибки может потребовать восстановления файловой системы. Так как это Linux, возможно, что при восстановлении файловой системы будут заданы некоторые вопросы, которые вы не понимаете, где вы можете только нажать Y и надеяться, что она уладится.

2.1 Если вы не знаете, что такое контракт fsync ()

Контракт fsync () является источником как хороших, так и плохих новостей. Сначала вы должны понять хорошие новости.

Хорошие новости: fsync()хорошо документирован как правильный способ записи данных файла, например, когда вы нажимаете «сохранить». И широко известно, что, например, текстовые редакторы должны заменять существующие файлы атомарно, используя rename(). Это делается для того, чтобы вы всегда сохраняли старый файл или получали новый файл (который был fsync()отредактирован до переименования). Вы не хотите, чтобы вас оставили наполовину написанную версию нового файла.

Плохая новость: в течение многих лет вызов fsync () для самой популярной файловой системы Linux может эффективно привести к зависанию всей системы на десятки секунд. Поскольку приложения ничего не могут с этим поделать, было очень распространено оптимистично использовать rename () без функции fsync (), которая в этой файловой системе оказалась относительно надежной.

Следовательно, существуют приложения, которые неправильно используют fsync ().

Следующая версия этой файловой системы обычно избегала зависания fsync () - в то же время, когда она начала полагаться на правильное использование fsync ().

Это все довольно плохо. Понимание этой истории, вероятно, не помогло пренебрежительным тоном и оскорблением, которое использовалось многими конфликтующими разработчиками ядра.

Текущее разрешение заключается в том, что текущая самая популярная файловая система Linux по умолчанию поддерживается шаблон rename () без использования fsync ()реализует совместимость «ошибка за ошибкой» с предыдущей версией. Это можно отключить с помощью опции монтирования noauto_da_alloc.

Это не полная защита. По сути, он сбрасывает ожидающий IO во время rename (), но не ожидает завершения ввода-вывода перед переименованием. Это намного лучше, чем, например, 60-секундное окно опасности! См. Также ответ на вопрос: Какие файловые системы требуют fsync () для обеспечения безопасности при сбое при замене существующего файла на rename ()?

Некоторые менее популярные файловые системы не обеспечивают защиту. XFS отказывается это сделать. И UBIFS также не реализовал это, по-видимому, это можно было бы принять, но для этого нужно много работать. На той же странице указывается, что у UBIFS есть несколько других проблем с «TODO» для обеспечения целостности данных, в том числе при потере питания. UBIFS - это файловая система, используемая непосредственно во флэш-памяти. Я полагаю, что некоторые трудности, о которых упоминает UBIFS с флеш-памятью, могут быть связаны с ошибками SSD.


5

В слегка загруженной системе ядро ​​позволит вновь записанным данным файла находиться в кэше страниц в течение, возможно, 30 секунд после a write(), перед тем как записать их на диск, чтобы оптимизировать ситуацию, когда они скоро будут удалены или изменены снова.

По dirty_expire_centisecsумолчанию Linux имеет значение 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_centisecs500 (5 секунд) , и PowerTop рекомендует установить его на 1500 (15 секунд) для снижения энергопотребления.


Задержка обратной записи также дает ядру время увидеть, насколько большим будет файл, прежде чем начать его запись на диск. Файловые системы с отложенным размещением (такие как XFS и, возможно, другие в наши дни) даже не выбирают, где на диске помещать данные вновь записанного файла, пока не потребуется, отдельно от выделения места для самого inode. Это уменьшает фрагментацию, позволяя им не помещать начало большого файла в промежуток в 1 мегабайт между другими файлами, например.

Если записывается много данных, обратная запись на диск может быть инициирована порогом того, сколько грязных (еще не синхронизированных на диске) данных может находиться в кэше страниц.

Однако если вы больше ничего не делаете, индикатор активности жесткого диска не будет светиться в течение 5 (или 15) секунд после нажатия кнопки «Сохранить» для небольшого файла.


Если ваш редактор использовался fsync()после записи файла, ядро ​​запишет его на диск без задержки. (И fsyncне вернется, пока данные не будут отправлены на диск).


Кэширование записи в диске также может быть вещью, но диски обычно пытаются совершить их от записи кэша для постоянного хранения как можно скорее, в отличии от алгоритмов страниц кэша для Linux. Кэши записи на диск - это скорее буфер хранилища для поглощения небольших пакетов записей, но, возможно, также для задержки записи в пользу операций чтения и предоставления места для прошивки дисков для оптимизации схемы поиска (например, две соседние операции записи или чтения вместо одной). затем ищет далеко, затем ищет назад.)

На вращающемся (магнитном) диске вы можете увидеть несколько задержек поиска от 7 до 10 мс каждый перед тем, как данные из команды записи SATA будут фактически защищены от отключения питания, если перед вашей записью были ожидающие чтения / записи. (Некоторые другие ответы на этот вопрос более подробно описывают кэши записи на диск и барьеры записи, которые журнализированные FS могут использовать, чтобы избежать повреждения.)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.