Есть жирный файл, в нём как-то лежат страницы килобайт по 64. Иногда надо сбросить «грязные» страницы на диск. Нельзя просто так взять и перезаписать страницу in-place: сдохнешь по середине записи и жопа тебе.
Какие вы знаете (видели в разных реализациях всяких там СУБД) способы безопасной записи таких вот страничек в файл?
Я чё-то читал про InnoDB: там в файле есть буферная зона на 128 страничек. Когда системе надо перезаписать несколько страниц, она сначала пишет их в сей буфер, делает fsync(), а потом начинает записывать страницы по своим местам. При поднятии после падения, если в буфере лежат страницы, CRC которых отличаются от CRC тех же страниц, находящихся на своих местах - значит что-то из этого буфера в прошлый раз не дописалось на свои места. Система читает страницы из буфера и дописывает их куда нужно снова. Не очень понимаю как в целом оно устроено...
Короче интересуют вот такие истории в кратком изложении про разные замуты с записью страниц на дисочку.
Читал про какие-то футеры в CouchDB, не понял почти ничего: http://guide.couchdb.org/draft/btree.html#figure/1
Я придумал такой боян:
1. Хотим записать группу страниц на диск.
2. Есть отдельный файл, растягиваемый в конец, на любое число страниц, куда мы сначала пишем все эти страницы тупо последовательно, делаем fsync.
3. В наш write ahead log пишем запись «скинуто в буфер, надо записать в большой файл».
4. Идём пишем в большой файл.
5. После записи всех страничек из буфера в «большой файл», делаем fsync, в журнал пишем «буфер вытряхнут успешно».
Но на VDS хостинге столкнулся с тем, что fsync не гарантирует, что отправленное в write() до него запишется на диск ДО того, что уйдёт во write() после него.