Skip to content

Functional index iterator is not stable #101

@Totktonada

Description

@Totktonada

So we can crash tarantool and observe other unwanted effects. Consider tarantool/tarantool#6786 for details.

See tarantool/doc#2102 and further links for some kind of definition of the 'stable iterator' term. Say, you open an iterator by a space index, moving on it and changing something in the space. The iterator is 'stable' when it is not invalidated by the changes in the space. It always has a predictable behavior and don't lead to crash, data corruption or other undesirable effects.

The most common use case for a stable iterator is to delete tuples while iterating over a space:

for _, tuple in box.space.s.index.foo:pairs() do
    box.space.s:delete({tuple[1]})
end

However it is not the only use case.

The problem can be reproduced on a debug tarantool build. It reproduces for me on expirationd 1.1.1-44-g838c2d1 on the test_memtx_tree_functional_index test case.

$ cd /home/alex/projects/tarantool-meta/r/t-6
$ cmake . -DCMAKE_BUILD_TYPE=Debug -DENABLE_BACKTRACE=ON -DENABLE_DIST=ON -DENABLE_FEEDBACK_DAEMON=OFF -DENABLE_BUNDLED_LIBCURL=OFF && make -j
$ cd /home/alex/projects/tarantool-meta/expirationd
$ export PATH="/home/alex/projects/tarantool-meta/r/t-6/src:${PATH}"
$ luatest -c -v -p test_memtx_tree_functional_index
<...>
    custom_index.engine:"memtx".index_type:"TREE".test_memtx_tree_functional_index ... 
2022-01-15 01:59:22.159 [7804] main/110/guardian of "clean_all" I> expiration: task "clean_all" restarted
tarantool: /home/alex/p/tarantool-meta/r/t-6/src/box/tuple_compare.cc:1394: int func_index_compare(tuple*, hint_t, tuple*, hint_t, key_def*) [with bool is_nullable = false; hint_t = long unsigned int]: Assertion `mp_typeof(*key_b) == MP_ARRAY' failed.
Aborted (core dumped)

According to what I said here, a year ago we didn't lean on the tree iterator stability, so the test would likely pass. So I guess we can consider this bug as a regression. I didn't check, though.

It seems, we should switch to the old 'get batch, process, get next batch using GT iterator' iteration way for functional indexes.

It was not catched by tests before, because we have no test runs on a debug tarantool build in CI. It seems, it is must have for expirationd, where we lean on non-trivial index guarantees. I filed #102 to add testing on the debug build into CI.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingcrash

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions