From 2245ef06a82f8eb0aee092af177ab90195a52658 Mon Sep 17 00:00:00 2001 From: Andrey Saranchin <Andrey22102001@gmail.com> Date: Tue, 15 Mar 2022 15:01:01 +0300 Subject: [PATCH] txm: relax conditions for memtx_story delete Since a transaction has been prepared its garbage (produced stories and replaced tuples) cannot be deleted because they are recognized as used in read-view even if there are no transactions in read-view. This problem makes it difficult to test the memory monitoring system, so this patch solves the problem. Close #6635 Part of #6150 NO_DOC=no visible changes NO_CHANGELOG=no visible changes --- src/box/memtx_tx.c | 9 +++- .../gh_6635_garbage_of_last_prep_txn_test.lua | 41 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 test/box-luatest/gh_6635_garbage_of_last_prep_txn_test.lua diff --git a/src/box/memtx_tx.c b/src/box/memtx_tx.c index 42d8917660..dd7a9b6d24 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 0000000000..e0e225069d --- /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 -- GitLab