Некоторое время назад было обсуждение того, что ext4 может оставлять пустые файлы после некорректного размонтирования, довольно хорошо изложенноев этой статье. По сути, из-за отложенного распределения записи могут храниться в кэше записи гораздо дольше, чем интервал фиксации по умолчанию для журнала ext (5 секунд).
Похоже, проблемы были устранены в патче, который принудительно выделяет блоки в определенных ситуациях, тем самым заставляя данные записываться на диск максимум через 5 секунд по умолчанию.
Мне интересно, что происходит, когда приложение перезаписывает существующие части файла, не обрезая и не дописывая сам файл. Будет ли это принудительно записано на диск в течение 5 секунд?
Похоже, что это другая ситуация, чем при добавлении в файл: при добавлении изменяется размер файла, что является изменением метаданных; следовательно, в течение 5 секунд потребуется фиксация журнала, а поскольку data=ordered, данные придется записать до этого из соображений безопасности (иначе части удаленных файлов других пользователей могут появиться у владельца добавленного файла).
При простой перезаписи данных файла нет причин, по которым запись данных должна происходить до фиксации журнала метаданных, поскольку старые данные принадлежат тому же пользователю, что и новые. Так происходит ли запись до фиксации в любом случае или она может быть отложена дольше, чем интервал фиксации журнала? Если да, то насколько?
Обновление: Я знаю, что все это не имеет значения, если делать все правильно, то есть использовать fsync(). (Это было главной причиной всех обсуждений ext4 и потери данных — проблема касалась только приложений, не использующих fsync(), или использующих его не в нужный момент.) Я не пишу свое собственное приложение, я спрашиваю, потому что не знаю, все ли мои приложения делают все правильно, и я хочу знать примерные временные рамки для таких «опасных» записей. Причина, по которой я спрашиваю, заключается в том, что мой графический драйвер регулярно вызывает панику ядра, и я хочу знать, стоит ли мне беспокоиться о чем-то большем, чем последние 5 секунд записи данных.
решение1
Вы можете установить интервал фиксации на пользовательское значение, которое, как я полагаю, может быть таким же высоким, как 32-битное беззнаковое целое число секунд; то есть около 4 миллиардов секунд или 136 лет. Это доступно через опцию монтирования commit
, которую вы можете включить следующим образом (это всего лишь пример; вы также можете установить это в fstab
):
mount /dev/sda1 -t ext4 -o rw,data=writeback,nobh,commit=12345678
Интервал фиксации не зависит от какого-либо типа условий, например, добавляются ли данные или перезаписываются ли существующие данные или что-то еще. commit
Параметр монтирования (который по умолчанию равен 5 секундам, если вы вообще не указываете параметр монтирования) эквивалентен выполнению чего-то вроде этого в оболочке bash:
#!/bin/bash
while :
do
echo "Syncing all uncommitted data and journal to disk"
sync
sleep 5
done
Не путайте этот глобальный интервал синхронизации файловой системы («интервал фиксации», возможно, менее значимый термин для тех из нас data=ordered
, кто понимает функциональность программы командной строки sync
, в этом случае его, возможно, лучше назвать «интервалом синхронизации»).data=ordered
заказв котором обновляются данные и метаданные (где data=writeback
"менее безопасно / быстрее" и data=journal
"более безопасно / медленнее"). commit=12345678
это частота, с которой сам драйвер файловой системы принудительно выполняет ПОЛНУЮ синхронизацию ВСЕХ грязных данных/журнала/метаданных/чего угодно на физическом носителе. И вы, безусловно, можете установить его на 136 лет, если хотите, и монтировать с помощью data=writeback,nobh
и программ, которые не вызывают fsync()
или sync()
будут иметь грязные страницы, находящиеся в оперативной памяти в течение... нескольких жизней.
Обновление: Исходя из контекста в редактировании вашего вопроса, я бы сказал, что вам следует запустить вашу файловую систему с параметрами монтирования data=journal,commit=1
или даже с sync
параметром монтирования, пока вы не сможете разрешить панику ядра графического драйвера. Это сохранит максимальную целостность данных, но за счет производительности. Вам особенно захочется сделать это, если вы часто записываете данные на диск, которые вы не можете позволить себе потерять, и это вдвойне важно, если вы не «доверяете» приложениям, которые вы используете, чтобы они работали fsync()
надлежащим образом.
Источник: здесьи личный опыт
решение2
Каким бы ни был ответ на ваш вопрос, это не имеет значения.
Theгарантированно выставленповедение файловой системы ext4 заключается в том, что "данные будут на диске после успешного вызова sync
/ fsync
". Поэтому, если у вас есть приложение, которое заставляет вас задавать этот вопрос, вам следует вставить вызовы синхронизации в критические точки, где необходимо обеспечить целостность данных. Если вы пользователь, обеспокоенный той же проблемой, вы можете вызвать утилиту sync
командной строки, прежде чем совершать какие-либо опасные действия, которые могут привести к некорректному завершению работы.