ワンクリックで
monitor-changefeed-job-status
Monitor and track changefeed job status, health, and progress using SQL commands and DB Console
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Monitor and track changefeed job status, health, and progress using SQL commands and DB Console
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Analyze table statistics and estimated row counts to understand optimizer decisions and diagnose plan quality issues
Use SHOW BACKUP to analyze incremental backup efficiency by comparing data_size, row_count, and performance metrics across backup chains. Calculate storage savings, monitor change rates, and optimize backup frequency based on data patterns. Essential for balancing RPO requirements with storage costs.
Use SHOW RANGES commands to analyze how table data and indexes are split into ranges and distributed across cluster nodes. Understand key-value encoding, range boundaries, replica placement, and leaseholder assignment for performance troubleshooting.
Analyze query latency using mean, max, and min metrics from statement statistics; percentile data (p50/p90/p99) only available in DB Console UI
Analyze how ranges and replicas are distributed across regions in multi-region clusters. Query range placement, verify regional constraints, identify misplaced ranges, and detect rebalancing issues. Essential for troubleshooting latency, verifying compliance, and optimizing multi-region performance.
Use USING HASH clause to distribute sequential keys across ranges, preventing write hotspots. Hash function maps sequential values to buckets (default 16) spreading writes across the cluster. Fixes timestamp, auto-increment, and date-based hotspots with trade-off on range scan efficiency.
| name | monitor-changefeed-job-status |
| description | Monitor and track changefeed job status, health, and progress using SQL commands and DB Console |
| metadata | {"domain":"Change Data Capture (CDC)","bloom_level":"Apply","version":"1.0.0","cockroachdb_version":"v26.1.0+","status":"production","prerequisites":["create-enterprise-changefeeds","understand-changefeed-fundamentals"],"related_skills":["query-changefeed-job-metrics","inspect-changefeed-errors-in-logs","pause-and-resume-changefeeds","troubleshoot-changefeed-performance","protect-changefeed-data-from-gc"],"estimated_time":"25 minutes"} |
Domain: Change Data Capture (CDC) Bloom's Level: Apply CockroachDB Version: v26.1.0+
You will learn how to monitor changefeed job status, track progress through high water timestamps, detect and diagnose errors, and manage the changefeed job lifecycle. This skill covers both SQL-based monitoring using SHOW CHANGEFEED JOBS and visual monitoring through the DB Console Jobs page and Changefeeds Dashboard.
Effective changefeed monitoring is critical for ensuring data consistency, detecting issues early, and maintaining operational visibility into your change data capture pipelines.
Changefeeds are long-running jobs that continuously emit data changes to external systems. Without proper monitoring, you risk:
Monitoring changefeed job status enables you to detect issues early, understand changefeed progress, and maintain reliable data pipelines.
Changefeeds run as jobs in CockroachDB's jobs subsystem. Each changefeed has:
The high water timestamp is the most critical metric for monitoring changefeed progress. It represents a point-in-time guarantee:
The lag between the high water timestamp and the current time indicates how far behind the changefeed is in processing changes.
Changefeed jobs progress through these status values:
| Status | Meaning | Next Actions |
|---|---|---|
running | Changefeed is actively processing and emitting changes | Normal operation; monitor for lag |
paused | Changefeed has been manually paused via PAUSE JOB | Resume with RESUME JOB when ready |
pause-requested | Pause operation is in progress but not yet complete | Wait for status to transition to paused |
failed | Changefeed encountered a terminal error and cannot continue | Investigate error, fix root cause, restart from cursor |
canceled | Changefeed was explicitly canceled or auto-canceled after protected timestamp expiry | Create new changefeed if needed |
Changefeeds handle two types of errors differently:
Retryable Errors (automatically retried):
Terminal Errors (cause job failure):
When a changefeed encounters a retryable error, it pauses briefly and retries. Terminal errors cause the job to fail permanently, requiring manual intervention.
Use SHOW CHANGEFEED JOBS to display all changefeed jobs across the cluster:
SHOW CHANGEFEED JOBS;
Output columns:
job_id: Unique job identifierdescription: Human-readable description of the changefeed configurationuser_name: User who created the changefeedstatus: Current job status (running, paused, failed, canceled)running_status: Additional runtime state informationcreated: Timestamp when the job was createdstarted: Timestamp when the job started runningfinished: Timestamp when the job completed (NULL for active jobs)modified: Timestamp of last modificationhigh_water_timestamp: Progress checkpoint in nanoseconds since Unix epochreadable_high_water_timestamptz: Human-readable timestamp with timezoneerror: Error message for failed jobssink_uri: Destination URI for the changefeed (redacted credentials)full_table_names: Fully-qualified names of watched tablestopics: Kafka/Pub/Sub topic names for the changefeedformat: Message format (json, avro, csv, parquet)Example output:
job_id | description | status | running_status | created | started | finished | modified | high_water_timestamp | readable_high_water_timestamptz | error | sink_uri | full_table_names | topics | format
---------------------+---------------------------------------------------+---------+-----------------------------------+----------------------+----------------------+----------+----------------------+----------------------+-----------------------------------+-------+-------------------------------+---------------------------+-------------------+--------
912345678901234567 | CREATE CHANGEFEED FOR TABLE mydb.public.orders... | running | running: resolving timestamps | 2026-03-07 10:15:23 | 2026-03-07 10:15:24 | NULL | 2026-03-07 14:22:10 | 1709821330000000000 | 2026-03-07 14:22:10+00:00 | NULL | kafka://broker:9092 | mydb.public.orders | orders | json
Query specific changefeed jobs by job ID:
SHOW CHANGEFEED JOB 912345678901234567;
This displays the same columns as SHOW CHANGEFEED JOBS but filtered to a single job.
Use standard SQL WHERE clauses to filter by status:
-- View only running changefeeds
SELECT job_id, status, readable_high_water_timestamptz, error
FROM [SHOW CHANGEFEED JOBS]
WHERE status = 'running';
-- View failed or paused changefeeds
SELECT job_id, status, error, sink_uri
FROM [SHOW CHANGEFEED JOBS]
WHERE status IN ('failed', 'paused');
-- View changefeeds by table name
SELECT job_id, status, full_table_names
FROM [SHOW CHANGEFEED JOBS]
WHERE full_table_names LIKE '%orders%';
Calculate how far behind a changefeed is by comparing the high water timestamp to the current time:
SELECT
job_id,
status,
running_status,
NOW() - readable_high_water_timestamptz AS lag,
readable_high_water_timestamptz AS high_water_mark,
full_table_names
FROM [SHOW CHANGEFEED JOBS]
WHERE status = 'running'
ORDER BY lag DESC;
Interpreting lag:
Monitor high water timestamp advancement to verify the changefeed is making progress:
-- Run this query periodically (e.g., every 30 seconds)
SELECT
job_id,
readable_high_water_timestamptz,
EXTRACT(epoch FROM (NOW() - readable_high_water_timestamptz))::INT AS lag_seconds
FROM [SHOW CHANGEFEED JOBS]
WHERE status = 'running';
If the readable_high_water_timestamptz value doesn't advance between queries, the changefeed may be stuck or experiencing issues.
Query the jobs table for changefeeds with error messages:
SELECT
job_id,
status,
error,
readable_high_water_timestamptz,
full_table_names
FROM [SHOW CHANGEFEED JOBS]
WHERE error IS NOT NULL OR status = 'failed'
ORDER BY modified DESC;
Common error patterns:
| Error Message | Cause | Resolution |
|---|---|---|
table offline | Table was dropped or is unavailable | Remove table from changefeed or restore table |
changefeed cannot handle column family | DDL added column family to watched table | Create new changefeed; some DDL changes are terminal |
protected timestamp verification failed | Changefeed fell behind GC window | Restart changefeed with cursor option from safe timestamp |
sink unavailable | Cannot connect to Kafka/Pub/Sub/webhook | Check sink connectivity, credentials, and configuration |
schema change occurred | Incompatible DDL operation | Review schema changes; restart changefeed if needed |
Navigate to the Jobs page in the DB Console:
Access: http://<cluster-host>:8080 → Jobs (left navigation)
Features:
Best practices:
Navigate to the Changefeeds Dashboard for metrics and aggregated health:
Access: http://<cluster-host>:8080 → Metrics → Dashboard → Changefeeds
Key metrics displayed:
When to use:
For programmatic monitoring or custom queries, use crdb_internal.jobs:
SELECT
job_id,
job_type,
status,
created,
NOW() - to_timestamp((high_water_timestamp/1000000000)::FLOAT) AS changefeed_lag,
LEFT(description, 100) AS config_summary,
error
FROM crdb_internal.jobs
WHERE job_type = 'CHANGEFEED'
AND status IN ('running', 'paused', 'pause-requested')
ORDER BY created DESC;
This query provides similar information to SHOW CHANGEFEED JOBS but allows more flexible SQL operations like joins, aggregations, and complex filtering.
For production environments, implement continuous monitoring:
Polling query for alerting systems (Prometheus, Datadog, etc.):
SELECT
COUNT(*) AS running_count,
SUM(CASE WHEN EXTRACT(epoch FROM (NOW() - readable_high_water_timestamptz)) > 300 THEN 1 ELSE 0 END) AS lagging_count,
MAX(EXTRACT(epoch FROM (NOW() - readable_high_water_timestamptz))) AS max_lag_seconds
FROM [SHOW CHANGEFEED JOBS]
WHERE status = 'running';
Alert thresholds:
lagging_count > 0 (any changefeed >5 minutes behind)max_lag_seconds > 600 (any changefeed >10 minutes behind)Pause a running changefeed to temporarily halt processing:
PAUSE JOB 912345678901234567;
When to pause:
ALTER CHANGEFEEDImportant considerations:
protect_data_from_gc_on_pause is enabled)gc_protect_expires_after duration, protected timestamps expire and the job is auto-canceledgc_protect_expires_after is 24 hoursVerify pause:
SELECT job_id, status FROM [SHOW CHANGEFEED JOBS] WHERE job_id = 912345678901234567;
Expected status: paused
Resume a paused changefeed:
RESUME JOB 912345678901234567;
The changefeed continues from its high water timestamp, emitting changes that occurred during the pause.
Verify resume:
SELECT job_id, status, running_status FROM [SHOW CHANGEFEED JOBS] WHERE job_id = 912345678901234567;
Expected status: running
Permanently stop a changefeed:
CANCEL JOB 912345678901234567;
When to cancel:
Important: Canceled changefeeds cannot be resumed. To continue capturing changes, create a new changefeed with the cursor option.
Symptoms:
SELECT job_id, status, error FROM [SHOW CHANGEFEED JOBS] WHERE status = 'failed';
Returns failed jobs with error messages.
Diagnosis:
error column for the root causegrep <job_id> /var/log/cockroach/cockroach.logResolution:
For terminal errors (schema changes, dropped tables):
-- Create new changefeed starting from the failed job's high water timestamp
CREATE CHANGEFEED FOR TABLE mydb.public.orders
INTO 'kafka://broker:9092'
WITH cursor = '1709821330000000000';
For transient errors (sink connectivity):
RESUME JOB 912345678901234567;
Symptoms: High water timestamp remains static across multiple queries over several minutes.
Diagnosis:
-- Check for errors and running status
SELECT job_id, status, running_status, error, readable_high_water_timestamptz
FROM [SHOW CHANGEFEED JOBS]
WHERE job_id = 912345678901234567;
Common causes:
Resolution:
Symptoms:
SELECT
job_id,
EXTRACT(epoch FROM (NOW() - readable_high_water_timestamptz))::INT AS lag_seconds
FROM [SHOW CHANGEFEED JOBS]
WHERE status = 'running';
Shows lag increasing from seconds to minutes.
Diagnosis:
diff, envelopeResolution:
resolved if not neededmin_checkpoint_frequency to reduce overheadfull_table_name=false if possibleSymptoms:
SELECT job_id, status, error FROM [SHOW CHANGEFEED JOBS] WHERE status = 'canceled';
Shows canceled status with error mentioning protected timestamp expiry.
Diagnosis:
Changefeed was paused longer than gc_protect_expires_after duration (default 24 hours), causing protected timestamps to expire and the job to auto-cancel.
Resolution:
-- Get the high water timestamp from the canceled job
SELECT job_id, high_water_timestamp FROM [SHOW CHANGEFEED JOBS] WHERE job_id = 912345678901234567;
-- Create new changefeed from the high water timestamp
CREATE CHANGEFEED FOR TABLE mydb.public.orders
INTO 'kafka://broker:9092'
WITH cursor = '1709821330000000000';
Prevention:
gc_protect_expires_after windowgc_protect_expires_after for longer maintenance windows:
ALTER CHANGEFEED 912345678901234567 SET gc_protect_expires_after = '48h';
protect_data_from_gc_on_pause=false if protected timestamps are not needed during pauseSymptoms:
Changefeeds Dashboard shows high changefeed.error_retries metric, or logs show repeated retryable errors.
Diagnosis:
-- Check for changefeeds with recent errors (requires monitoring external metrics)
SELECT job_id, status, running_status, readable_high_water_timestamptz
FROM [SHOW CHANGEFEED JOBS]
WHERE status = 'running';
Check Changefeeds Dashboard for error retry trends.
Common retryable errors:
Resolution:
Before deploying changefeeds to production, establish baseline metrics:
Use these baselines to set meaningful alert thresholds.
Configure alerts for:
| Metric | Threshold | Severity | Action |
|---|---|---|---|
changefeed.max_behind_nanos | >5 minutes | Warning | Investigate lag causes |
changefeed.max_behind_nanos | >10 minutes | Critical | Immediate intervention required |
Changefeed status = failed | Any failed job | Critical | Investigate and restart |
changefeed.error_retries | Sudden spike | Warning | Check sink and cluster health |
| High water timestamp not advancing | >2 minutes | Warning | Check for stuck changefeeds |
Changefeeds hold protected timestamps to prevent garbage collection of data they haven't yet emitted. Monitor protected timestamp age:
SELECT
c.job_id,
c.status,
NOW() - c.readable_high_water_timestamptz AS protected_age
FROM [SHOW CHANGEFEED JOBS] c
WHERE c.status IN ('running', 'paused')
ORDER BY protected_age DESC;
Risk: Old protected timestamps prevent garbage collection, causing data accumulation and storage growth.
Mitigation: Cancel or resume long-paused changefeeds promptly.
Maintain an inventory of all production changefeeds:
SELECT
job_id,
status,
full_table_names,
sink_uri,
created,
user_name
FROM [SHOW CHANGEFEED JOBS]
ORDER BY created DESC;
Document the purpose and owner of each changefeed to avoid orphaned or forgotten changefeeds.
Implement a periodic health check script (run every 5 minutes):
-- Changefeed health check query
SELECT
'total_changefeeds' AS metric,
COUNT(*)::STRING AS value
FROM [SHOW CHANGEFEED JOBS]
UNION ALL
SELECT
'running_changefeeds',
COUNT(*)::STRING
FROM [SHOW CHANGEFEED JOBS]
WHERE status = 'running'
UNION ALL
SELECT
'failed_changefeeds',
COUNT(*)::STRING
FROM [SHOW CHANGEFEED JOBS]
WHERE status = 'failed'
UNION ALL
SELECT
'lagging_changefeeds',
COUNT(*)::STRING
FROM [SHOW CHANGEFEED JOBS]
WHERE status = 'running'
AND EXTRACT(epoch FROM (NOW() - readable_high_water_timestamptz)) > 300;
Send results to your monitoring system (Prometheus, Datadog, CloudWatch, etc.).
The DB Console provides visual, real-time monitoring:
Recommended workflow:
Prerequisites:
Next steps:
Advanced topics:
changefeed.max_behind_nanos: Maximum lag across all changefeedschangefeed.error_retries: Total retryable errors encounteredchangefeed.checkpoint_progress: Changefeed checkpoint persistence statusVersion: 1.0.0 Last Updated: 2026-03-07 Skill Author: CockroachDB University License: CC BY-NC-SA 4.0