-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: Checkpoints
-
None
-
Environment:GCC 13, Ubuntu 24.04
-
Storage Engines - Persistence
-
436.546
-
StorEng - Defined Pipeline
-
1
In __checkpoint_lock_dirty_tree (checkpoint_txn.c), when dropping a named checkpoint via session->checkpoint("drop=(...)"), session->ckpt.drop_list is only allocated and assigned to the local drop_list pointer on the first btree visited during handle gathering in __checkpoint_prepare. The code assumes the drop list is identical across all trees and only needs to be produced once, but this assumption fails when tables are created at different times. If a database contains a table whose URI sorts lexicographically before the table holding the named checkpoint (for example, table:table_a created after table:table_b took named checkpoint test_ckpt), table_a is visited first during the drop traversal. Because table_a has no record of test_ckpt in its checkpoint list, session->ckpt.drop_list is initialized and immediately closed as "()". On subsequent btrees like table:table_b, session->ckpt.drop_list is already non-NULL so the local drop_list pointer remains NULL. Consequently, __checkpoint_drop never invokes __checkpoint_drop_list_add, test_ckpt is never recorded, and __checkpoint_drop_list_execute runs on an empty list without calling __wt_meta_sysinfo_clear. As a result, the system metadata records (system:checkpoint_snapshot.<name>, system:checkpoint.<name>, and system:oldest.<name>) remain permanently orphaned in the metadata file.
For Reproduce;
I added python test (test_checkpoint41.py) reproduces the failure mode across named, from_named, and from_all scenarios (I added before/after outputs and test code added on Jira).
In the test scenario, table:table_b is created first and a named checkpoint test_ckpt is taken, which successfully writes system:checkpoint_snapshot.test_ckpt into the metadata table. Afterward, table:table_a is created, which sorts lexicographically before table_b and contains no checkpoints. When the session calls checkpoint("drop=(test_ckpt)"), the drop pass visits table_a first, finalizing the drop list as empty before ever reaching table_b. Searching for system:checkpoint_snapshot.test_ckpt on the metadata cursor returns 0 instead of WT_NOTFOUND, failing the assertion and demonstrating that the system metadata entry was never cleared.
With the fix applied, the drop pass gathers checkpoint names across all visited trees, the cursor search returns WT_NOTFOUND for all three system metadata entries, and the test passes cleanly.
Proposed Fix & Discussion;
I prepared a patch addressing this issue and added it to the Jira (checkpoint_drop_metadata.patch) for review. In the proposed fix, the drop list is maintained and accessible across all visited trees rather than only the first one, closing the group with ")" is moved to __checkpoint_drop_list_execute for clean encapsulation, in-place de-duplication is added in __checkpoint_drop_list_add so memory usage stays bounded at O(U) even across hundreds of collections without duplicate metadata searches, and an explicit drop request records the name even if the table itself was dropped.
Rather than opening a pr directly on github, I wanted to open this jira discussion first to share findings and consult with the team on whether this fix aligns with the codebase conventions and whether there are concerns regarding the complexity added to the drop gathering path before proceeding with a pr or like if that doesn't work, the team can look into it, etc.