Commit 06adab50 authored by John Esmet's avatar John Esmet

Fix up a race where two threads could update the oldest referenced xid

in a different order than they began, and blow up a bad assert.
parent 96fc41fc
...@@ -2606,12 +2606,6 @@ void toku_ft_leaf_apply_cmd( ...@@ -2606,12 +2606,6 @@ void toku_ft_leaf_apply_cmd(
node->max_msn_applied_to_node_on_disk = cmd_msn; node->max_msn_applied_to_node_on_disk = cmd_msn;
} }
if (gc_info->mvcc_needed) { // False during recover and non-transactional environments
// Caller should have recognized that the oldest referenced xid for
// simple gc is this node's oldest referenced xid known.
invariant(gc_info->oldest_referenced_xid_for_implicit_promotion == node->oldest_referenced_xid_known);
}
if (ft_msg_applies_once(cmd)) { if (ft_msg_applies_once(cmd)) {
unsigned int childnum = (target_childnum >= 0 unsigned int childnum = (target_childnum >= 0
? target_childnum ? target_childnum
...@@ -2670,10 +2664,14 @@ static void inject_message_in_locked_node( ...@@ -2670,10 +2664,14 @@ static void inject_message_in_locked_node(
invariant(toku_ctpair_is_write_locked(node->ct_pair)); invariant(toku_ctpair_is_write_locked(node->ct_pair));
toku_assert_entire_node_in_memory(node); toku_assert_entire_node_in_memory(node);
// If the current gc_info knows about a newer xid suitible for implicit // Take the newer of the two oldest referenced xid values from the node and gc_info.
// promotions, update the oldest referenced xid known for this node. // The gc_info usually has a newer value, because we got it at the top of this call
if (gc_info->oldest_referenced_xid_for_implicit_promotion >= node->oldest_referenced_xid_known) { // stack from the txn manager. But sometimes the node has a newer value, if some
// other thread sees a newer value and writes to this node before we got the lock.
if (gc_info->oldest_referenced_xid_for_implicit_promotion > node->oldest_referenced_xid_known) {
node->oldest_referenced_xid_known = gc_info->oldest_referenced_xid_for_implicit_promotion; node->oldest_referenced_xid_known = gc_info->oldest_referenced_xid_for_implicit_promotion;
} else if (gc_info->oldest_referenced_xid_for_implicit_promotion < node->oldest_referenced_xid_known) {
gc_info->oldest_referenced_xid_for_implicit_promotion = node->oldest_referenced_xid_known;
} }
// Get the MSN from the header. Now that we have a write lock on the // Get the MSN from the header. Now that we have a write lock on the
......
...@@ -155,11 +155,11 @@ struct txn_gc_info { ...@@ -155,11 +155,11 @@ struct txn_gc_info {
// suitible for simple garbage collection that cleans up multiple committed // suitible for simple garbage collection that cleans up multiple committed
// transaction records into one. not suitible for implicit promotions, which // transaction records into one. not suitible for implicit promotions, which
// must be correct in the face of abort messages - see ftnode->oldest_referenced_xid // must be correct in the face of abort messages - see ftnode->oldest_referenced_xid
const TXNID oldest_referenced_xid_for_simple_gc; TXNID oldest_referenced_xid_for_simple_gc;
// lower bound on the oldest xid in any live when the messages to be cleaned // lower bound on the oldest xid in any live when the messages to be cleaned
// had no messages above them. suitable for implicitly promoting a provisonal uxr. // had no messages above them. suitable for implicitly promoting a provisonal uxr.
const TXNID oldest_referenced_xid_for_implicit_promotion; TXNID oldest_referenced_xid_for_implicit_promotion;
// whether or not mvcc is actually needed - false during recovery and non-transactional systems // whether or not mvcc is actually needed - false during recovery and non-transactional systems
const bool mvcc_needed; const bool mvcc_needed;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment