[about] [index] [prev] [2022-07-14 14:06:26+03:00] [22b9eb13c837497c09b0d17e11cffac8aa655999]
Topics: [bsd][zfs]

Быстрый locate и инкрементальное обновление его БД

С появлением дополнительного большого раздела
(324ba83a7eba5331bd93e0360fd181657dddf3d0) и переноса на него всяких
всячин, которые время от времени обновляются, выяснилось что суммарно
уже на диске находится более 17.5M файлов и директорий. Просто
выполнение find-а на нём занимает 51мин. Я редко ищу что-то совершенно
не зная где оно примерно может находится, поэтому find натравливался на
поддиректории. Но всё же может понадобится поиск и по всему диску.

51 минута это ни в какие ворота конечно же. Можно сделать дамп вывода
find, использовать locate команду. Но мне не нравится тот факт, что
пересоздание этих state-ов всё равно займёт час времени постоянной
трескотни дисков. Пускай это у меня и так штатно происходило каждую
ночь, но чтение с HDD всё же является для них нагрузкой и износов,
учитывая большое количество random IO. Чай не SSD.

Хочется инкрементального обновления этой БД. Но как понять что у меня
изменилось? mtime на директориях меняется только если изменился, грубо
говоря, список файлов в ней. У вышестоящих директорий уже ничего не
будет затронуто. Штатные средства POSIX-а тут бессильны.

Видел что есть реализации locate следящие за событиями связанными с ФС.
Какой-нибудь kqueue тут тоже не подойдёт, как мне кажется, ибо он может
наблюдать только за одним объектом (одной директорией), без рекурсии.
Придётся создавать колоссальное количество kqueue объектов, что вряд ли
будет приятно ядру.

Но я знаю в общих чертах устройство ZFS, которое само по себе идеально
подходит для того, чтобы быстро понимать где что и как изменилось
относительно какого-то предыдущего состояния. Полез смотреть все данные
связанные с объектом в ZFS через zdb. В нём есть поле "gen", несущее
номер транзакции при которой был создан данный объект. Но нигде нет
информации о текущем txg. Насколько понимаю, эта информация находится не
в dnode-е, а в block pointer-е несущем эту dnode-у, до которого я не
нашёл как бы можно было вменяемо достучаться. Полез в исходный код
zfs-diff команды, а она просто бегает про объектам и сравнивает по сути
эти же самые поля что я видел и в zdb выводе, никакой магии. Вот только
это требует особых привилегий для запуска.

В общем, судя по всему, быстро найти что изменилось на ФС, можно только
через zfs diff, сравнивая snapshot-ы. И проще всего это буквально
вызывать эту команду и парсить её вывод. Готового решения для этого не
видел, так что придётся, видимо, писать самому. Ведь мне ещё и размеры
файлов хотелось бы знать, чтобы на основе этого можно было красивый
tree-like вывод делать.

В ZFS, с какой-то версии, появился special VDEV allocation class:
https://en.wikipedia.org/wiki/ZFS#Special_VDEV_Class
при котором можно метаданные сохранять например на SSD отдельные,
существенно ускоряя с ними работу. Мне бы точно помогло такое. Даже
есть две неиспользуемые SSD. Но у меня достаточно старая FreeBSD где
такого функционала нет. Да и сильного желания всё же тоже: кроме зеркала
из двух HDD, ещё придётся иметь зеркало из двух SSD, которые у меня и
так полудохлые.

[leave comment]