База данных захлебывается в дисковом I/O wait, хотя на сервере стоят корпоративные NVMe накопители с линейным чтением под два гигабайта в секунду. Метрики диска упираются в потолок, CPU простаивает в ожидании шины PCIe, а разработчики бегут менять NVMe на более дорогие модели. Но дело не в железе. Настоящий виновник - фатальное несоответствие размера блоков ZFS ARC и структуры данных СУБД при случайных чтениях.
В классическом Linux pagecache работает на уровне файловой системы с универсальным размером страниц в 4 килобайта. Если база запрашивает случайный ключ из индекса B-Tree размером 8 килобайт, ядро читает ровно два блока с диска.
У ZFS свои правила игры. ARC - это не просто кэш в оперативности, это адаптивный вытесняющий кэш, оперирующий блоками переменного размера. Параметр recordsize задает максимальный размер блока для конкретной файловой системы или dataset, и по умолчанию он равен 128 килобайтам.
Когда СУБД - например, PostgreSQL с индексом btree или MySQL с InnoDB и размером страницы в 16 килобайт - выполняет случайный точечный поиск (random seek), происходит дивергенция уровней абстракции. При дефолтном recordsize=128K ZFS вынуждена поднимать с NVMe накопителя в 128 килобайт данных ради того, чтобы отдать базе один-единственный фрагмент в 16 килобайт.
Возникает классический эффект amplification - коэффициент усиления ввода-вывода. Вместо реальных нагрузок на чтение контроллер NVMe перегружается избыточными операциями чтения больших блоков. ARC забивается мусором: в оперативной памяти оседают огромные 128-килобайтные блоки, из которых СУБД использует лишь малую долю. Эффективность кэширования падает до нуля, вытесняя горячие индексные страницы. На шине PCIe растет очередь запросов, а p99 латентность улетает в космос, порождая тот самый I/O wait.
Лечится это жестким тюнингом под специфику нагрузки. Для баз данных с постраничной структурой хранения размер recordsize должен строго соответствовать размеру страницы СУБД или быть кратным ему. Для InnoDB это `zfs set recordsize=16k`, для PostgreSQL с дефолтными блоками - `zfs set recordsize=8k`.
Такой шаг схлопывает amplification factor в единицу, разгружает ARC, снижает износ ячеек памяти NVMe и возвращает предсказуемый tail latency в production.
- Инфраструктурный аудит и калькулятор TCO кластера: @Personnel_run_bot (/tma)
- База знаний и разборы: ftops.space
- ftops.space | Run-As-Daemon Infrastructure
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | База данных захлебывается в дисковом I/O wait, хотя на сервере ... | 0 | 8.6 | 26-09-2026 |
| 2 | База данных захлебывается в дисковом I/O wait, хотя на сервере ... | 0 | 7.98 | 25-09-2026 |
| 3 | Каждые 5 минут транзакции в PostgreSQL замирают на 3 - ... | 0 | 11.32 | 24-09-2026 |
| 4 | Каждые 5 минут транзакции в высоконагруженной PostgreSQL базе внезапно замирают ... | 0 | 11.86 | 24-09-2026 |
| 5 | Каждые 5 минут транзакции в PostgreSQL замирают на 3 - ... | 0 | 10.65 | 25-09-2026 |
| 6 | Каждые 5 минут транзакции в PostgreSQL замирают на 3 - ... | 0 | 12.14 | 19-09-2026 |
| 7 | Каждые 5 минут транзакции в PostgreSQL замирают на 3 - ... | 0 | 11.17 | 21-09-2026 |
| 8 | Каждые 5 минут транзакции в PostgreSQL замирают на 3-7 секунд. ... | -1 | 8.77 | 21-09-2026 |
| 9 | В systemd-journald спустя 6 лет признали проблему избыточной нагрузки на накопители | 0 | 14.65 | 14-08-2026 |
| 10 | Каждые 5 минут транзакции в PostgreSQL замирают на 3 - ... | 0 | 9.34 | 22-09-2026 |