Skip to content
Snippets Groups Projects
Commit 46340d0f authored by Georgiy Lebedev's avatar Georgiy Lebedev Committed by Aleksandr Lyapunov
Browse files

memtx: fix rollback of prepared statements deleting MVCC stories

When we rollback a prepared statement that deletes an MVCC story, we need
to reset the deleted story's PSN.

Closes #7930

NO_DOC=bugfix

(cherry picked from commit de938a6f)
parent f9d24d6b
No related branches found
No related tags found
No related merge requests found
## bugfix/memtx
* Fixed possible loss of committed tuple after prepared transaction rollback
(gh-7930).
......@@ -2323,8 +2323,14 @@ memtx_tx_history_rollback_added_story(struct txn_stmt *stmt)
static void
memtx_tx_history_rollback_deleted_story(struct txn_stmt *stmt)
{
assert(stmt->del_story != NULL);
memtx_tx_story_unlink_deleted_by(stmt->del_story, stmt);
struct memtx_story *story = stmt->del_story;
/*
* There can be no more than one prepared statement deleting a story at
* any point in time.
*/
assert(story->del_psn == 0 || story->del_psn == stmt->txn->psn);
story->del_psn = 0;
memtx_tx_story_unlink_deleted_by(story, stmt);
}
void
......
local server = require('luatest.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,
replication_synchro_quorum = 2,
replication_synchro_timeout = 0.0001,
}
}
cg.server:start()
cg.server:exec(function()
local s = box.schema.space.create("s", {is_sync = true})
s:create_index("pk")
local as = box.schema.space.create("as")
as:create_index("pk")
box.ctl.promote()
end)
end)
g.after_all(function(cg)
cg.server:drop()
end)
-- Checks that preparation of an insert statement with an older story deleted by
-- a prepared transaction does not fail assertion.
g.test_preparation_with_deleted_older_story_assertion = function(cg)
cg.server:exec(function()
local t = require('luatest')
box.space.as:replace{0}
t.assert_error_msg_content_equals(
'Quorum collection for a synchronous transaction is timed out',
function()
box.atomic(function()
box.space.s:replace{0}
box.space.as:delete{0}
end)
end)
t.assert_equals(box.space.as:get{0}, {0})
end)
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment