forked from tarantool/tarantool
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
memtx: fix story delete statement list
Current implementation of tracking statements that delete a story has a flaw, consider the following example: tx1('box.space.s:replace{0, 0}') -- statement 1 tx2('box.space.s:replace{0, 1}') -- statement 2 tx2('box.space.s:delete{0}') -- statement 3 tx2('box.space.s:replace{0, 2}') -- statement 4 When statement 1 is prepared, both statements 2 and 4 will be linked to the delete statement list of {0, 0}'s story, though, apparently, statement 4 does not delete {0, 0}. Let us notice the following: statement 4 is "pure" in the sense that, in the transaction's scope, it is guaranteed not to replace any tuple — we can retrieve this information when we check where the insert statement violates replacement rules, use it to determine "pure" insert statements, and skip them later on when, during preparation of insert statements, we handle other insert statements which assume they do not replace anything (i.e., have no visible old tuple). We also need to fix relinking of delete statements from the older story (in terms of the history chain) to the new one during preparation of insert statements: a statement needs to be relinked iff it comes from a different transaction (to be precise, there must, actually, be no more than one delete statement from the same transaction). Additionally, added assertions to verify the invariant that the story's add (delete) psn is equal to the psn of the add (delete) statement's transaction psn and to verify that no self-conflicting of transactions occurs. Closes tarantool#7214 Closes tarantool#7217 NO_DOC=bugfix
- Loading branch information
1 parent
0eac13b
commit f333b72
Showing
5 changed files
with
155 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
## bugfix/memtx | ||
|
||
* Fixed repeatable replace with memtx transaction manager enabled which | ||
triggered assertion (gh-7214). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
local server = require('test.luatest_helpers.server') | ||
local t = require('luatest') | ||
|
||
local g = t.group() | ||
|
||
g.before_all = function() | ||
g.server = server:new{ | ||
alias = 'dflt', | ||
box_cfg = {memtx_use_mvcc_engine = true} | ||
} | ||
g.server:start() | ||
g.server:exec(function() | ||
local s = box.schema.create_space('s') | ||
s:create_index('pk') | ||
end) | ||
end | ||
|
||
g.after_all = function() | ||
g.server:drop() | ||
end | ||
|
||
g.test_repeatable_replace = function() | ||
g.server:exec(function() | ||
local t = require('luatest') | ||
local txn_proxy = require('test.box.lua.txn_proxy') | ||
|
||
local tx1 = txn_proxy:new() | ||
tx1('box.begin()') | ||
|
||
local tx2 = txn_proxy:new() | ||
tx2('box.begin()') | ||
|
||
tx1('box.space.s:replace{0, 0}') | ||
|
||
tx2('box.space.s:replace{0, 1}') | ||
tx2('box.space.s:delete{0}') | ||
tx2('box.space.s:replace{0, 2}') | ||
|
||
tx1('box.commit()') | ||
t.assert_equals(tx2:commit(), "") | ||
end) | ||
end | ||
|
||
g.test_repeatable_insert = function() | ||
g.server:exec(function() | ||
local t = require('luatest') | ||
local txn_proxy = require('test.box.lua.txn_proxy') | ||
|
||
local tx1 = txn_proxy:new() | ||
tx1('box.begin()') | ||
|
||
local tx2 = txn_proxy:new() | ||
tx2('box.begin()') | ||
|
||
tx1('box.space.s:replace{0, 0}') | ||
|
||
tx2('box.space.s:replace{0, 1}') | ||
tx2('box.space.s:delete{0}') | ||
tx2('box.space.s:insert{0, 2}') | ||
|
||
tx1('box.commit()') | ||
t.assert_equals(tx2:commit(), "") | ||
end) | ||
end | ||
|
||
g.test_repeatable_upsert = function() | ||
g.server:exec(function() | ||
local t = require('luatest') | ||
local txn_proxy = require('test.box.lua.txn_proxy') | ||
|
||
local tx1 = txn_proxy:new() | ||
tx1('box.begin()') | ||
|
||
local tx2 = txn_proxy:new() | ||
tx2('box.begin()') | ||
|
||
tx1('box.space.s:replace{0, 0}') | ||
|
||
tx2('box.space.s:replace{0, 1}') | ||
tx2('box.space.s:delete{0}') | ||
tx2('box.space.s:upsert({0, 2}, {{"=", 2, 2}})') | ||
|
||
tx1('box.commit()') | ||
t.assert_equals(tx2:commit(), "") | ||
end) | ||
end |