Когда программа вызывает запись и получает успешный код возврата, данные обычно ещё не лежат на носителе. Между приложением и пластиной жёсткого диска или ячейкой NAND стоит цепочка буферов, каждый из которых существует ради скорости и каждый из которых теряет содержимое при пропадании питания. Понимание того, где именно задерживается запись и что происходит с ней в момент обрыва, объясняет большую часть странных повреждений файловой системы после аварийного выключения.

Три слоя, где задерживается запись

Первый слой — страничный кеш операционной системы. Запись попадает в оперативную память, помечается как грязная и уходит на устройство фоновым потоком через сотни миллисекунд или единицы секунд. Второй слой — буфер самого накопителя: у жёсткого диска это десятки мегабайт DRAM, у твердотельного — область под таблицу трансляции плюс быстрый участок памяти в однобитовом режиме, куда попадают пользовательские данные. Третий слой появляется в серверных машинах — кеш RAID-контроллера объёмом от сотен мегабайт до единиц гигабайт.

Каждый уровень отвечает подтверждением сразу после приёма данных в память, не дожидаясь физической фиксации. Это отложенная запись, write-back. Альтернатива — сквозная запись, write-through, когда подтверждение выдаётся только после реальной фиксации на носителе. Она безопаснее и заметно медленнее на случайных операциях, потому что каждая операция оплачивается полной задержкой устройства.

Зачем откладывать запись

Буферизация нужна не ради красивых цифр в тестах. Жёсткому диску она позволяет переупорядочить очередь так, чтобы головка прошла по дорожкам за один проход, а не металась между краем и центром пластины. Твердотельному накопителю она даёт возможность собрать множество мелких запросов в одну страницу флеш-памяти: физическая страница пишется целиком, и запись четырёх килобайт в страницу большего размера означала бы чтение, модификацию и обратную запись с многократным усилением записи. Контроллер использует буфер и для того, чтобы не обновлять таблицу трансляции на каждую операцию, иначе служебные структуры изнашивали бы память быстрее пользовательских данных.

Что теряется в момент обрыва

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

У жёсткого диска возможен оборванный сектор: питание пропало посреди записи, контрольная сумма сектора не сходится, и чтение возвращает ошибку до тех пор, пока сектор не перезапишут целиком. У твердотельного накопителя худший сценарий — повреждение таблицы трансляции. Пользовательские данные физически на месте, но карта соответствия логических адресов физическим потеряна, и устройство либо не определяется вовсе, либо рапортует нулевой объём.

Отдельная беда у массивов с чётностью. Запись в RAID 5 — это чтение старых данных и старой чётности, вычисление новых значений и запись двух блоков. Обрыв между этими записями оставляет полосу, где чётность не соответствует данным, и массив об этом не подозревает. Проблема известна как write hole: она проявится не сразу, а при восстановлении после отказа диска, когда вместо исходного содержимого восстановится мусор.

Барьеры, сброс кеша и защита питанием

Чтобы не полагаться на удачу, интерфейсы предусматривают явный сброс: команды сброса кеша и признак принудительной записи для отдельных операций. Журналируемые файловые системы строят на них порядок действий: сначала запись в журнал, затем сброс, затем изменение основных структур, затем ещё один сброс. Гарантия работает только при честном поведении устройства. Если накопитель подтверждает сброс, ничего не сбросив, вся конструкция превращается в фикцию, и журнал перестаёт защищать.

Аппаратное решение — накопители с защитой от потери питания. Внутри стоит батарея конденсаторов, и запасённой энергии хватает, чтобы после исчезновения внешнего напряжения дописать содержимое буфера в энергонезависимую память. Такая защита характерна для устройств, рассчитанных на непрерывную нагрузку; классы и назначение таких моделей разобраны в разделе про серверные накопители. У RAID-контроллеров ту же роль играет батарея или модуль с флеш-памятью. При её разряде или отсутствии контроллер сам переключает кеш в сквозной режим, и скорость случайной записи падает в разы — это не поломка, а штатная защита, о которой стоит помнить при подборе RAID-контроллера.

Практические следствия

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