Description
Related dev. issue(s): tarantool/tarantool#1944
Product: Tarantool
Since: always
Audience/target: users
Root document: https://www.tarantool.io/en/doc/latest/book/box/engines/memtx_vinyl_diff/
SME: @ locker @ alyapunov @ Mons
Details
There's a documentation page that enumerates differences between memtx and vinyl engines. We need to mention that starting from 2.6.1 memtx supports MVCC (aka yields in transactions) provided the box.cfg.memtx_use_mvcc_engine
is set. Vinyl has always supported MVCC.
We also need to describe differences between memtx and vinyl implementations of MVCC. There's the only difference known so far: how tracking non-existing/deleted keys is implemented. Let's assume that one transaction reads a range of keys using select
and yields. During the yield, another transaction deletes a key that doesn't exist in the index from the range using delete
. The delete
would abort the first transaction in vinyl, but wouldn't abort it in memtx. In particular, if a transaction reads a single key that doesn't exist in the index, then deleting the key in another transaction would abort it in vinyl, but not in memtx.
Example:
local net = require('net.box')
box.cfg{
listen = 3301,
log_level = 'warn',
memtx_use_mvcc_engine = true,
}
box.once('init', function()
box.schema.user.grant('guest', 'super')
box.schema.create_space('memtx', {engine = 'memtx'})
box.space.memtx:create_index('primary')
box.schema.create_space('vinyl', {engine = 'vinyl'})
box.space.vinyl:create_index('primary')
end)
box.space.memtx:truncate()
box.space.vinyl:truncate()
local conn = net.connect('localhost:3301')
local stream = conn:new_stream()
stream:begin()
stream.space.memtx:get{1}
stream.space.memtx:replace{2}
box.space.memtx:delete{1}
local ok, err = pcall(stream.commit, stream)
print(string.format("memtx: %s", ok and 'Success' or tostring(err)))
stream:begin()
stream.space.vinyl:get{1}
stream.space.vinyl:replace{2}
box.space.vinyl:delete{1}
local ok, err = pcall(stream.commit, stream)
print(string.format("vinyl: %s", ok and 'Success' or tostring(err)))
os.exit(0)
Output:
memtx: Success
vinyl: Transaction has been aborted by conflict
The issue is closely related to another memtx vs vinyl difference: in memtx delete
returns the deleted tuple while in vinyl it doesn't, because it may not know if a tuple was actually deleted - it just writes a "delete" statement to the index without reading the key.
Definition of done
- Added MVCC / yields in transactions entry to the memtx vs vinyl comparison table.
- Described differences between memtx and vinyl transaction managers.
Planning checklist
- Pick product label:
- Pick type label:
- reference,
- getting started,
- user_guide, etc.
- Estimate complexity in storypoints in the title
- Add to Documentation board → Backlog