Log cleaner stalled
Alerts: KrabkaLogCleanerFailures
(sum by (instance, topic, reason) (rate(krabka_broker_log_cleaner_failures_total[15m])) > 0
for 15m) and KrabkaUncleanablePartitions
(krabka_broker_log_cleaner_uncleanable_partitions > 0 for 30m).
What it means
A compaction pass failed on a partition this broker hosts, and the partition
has not compacted since. The cleaner keeps sweeping; the partition keeps
failing, except one refused for a record above max.decompressed.message.bytes
(other, with Invalid record size in the log line), which the cleaner
leaves alone as Kafka trunk does until that limit changes. It stays in the
uncleanable count, and the failure counter does not grow past the first
refusal, so KrabkaLogCleanerFailures resolves while
KrabkaUncleanablePartitions keeps firing.
The replica need not be a leader. The cleaner sweeps every log this broker
holds, as Kafka’s LogCleanerManager does, so a follower replica of a
compacted topic appears here on its own account. Moving the leadership away
does not clear it.
On a compacted topic the cleaner is the only thing that bounds the log.
cleanup.policy=compact has no size or time retention behind it, and even
compact,delete deletes only whole sealed segments the cleaner has already
rewritten. So compaction and local retention stop together: the partition
grows at the full produce rate, and nothing else on the broker says so. The
disk is the next thing to fail, and it takes every partition on it, not the
one that stalled.
A reason of io is a storage failure. The broker has already asked its
log-dir registry to take the owning directory offline, so
KrabkaOfflineLogDirs should be firing beside this one — read
offline-log-dir first, and treat this rule as the
symptom. writer is a partition whose writer actor is gone, which is a broker
bug. other is the log layer refusing the rewrite, usually a segment it
cannot read.
Confirm
sum by (topic, reason) (rate(krabka_broker_log_cleaner_failures_total[15m]))
krabka_broker_log_cleaner_uncleanable_partitions
rate(krabka_broker_log_cleaner_runs_total[15m])
The run counter counts only sweeps that failed no partition, so a flat run rate beside a positive failure rate means every sweep is failing. A run rate that is still healthy means one partition is failing and the rest are fine.
krabka_broker_partition_disk_bytes for the topic the first query names is
what turns this from a background warning into a deadline: a compacted
partition that climbs on a straight line has no upper bound.
Diagnose
- Read the broker log. Every failed pass logs one
compaction failed for partitionline with the topic, the partition and the underlying error. - For
io, the error names the file. A dead disk, a filesystem remounted read-only, and a full filesystem all read differently, and the third is the one that a full disk caused rather than the one that will cause it. - For
other, aCorrupterror names the segment the rewrite could not read. That segment is unreadable to consumers too; check whether fetches of that offset range fail. krabka_broker_log_compactions_totalfor the same partition tells you when it last succeeded. A partition that has never compacted since broker start was broken before this alert fired.
Fix
- For
io, follow offline-log-dir. The cleaner recovers on its own once writes to the directory succeed again: the next sweep compacts the partition, the uncleanable count falls, and the run counter resumes. - For a corrupt segment, move the replica to another broker with
kafka-reassign-partitionsand let the new replica build its log from the leader. Moving only the leadership does not help: this broker still holds the replica and still owes it a pass. Do not delete segment files under a running broker. - For a record above
max.decompressed.message.bytes, raise the limit on the topic, the broker or the cluster to at least the size the log line names. The first sweep after the change runs the partition again. Kafka trunk holds the partition until the broker restarts. - While the cause is being fixed, buy disk headroom by lowering the topic’s
segment.bytes— smaller segments seal sooner and the first successful pass reclaims more — or by moving the largest partitions off the broker. writeris a broker bug. Collect the log lines around the failure and restart the broker; the partition’s writer is respawned on start.
Escalate
A partition that is still uncleanable after the storage fault is fixed, or a
compacted partition whose disk bytes will reach the volume’s capacity before
the fix lands, is an outage on a timer. Escalate with the topic, the
partition, krabka_broker_partition_disk_bytes for it, and the free space on
the log dir.