vinyl: don't produce deferred DELETE on commit if key isn't updated
Consider the following example: s = box.schema.space.create('test', {engine = 'vinyl'}) s:create_index('primary') s:create_index('secondary', {parts = {2, 'unsigned'}}) s:insert{1, 1, 1} s:replace{1, 1, 2} When REPLACE{1,1} is committed to the secondary index, the overwritten tuple, i.e. INSERT{1,1}, is found in the primary index memory, and so deferred DELETE{1,1} is generated right away and committed along with REPLACE{1,1}. However, there's no need to commit anything to the secondary index in this case, because its key isn't updated. Apart from eating memory and loading disk, this also breaks index stats, as vy_tx implementation doesn't expect two statements committed for the same key in a single transaction. Fix this by checking if there's a statement in the log for the deleted key and if there's skipping them both as we do in the regular case, see the comment in vy_tx_set. Closes #3693
Showing
- src/box/vy_tx.c 18 additions, 0 deletionssrc/box/vy_tx.c
- test/vinyl/deferred_delete.result 78 additions, 0 deletionstest/vinyl/deferred_delete.result
- test/vinyl/deferred_delete.test.lua 26 additions, 0 deletionstest/vinyl/deferred_delete.test.lua
- test/vinyl/quota.result 1 addition, 1 deletiontest/vinyl/quota.result
- test/vinyl/stat.result 3 additions, 3 deletionstest/vinyl/stat.result
- test/vinyl/stat.test.lua 1 addition, 1 deletiontest/vinyl/stat.test.lua
- test/vinyl/write_iterator.result 1 addition, 1 deletiontest/vinyl/write_iterator.result
- test/vinyl/write_iterator.test.lua 1 addition, 1 deletiontest/vinyl/write_iterator.test.lua
Loading
Please register or sign in to comment