August 20, 2023·4 min read·engineeringcassandracompactionmaintenancecorrectness

Cassandra 3.11.16 aligns garbage collection with repaired-only purging

Cassandra fixes a maintenance operation that mishandled excluded SSTables. The release also corrects float-to-decimal casting and improves the identity recorded for compaction history.

Excluding an SSTable from an operation requires updating the operation's bookkeeping as well as its work list. Cassandra 3.11.16, released on August 20, fixes that mismatch during garbage-collection compaction when only_purge_repaired_tombstones is true. The operation must leave unrepaired SSTables outside the transaction it proceeds to execute.

The release changelog lists the fix alongside numeric-cast and operational corrections. These are changes to an existing maintenance line. Their importance comes from preserving the meaning of configured operations and returned values, rather than adding another database feature.

I find Cassandra useful when its distribution model matches the application's requirements. Operating that model also means understanding the conditions under which maintenance may remove old data. A setting intended to restrict purging needs the execution path to preserve that restriction consistently.

Filtering work must release excluded files

CASSANDRA-14204 reports an assertion failure when manually running garbage-collection compaction on a table containing unrepaired SSTables with repaired-only purging enabled. The issue explains that the filtering step excluded those files without removing them from the transaction.

That creates two different descriptions of the work. The selected list says the files will not be processed, while the transaction still includes them. The failure therefore concerns lifecycle bookkeeping around the operation, not merely the boolean expression selecting eligible files.

The 3.11.16 CompactionManager implementation handles the exclusion explicitly. When repaired-only purging is enabled, it examines the original SSTables. For each unrepaired one, it calls the transaction's cancel method. Repaired files enter the filtered list.

When the option is not enabled, the original files enter the list without that repaired-state filter. The method then sorts the selected files by maximum timestamp before returning them for processing. The behavior follows the table's configured policy while keeping the transaction aligned with the chosen input.

The word cancel has a specific scope here. It removes an excluded SSTable from this transaction. It should not be paraphrased as deleting that file or repairing it. The fix makes the operation account for data it has chosen not to process.

This is distinct from garbage-collector tuning

The affected operation is Cassandra's garbage-collection compaction over stored data. It is not a change to the JVM's heap collector. Using the same everyday term for both can obscure which resource and procedure the patch affects.

The issue's preconditions are also specific. It concerns a manual garbage-collection operation, unrepaired SSTables, and the repaired-only purge option. A release description need not claim every compaction has the same defect to explain why this path needs correction.

My preference is for maintenance controls to preserve their documented intent without requiring the operator to understand internal transaction membership. The implementation still needs that internal consistency, and this patch supplies it for the filtered SSTables.

Numeric conversion has a separate representation problem

The release also fixes casting a float to decimal. CASSANDRA-18647 gives a value written as 5.2 and shows a decimal result containing additional digits after conversion through a double. The reporter contrasts that result with conversion of the float to text.

A binary float does not acquire decimal exactness merely because the target type is decimal. The issue concerns which representation the conversion chooses. Widening the stored float to double before decimal conversion can expose digits that differ from the shorter decimal representation expected for the original type.

That distinction prevents an inaccurate explanation of the fix. The patch does not make every value stored as a binary float an exact copy of the decimal literal a person originally entered. It corrects the float-to-decimal conversion behavior identified by the report.

For application code, the meaningful question is what a cast promises about the resulting value. A representation change can affect exports and comparisons even if the original storage type remains the same. The maintenance entry therefore concerns observable query behavior as well as implementation details.

Compaction records need consistent identifiers

Another entry passes the compaction task identifier into system.compaction_history. The associated report compares a task visible in current compaction status and completion logs with a history lookup using that identifier.

The distinction is between performing work and identifying its historical record. If the identifier used by a running task differs from the one attached to its history, an operator cannot reliably connect those observations by the task identifier. The changelog describes preserving that connection.

Cassandra 3.11.16 consequently repairs several concrete contracts. A filtered maintenance operation keeps its transaction membership consistent with its chosen files. A numeric cast respects the intended source-type conversion, and compaction history receives the task identity used elsewhere in the operation. Each correction makes an existing interface easier to interpret without changing the application's distributed data model.