Skip to content

vinyl: rollback may cause duplicate in secondary index with deferred deletes #11969

@drewdzzz

Description

@drewdzzz

Consider the script:

-- Cleanup.
os.execute('rm 00*')

fiber = require('fiber')

box.cfg{vinyl_defer_deletes=true}

box.schema.space.create("test", {engine = 'vinyl'})
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:insert{1, 1}
box.space.test:insert{2, 2}

-- block WAL queue
box.cfg{wal_queue_max_size=1}
box.begin()
	box.space.test:insert{10000, 10000}
box.error.injection.set('ERRINJ_WAL_DELAY', true)
box.commit({wait='none'})

-- Delete tuple with secondary key `2`. It will be rolled back due to WAL error.
f1 = fiber.create(function()
	box.space.test:delete(2)
end)
f1:set_joinable(true)

-- Write a tuple with secondary key `2`.
f2 = fiber.create(function()
	box.begin()
		box.space.test:replace{1, 2}
		fiber.sleep(2)
	box.commit()
end)
f2:set_joinable(true)

box.error.injection.set('ERRINJ_WAL_IO', true)
box.error.injection.set('ERRINJ_WAL_DELAY', false)

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

box.error.injection.set('ERRINJ_WAL_IO', false)

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

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

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

The result:

f2: 	true	nil
---
- [1, 2]
- [2, 2]
- [10000, 10000]
...

We observe a duplicate in unique index!

(Actually, this is adaptation of #11660 for vinyl).

Metadata

Metadata

Assignees

Labels

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

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions