tarantool icon indicating copy to clipboard operation
tarantool copied to clipboard

DDL transaction abort unrelated transactions

Open godzie44 opened this issue 1 year ago • 0 comments

Bug description

Basically we observe that creating temporary space on replica forces <space_object>:format(<my new format>) to fail with transaction has been aborted by error. The reason of this error that one DDL transaction abort another DDL transaction without any reason (this is totaly independent transactions.

  • OS: Linux
  • OS Version: Ubuntu 22.04
  • Architecture: amd64

2.11.3-entrypoint-40-gc2e104c53b

Steps to reproduce

Run two tarantool instances iteractively.

  1. tarantool instanceA.lua
  2. tarantool instanceB.lua

instanceA.lua:

local fiber = require('fiber')
local log = require('log')

box.cfg{
    listen = '0.0.0.0:3301',
    replication = { 'localhost:3301', 'localhost:3302' },
    log = 'instanceA.log'
}

box.once('grant guest', function() 
    box.schema.user.grant('guest', 'read,write,execute', 'universe')
end)

local format = {
    { name = 'field_1', type = 'unsigned' },
    { name = 'field_2',   type = 'string', is_nullable = true },
}    

local new_format = {
    { name = 'field_1', type = 'unsigned' },
    { name = 'field_2',   type = 'string', is_nullable = true },
    { name = 'field_3',   type = 'string', is_nullable = true },
}

local function alter_format()
    local space_a = box.space.A
    space_a:format(new_format)
    space_a:format(format)
end

local function create_space(space_name)
    local opts = {
        engine = 'memtx',
        format = format,
    }    

    local space = box.schema.space.create(space_name, opts)
    space:create_index(
        'primary',
        {
            unique = true,
            parts = {
                { field = 'field_1', type = 'unsigned' }
            }    
        }    
    )    
end    

local function fill_space(space_name)
    local iterations = 1000000
    local space = box.space[space_name]
    for i = 1, iterations, 1 do
        space:insert({ i, 'string' })
    end        
end    

create_space('A')
fill_space('A')

while true do
    local status, res = pcall(alter_format)
    if status ~= true then
        log.error('Error occured: '..res)
    end
end

instanceB.lua:

local fiber = require('fiber')
local log = require('log')
local uuid = require('uuid')

box.cfg{
    listen = '0.0.0.0:3302',
    replication = { 'localhost:3301', 'localhost:3302' },
    log = 'instanceB.log'
}

box.once('grant guest', function() 
    box.schema.user.grant('guest', 'read,write,execute', 'universe')
end)


local function create_space()
    local space_name = uuid:str()
    local space = box.schema.space.create(space_name..'_TMP', { type = 'temporary' })
    space:drop()
end

while true do
    local status, res = pcall(create_space)
    if status ~= true then
        log.error('Error occured: '..res)
    end

    fiber.sleep(0.1)
end

Actual behavior

2024-02-13 23:35:15.661 [50329] main/103/instanceB.lua memtx_tx.c:697 W> Transaction committing DDL (id=2001465) has aborted another TX (id=2001464)
2024-02-13 23:35:16.033 [50329] main/110/applier/localhost:3301 I> can't read row
2024-02-13 23:35:16.033 [50329] main/110/applier/localhost:3301 txn.h:566 E> ER_TRANSACTION_CONFLICT: Transaction has been aborted by conflict

Expected behavior

Cause space at instance B not depend on any space at instance A i'm expect that there is no conflicts here.

godzie44 avatar Feb 15 '24 13:02 godzie44