Skip to content

Assertion on two DDL of the same space in a row and WAL failure #11833

@nshy

Description

@nshy

Found in 3.6.0-entrypoint-8-g61b744cbc5.

Found by fuzzer and moved here from #10082 (comment).

Currently if there is a uncommitted DDL in the space the second DDL into the same space will wait for the first to be committed (see AlterYieldGuard). Now if there is WAL failure then changes in _space done by the first DDL will be rolled back but the _space already has changes from the second DDL which is unexpected.

Note that simply failing second DDL does not work due to current state of applier - see fee8c5d commit message.

Reproducer:

local fiber = require('fiber')
os.execute('rm -rf *.snap *.xlog')
box.cfg{log_level = 'warn'}

local s = box.schema.create_space('test', {format = {
    {'a', 'unsigned'},
    {'b', 'unsigned'},
}})
s:create_index('pk')

local errinj = box.error.injection
errinj.set('ERRINJ_WAL_DELAY', true)

-- Change format in _space and wait it to be written to WAL.
fiber.create(function()
    s:format({
        {'a', 'unsigned'},
        {'b', 'unsigned', is_nullable = true},
    })
end)

-- Change format in _space and wait for the first change to complete.
fiber.create(function()
    s:format({
        {'a', 'unsigned'},
        {'b', 'unsigned'},
    })
end)

-- WAL write failed so rollback in _space is done for the format
-- change from the first fiber which breaks change order.
errinj.set('ERRINJ_WAL_WRITE', true)
errinj.set('ERRINJ_WAL_DELAY', false)

os.exit()

Result:

$ ./build-dev/src/tarantool test.lua
2025-09-12 10:35:09.359 [354911] wal/101/main xlog.c:1253 E> Error injection 'xlog write injection' {"type":"ClientError","code":8,"name":"INJECTION","details":"xlog write injection","trace":[{"file":"./src/box/xlog.c","line":1253}]}
2025-09-12 10:35:09.359 [354911] main index.cc:298 E> Duplicate key exists in unique index "primary" in space "_space" with old tuple - [512, 1, "test", "memtx", 0, {}, [{"name": "a", "type": "unsigned"}, {"name": "b", "type": "unsigned"}]] and new tuple - [512, 1, "test", "memtx", 0, {}, [{"name": "a", "type": "unsigned"}, {"name": "b", "type": "unsigned"}]] {"type":"ClientError","code":3,"name":"TUPLE_FOUND","index":"primary","space":"_space","old_tuple":[512, 1, "test", "memtx", 0, {}, [{"name": "a", "type": "unsigned"}, {"name": "b", "type": "unsigned"}]],"new_tuple":[512, 1, "test", "memtx", 0, {}, [{"name": "a", "type": "unsigned"}, {"name": "b", "type": "unsigned"}]],"trace":[{"file":"./src/box/index.cc","line":298}]}
tarantool: ./src/box/memtx_engine.cc:865: void memtx_engine_rollback_statement(engine*, txn*, txn_stmt*): Assertion `0' failed.
Aborted                    (core dumped) ./build-dev/src/tarantool test.lua

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingddl

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions