Short summary
Конспект Лекции: Восстановление Файловых Систем – От FSCK до COW
Часть 1: Проблема Неконсистентности и Традиционные Решения
1. Фундаментальная Проблема: Неконсистентность Файловой Системы (ФС) после Сбоев
- Контекст: Файловые системы – это сложные структуры данных, хранящиеся на долговременных носителях (HDD, SSD, флешки). Их основная задача – организация хранения файлов и каталогов, а также управление доступом к ним.
- Уязвимость: Любая операция, изменяющая состояние ФС (создание файла, запись данных, удаление, изменение размера), требует модификации различных участков на диске. Если в процессе этих модификаций происходит внезапный сбой – отключение питания, аппаратный отказ, некорректное извлечение носителя, сбой сетевого подключения к хранилищу (SAN) – последовательность операций может быть прервана.
- Последствие: Структуры данных ФС на диске остаются в неконсистентном (противоречивом, нецелостном) состоянии. Это означает, что записанная информация не соответствует внутренним правилам и инвариантам файловой системы.
2. Анатомия Критической Неконсистентности
- Разделение Информации: Ключевая проблема возникает из-за того, что информация о состоянии дисковых блоков хранится в разных местах и часто в разных форматах:
- Информация о принадлежности блоков файлам: Хранится в метаданных файлов (например, в inode в Unix-подобных системах или MFT в NTFS). Здесь указывается, какие конкретно блоки данных составляют содержимое файла.
- Информация о свободных блоках: Хранится отдельно, часто в виде битовой карты (bitmap), где каждый бит соответствует одному блоку на диске и указывает, свободен он (например, 1) или занят (0).
- Опасная Операция – Изменение Размера Файла: Самая частая операция, приводящая к модификации обеих этих структур – это изменение размера файла, особенно его увеличение (дозапись в конец или запись в “дыру” разреженного файла). Этот процесс требует:
- Найти свободный блок(и) в bitmap.
- Пометить его (их) как занятый в bitmap.
- Добавить указатель на этот блок(и) в метаданные файла (inode).
- Обновить размер файла в метаданных.
- Сбой в Процессе: Если сбой происходит между этими шагами, возникают критические ошибки:
- Cross-linked Файлы (Перекрестные Ссылки): Самый опасный вариант. Блок помечен как занятый в inode одного файла, но все еще помечен как свободный в bitmap. Позже этот же блок может быть выделен другому файлу. В результате один физический блок принадлежит двум файлам одновременно. Запись в один файл неминуемо повредит данные другого, часто – обоих.
- Потерянные Блоки (Lost Blocks): Менее разрушительно, но неприятно. Блок успешно помечен как занятый в bitmap, но система “упала” до того, как ссылка на него была добавлена в inode файла. В итоге блок не принадлежит ни одному файлу, но и не считается свободным. Это приводит к необратимой потере дискового пространства, пока не будет выполнена проверка.
- Усугубляющий Фактор – Переупорядочение Записи Диском: Современные диски (особенно HDD с движущимися головками) для оптимизации производительности могут выполнять запрошенные операции записи не в том порядке, в котором их отправила ОС (используя алгоритмы вроде “лифта”). Это может привести к неконсистентному состоянию даже в том случае, если порядок операций ОС был логически спроектирован как “безопасный” (например, сначала пометить блок как занятый, потом добавить в inode – сбой после первого шага привел бы только к потере блока, но из-за переупорядочения может получиться и cross-link).
3. Традиционный Метод Восстановления: Полная Проверка (FSCK / Check Disk)
- Исторический Подход: До широкого распространения журналируемых ФС основным методом борьбы с неконсистентностью была полная проверка целостности при загрузке после сбоя.
- Механизм Обнаружения Сбоя – “Грязный Флаг” (Dirty Flag):
- В заголовке файловой системы (часто в суперблоке) хранится специальный флаг.
- При монтировании ФС в режиме чтения-записи (R/W) этот флаг устанавливается (“загрязняется”).
- При корректном размонтировании (shutdown, unmount) флаг снимается.
- При старте системы ОС проверяет этот флаг. Если он установлен – значит, предыдущий сеанс работы завершился некорректно (был сбой), и необходимо запустить утилиту проверки.
- Утилиты Проверки:
fsck(File System Check) в Unix/Linux,chkdsk(Check Disk) в Windows. - Принцип Работы – Аналог Сборки Мусора “Mark-and-Sweep”:
- Фаза “Mark” (Пометка): Утилита игнорирует существующую информацию о свободных блоках (старый bitmap считается недостоверным). Она начинает обход с корневого каталога и рекурсивно проходит по всем файлам и подкаталогам, идентифицируя все блоки данных и метаданных, на которые существуют действительные ссылки из структуры каталогов и файлов. По сути, строится карта реально используемых блоков.
- Фаза “Sweep” (Чистка/Сборка): Все блоки на диске, которые не были помечены как используемые на предыдущем шаге, объявляются свободными. На основе этой информации генерируется новый, гарантированно корректный bitmap свободных блоков.
- Исправление Других Ошибок: В процессе обхода
fsck/chkdskтакже проверяет и исправляет другие типы неконсистентности метаданных:- Несоответствие счетчиков ссылок в inode количеству имен файла в каталогах (приводит к “потерянным” файлам или преждевременному удалению).
- Потерянные файлы (inode с ненулевым счетчиком ссылок, но без имени в каталоге) часто помещаются в специальный каталог
lost+foundв корне ФС, получая имя по номеру inode.
- Ключевые Недостатки Традиционного Подхода:
- Чрезвычайно Долго: Время проверки прямо пропорционально общему размеру файловой системы и количеству файлов/каталогов на ней, а не объему изменений или размеру активных данных. На больших дисках (терабайты) проверка могла занимать многие часы, делая серверы недоступными на длительное время после сбоя.
- Высокая Ресурсоёмкость: Процесс требует значительного количества оперативной памяти для хранения промежуточных структур данных (карт блоков). Если памяти недостаточно, утилита вынуждена использовать сам проверяемый диск для временных файлов, что еще больше замедляет процесс. Также проверка интенсивно нагружает диск операциями чтения.
Часть 2: Современные Решения – Журналирование и Copy-on-Write
4. Революция Журналирования (Journaling File Systems)
- Мотивация: Длительное время простоя из-за
fsckстало неприемлемым, особенно для серверов. Решение пришло из мира баз данных. - Ключевая Концепция – Транзакции: Операции, изменяющие состояние ФС, группируются в транзакции. Транзакция обладает свойством атомарности: либо все входящие в нее операции успешно завершаются и их результат становится видимым, либо (в случае сбоя) система откатывается к состоянию до начала транзакции, как будто она и не начиналась. Важно: до начала и после успешного завершения транзакции ФС гарантированно консистентна.
- Инструмент – Журнал (Log): На диске выделяется специальная область фиксированного размера, организованная чаще всего как кольцевой буфер – журнал.
- Механизм Работы (на примере Redo Log):
- Запись в Журнал: Прежде чем изменять основные структуры ФС (inode, bitmap и т.д.), описание этих изменений (операции транзакции) записывается в журнал.
- Синхронизация Журнала (
sync/flush): Система убеждается, что записи журнала физически сохранены на диске. Это критический шаг. - Применение к ФС (“Накат”): Только после успешной записи в журнал система начинает применять изменения к основным данным ФС.
- (Опционально) Запись Commit: В журнал может быть добавлена специальная отметка (
commit), сигнализирующая об успешном завершении записи описания транзакции в журнал.
- Восстановление После Сбоя:
- Системе нужно прочитать только журнал (обычно небольшой).
- Незавершенные транзакции (нет
commitили запись оборвалась) игнорируются. - Полностью записанные в журнал, но, возможно, не до конца примененные к ФС транзакции (определяется по специальным отметкам
syncили чекпойнтам) повторно применяются (“накатываются”). - Идемпотентность: Если операции в журнале идемпотентны (повторное выполнение дает тот же результат, что и однократное, например,
x=10), процесс восстановления упрощается – можно просто повторить все необходимые операции из журнала без риска повредить данные.
- Главное Преимущество – Скорость Восстановления: Время восстановления зависит только от размера активной части журнала, а не от размера всего диска. Это занимает обычно секунды, максимум минуты, что на порядки быстрее
fsck. - Неочевидное Преимущество – Производительность Записи: Парадоксально, но журнальные ФС часто быстрее нежурнальных при операциях записи. Наличие журнала позволяет ОС гораздо агрессивнее кэшировать операции записи в ОЗУ, объединять их и сбрасывать на диск более оптимальными порциями, не боясь потерять данные при сбое (так как все необходимое для восстановления уже в журнале).
- Недостатки и Особенности Журналирования:
- Двойная Запись Метаданных: Данные метаданных пишутся дважды (в журнал и на основное место), что немного увеличивает нагрузку на диск и может влиять на ресурс SSD.
- Усложнение Кода Драйвера: Логика работы с журналом сложна, что повышает вероятность ошибок (багов).
- Риск Багов в Журналировании: Ошибка в коде записи журнала или восстановления может привести к катастрофическому разрушению ФС при попытке восстановления после сбоя (исторический пример: проблемы стабильности ранних версий NTFS).
- Гибридный Подход (Ext3): Чтобы снизить риски при переходе на журналирование, был популярен подход добавления модуля журнала к уже стабильной нежурнальной ФС (Ext2 -> Ext3).
- Критическое Ограничение – Только Метаданные: Стандартные журнальные ФС (NTFS, Ext4, XFS и др.) включают в транзакции только изменения метаданных. Пользовательские данные внутри файлов не защищены механизмом журнала ФС.
- Причины: 1) ФС не знает логических границ транзакций приложения (когда пользователь закончил осмысленное изменение данных?). 2) Включение пользовательских данных резко увеличило бы объем журнала и снизило бы производительность.
- Следствие для Приложений (СУБД и т.п.): Приложения, требующие гарантий целостности своих данных, должны реализовывать собственное журналирование и использовать системный вызов
fsync()для файла своего журнала, чтобы обеспечить его физическую запись на диск перед подтверждением транзакции пользователю.
5. Проблема Резервного Копирования и Технология Снимков (Snapshots)
- Вызов: Как создать консистентную резервную копию работающей системы (например, сервера базы данных), не останавливая ее? Простое копирование файлов данных и журнала приложения приведет к несогласованному состоянию.
- Решение – Моментальные Снимки: Технология, позволяющая создать “замороженную”, консистентную на определенный момент времени, виртуальную копию файловой системы, доступную обычно только для чтения. С этой копии можно безопасно выполнять резервное копирование, пока основная система продолжает работать.
- Принцип Работы – Copy-on-Write (COW): Когда после создания снимка происходит попытка изменить какой-либо блок на основной ФС, система не перезаписывает старый блок. Вместо этого:
- Выделяется новое место на диске.
- Измененные данные записываются в этот новый блок.
- Старый блок остается неизменным (на него ссылается снимок).
- Пример Реализации: Windows Volume Shadow Copy Service (VSS) реализует снимки поверх NTFS, используя свободное место тома для хранения “старых” версий блоков, на которые ссылаются снимки.
6. Эволюция: Файловые Системы на Основе Copy-on-Write (COW) / Log-structured
- Фундаментальный Сдвиг: Вместо того, чтобы модифицировать данные “на месте” и использовать журнал для защиты метаданных, эти ФС применяют принцип COW ко всем операциям записи. Данные никогда не перезаписываются на старом месте.
- Механизм:
- При изменении любого блока (данных или метаданных) он записывается в новое свободное место на диске.
- Указатель на этот новый блок должен быть обновлен в родительском блоке (например, в блоке косвенных указателей или inode).
- Но так как родительский блок тоже нельзя перезаписывать, создается его новая копия с обновленным указателем, которая также пишется в новое место.
- Этот процесс (“каскад копирования”) рекурсивно распространяется вверх по дереву структуры ФС до самого корневого узла.
- В конце группы операций система атомарно обновляет один главный указатель (суперблок), чтобы он указывал на новый корневой узел, представляющий новое состояние всей ФС.
- Роль Журнала (Другая!): Часто используется не для отката/наката, а как “журнал намерений” (intent log) для группировки (батчинга) операций записи перед фиксацией нового корневого узла. Он помогает восстановить последнюю незавершенную “пачку” изменений при сбое.
- Примеры: ZFS (Sun/Oracle), BTRFS (Linux), ReFS (Microsoft, частично), WAFL (NetApp).
- Ключевые Преимущества Архитектуры COW:
- Высочайшая Надежность: Сбой во время записи не может повредить предыдущее консистентное состояние ФС, так как старые данные не затрагиваются до атомарного переключения на новый корень. Восстановление обычно мгновенное.
- Встроенные и “Дешевые” Снимки/Клоны: Каждый зафиксированный корневой узел – это, по сути, снимок. Создание снимка (read-only) или клона (read-write копия снимка) – это просто сохранение указателя на соответствующий корневой узел; операция мгновенна и не требует копирования данных до момента внесения изменений в клон.
- Целостность Данных: Часто имеют встроенные механизмы проверки контрольных сумм для данных и метаданных, позволяющие обнаруживать “тихие” повреждения на диске.
- Основные Недостатки и Сложности COW:
- Фрагментация: Постоянное выделение новых блоков для любых изменений может привести к сильной фрагментации как файлов, так и свободного пространства, что потенциально снижает производительность чтения.
- Производительность Записи: Может быть непредсказуемой и ниже, чем у оптимизированных журнальных ФС, особенно при случайной записи мелкими блоками и высокой фрагментации.
- Повышенное Потребление ОЗУ: Требуется больше памяти для хранения сложных метаданных, особенно для эффективного управления свободным пространством при наличии множества снимков.
- Сложность Управления Свободным Пространством: Блок можно считать свободным, только если на него не ссылается ни текущее состояние ФС, ни один из существующих снимков. Отслеживание этих ссылок и освобождение блоков при удалении старых снимков – нетривиальная и потенциально медленная задача.
Вывод: Эволюция методов обеспечения консистентности ФС прошла путь от медленных полных проверок (FSCK) к быстрым восстановлениям метаданных с помощью журналов (стандарт де-факто сегодня) и далее к архитектурам Copy-on-Write, предлагающим встроенные снимки и высокую надежность ценой потенциальных проблем с фрагментацией и управлением пространством. Выбор конкретной технологии зависит от приоритетов (скорость восстановления, производительность, необходимость в снимках, простота управления).