(Ахтунг! Рассматриваем только исправное оборудование, файловую систему и ядро без глюков.)
Требуется добавлять записи переменной длины (от байта до сотни МБ) в конец файла так, чтобы при любом фейле питания можно было бы надёжно отличить последнюю ошибочную запись (если такая была) от предыдущих нормальных.
Решение такое:
запись
- пример: хотим добавить 76 кб данных
- добавляем в конец файла header фиксированного размера, в который пишем hash данных + размер данных (76*1024). Можно записать hash этого header прямо перед ним самим
- вызываем fsync() — это как барьер памяти, не позволяющий переупорядочить операции записи перед ним и за ним
- дописываем наши данные (76 kb payload)
- вызываем fsync()
чтение после сбоя
1. Открываем файл сначала и последовательно проверяем: если очередной header в неадеквате (файл кончился раньше размера header (он фиксир.), hash header-a не совпало) — считаем всё пространство файла начиная с header-а далее пустым. Потеряем только 1 запись, ведь в середине ничего не переписывали.
2. если header вменяем, но в файле осталось меньше данных чем сказано в header или данных хватило, но их hash не совпал с указанным в header - пункт (1) - считаем файл пустым, начиная с начала header
Данная фигня как-бэ гарантирует, что мы можем потерять только последнюю запись и надёжно её выкинуть без утечек «дисковой памяти» и можем продолжить дописывать в файл с правильного места, не создав далее ошибок для его разбора. Обсудите, так ли это?