diff --git a/src/box/memtx_tx.c b/src/box/memtx_tx.c index 42d8917660a013009ffc87e2e504e65855fa8940..dd7a9b6d2405c17997f706ac7c7d407e8f8e7ce6 100644 --- a/src/box/memtx_tx.c +++ b/src/box/memtx_tx.c @@ -924,8 +924,13 @@ memtx_tx_story_gc_step() return; } - /* Lowest read view PSN */ - int64_t lowest_rv_psn = txn_last_psn; + /* + * Lowest read view PSN. + * Default value is more than txn_last_psn because if it is not so some + * stories (stories produced by last txn at least) will be marked as + * potentially in read view even though there are no txns in read view. + */ + int64_t lowest_rv_psn = txn_last_psn + 1; if (!rlist_empty(&txm.read_view_txs)) { struct txn *txn = rlist_first_entry(&txm.read_view_txs, struct txn, diff --git a/test/box-luatest/gh_6635_garbage_of_last_prep_txn_test.lua b/test/box-luatest/gh_6635_garbage_of_last_prep_txn_test.lua new file mode 100644 index 0000000000000000000000000000000000000000..e0e225069db322f127a64aa980e0e4c2ea0df9a1 --- /dev/null +++ b/test/box-luatest/gh_6635_garbage_of_last_prep_txn_test.lua @@ -0,0 +1,41 @@ +local server = require('test.luatest_helpers.server') +local t = require('luatest') + +local g = t.group() + +g.before_all = function() + g.server = server:new{ + alias = 'default', + box_cfg = {memtx_use_mvcc_engine = true} + } + g.server:start() +end + +g.after_all = function() + g.server:drop() +end + +g.test_garbage_of_last_prepared_txn_cannot_be_deleted = function() + g.server:exec(function() + local t = require('luatest') + + local s = box.schema.create_space('test') + s:create_index('pk') + + -- Collect garbage before replacing tuples + box.internal.memtx_tx_gc(10) + collectgarbage('collect') + + s:replace{0, string.rep('a', 1100)} + box.internal.memtx_tx_gc(10) + collectgarbage('collect') + local items_used_with_huge_tuple = box.slab.info()['items_used'] + + s:replace{0, 1} + box.internal.memtx_tx_gc(10) + collectgarbage('collect') + local items_used_without_huge_tuple = box.slab.info()['items_used'] + t.assert_lt(items_used_without_huge_tuple, items_used_with_huge_tuple) + t.assert_ge(items_used_with_huge_tuple - items_used_without_huge_tuple, 1000) + end) +end