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

Что: 22b9eb13c837497c09b0d17e11cffac8aa655999

Когда: 2022-07-14 14:06:26+03:00

Темы: 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, которые у меня и
так полудохлые.

оставить комментарий

Сгенерирован: SGBlog 0.34.0