2026-08-25 macOS 27 Upgrade and the Sixth Replication Queue Repair

What I set out to do

Run the routine post-upgrade check for a stuck ClickHouse replication queue on atlas, after upgrading to macOS 27.0 (build 26A5421a). The alert 019fcc74-3f22-7500-a25c-dad25cd9ca33 was already showing history worth looking at.

What I found

Sixth recurrence. Fifteen GET_PART entries carrying Code 234 NO_REPLICA_HAS_PART across eight tables, in both signoz_metrics and signoz_traces.

New trigger class, though the shape is the 2026-08-17 one: two stack starts, not a crash. The upgrade reboot brought SigNoz up around 18:41 UTC and the queue entries were all created 18:41:17-18:41:52 during that first recovery. A second start seven minutes later broke exactly the parts those entries were waiting on: 197 broken-on-start plus 1,686 covered-by-broken in seven seconds at 18:48:02-18:48:09, and the ClickHouse process that answered my queries dated to 18:48:57. No Docker Desktop panic in the log this time, so this is neither the semawakeup nor the sailor pthread_create class.

Proving it stuck mattered again. CPU was 35% ClickHouse / 2.4% ZooKeeper, nowhere near the ~120% pinning of the first two incidents, and count() sat frozen at 15. What moved was num_postponed: 225,572 to 226,376 across about ninety seconds, with num_tries creeping 1888 to 1898. Two samples, not one.

The alert had fired at 19:15:14 with value 15, thirty-four minutes after the queue went non-empty, which is the 30m window behaving correctly. No resolve row yet at that point; it went inactive at 20:55:14, so 1h40m firing in total.

The repair

Standard per-table replica rebuild driven by a scratchpad repair.sh that reads zookeeper_path and replica_name before the DETACH (the system.replicas row disappears with the table). The run_batch.sh driver was blocked by the auto-mode classifier, same as the inline loops in prior incidents, so I ran the eight tables one call at a time. Smallest first, the two plain ReplicatedMergeTree tables last.

Deltas, read by engine:

tableenginedelta
top_level_operationsReplacing27 8
dependency_graph_minutes_v2Aggregating-845 (-0.6%)
metadataAggregating-62,428 (-7.7%)
trace_summaryAggregating-34,094 (-0.4%)
samples_v4_agg_5mAggregating-173,839 (-0.12%)
samples_v4_agg_30mAggregating-211,484 (-0.65%)
signoz_index_v3plain+0
samples_v4plain-1,195,183 (-0.045%)

signoz_index_v3 at exactly +0 is the one piece of honest evidence a plain no-dedup engine can give, and samples_v4’s -0.045% sits right on top of the -0.046% and -0.048% from the two prior incidents.

metadata at -7.7% looked out of band until I checked partitions rather than totals: today’s 2026-08-25 partition holds 23,704 rows against 15k-32k on the six preceding days. The drop is merge collapse on an aggregating engine, not the whole-day loss its part name 20260825_0_18259_3723 predicted.

Verification

Queue at 0 entries, 0 readonly replicas, max(absolute_delay) 0. CPU fell to 12.8% / 0.25%. The rollup identity over the closed 19:00 hour held exactly: samples_v4 count() under bitAnd(flags,1)=0 and samples_v4_agg_5m FINAL sum(count) both 683,426, the same number I captured before touching anything.

Nicest confirmation was watching the alert’s own source metric drain in real time: ClickHouseAsyncMetrics_ReplicasSumQueueSize went 15, 15, 15, 15, 10, 7, 3, 0 across the minutes the repair ran, then held 0. The alert resolved on the next eval cycle after that, at 20:55:14.

Small trap in rule_state_history_v0: the inactive row carries value = 7, not 0. That is the sample the ruler was holding when the all_the_times condition broke, not the queue depth at resolution, so a non-zero value on a resolve row is not evidence of a partial fix.

What I decided not to do

top_level_operations came out at 13 rows over 7 distinct (serviceName, name) keys, down from 27 over 11. The 2026-08-21 incident is the one case where re-attaching the RESTORE-detached batch was worth it, and the parts were sitting right there with reason='' and today’s timestamp. I left them. Rows are approximately equal to distinct keys and the service list matches signoz_index_v3 over 24h exactly (claude-code, litellm-proxy, open-webui, sillytavern), which is the 2026-08-23 signature for sorting-key collapse rather than loss. The table was already refilling from live traces while I looked at it, 8 to 10 to 13 rows in a few minutes. The lesson that keeps holding is that the table left alone verifies clean and the table “repaired” goes corrupt.

Also left alone: dependency_graph_minutes_v2 shows nothing before the 18:00 hour today, but the host was off for the upgrade, so there was never anything there to lose.

Related: 2026-08-23 Sailor Crash and the Fifth Replication Queue Repair, 2026-08-21 Docker Crash Stranded the ClickHouse Replication Queue, 2026-08-17 SigNoz Replication Queue Third Recurrence and Rollup Repair.