Skip to content

memtx transaction manager MVCC tuple story list invariant violation #7490

@CuriousGeorgiy

Description

@CuriousGeorgiy

Bug description

Consider the following fair assertion:

diff --git a/src/box/memtx_tx.c b/src/box/memtx_tx.c
index 2b858944b..362b80fbe 100644
--- a/src/box/memtx_tx.c
+++ b/src/box/memtx_tx.c
@@ -1234,6 +1234,7 @@ memtx_tx_story_full_unlink(struct memtx_story *story)
 			if (story->del_psn > 0 && link->in_index != NULL) {
 				struct index *index = link->in_index;
 				struct tuple *removed, *unused;
+				assert(link->older_story == NULL);
 				if (index_replace(index, story->tuple, NULL,
 						  DUP_INSERT,
 						  &removed, &unused) != 0) {

It asserts the invariant that the top of the MVCC tuple story chain is always in the index: when fully unlinking a story we delete (sic: not replace) a tuple from the index, it must be the last story left in the history chain.

Steps to reproduce

os.execute('rm -rf *.snap *.xlog *.vylog 512')

local ffi = require('ffi')
local json = require('json')
local log = require('log')
local txn_proxy = require('txn_proxy')

box.cfg{memtx_use_mvcc_engine = true}

local s = box.schema.space.create('s')
s:create_index('pk')

box.internal.memtx_tx_gc(100)

box.space.s:insert{0, 0}

local tx = txn_proxy:new()

tx:begin()
tx('box.space.s:select{0}')
s:replace{0, 1}
tx:commit()
s:delete{0}

box.internal.memtx_tx_gc(100)

os.exit()

Actual behavior

Assertion failed: (link->older_story == NULL), function memtx_tx_story_full_unlink, file memtx_tx.c, line 1240.

Expected behavior

Script successfully exits.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions