Schedule icon
Webhook icon
Query icon
OutputValues icon
If icon
SlackIncomingWebhook icon
Log icon

ClickHouse Mutation and Partition Parts Watchdog Sentinel

Orchestrate ClickHouse cluster health monitoring with Kestra. Detect long-running table mutations and active partition parts bloat before query slowdowns occur.

Categories
DataInfrastructure

ClickHouse relies on asynchronous background processes for table mutations (ALTER ... UPDATE / DELETE) and continuous part merges. Under heavy ingestion bursts, frequent single-row updates, or hardware resource constraints, two dangerous failure modes often emerge:

  1. Stuck Table Mutations: Unfinished mutations in system.mutations consume CPU and disk I/O, hold table metadata locks, and can stall subsequent schema operations indefinitely if a part fails to rewrite.
  2. Partition Parts Explosion: Ingestion without batching or stalled background merges produces hundreds of active parts per partition in system.parts, eventually triggering ClickHouse's defensive "Too many parts in all data parts in table" error and rejecting further writes.

This blueprint provides an automated, non-invasive health watchdog for ClickHouse clusters. It audits system.mutations for long-running mutations, analyzes system.parts for partition bloat exceeding operational thresholds, exports diagnostic metrics, and alerts database administrators and platform engineers on Slack with contextual remediation steps.

Use Cases

  • Proactive Cluster Observability: Detect stalled asynchronous updates before they cascade into cluster-wide write rejection errors.
  • Merge Bottleneck Triage: Identify tables experiencing merge lag or unoptimized partitions across high-frequency time-series datasets.
  • Incident Prevention: Alert SRE and data engineering teams before TOO_MANY_PARTS exceptions interrupt real-time streaming ingestion pipelines.
  • Audit Compliance: Maintain a traceable execution log of database mutation lifetimes and partition density over time.

How It Works

  1. check_stuck_mutations (io.kestra.plugin.jdbc.clickhouse.Query) queries system.mutations with fetchType: FETCH to find incomplete mutations (is_done = 0) that have been executing longer than inputs.max_mutation_age_minutes.
  2. check_partition_parts_explosion (io.kestra.plugin.jdbc.clickhouse.Query) scans system.parts for active data parts (active = 1) grouped by database, table, and partition, identifying partitions that exceed inputs.max_active_parts_threshold.
  3. emit_cluster_health_metrics (io.kestra.plugin.core.output.OutputValues) exports structured count metrics and cluster metadata into execution outputs.
  4. evaluate_cluster_health (io.kestra.plugin.core.flow.If) evaluates whether any stuck mutations or overloaded partitions were detected:
    • If anomalies exist, notify_cluster_alert_slack dispatches a Slack notification with the offending table names, mutation IDs, part counts, failure reasons, and suggested operational commands.
    • If all metrics are within safe boundaries, log_cluster_healthy records a success log.
  5. alert_on_failure in the errors block alerts on-call responders if network connectivity or authentication to ClickHouse fails.

Prerequisites

  • A running ClickHouse instance or cluster (Cloud or self-hosted) accessible via HTTP interface (port 8123 by default).
  • Database user credentials with SELECT permissions on system.mutations and system.parts.
  • A Slack Incoming Webhook URL configured for channel alerting.

Secrets

Configure the following secrets in your Kestra namespace:

  • CLICKHOUSE_USERNAME: ClickHouse database user (e.g. default or sentinel_user).
  • CLICKHOUSE_PASSWORD: Password for the ClickHouse user.
  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL for diagnostic alerts.
  • WEBHOOK_KEY: Authentication secret for manual on-demand execution via webhook.

Configuration

Adjust the flow inputs to match your cluster's operational profile:

  • clickhouse_url: ClickHouse JDBC connection URL (default: jdbc:clickhouse://clickhouse:8123/default).
  • max_mutation_age_minutes: Maximum allowed execution age in minutes before a mutation is flagged as stuck (default: 60).
  • max_active_parts_threshold: Maximum active parts per partition before parts explosion is flagged (default: 150).

Step-by-Step

┌──────────────────────────────┐
│  Schedule / Webhook Trigger  │
└──────────────┬───────────────┘
               │
               ▼
┌──────────────────────────────┐
│ Check system.mutations       │
└──────────────┬───────────────┘
               │
               ▼
┌──────────────────────────────┐
│ Check system.parts (Active)  │
└──────────────┬───────────────┘
               │
               ▼
┌──────────────────────────────┐
│ Emit Health Metrics          │
└──────────────┬───────────────┘
               │
     [Any Anomaly Detected?]
           /                     YES         NO
         /                         ▼               ▼
┌───────────────┐ ┌───────────────┐
│ Dispatch      │ │ Log Verified  │
│ Slack Alert   │ │ Clean Health  │
└───────────────┘ └───────────────┘

Expected Output

  • Clean Cluster Run: An execution summary with stuck_mutations_count: 0, exploded_partitions_count: 0, and a confirmation log.
  • Alert Run: A formatted Slack notification identifying offending databases, tables, partition identifiers, active part counts, and mutation error details.

Customization

  • Automated Partition Optimization: Add an io.kestra.plugin.jdbc.clickhouse.Queries task to run targeted OPTIMIZE TABLE ... PARTITION ... FINAL commands during off-peak hours for non-critical tables.
  • System Merges Correlation: Extend the inspection to join with system.merges to surface current background merge speed, disk read/write rates, and remaining merge durations.
  • Multi-Node Cluster Support: Query clusterAllReplicas(...) table functions to inspect mutations and parts across all distributed nodes simultaneously.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.