From: Ilya Kosarev <i.kosarev@tarantool.org> To: tarantool-patches@dev.tarantool.org Cc: v.shpilevoy@tarantool.org Subject: [Tarantool-patches] [PATCH v4 4/4] test: add tests for truncation and deletion Date: Fri, 14 Feb 2020 22:39:46 +0300 [thread overview] Message-ID: <ed190902e77476dc2cd03ef032ae74f0a4cbd455.1581705033.git.i.kosarev@tarantool.org> (raw) In-Reply-To: <cover.1581705033.git.i.kosarev@tarantool.org> In-Reply-To: <cover.1581705033.git.i.kosarev@tarantool.org> Trying to perform space:truncate() and space:delete() while reaching memtx_memory limit we could experience slab allocator failure. Now it is solved through quota overuse tech. This commit introduces corresponding tests. Part of #3807 --- src/box/memtx_space.c | 15 +++- src/lib/core/errinj.h | 1 + test/box/errinj.result | 1 + test/engine/engine.cfg | 6 ++ test/engine/low_memory.lua | 8 ++ test/engine/stress_delete.result | 111 +++++++++++++++++++++++++++ test/engine/stress_delete.test.lua | 55 +++++++++++++ test/engine/stress_truncate.result | 103 +++++++++++++++++++++++++ test/engine/stress_truncate.test.lua | 52 +++++++++++++ 9 files changed, 349 insertions(+), 3 deletions(-) create mode 100644 test/engine/low_memory.lua create mode 100644 test/engine/stress_delete.result create mode 100644 test/engine/stress_delete.test.lua create mode 100644 test/engine/stress_truncate.result create mode 100644 test/engine/stress_truncate.test.lua diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c index 3542450f7..2ce09018d 100644 --- a/src/box/memtx_space.c +++ b/src/box/memtx_space.c @@ -261,9 +261,18 @@ memtx_space_replace_all_keys(struct space *space, struct tuple *old_tuple, * Ensure we have enough slack memory to guarantee * successful statement-level rollback. */ - if (memtx_index_extent_reserve(memtx, new_tuple != NULL ? - RESERVE_EXTENTS_BEFORE_REPLACE : - RESERVE_EXTENTS_BEFORE_DELETE) != 0) + int reserve_extents_num = new_tuple != NULL ? + RESERVE_EXTENTS_BEFORE_REPLACE : + RESERVE_EXTENTS_BEFORE_DELETE; + ERROR_INJECT(ERRINJ_RESERVE_EXTENTS_BEFORE_DELETE, { + /** + * Set huge number of needed reserved extents to + * provoke delete failure. + */ + if (new_tuple == NULL) + reserve_extents_num = memtx->num_reserved_extents + 1; + }); + if (memtx_index_extent_reserve(memtx, reserve_extents_num) != 0) return -1; uint32_t i = 0; diff --git a/src/lib/core/errinj.h b/src/lib/core/errinj.h index 672da2119..2d3331cfa 100644 --- a/src/lib/core/errinj.h +++ b/src/lib/core/errinj.h @@ -135,6 +135,7 @@ struct errinj { _(ERRINJ_COIO_SENDFILE_CHUNK, ERRINJ_INT, {.iparam = -1}) \ _(ERRINJ_SWIM_FD_ONLY, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_DYN_MODULE_COUNT, ERRINJ_INT, {.iparam = 0}) \ + _(ERRINJ_RESERVE_EXTENTS_BEFORE_DELETE, ERRINJ_BOOL, {.bparam = false}) \ ENUM0(errinj_id, ERRINJ_LIST); extern struct errinj errinjs[]; diff --git a/test/box/errinj.result b/test/box/errinj.result index f043c6689..1f99470e3 100644 --- a/test/box/errinj.result +++ b/test/box/errinj.result @@ -63,6 +63,7 @@ evals - ERRINJ_RELAY_SEND_DELAY: false - ERRINJ_RELAY_TIMEOUT: 0 - ERRINJ_REPLICA_JOIN_DELAY: false + - ERRINJ_RESERVE_EXTENTS_BEFORE_DELETE: false - ERRINJ_SIO_READ_MAX: -1 - ERRINJ_SNAP_COMMIT_DELAY: false - ERRINJ_SNAP_WRITE_DELAY: false diff --git a/test/engine/engine.cfg b/test/engine/engine.cfg index f1e7de274..c8c6fb130 100644 --- a/test/engine/engine.cfg +++ b/test/engine/engine.cfg @@ -5,6 +5,12 @@ }, "func_index.test.lua": { "memtx": {"engine": "memtx"} + }, + "stress_delete.test.lua": { + "memtx": {"engine": "memtx"} + }, + "stress_truncate.test.lua": { + "memtx": {"engine": "memtx"} } } diff --git a/test/engine/low_memory.lua b/test/engine/low_memory.lua new file mode 100644 index 000000000..46fd26d1b --- /dev/null +++ b/test/engine/low_memory.lua @@ -0,0 +1,8 @@ +#!/usr/bin/env tarantool +os = require('os') +box.cfg({ + listen = os.getenv("LISTEN"), + memtx_memory = 32 * 1024 * 1024, +}) + +require('console').listen(os.getenv('ADMIN')) diff --git a/test/engine/stress_delete.result b/test/engine/stress_delete.result new file mode 100644 index 000000000..bf92c780b --- /dev/null +++ b/test/engine/stress_delete.result @@ -0,0 +1,111 @@ +-- test-run result file version 2 +test_run = require('test_run').new() + | --- + | ... + + +test_run:cmd("create server master with script='engine/low_memory.lua'") + | --- + | - true + | ... +test_run:cmd('start server master') + | --- + | - true + | ... +test_run:cmd("switch master") + | --- + | - true + | ... + + +test_run:cmd("setopt delimiter ';'") + | --- + | - true + | ... +function create_space(name) + local space = box.schema.create_space(name) + space:format({ + { name = "id", type = "unsigned" }, + { name = "val", type = "str" } + }) + space:create_index('primary', { parts = { 'id' } }) + return space +end; + | --- + | ... + +function insert(space, i) + space:insert({ i, string.rep(string.char(32 + math.random(127-32)), math.random(1024)) }) +end; + | --- + | ... + +function fill_space(space, start) + local _, err = nil + local i = start + while err == nil do _, err = pcall(insert, space, i) i = i + 1 end +end; + | --- + | ... + +function stress_deletion(i, spaces) + local res, space = pcall(create_space, 'test' .. tostring(i)) + if res then spaces[i] = space return end + fill_space(box.space.test, box.space.test:len()) + for _, s in pairs(spaces) do fill_space(s, s:len()) end + box.space.test:delete(box.space.test:len() - 1) +end; + | --- + | ... +test_run:cmd("setopt delimiter ''"); + | --- + | - true + | ... + + +_ = create_space('test') + | --- + | ... +for i = 0, 27000 do insert(box.space.test, i) end + | --- + | ... + +spaces = {} + | --- + | ... +counter = 0 + | --- + | ... +status = true + | --- + | ... +res = nil + | --- + | ... +errinj = box.error.injection + | --- + | ... +errinj.set('ERRINJ_RESERVE_EXTENTS_BEFORE_DELETE', true) + | --- + | - ok + | ... +while counter < 1400 do status, res = pcall(stress_deletion, counter, spaces) counter = counter + 1 end + | --- + | ... +status + | --- + | - true + | ... +res + | --- + | - null + | ... + +-- Cleanup. +test_run:cmd('switch default') + | --- + | - true + | ... +test_run:drop_cluster({'master'}) + | --- + | ... diff --git a/test/engine/stress_delete.test.lua b/test/engine/stress_delete.test.lua new file mode 100644 index 000000000..b9014ece5 --- /dev/null +++ b/test/engine/stress_delete.test.lua @@ -0,0 +1,55 @@ +test_run = require('test_run').new() + + +test_run:cmd("create server master with script='engine/low_memory.lua'") +test_run:cmd('start server master') +test_run:cmd("switch master") + + +test_run:cmd("setopt delimiter ';'") +function create_space(name) + local space = box.schema.create_space(name) + space:format({ + { name = "id", type = "unsigned" }, + { name = "val", type = "str" } + }) + space:create_index('primary', { parts = { 'id' } }) + return space +end; + +function insert(space, i) + space:insert({ i, string.rep(string.char(32 + math.random(127-32)), math.random(1024)) }) +end; + +function fill_space(space, start) + local _, err = nil + local i = start + while err == nil do _, err = pcall(insert, space, i) i = i + 1 end +end; + +function stress_deletion(i, spaces) + local res, space = pcall(create_space, 'test' .. tostring(i)) + if res then spaces[i] = space return end + fill_space(box.space.test, box.space.test:len()) + for _, s in pairs(spaces) do fill_space(s, s:len()) end + box.space.test:delete(box.space.test:len() - 1) +end; +test_run:cmd("setopt delimiter ''"); + + +_ = create_space('test') +for i = 0, 27000 do insert(box.space.test, i) end + +spaces = {} +counter = 0 +status = true +res = nil +errinj = box.error.injection +errinj.set('ERRINJ_RESERVE_EXTENTS_BEFORE_DELETE', true) +while counter < 1400 do status, res = pcall(stress_deletion, counter, spaces) counter = counter + 1 end +status +res + +-- Cleanup. +test_run:cmd('switch default') +test_run:drop_cluster({'master'}) diff --git a/test/engine/stress_truncate.result b/test/engine/stress_truncate.result new file mode 100644 index 000000000..3e2573021 --- /dev/null +++ b/test/engine/stress_truncate.result @@ -0,0 +1,103 @@ +-- test-run result file version 2 +test_run = require('test_run').new() + | --- + | ... + + +test_run:cmd("create server master with script='engine/low_memory.lua'") + | --- + | - true + | ... +test_run:cmd('start server master') + | --- + | - true + | ... +test_run:cmd("switch master") + | --- + | - true + | ... + + +test_run:cmd("setopt delimiter ';'") + | --- + | - true + | ... +function create_space(name) + local space = box.schema.create_space(name) + space:format({ + { name = "id", type = "unsigned" }, + { name = "val", type = "str" } + }) + space:create_index('primary', { parts = { 'id' } }) + return space +end; + | --- + | ... + +function insert(space, i) + space:insert({ i, string.rep(string.char(32 + math.random(127-32)), math.random(1024)) }) +end; + | --- + | ... + +function fill_space(space, start) + local _, err = nil + local i = start + while err == nil do _, err = pcall(insert, space, i) i = i + 1 end +end; + | --- + | ... + +function stress_truncation(i, spaces) + local res, space = pcall(create_space, 'test' .. tostring(i)) + if res then spaces[i] = space return end + fill_space(box.space.test, box.space.test:len()) + for _, s in pairs(spaces) do s:truncate() end +end; + | --- + | ... +test_run:cmd("setopt delimiter ''"); + | --- + | - true + | ... + + +_ = create_space('test') + | --- + | ... +for i = 0, 27000 do insert(box.space.test, i) end + | --- + | ... + +spaces = {} + | --- + | ... +counter = 0 + | --- + | ... +status = true + | --- + | ... +res = nil + | --- + | ... +while counter < 1400 do status, res = pcall(stress_truncation, counter, spaces) counter = counter + 1 end + | --- + | ... +status + | --- + | - true + | ... +res + | --- + | - null + | ... + +-- Cleanup. +test_run:cmd('switch default') + | --- + | - true + | ... +test_run:drop_cluster({'master'}) + | --- + | ... diff --git a/test/engine/stress_truncate.test.lua b/test/engine/stress_truncate.test.lua new file mode 100644 index 000000000..83abd3d11 --- /dev/null +++ b/test/engine/stress_truncate.test.lua @@ -0,0 +1,52 @@ +test_run = require('test_run').new() + + +test_run:cmd("create server master with script='engine/low_memory.lua'") +test_run:cmd('start server master') +test_run:cmd("switch master") + + +test_run:cmd("setopt delimiter ';'") +function create_space(name) + local space = box.schema.create_space(name) + space:format({ + { name = "id", type = "unsigned" }, + { name = "val", type = "str" } + }) + space:create_index('primary', { parts = { 'id' } }) + return space +end; + +function insert(space, i) + space:insert({ i, string.rep(string.char(32 + math.random(127-32)), math.random(1024)) }) +end; + +function fill_space(space, start) + local _, err = nil + local i = start + while err == nil do _, err = pcall(insert, space, i) i = i + 1 end +end; + +function stress_truncation(i, spaces) + local res, space = pcall(create_space, 'test' .. tostring(i)) + if res then spaces[i] = space return end + fill_space(box.space.test, box.space.test:len()) + for _, s in pairs(spaces) do s:truncate() end +end; +test_run:cmd("setopt delimiter ''"); + + +_ = create_space('test') +for i = 0, 27000 do insert(box.space.test, i) end + +spaces = {} +counter = 0 +status = true +res = nil +while counter < 1400 do status, res = pcall(stress_truncation, counter, spaces) counter = counter + 1 end +status +res + +-- Cleanup. +test_run:cmd('switch default') +test_run:drop_cluster({'master'}) -- 2.17.1
next prev parent reply other threads:[~2020-02-14 19:39 UTC|newest] Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-02-14 19:39 [Tarantool-patches] [PATCH v4 0/4] Safe " Ilya Kosarev 2020-02-14 19:39 ` [Tarantool-patches] [PATCH v4 1/4] small: bump small version Ilya Kosarev 2020-02-14 19:39 ` [Tarantool-patches] [PATCH v4 2/4] b-tree: return NULL on matras_alloc fail Ilya Kosarev 2020-02-14 23:50 ` Vladislav Shpilevoy 2020-02-14 19:39 ` [Tarantool-patches] [PATCH v4 3/4] memtx: allow quota overuse for truncation and deletion Ilya Kosarev 2020-02-14 23:50 ` Vladislav Shpilevoy 2020-02-14 19:39 ` Ilya Kosarev [this message] 2020-02-14 23:50 ` [Tarantool-patches] [PATCH v4 4/4] test: add tests " Vladislav Shpilevoy 2020-02-14 21:00 ` [Tarantool-patches] [PATCH v4 0/4] Safe " Konstantin Osipov 2020-02-14 21:12 ` Ilya Kosarev
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=ed190902e77476dc2cd03ef032ae74f0a4cbd455.1581705033.git.i.kosarev@tarantool.org \ --to=i.kosarev@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v4 4/4] test: add tests for truncation and deletion' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox