From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Subject: [tarantool-patches] [PATCH 1/1] vinyl: fix crash in vinyl_iterator_secondary_next Date: Sat, 12 May 2018 02:24:41 +0300 [thread overview] Message-ID: <dff067540ee7081cc4e488f283b7475f72b0c937.1526080999.git.v.shpilevoy@tarantool.org> (raw) Vinyl_iterator_secondary_next is a method to iterate over a secondary index. It gets a tuple from the secondary index and looks up its full version in the primary index. But during lookup the tuple can be deleted from the former, and the iterator must take it in the hopper. Closes #3393 --- Branch: https://github.com/tarantool/tarantool/tree/gh-3393-vinyl-iterator-crash Issue: https://github.com/tarantool/tarantool/issues/3393 src/box/vinyl.c | 8 ++++- test/vinyl/errinj.result | 73 ++++++++++++++++++++++++++++++++++++++++++++++ test/vinyl/errinj.test.lua | 26 +++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/box/vinyl.c b/src/box/vinyl.c index ff4c28314..460b9b5e7 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -3853,7 +3853,7 @@ vinyl_iterator_secondary_next(struct iterator *base, struct tuple **ret) goto fail; } - +next_tuple: if (vy_read_iterator_next(&it->iterator, &tuple) != 0) goto fail; @@ -3879,6 +3879,12 @@ vinyl_iterator_secondary_next(struct iterator *base, struct tuple **ret) if (vy_point_lookup(it->lsm->pk, it->tx, vy_tx_read_view(it->tx), tuple, &tuple) != 0) goto fail; + /* + * The tuple can be removed by the same transaction during + * primary index lookup. + */ + if (tuple == NULL) + goto next_tuple; *ret = tuple_bless(tuple); tuple_unref(tuple); if (*ret != NULL) diff --git a/test/vinyl/errinj.result b/test/vinyl/errinj.result index fd21f7bb4..b63d01c18 100644 --- a/test/vinyl/errinj.result +++ b/test/vinyl/errinj.result @@ -1395,3 +1395,76 @@ s:count() -- 200 s:drop() --- ... +-- +-- gh-3393: vinyl secondary index iterator must take in the hopper +-- that a tuple can disappear from the primary index after the +-- secondary index lookup. +-- +s = box.schema.create_space('test', {engine = 'vinyl'}) +--- +... +pk = s:create_index('pk') +--- +... +sk = s:create_index('sk', {parts = {{2, 'unsigned'}, {1, 'unsigned'}}}) +--- +... +s:replace{1, 2} +--- +- [1, 2] +... +s:replace{3, 4} +--- +- [3, 4] +... +box.snapshot() +--- +- ok +... +ret = nil +--- +... +function iterate(i) ret = i.next() end +--- +... +box.begin() +--- +... +s:replace{5, 6} -- Start a transaction in the engine. +--- +- [5, 6] +... +iter = create_iterator(sk, {4}, {iterator = 'GE'}) +--- +... +errinj.set("ERRINJ_VY_DELAY_PK_LOOKUP", true) +--- +- ok +... +f = fiber.create(iterate, iter) +--- +... +s:delete{3} +--- +... +errinj.set("ERRINJ_VY_DELAY_PK_LOOKUP", false) +--- +- ok +... +while not ret do fiber.sleep(0.1) end +--- +... +ret +--- +- [5, 6] +... +iter.iterate_over() +--- +- [] +... +box.commit() +--- +... +s:drop() +--- +... diff --git a/test/vinyl/errinj.test.lua b/test/vinyl/errinj.test.lua index 64d04c62d..c551de1b3 100644 --- a/test/vinyl/errinj.test.lua +++ b/test/vinyl/errinj.test.lua @@ -548,3 +548,29 @@ ch:get() s:count() -- 200 s:drop() + +-- +-- gh-3393: vinyl secondary index iterator must take in the hopper +-- that a tuple can disappear from the primary index after the +-- secondary index lookup. +-- +s = box.schema.create_space('test', {engine = 'vinyl'}) +pk = s:create_index('pk') +sk = s:create_index('sk', {parts = {{2, 'unsigned'}, {1, 'unsigned'}}}) +s:replace{1, 2} +s:replace{3, 4} +box.snapshot() +ret = nil +function iterate(i) ret = i.next() end +box.begin() +s:replace{5, 6} -- Start a transaction in the engine. +iter = create_iterator(sk, {4}, {iterator = 'GE'}) +errinj.set("ERRINJ_VY_DELAY_PK_LOOKUP", true) +f = fiber.create(iterate, iter) +s:delete{3} +errinj.set("ERRINJ_VY_DELAY_PK_LOOKUP", false) +while not ret do fiber.sleep(0.1) end +ret +iter.iterate_over() +box.commit() +s:drop() -- 2.15.1 (Apple Git-101)
next reply other threads:[~2018-05-11 23:24 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-05-11 23:24 Vladislav Shpilevoy [this message] 2018-05-11 23:52 ` [tarantool-patches] " Konstantin Osipov 2018-05-12 0:30 ` [tarantool-patches] " Vladimir Davydov
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=dff067540ee7081cc4e488f283b7475f72b0c937.1526080999.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH 1/1] vinyl: fix crash in vinyl_iterator_secondary_next' \ /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