Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Wait Events

AngaraBase 0.6.3.9 §S11 — базовая модель wait events. RM-0.6.4.10 добавляет QoS scheduler events. RM-0.6.4.19 Track C C1 добавляет per-session счётчики и per-session запрос angara_stat_wait_events.

Эта страница описывает taxonomy WaitEvent, которую AngaraBase использует для классификации блокирующих операций. Для оператора wait events отвечают на вопрос: “на чём кластер сейчас ждёт?” без strace, ручного разбора stack traces и инструментации каждого call site.

Зачем нужна модель wait events

Модель похожа на pg_stat_activity.wait_event в PostgreSQL или sys.dm_os_wait_stats в SQL Server:

  • каждый блокирующий участок кода получает конкретную причину ожидания;
  • текущий wait виден на уровне session/activity;
  • агрегированные метрики дают rate, active count и latency distribution по каждому событию;
  • dashboards сравнивают разные классы ожиданий через единый label event=<variant_snake_case>.

Два слоя observability:

  1. Текущий wait сессииangara_stat_activity.wait_event_type и angara_stat_activity.wait_event.
  2. Агрегированные метрики Prometheus — counters, gauges и histograms по каждому wait event.

События

WaitEvent — стабильный public API. Добавление variant является non-breaking: dashboards увидят новый event=... label после upgrade. Удаление, renumbering или изменение as_str() значения считается breaking change.

VariantLabelWait typeКогда срабатывает
RowLockrow_lockLockОжидание tuple-level lock.
PageLockpage_lockLockОжидание page-level latch.
TableLocktable_lockLockОжидание relation-level lock для DDL/lock manager.
TransactionLocktransaction_lockLockОжидание commit/finish другой транзакции.
PredicateLockAcquirepredicate_lock_acquireLockОжидание захвата predicate lock для SSI foundation.
PredicateConflictCheckpredicate_conflict_checkLockОжидание проверки predicate conflict graph.
PageReadpage_readIOЧтение heap/index page при cache miss.
PageWritepage_writeIOWrite-back страницы при checkpoint или eviction.
WalFlushwal_flushIOWAL flush / fsync path.
FsyncfsyncIOПрочие fsync пути: catalog, FPI и смежные операции.
WalSyncwal_syncIOStrict WAL sync wait в durability path.
WalGroupCommitwal_group_commitIOОжидание group commit batch.
ColumnarCompactioncolumnar_compactionIOBackground compactor ждёт disk I/O или manifest append mutex в compact_l0_to_l1().
ClientReadclient_readNetЧтение из client socket.
ClientWriteclient_writeNetЗапись в client socket.
ReplicaReadreplica_readNetЧтение из replica connection.
ReplicaWritereplica_writeNetЗапись в replica connection.
NetReadnet_readNetGeneric network read.
NetWritenet_writeNetGeneric network write.
CpuRuncpu_runCPUСессия исполняется на CPU, это не блокировка.
PageDecompressionpage_decompressionCPUCPU time на decompression страницы при buffer-pool miss.
PageCompressionpage_compressionCPUCPU time на compression dirty page перед flush.
AdmissionQueueadmission_queueSchedulerОжидание admission control queue.
IoSchedulerQueueio_scheduler_queueSchedulerОжидание I/O scheduler queue.
MemoryGrantQueuememory_grant_queueSchedulerОжидание memory grant.
BufferPoolEvictionbuffer_pool_evictionSchedulerСессия ждёт свободный или evictable buffer-pool slot.
BackpressureThrottlebackpressure_throttleSchedulerUnified backpressure coordinator throttles caller.
DiskRestartHarnessdisk_restart_harnessSchedulerTest harness ждёт re-hydration on-disk state при disk-restart тесте.
QosQueueqos_queueSchedulerAsync task стоит в per-shard DRR queue QoS scheduler до dispatch.
QosBlockingqos_blockingSchedulerBlocking task ждёт dispatch через QoS blocking path.

QoS события RM-0.6.4.10

qos_queue означает, что задача уже классифицирована по service level (critical, interactive, background) и ожидает dispatch в scheduler queue. Рост этого wait обычно указывает на scheduler saturation или burst нагрузки.

qos_blocking означает, что задача попала в blocking path QoS scheduler. Смотрите его вместе с gauge angarabase_qos_blocking_inflight и angarabase_spawn_blocking_max: если blocking wait растёт, а inflight близок к лимиту, cluster pressure находится не в SQL locks, а в runtime/blocking pool.

В Sprint 2A granularity по service level намеренно coarse: нет отдельных qos_queue_critical, qos_queue_interactive, qos_queue_background. Для уровня сервиса используйте QoS counters: angarabase_qos_queued_*_total и angarabase_qos_rejected_*_total.

Ordinals и compatibility

Ordinals append-only и закреплены в WaitEvent::ordinal():

  • QosQueue имеет ordinal 28;
  • QosBlocking имеет ordinal 29.

Массив WaitEvent::ALL используется для рендера всех label values в metrics. Фиксированный размер metrics array задаётся N_WAIT_EVENT_VARIANTS.

Правила совместимости:

  • добавление variant — non-breaking;
  • удаление variant — breaking;
  • renumbering ordinal — breaking;
  • переименование label value из as_str() — breaking для dashboards и alerts.

Per-session wait events (RM-0.6.4.19 Track C C1)

Начиная с RM-0.6.4.19 angara_stat_wait_events поддерживает per-session режим:

-- Process-wide aggregates (как раньше):
SELECT * FROM angara_stat_wait_events;

-- Per-session счётчики текущей сессии:
SELECT * FROM angara_stat_wait_events WHERE session_id = current_session();

В per-session режиме:

  • total — суммарное число входов в данный wait event для текущей сессии с момента её запуска.
  • active и total_duration_us — всегда 0 в phase 1 (per-session histogram deferred to phase 2).
  • Счётчики инкрементируются через WaitEventGuard::enter и хранятся в AtomicWaitState::event_counts (per-session registry, indexed by session_id).

Если сессия не совершала ни одного wait event, все total = 0 (пустой wait state возвращает нули).

Метрики

Для каждого события экспортируются три Prometheus series с label event=<variant_snake_case>:

МетрикаТипСмысл
angarabase_wait_events_totalcounterСколько раз код входил в ожидание этого типа.
angarabase_wait_events_activegaugeСколько ожиданий этого типа активно прямо сейчас.
angarabase_wait_event_duration_secondshistogramРаспределение длительности ожидания.

Histogram buckets в секундах: 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, +Inf.

PromQL примеры

Top-N wait classes по накопленному времени за 5 минут:

topk(
  5,
  rate(angarabase_wait_event_duration_seconds_sum[5m])
)

Активные ожидания прямо сейчас:

sum by (event) (angarabase_wait_events_active)

p99 latency для buffer-pool eviction:

histogram_quantile(
  0.99,
  rate(angarabase_wait_event_duration_seconds_bucket{event="buffer_pool_eviction"}[5m])
)

Backpressure throttle rate:

rate(angarabase_wait_events_total{event="backpressure_throttle"}[1m])

QoS queue wait rate:

rate(angarabase_wait_events_total{event="qos_queue"}[5m])

p95 ожидания в QoS queue:

histogram_quantile(
  0.95,
  rate(angarabase_wait_event_duration_seconds_bucket{event="qos_queue"}[5m])
)

Активные blocking waits QoS:

angarabase_wait_events_active{event="qos_blocking"}

Alert на длительную очередь QoS:

histogram_quantile(
  0.99,
  rate(angarabase_wait_event_duration_seconds_bucket{event="qos_queue"}[5m])
) > 0.5

Alert на blocking pool pressure:

angarabase_wait_events_active{event="qos_blocking"} > 0
and
angarabase_qos_blocking_inflight > 0

Корреляция QoS waits с rejections:

rate(angarabase_wait_events_total{event="qos_queue"}[5m])
and
sum(rate({__name__=~"angarabase_qos_rejected_.*_total"}[5m])) > 0

Operator playbook

BufferPoolEviction растёт:

  • buffer pool меньше рабочего набора;
  • достигнут max_cached_pages;
  • проверьте buffer-pool-pressure runbook.

BackpressureThrottle растёт:

  • WAL queue или buffer pool exhaustion замедляет клиентов;
  • проверьте angarabase_buffer_pool_uncommitted_pages_ratio;
  • сопоставьте с WAL group-commit latency.

WalFlush или WalSync p99 выше 100 ms:

RowLock имеет высокие duration:

QosQueue растёт:

  • проверьте angara_stat_qos_queues;
  • смотрите angarabase_qos_rejected_*_total;
  • снизьте concurrency batch jobs;
  • переведите тяжёлые jobs в SET service_level = 'background';
  • пересмотрите ANGARABASE_QOS_WEIGHTS и ANGARABASE_QOS_MAX_QUEUED.

QosBlocking растёт:

  • проверьте angarabase_qos_blocking_inflight;
  • проверьте angarabase_spawn_blocking_max;
  • ищите blocking workload, который вытесняет runtime capacity;
  • не лечите это увеличением SQL lock timeout: wait находится в scheduler/runtime path.

Source of truth

  • Code: crates/angarabase/src/observability/wait_events.rs
  • Per-session dispatch: crates/angarabase/src/virtual_catalog.rs + virtual_catalog/shared_catalog.rs
  • Metrics: crates/angarabase/src/metrics/core.rs
  • Render: crates/angarabase/src/metrics/render.rs
  • QoS scheduler: crates/angarabase/src/qos_manager.rs
  • RM: docs/planning/v0.6/RM-0.6.3.9.md §S11, docs/planning/v0.6/RM-0.6.4.10.md, docs/planning/v0.6/RM-0.6.4.19.md Track C C1