(gdb) p hs_inserted $2 = true (gdb) p *list $3 = {ins = 0x7fa540cfcca0, ripcip = 0x0, onpage_upd = 0x7fa54636f240, restore = false} (gdb) p *list->onpage_upd $4 = {txnid = 149, durable_ts = 0, start_ts = 0, next = 0x7fa545f32380, size = 45, type = 3 '\003', prepare_state = 0 '\000', flags = 2 '\002', data = 0x7fa54636f267 "-"} (gdb) p *list->onpage_upd->next $5 = {txnid = 147, durable_ts = 6864857421328678914, start_ts = 6864857421328678914, next = 0x7fa54636fc60, size = 80, type = 3 '\003', prepare_state = 0 '\000', flags = 8 '\b', data = 0x7fa545f323a7 "P"}
We have the code to handle mixed mode operation by marking the timestamped updates after it as obsolete.
In WT-6585, we added a panic to ensure we are not reinserting anything again to the history store that may corrupt the history store data.
However, the panic missed one valid edge case that handles mixed mode operation.
Suppose there is the following update chain:
U@0 -> U@20 -> U@0
The mixed mode operation handling code will mark U@20 as obsolete. However, after we have inserted the oldest U@0 into history store which sets hs_inserted to true, we will trigger the following panic because U@20 is marked as obsolete in this case:
/* Skip updates that are already in the history store or are obsolete. */ if (F_ISSET(upd, WT_UPDATE_HS | WT_UPDATE_OBSOLETE)) { if (hs_inserted) WT_ERR_PANIC(session, WT_PANIC, "Inserting updates older than obsolete updates or updates that are already " "in the history store to the history store may corrupt the data."); continue; }
However, in this case, it is actually valid to ignore that obsolete update.