Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

driver: possible data races in kick method #231

Open
4 tasks
DerekBum opened this issue May 14, 2024 · 0 comments
Open
4 tasks

driver: possible data races in kick method #231

DerekBum opened this issue May 14, 2024 · 0 comments
Labels
2sp bug Something isn't working

Comments

@DerekBum
Copy link
Contributor

DerekBum commented May 14, 2024

kick method is used to unbury several tasks in the tube. After analyzing this method for drivers fifo, fifottl, utube, utubettl, I came to the conclusion, that it still possible to get a data race and incorrect, unexpected result.

-- unbury several tasks
function method.kick(self, count)
for i = 1, count do
local task = self.space.index.status:min{ state.BURIED }
if task == nil then
return i - 1
end
if task[2] ~= state.BURIED then
return i - 1
end
task = self.space:update(task[1], {{ '=', 2, state.READY }})
self.on_task_change(task, 'kick')
end
return count
end

We take a task with minimal task_id and BURIED status. After that we are updating it, commiting. But lua can also yield before WAL write. So this very task could also be taken in a parallel kick call for the second time.

Possible fix: do changes inside a transaction, like in put, take methods. But there is a subtle point here (which is described in a comment below).

-- Taking the minimum is an implicit transactions, so it is
-- always done with 'read-confirmed' mvcc isolation level.
-- It can lead to errors when trying to make parallel 'take' calls with mvcc enabled.
-- It is hapenning because 'min' for several takes in parallel will be the same since
-- read confirmed isolation level makes visible all transactions that finished the commit.
-- To fix it we wrap it with box.begin/commit and set right isolation level.
-- Current fix does not resolve that bug in situations when we already are in transaction
-- since it will open nested transactions.
-- See https://github.com/tarantool/queue/issues/207
-- See https://www.tarantool.io/ru/doc/latest/concepts/atomic/txn_mode_mvcc/
if box.cfg.memtx_use_mvcc_engine and (not box.is_in_txn()) then
box.begin({txn_isolation = 'read-committed'})
task = self.space.index.status:min{state.READY}
box.commit()
else
task = self.space.index.status:min{state.READY}
end

Tasks

@DerekBum DerekBum added the bug Something isn't working label May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2sp bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants