Skip to content

mvcc: insert-after-delete in single transaction may cause duplicates in secondary indexes #11686

@Astronomax

Description

@Astronomax

Bug description

Transaction with is_own_change = true may result in duplicate.

This check skips the second transaction, considering that it cannot lead to duplicates. But it's wrong.

tarantool/src/box/memtx_tx.c

Lines 2841 to 2843 in e6ec4aa

if (test_stmt->is_own_change &&
test_stmt->del_story == NULL)
continue;

Steps to reproduce

Run the following reproducer.lua script:

fiber = require('fiber')

box.cfg{memtx_use_mvcc_engine=true}

box.schema.space.create("test")
box.space.test:format{{'a', type='unsigned'}, {'b', type='unsigned'}}
box.space.test:create_index("pk", {parts={{'a'}}})
box.space.test:create_index("sk", {parts={{'b'}}, unique=true})

box.space.test:truncate()

f1 = fiber.create(function()
	box.begin()
	box.space.test:replace{1, 3}
	fiber.sleep(1)
	box.commit()
end)
f1:set_joinable(true)

f2 = fiber.create(function()
	box.begin()
	box.space.test:replace{4, 4}
	box.space.test:delete{4}
	box.space.test:replace{4, 3}
	fiber.sleep(2)
	box.commit()
end)
f2:set_joinable(true)

local ok, err = f1:join()
print(ok, err)

ok, err = f2:join()
print(ok, err)

print(require('yaml').encode(box.space.test:select{}))

box.space.test:drop()
os.exit()

How to run:

$ tarantool -i reproducer.lua

Actual output:

---
- [1, 3]
- [4, 3]
...

Actual behavior

Duplicates appear in secondary index.

Expected behavior

No duplicates appear in secondary index (the second transaction must be rolled back).

Metadata

Metadata

Assignees

Labels

3.2Target is 3.2 and all newer release/master branchesbugSomething isn't workingmvcc

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions