memtx: do not use space_vtab::commit_alter for freeing tuples
When the last index of a memtx space is dropped, we need to delete all tuples stored in the space. We do it in space_vtab::commit_alter, but this is wrong, because this function is not rolled back and so we may get use-after-free error if we fail to write a DDL operation to WAL. To avoid that, let's delete tuples in index_vtab::commit_drop, which is called after WAL write. There's a nuance here: index_vtab::commit_drop is called if an index is rebuilt (because essentially it is drop + create) so we must elevate the reference counter of every tuple added to the new index during rebuild and, respectively, drop all the references in index_vtab::abort_create, which is called if index creation is aborted for some reason. This also means that now we iterate over all tuples twice when a primary key is rebuilt - first to build the new index, then to unreference all tuples stored in the old index. This is OK as we can make the last step asynchronous, which will also speed up the more common case of space drop. Closes #3289
Showing
- src/box/memtx_bitset.c 2 additions, 2 deletionssrc/box/memtx_bitset.c
- src/box/memtx_engine.c 47 additions, 0 deletionssrc/box/memtx_engine.c
- src/box/memtx_engine.h 12 additions, 0 deletionssrc/box/memtx_engine.h
- src/box/memtx_hash.c 2 additions, 2 deletionssrc/box/memtx_hash.c
- src/box/memtx_rtree.c 2 additions, 2 deletionssrc/box/memtx_rtree.c
- src/box/memtx_space.c 7 additions, 38 deletionssrc/box/memtx_space.c
- src/box/memtx_tree.c 2 additions, 2 deletionssrc/box/memtx_tree.c
- test/box/errinj.result 66 additions, 0 deletionstest/box/errinj.result
- test/box/errinj.test.lua 17 additions, 0 deletionstest/box/errinj.test.lua
Loading
Please register or sign in to comment