# RU Limit Inspection Metrics

Use this reference to choose evidence and make inspection judgments. Metric names vary by
dashboard profile; keep the semantic role stable even when labels differ.

## Contents

- [Metric Contract](#metric-contract)
- [Evidence Map](#evidence-map)
- [Target Group Behavior](#target-group-behavior)
- [Task Progress Signals](#task-progress-signals)
- [Concurrency Impact](#concurrency-impact)
- [TiKV Tail-Latency Correlation](#tikv-tail-latency-correlation)
- [Data Absence](#data-absence)

## Metric Contract

Use only the versioned `dedicated-classic-v1` contract. Preserve these query fact states:

| State | Meaning |
|---|---|
| `success-present` | A successful query returned valid non-zero samples. |
| `success-zero` | A successful query returned real zero samples. |
| `success-empty` | A successful query returned no series; this is not automatically inactivity. |
| `not-run` | A declared conditional query was not triggered. |
| `error` | HTTP, datasource, timeout, parse, or query execution failed. |
| `semantic-mismatch` | Metric family, labels, profile, cluster, result shape, or window differs from the contract. |

Only contract-approved `success-empty` facts may be rendered as inactivity. Required missing facts,
errors, semantic mismatches, unsafe query scope, incomplete baselines, and configuration-history
gaps set `deliveryReady=false`. Warning and Critical inspection findings do not.
Use the collector's recorded contract result; do not reinterpret failed or mismatched queries as
usable evidence.

## Evidence Map

| Inspection question | Primary evidence | Secondary evidence |
|---|---|---|
| Are target resource groups configured correctly? | `ru_per_sec`, `priority`, `burstable`, active groups | SQL `resource_group`, dashboard Resource Manager view |
| Are target groups close to or over their RU limit? | RU/s rate max, over-limit duration, headroom | RU max-per-second, optional historical utilization after an alert |
| Are target tasks still progressing? | DDL waiting/running, Analyze QPM, AnalyzeTable p95, Batch QPS/p99 | DDL duration, backfill throughput, Statements, Slow Query, PROCESSLIST |
| Is RC queueing visible? | KV request wait p99 by target group | token request duration, `Time_queued_by_rc` from SQL evidence |
| Are other requests affected? | non-target group p99/QPS/RU, global SQL p99/QPS | failed QPS, slow query/statement deltas |
| Are TiDB/TiKV resources pressured? | TiDB/TiKV CPU comparison | memory, IO, disk latency, read pool, scheduler, raftstore, RocksDB/background worker CPU |

For active/inactive CPU comparison, use `>= 2x` as the Warning threshold. Preserve
`>= 1.2x` and `< 2x` movement as an Info observation instead of describing it as no increase.

## Target Group Behavior

Always start with current configuration. The external report should list target groups only;
do not list `default` as a configured target unless it is explicitly under inspection.

Use these RU-limit usage fields:
- `RU/s Max`: maximum of the 1-minute RU rate series over the inspected window.
- `over-limit duration`: accumulated time where RU/s rate is above the current `ru_per_sec`.
- `headroom`: `ru_per_sec - RU/s Max`.
- `utilization`: `RU/s Max / ru_per_sec`.
- `RU max-per-second`: short spike evidence only; not a sustained-over-limit judgment by itself.
- `burstable`: derive from `ru_capacity`; `ru_capacity < 0` means burstable.

Recommended alert levels:
- `Warning`: `RU/s Max` utilization is `>= 80%` and `< 100%`.
- `Critical`: `RU/s Max` utilization is `>= 100%`.
- `Critical`: over-limit duration is `> 0`.

## Task Progress Signals

Resolve target group workload type before using global task signals. Use `ddl`, `analyze`,
`batch`, or `custom`; require an explicit mapping for custom group names.
Use global DDL/Analyze signals only when the workload type matches and target-group
RU/QPS/query-duration/RC-wait activity overlaps the same window.

DDL:
- Running jobs means DDL activity exists.
- Waiting jobs is the stronger queue/backlog signal.
- Treat waiting jobs alone as an Info observation. Promote it to Warning only when it overlaps
  target-group RU pressure or another concrete slowdown, concurrency-impact, or resource-pressure signal.
- Duration or backfill throughput degradation matters only when it overlaps with target group activity, RC wait, resource pressure, or concurrency impact.

Analyze:
- Use Auto Analyze QPM to identify activity.
- Use Auto Analyze duration and AnalyzeTable p95 to judge progress.
- If only instance-level AnalyzeTable p95 is abnormal, keep instance identity in internal notes unless it is needed for a user-facing finding.

Batch:
- Use the batch resource group's QPS, query duration p99, RU/s, and KV request wait.
- Absence of these series with a valid group configuration usually means no batch activity in the window.

## Concurrency Impact

Inspect non-target groups separately from target groups. `default` is often the most important
business group, but it is not the only possible affected group.
The bundled collector compares only the queried `--business-groups` plus global SQL signals, so
state that scope in the report and add known business groups explicitly.

Candidate impact events:
- latency surge: non-target or global SQL p99 active-window p95/p99 reaches `2x` the inactive baseline.
- latency surge from max only: require both `2x` baseline and active max `>= 100ms`.
- QPS drop: active-window average is below `70%` of inactive baseline.

Treat failed QPS as supporting evidence only; it does not prove concurrency impact by itself.
Classify a latency surge as Warning only when TiKV tail-latency correlation also shows same-instance movement.
Without that correlation, keep it as Info.

## TiKV Tail-Latency Correlation

Run this only after a DDL/Analyze trigger. Query the top 5 TiKV instances per timestamp and at most 3
short windows, each centered around warning-line utilization, over-limit, or candidate impact point
with roughly 30 minutes of padding.
Do not query the whole inspection window for this correlation unless the whole window is itself the trigger interval.
Range-query membership may rotate, so the total unique instances can exceed 5. If a trigger fires,
skipping or disabling the check sets `deliveryReady=false`; it is not `not-applicable`.

Compare:
- Analyze KV time source with TiKV coprocessor p99 on the same instance.
- DDL KV time source with TiKV prewrite/commit p99 on the same instance.

When both workload types trigger, require usable query and baseline evidence for both pairs. One
workload's successful correlation or non-correlation must not mask missing evidence for the other.

Build active/baseline samples per source instance. A source that moves from zero to positive is
active even though its ratio is undefined. Treat same-instance tail-latency `>= 2x`
active/baseline movement as correlation evidence, but only for the target workload type: Analyze
source/coprocessor cannot satisfy a DDL-only correlation requirement, and DDL
source/prewrite/commit cannot satisfy an Analyze-only correlation requirement. In the external
report, describe only window count, top-N scope, whether Analyze/DDL KV activity existed, and
whether same-instance tail latency moved. Keep raw instance identities internal unless the user
explicitly asks for node-level evidence.

## Data Absence

Use "no observed activity" when:
- target group configuration exists,
- every core metric has a target series or another healthy resource-group series from the same metric family,
- target group RU/QPS/query-duration/wait are zero or absent,
- and short-spike RU max is also zero or absent.

Use "insufficient data" when:
- the query failed,
- configuration is missing,
- label matching is ambiguous,
- or no comparable peer group/query can prove the data source is healthy.
