Skip to content

Commit

Permalink
memtx: fix wrong index mask in rebound read tracker during rollback
Browse files Browse the repository at this point in the history
During rollback read trackers are rebound to newer or older story, if
present: the index mask passed to `memtx_tx_track_read_story_slow`
is equal to the current index from which the story is unlinked and it
overwrites the tracker's index mask — pass the tracker's index mask
instead.

Closes tarantool#7828

NO_DOC=bugfix
  • Loading branch information
CuriousGeorgiy committed Oct 23, 2022
1 parent b481e12 commit d1955f2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
@@ -0,0 +1,4 @@
## bugfix/memtx

* Fixed phantom read possible after reads from different indexes followed by a
rollback (gh-7828).
2 changes: 1 addition & 1 deletion src/box/memtx_tx.c
Expand Up @@ -1235,7 +1235,7 @@ memtx_tx_story_unlink_both_on_rollback(struct memtx_story *story, uint32_t idx)
if ((tracker->index_mask & index_mask) != 0) {
memtx_tx_track_read_story_slow(tracker->reader,
rebind_story,
index_mask);
tracker->index_mask);
rlist_del(&tracker->in_reader_list);
rlist_del(&tracker->in_read_set);
}
Expand Down
@@ -0,0 +1,50 @@
local server = require('test.luatest_helpers.server')
local t = require('luatest')

local g = t.group()

g.before_all(function(cg)
cg.server = server:new {
alias = 'dflt',
box_cfg = {memtx_use_mvcc_engine = true}
}
cg.server:start()
cg.server:exec(function()
local s = box.schema.create_space('s')
s:create_index('pk')
s:create_index('sk', {parts = {{2}}})
end)
end)

g.after_all(function(cg)
cg.server:drop()
end)

--[[
Checks that during rollback read tracker is rebound with correct index mask.
]]
g.test_rollback_rebind_read_tracker_correct_idx_mask = function(cg)
local stream1 = cg.server.net_box:new_stream()
local stream2 = cg.server.net_box:new_stream()
local stream3 = cg.server.net_box:new_stream()

stream1:begin()
stream2:begin()
stream3:begin()

stream1.space.s:insert{1, 0}
stream2.space.s:insert{1, 0, 0}

stream3.space.s.index[1]:get{0}
stream3.space.s:select{1}

stream1:rollback()

cg.server:exec(function()
box.space.s:insert{0, 0}
end)

t.assert_equals(stream3.space.s:select{}, {})
t.assert_error_msg_content_equals('Transaction has been aborted by conflict',
function() stream3.space.s:replace {0, 0} end)
end

0 comments on commit d1955f2

Please sign in to comment.