LINUX.ORG.RU

Какие алгоритмы безопасной записи страничек B+Tree на диск вы знаете?

 


1

2

Есть жирный файл, в нём как-то лежат страницы килобайт по 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() после него.

Я чё-то читал про InnoDB: там в файле есть буферная зона на 128 страничек. Когда системе надо перезаписать несколько страниц, она их сначала пишет в этот буфер, делает fsync(), потом начинает записывать по своим местам. При поднятии, если в буфере лежат страницы, CRC которых отличаются от CRC тех же страниц, находящихся на своих местах - значит что-то из этого буфера в прошлый раз не дописалось на свои места. Система читает страницы из буфера и дописывает их куда нужно снова.

Это назвается «журналирование», и в таком виде используется в линуксовых ФС. Только, если я правильно помню, необходимость переигрывать журнал определяется не по контрольной сумме записываемых данных, а по полю в суперблоке.

i-rinat ★★★★★ ()

журнал

1. пишешь новые данные в свободные блоки

2. обновляешь «указатель» на данные

3. помечаешь старые блоки свободными

anonymous ()

2. Есть отдельный файл, растягиваемый в конец, на любое число страниц, куда мы сначала пишем все эти страницы тупо последовательно, делаем fsync.

И в самый интересный момент крашишь либо ФС, если она не журнализируемая и не отказоустойчивая, либо сам файл с буфером.

Не делай этого!

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

В начале этого файла сделай две карты с «состояниями» страниц, которые ты туда пишешь. Перед записью страницы меняешь «состояние» страницы в первой карте, делаешь fsync, дальше пишешь страницу в буфер, делаешь fsync, дальше обновляешь «состояние» страницы во второй карте, делаешь fsync.

В таком случае ты сможешь БЫСТРО определить, сколько страниц ты успел скинуть в буфер, не надо будет шариться по большому файлу и читать страницы из него.

Дальше - при восстановлении перезаписываешь то, что успел скинуть в файл, обновяешь «состояния» страниц в картах так же, как при записи в буфер.

Если будет сбой в момент восстановления - это тоже БЫСТРО детектится, можно будет продолжить с того места, на котором остановился.

shkolnick-kun ★★★ ()
Ответ на: комментарий от shkolnick-kun

И в самый интересный момент крашишь либо ФС, если она не журнализируемая и не отказоустойчивая, либо сам файл с буфером.

Там CRC есть, побитость страниц в промежуточном файле легко детектится.

При постановке задачи «убиваем файловую систему между стартами нашей СУБД» не выживет никакая система.

hlamotron ()
Последнее исправление: hlamotron (всего исправлений: 1)
Ответ на: комментарий от hlamotron

При постановке задачи «убиваем файловую систему между стартами нашей СУБД» не выживет никакая система.

4.2

При проектировании нужно учитывать ВСЕ ВОЗМОЖНЫЕ ОТКАЗЫ.

shkolnick-kun ★★★ ()
Ответ на: комментарий от shkolnick-kun

4.2

Выше уже это угадывали - не взлетело.

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

А то критикунов развелось, а предложений по делу ноль.

hlamotron ()
Последнее исправление: hlamotron (всего исправлений: 1)
Ответ на: комментарий от hlamotron

https://colonelcassad.livejournal.com/tag/Греф

Греф летит на воздушном шаре, сбился с курса, и решил срочно опуститься вниз - спросить дорогу. Увидев внизу человека, он крикнул:

- Извините, где я нахожусь?

- Вы находитесь на воздушном шаре, в 15метрах над землей, ответил прохожий.

- Не могли бы вы быть поточнее, - злится Греф.

- ОК. Ваши координаты - 5°28'17" N и 100°40'19" E, - слышит ответ с земли.

- Похоже, вы математик, - вздохнул Греф.

- Да, я математик, - согласился прохожий. - Как вы догадались?

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

- А вы, похоже, из управленцев, - заметил математик.

- Я действительно топ-менеджер очень серьезной компании, - горделиво сказал Греф. - Сбербанка. Но как вы догадались? Наверное, видели меня по телевизору?

- Зачем? - удивился математик. - Судите сами: вы не понимаете ни где вы находитесь, ни что вам следует делать, в этом вы полагаетесь на нижестоящих. Спрашивая совета у эксперта, вы ни на секунду не задумываетесь, способны ли вы понять его ответ, и когда оказывается, что это - не так, вы возмущаетесь вместо того, чтобы переспросить. Вы находитесь ровно в том же положении, что и до моего ответа, но теперь почему-то обвиняете в этом меня. Наконец, вы находитесь выше других только благодаря дутому пузырю, и если с ним что-то случится - падение станет для вас фатальным...

shkolnick-kun ★★★ ()
Последнее исправление: shkolnick-kun (всего исправлений: 1)
Ответ на: комментарий от shkolnick-kun

Очередная попытка обосрать афтара, лишь бы не писать ничего по делу, да? У тебя так много звёзд, а кратко выражать мысль не умеешь - постишь войны и миры на каждый пук.

hlamotron ()
Последнее исправление: hlamotron (всего исправлений: 2)
Ответ на: комментарий от hlamotron

У тебя так много звёзд, а кратко выражать мысль не умеешь - постишь войны и миры на каждый пук.

==

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

shkolnick-kun ★★★ ()