Найти в Дзене
Postgres DBA

PostgreSQL и тест Грэнджера: Почему «не работает» — это тоже результат.

Оглавление

Дисперсия меняется во времени — математика дает сбой.
Дисперсия меняется во времени — математика дает сбой.

Предисловие

Диагностика PostgreSQL — это поиск причин в хаосе метрик. Когда мы видим, что всплеск блокировок совпадает по времени с ростом дискового ввода-вывода, возникает соблазн проверить гипотезу тестом Грэнджера: «А не является ли IO причиной Lock?». Однако прямой перенос этого эконометрического инструмента в мир баз данных наталкивается на фундаментальное препятствие — нестационарность.

Среди множества её проявлений (тренды роста данных, сезонные циклы) наиболее вероятной и коварной для PostgreSQL является гетероскедастичность — изменение волатильности процесса во времени. Дисперсия метрик может кардинально различаться. Это нарушает ключевое допущение теста Грэнджера о постоянстве дисперсии, заставляя его видеть ложные закономерности там, где есть лишь хаотичные всплески разной амплитуды.

Часть 1. Гипотезы о причинах нестационарности рядов ожиданий (Wait Events)

Значения метрик ожиданий в PostgreSQL редко бывают стационарными. Гипотезы, объясняющие это, можно разделить на три категории: детерминированные тренды, стохастические тренды и изменения дисперсии.

1. Гипотеза детерминированного тренда (роста нагрузки)

🔴Формулировка: Временной ряд содержит монотонно возрастающую или убывающую компоненту, связанную с изменением масштаба системы.

🔴Причины:

 ◽Рост объема данных.

 ◽Увеличение пользовательской нагрузки.

2. Гипотеза стохастического тренда❓

🔴Формулировка: Текущее значение ожиданий зависит от предыдущего значения плюс случайное возмущение (шум). Система не возвращается к среднему, а "гуляет" под влиянием накопленных случайных событий.

🔴Причины:

Эффект "перегрева" кеша: Если в прошлом моменте кеш был холодным (много IO), это привело к загрузке данных в shared_buffers. В следующем моменте времени те же запросы могут выполняться из кеша (мало IO), и наоборот. Уровень ряда "запоминает" состояние кеша.

3. Гипотеза структурных сдвигов (изменение режимов работы)

🔴Формулировка: Параметры распределения ряда (среднее, дисперсия) меняются скачкообразно в определенные моменты времени.

🔴Причины:

◽Проведение обслуживания (VACUUM/ANALYZE): Запуск VACUUM может временно заблокировать таблицы (вызвав пик ожиданий), а затем, очистив "мертвые" кортежи, снизить нагрузку на IO, изменив средний уровень ряда после завершения операции.

4. Гипотеза сезонности и цикличности❓

🔴Формулировка: Существуют периодически повторяющиеся паттерны ожиданий.

⚠️5. Гипотеза гетероскедастичности (изменение волатильности)

🔴Формулировка: Дисперсия (разброс) значений ожиданий меняется во времени.

🔴Причины:

 ◽Эффект "перегрузки" (Near-Saturation): Когда система работает при 30% нагрузки, волатильность мала. ➡️Когда система приближается к 100% утилизации ресурсов (CPU, IOPS), даже малое изменение входного потока запросов вызывает лавинообразный рост времени ожиданий (дисперсия кластеризуется — периоды покоя сменяются периодами турбулентности).

Часть 2. Почему это делает невозможным анализ причинности по Грэнджеру (в сыром виде)

ℹ️Тест причинности по Грэнджеру основан на авторегрессионных моделях и имеет жесткие предпосылки.

⚠️Нестационарность делает его результаты недостоверными или бессмысленными по следующим причинам:

1. Проблема "Spurious Regression" (ложная регрессия)

🔴Если ряды X и Y нестационарны (например, содержат тренд), то регрессия одного на другой почти всегда покажет высокую статистическую значимость, даже если эти ряды — совершенно независимые случайные величины (например, количество ожиданий в PostgreSQL и курс юаня).

➡️Следствие для Грэнджера: Тест может показать, что "Рост продаж (нагрузка) Грэнджер-причина роста ожиданий", хотя на самом деле это просто два независимых растущих тренда. Это классическая ложная корреляция.⚠️

2. Нарушение предпосылки о стационарности VAR

🔴Тест Грэнджера обычно выполняется в рамках векторной авторегрессии (VAR). Если ряды имеют единичный корень (стохастический тренд), оценки коэффициентов модели в уровневой форме будут несостоятельными, а t-статистики — смещенными. Распределение тестовой статистики Фишера (F-статистики) не будет стандартным.

3. Игнорирование структурных сдвигов

🔴Если в ряде был структурный сдвиг (например, после индексации), то модель VAR, построенная на всем ряде, будет пытаться "усреднить" поведение до и после. Остатки такой модели будут автокоррелированы, и тест Грэнджера потеряет мощность (может не найти связь там, где она есть, или найти там, где её нет, из-за выбросов на границе сдвига).

4. Проблемы с сезонностью

🔴Сезонность — это тоже форма нестационарности (сезонный единичный корень или детерминированная сезонность). Если её не удалить, тест может показать, что "Ожидания вчера в 14:00" являются причиной "Ожиданий сегодня в 14:00", что является лишь отражением суточного цикла работы приложения, а не реальной причинно-следственной связью между разными типами событий (например, влиянием IO на Lock).

⚠️Таким образом, невозможность использования теста Грэнджера напрямую связана с тем, что математические ожидания и дисперсии метрик PostgreSQL зависят от времени (из-за роста данных, изменения конфигураций и циклов нагрузки), что нарушает математические основы теста.

Послесловие

⚠️Осознание того, что данные почти всегда нестационарны — будь то из-за трендов роста, смены режимов работы или скачков волатильности — это не просто академическое знание. Это прививка от «ложной корреляции».

ℹ️Отказ от прямого использования теста Грэнджера к сырым данным — это не поражение, а первый шаг к честному анализу. Попытка применить эконометрический инструмент к немодифицированным логам ожиданий так же наивна, как попытка измерить температуру больного линейкой: цифры будут, но пользы — никакой.

Означает ли это, что путь к пониманию причинно-следственных связей в PostgreSQL закрыт? Вовсе нет. Просто теперь мы знаем правила игры. Дальнейшая работа лежит в плоскости приведения рядов к стационарному виду: выделение сезонности, взятие разностей (differencing) для удаления трендов, работа с волатильностью и анализ на предмет коинтеграции.

➡️Диагностика PostgreSQL — это всегда поиск сигнала в шуме. И теперь, вооружившись знанием о природе этого шума, мы можем приступать к настройке приемников.