Всем отличных выходных! Приглашаем на бесплатный Demo-урок «Конфигурирование web-сервера (Apache, Nginx, балансировка Nginx)», который проведёт Андрей Буранов — специалист по UNIX-системам в компании Mail.Ru Group. А также публикуем статью Jonathan Corbet — Executive Editor в LWN.net.

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

Файловая система, такая как ext3, использует отдельную область на диске, называемую журнал. При внесении изменений в метаданные файловой системы, эти изменения сначала записываются в журнал без модификации остальной файловой системы. После записи всех изменений в журнал в него добавляется "коммит блок", указывающий на завершение транзакции. И только после записи коммит блока, транзакция фиксируется, и измененные метаданные записываются на диск. Если система в какой-то момент выйдет из строя, то с помощью информации в журнале можно безопасно завершить работу и избежать повреждений файловой системы из-за того, что обновилась только часть метаданных.

Однако есть одна загвоздка: код файловой системы перед записью коммит блока должен быть абсолютно уверен, что вся информация о транзакции уже попала в журнал. Просто записывать операции в правильном порядке недостаточно — современные диски поддерживают большие внутренние кэши и переупорядочивают операции для улучшения  производительности. Поэтому перед коммит блоком необходимо явным образом указать на перенос всех данных журнала на диск. Если коммит блок будет записан раньше, то журнал может быть поврежден. Для решения этой проблемы используются барьеры. По сути, барьер запрещает запись любых блоков после барьера, пока все блоки, записанные до барьера, не будут перенесены на диск. Используя барьеры, файловые системы гарантируют согласованность файловых структур.

Но есть еще одна проблема: файловые системы ext3 и ext4 по умолчанию не используют барьеры. Опция есть, но если администратор не включил их явно, то эти файловые системы работают без барьеров, хотя в некоторых дистрибутивах (например, SUSE) значения по умолчанию другие. Эрик Сандин (Eric Sandeen) недавно решил, что эту ситуацию надо изменить и сделал патч, модифицирующий настройки по умолчанию для ext3 и ext4. И тогда началось бурное обсуждение.

Эндрю Мортон (Andrew Morton) очень подробно ответил, почему значение по умолчанию именно такое:

В прошлый раз, когда мы пытались это изменить, производительность на многих нагрузках ухудшилась на 30%, поэтому я в ужасе выбросил все эти патчи. Я думаю, что мы не можем пойти на это и замедлить работу всех машин настолько серьезно…

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

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

Но это не просто везение. Тед Тсо (Ted Ts'o) объясняет это тем, что журнал ext3 / ext4 обычно расположен непрерывно. Во-первых, драйвер файловой системы пытается создать его непрерывным. Во-вторых, журнал обычно создается одновременно с файловой системой, когда легко найти непрерывное пространство. Непрерывность и упорядоченность полезны не только для производительности, но и для предотвращения переупорядочивания. Обычно коммит блок будет размещаться сразу после остальных данных в журнале, поэтому у диска нет причин для переупорядочивания. Коммит блок естественным образом записывается на диск сразу после остальных записей журнала.

Тем не менее никто не утверждает, что так будет всегда. Дисковые накопители могут вести себя и по-другому. Кроме того, журнал представляет собой кольцевой буфер. Поэтому когда транзакция записывается в конец журнала, то коммит блок может оказаться в более раннем блоке, перед другими записями журнала. Так что вероятность повреждения есть всегда. На самом деле, у Криса Мэйсона (Chris Mason) есть для этого тесты. Нет сомнений, что работа без барьеров менее безопасна, чем с ними.

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

Текущая реализация ext3 (когда барьеры включены) для каждой транзакции выполняет следующую последовательность операций:

  1. Данные записываются в журнал

  2. Выполняется барьер

  3. Записывается коммит блок

  4. Выполняется следующий барьер

  5. Позже метаданные сбрасываются на диск

В ext4 первый барьер (шаг 2) можно опустить, так как файловая система ext4 поддерживает контрольные суммы в журнале.

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

Крис Мейсон полагает, что было бы "в целом безопасно" убрать этот барьер и в ext3, с возможным исключением, когда журнал доходит до конца и начинает писаться с начала. 

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

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

Похоже, пришло время подумать, как сделать стоимость барьеров приемлемой. Тед Тсо, кажется, считает аналогично:

Я думаю, что мы должны включить барьеры в ext3/4, а затем работать над уменьшением накладных расходов в ext4 / jbd2. Скорее всего, подавляющее большинство систем не работают в условиях, подобных тем, которые использовал Крис для демонстрации проблемы и безопасность файловой системы по умолчанию должна быть в приоритете.

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


Интересно развиваться в данном направлении? Запишитесь на бесплатный Demo-урок «Конфигурирование web-сервера (Apache, Nginx, балансировка Nginx)» и участвуйте в трансляции «Работа с логами в Linux», которую проведёт Павел Викирюк — оператор связи MVNO, DevOps-инженер.