-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Description
Describe the problem:
In the legacy schema changer, when a CREATE TABLE statement with inline FOREIGN KEY constraints is rolled back (e.g. because the schema change job fails permanently), the rollback path marks the new table as Dropped and queues it for GC, but does not remove the InboundFK entries that were added to the referenced table(s) during the original SQL transaction.
This leaves orphaned FK back-references pointing to a descriptor that no longer exists, causing descriptor validation errors such as:
relation "parent" (209): invalid foreign key backreference:
missing table=264: referenced descriptor not found
The bug is in the ADD-state rollback path of rollbackSchemaChange(). View dependency cleanup already exists in that path, but FK back-reference cleanup was missing entirely.
To Reproduce:
- Create a parent table:
CREATE TABLE parent (id INT PRIMARY KEY);
- Begin a
CREATE TABLEwith an inlineFOREIGN KEYreferencingparent, in a way that causes the schema change job to fail permanently (e.g. inject a job failure, or construct a scenario where the job cannot complete):CREATE TABLE child ( id INT PRIMARY KEY, parent_id INT REFERENCES parent(id) );
- Allow the schema change job to fail and roll back.
- Inspect the
parenttable descriptor. It retains anInboundFKentry pointing to the now-droppedchildtable. - Run descriptor validation — observe the error:
relation "parent" (209): invalid foreign key backreference: missing table=264: referenced descriptor not found
Expected behavior:
When the CREATE TABLE schema change is rolled back, all FK back-references added to referenced tables (InboundFKs) and any outbound FK entries on tables referencing the rolled-back table (OutboundFKs) should be cleaned up. After rollback, referenced table descriptors should be left in a valid state with no dangling references.
Environment:
- CockroachDB version: v25.1 and later
- Schema changer: Legacy schema changer
- Deployment: Any
Additional context:
The fix reuses the existing removeFKBackReferenceFromTable() helper (already used by dropTableImpl() and maybeReverseMutations()) in the ADD-state rollback path of rollbackSchemaChange(), iterating over both outbound and inbound FKs on the table being rolled back. Cleanup errors are logged as warnings and skipped (best-effort), matching the pattern used by dropViewDeps().
Fixed in commit b49a6a2.
Jira issue: CRDB-61445