
Buffer Pool и Clock-sweep: как мы боремся с cache pollution и p99 latency
anishukserg 7 минут назад Buffer Pool и Clock-sweep: как мы боремся с cache pollution и p99 latency Уровень сложности Сложный Время на прочтение 16 мин Охват и читатели 80 Базы данных * Высоконагруженные системы * Rust...
Anthropic — What company has the best second artificial intelligence model at the end of June?
В сфере искусственного интеллекта произошло заметное событие. anishukserg 7 минут назад Buffer Pool и Clock-sweep: как мы боремся с cache pollution и p99 latency Уровень сложности Сложный Время на прочтение 16 мин Охват и читатели 80 Базы данных * Высоконагруженные системы * Rust * Системное программирование * Алгоритмы * Один аналитик с одним SELECT count(*) FROM orders способен серьёзно ухудшить p99 latency всего OLTP-трафика. Пока скан читает таблицу страница за страницей, Buffer Pool заполняется «холодными» данными, горячие OLTP-страницы вытесняются, и после окончания скана приложение тянет данные с диска вместо кэша — ровно до тех пор, пока hot working set не прогреется заново. Это классический cache pollution, и с ним рано или поздно сталкивается любая СУБД с честным LRU.
В предыдущей статье мы разобрали API-контракты между слоями OLTP-ядра, USDT/eBPF-наблюдаемость и Adaptive Tuning. Сейчас — разбор Buffer Pool: почему Clock-sweep лучше LRU для конкурентной среды, как BufferRing изолирует сканы от горячего рабочего набора, и почему no-steal это не выбор стиля, а вопрос корректности recovery. Здесь описана текущая реализация: что работает в коде, какие компромиссы зафиксированы как MVP, где что-то не готово — скажем прямо.
Технические детали
За рамками статьи намеренно остаются sharded buffer pool, алгоритмы GCLOCK / CLOCK-Pro / ARC, полный Resource Broker с динамическим перераспределением памяти и bulk write маршрут — это отдельные задачи, у каждой свой дизайн-документ. Что реализовано на момент публикации: Clock-sweep в основном BufferPool; BufferRing (BulkRead path) в HeapStore::seq_scan_with_strategy ; BackpressureCoordinator с тремя источниками давления; все метрики из §7. Что ещё не готово: SQL-планировщик пока не переключает seq_scan на BulkRead автоматически; счётчик clock_sweep_evictions_total в основном пуле ещё не добавлен.
Cache pollution: почему наивная LRU умирает на смешанной нагрузке Классический сценарий, который ломает любую базу с честным LRU. У вас есть OLTP-приложение: 99% запросов это короткие точечные чтения по индексу, hot working set спокойно влезает в Buffer Pool, hit ratio под 99%, p99 latency предсказуемая. И тут приходит аналитик и запускает безобидный SELECT count(*) FROM orders или генератор отчётов из BI-системы.
Что происходит дальше с LRU-кэшем: Полный скан читает таблицу страница за страницей. Каждая прочитанная страница помещается в Buffer Pool. Поскольку страница «свежая», LRU держит её сверху списка.
Отраслевые последствия
Hot OLTP-страницы (например, корни B-tree-индексов) выталкиваются вниз и эвиктятся. После окончания скана hit ratio резко падает, запросы начинают идти в I/O, p99 уезжает на порядок-полтора вверх. Это и есть cache pollution .
Самое неприятное в нём это асимметрия: один аналитик с одним «непринципиальным» запросом способен существенно ухудшить tail latency для всего OLTP-трафика — на время, которое займёт прогрев hot working set заново через random reads с диска.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.





