CockroachDB TRUNCATE could publish a partly built index
A 20.2 truncation change could leave an old secondary index attached to newly empty indexes. Advisory 62842 explains the overlap, detection signal and required index repair.
A table can appear empty through its primary index while an old secondary index still exposes pre-truncation data. CockroachDB's advisory 62842 explains how a truncation operation could produce that disagreement. The critical overlap is an index that is still being added when TRUNCATE runs.
The July 29 advisory affects versions 20.2.0 through 20.2.8. Version 20.2.9 contains the fix. The disclosure explains how to find suspect indexes and tells operators to drop and rebuild them.
I value a database that handles schema changes without requiring application code to coordinate every physical step. That places an obligation on the engine to preserve the relationship between an object's logical state and its partially completed storage work. This bug violated that obligation during truncation.
Stable table identity changed truncation
The advisory says CockroachDB 20.2 changed TRUNCATE to preserve the table ID. Its new implementation replaced existing indexes with new empty indexes. The table remained the same logical object while its indexes received fresh empty storage identities.
An index under construction was a different case. It was not yet public, so it did not belong to the same set as the table's ready indexes. The faulty implementation failed to handle that distinction consistently.
The patch description identifies the order of operations. The code decided which indexes to clone and then made mutations public. An index undergoing backfill or validation could become public after missing the earlier selection step.
The result combined newly truncated indexes with an old, partly populated secondary index. That old index could still contain pre-truncation data. Publishing it made those stale entries available to the query engine.
The failure is therefore more specific than TRUNCATE not deleting enough rows. The table's index definitions and contents no longer described one coherent state. Different access paths could encounter different representations of what the table contained.
A schema-change job also retains state
The patch description identifies another consequence. The truncation code assumed mutation jobs would discover that their mutations had disappeared and stop cleanly. That assumption did not hold for every job state.
For example, index validation could fail after the index became public. Reverting the failed index build could then fail too, because the index was already public. The descriptor could be left with an orphaned mutation job.
This matters because a schema change is more than the visible list of columns and indexes. Work in progress has a job state and a descriptor state that need to agree. Publishing an unfinished object can invalidate both its data and its cleanup path.
The fix restricts TRUNCATE to concurrent mutations considered safe and repairs behavior for those supported cases. It does not claim that every possible overlapping schema operation becomes valid. Rejecting an unsafe overlap preserves a defined state where trying to continue would not.
The 20.2.9 release notes describe the correction as fixing corruption from TRUNCATE concurrent with index construction and other schema changes. They date that maintenance release to May 10. July's advisory provides the more detailed public explanation and detection guidance.
Index identifiers supply a detection signal
The advisory first asks operators to check logs for TRUNCATE. That establishes whether the relevant operation occurred, but it does not establish whether an index build overlapped it. The next detection step inspects index IDs.
Its query decodes table descriptors from system.descriptor, selects the primary-index ID and expands the secondary-index definitions. It flags a secondary index whose ID is less than the primary-index ID. The report joins those descriptors to crdb_internal.tables to return database, schema, table and index names.
The relationship follows the mechanism. Replacing an index during truncation assigns a new identity, while the incorrectly published secondary index retains its older one. The resulting order can reveal an object that did not follow the same replacement path.
The advisory calls an index found by its example possibly corrupted. That qualification belongs in the interpretation. The query produces a useful suspect list, not a complete proof about every historical operation on every returned table.
An empty result should also not be expanded into an unsupported guarantee about all forms of database correctness. The query targets the ID relationship associated with this particular bug. It is not a general index-validation command.
I find this detection guidance useful because it connects an internal identity rule with an actionable object name. An operator can identify the index to investigate without needing to infer it from an incorrect application result.
Updating and repairing address different states
The advisory recommends upgrading 20.2 installations to 20.2.9 or later. That prevents the faulty implementation from creating the same state during subsequent truncation operations. It does not say that installing the binaries reconstructs an already affected secondary index.
For suspect indexes, the published mitigation is to drop and rebuild them. That creates index contents corresponding to the table's current data. The advisory separately says not to truncate a table while an index is being built as a preventive measure. This includes work whose completion is still pending even if the statement that requested the index has already been issued. The relevant state is the ongoing construction described in the disclosure.
These actions have different purposes. Avoiding the overlap changes when the risky operation can occur. Updating corrects the implementation. Rebuilding a suspect index addresses persistent state that an earlier execution may have left behind.
The version range is narrow enough to matter. The advisory identifies the early 20.2 releases explicitly and does not present this as an unqualified failure of every CockroachDB version. An assessment should preserve that scope.
The substantive failure is an unfinished index becoming public at the wrong point in truncation. The correction preserves agreement between the indexes selected for replacement, the states exposed to queries and the jobs responsible for completing schema work. Existing suspect indexes still need the repair the advisory names.