From f92473f39ae7f10ad9254ec004ef83658084d10d Mon Sep 17 00:00:00 2001 From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Date: Thu, 15 Feb 2018 22:07:47 +0300 Subject: [PATCH] test: vinyl secondary idx iterator skips changes of read keys If a key is updated after a secondary index scan, but before a primary index lookup, then ignore this update. Closes #2442 --- src/box/vinyl.c | 8 +++++ src/errinj.h | 1 + test/box/errinj.result | 2 ++ test/vinyl/errinj.result | 65 ++++++++++++++++++++++++++++++++++++++ test/vinyl/errinj.test.lua | 23 ++++++++++++++ 5 files changed, 99 insertions(+) diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 69db2c81d3..df518fcc15 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -3868,6 +3868,14 @@ vinyl_iterator_next(struct iterator *base, struct tuple **ret) } if (it->index->id > 0) { +#ifndef NDEBUG + struct errinj *delay = errinj(ERRINJ_VY_DELAY_PK_LOOKUP, + ERRINJ_BOOL); + if (delay && delay->bparam) { + while (delay->bparam) + fiber_sleep(0.01); + } +#endif /* Get the full tuple from the primary index. */ if (vy_index_get(it->index->pk, it->tx, it->rv, tuple, &tuple) != 0) diff --git a/src/errinj.h b/src/errinj.h index 512d2342f3..20f3824cfa 100644 --- a/src/errinj.h +++ b/src/errinj.h @@ -105,6 +105,7 @@ struct errinj { _(ERRINJ_BUILD_SECONDARY, ERRINJ_INT, {.iparam = -1}) \ _(ERRINJ_VY_POINT_ITER_WAIT, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_RELAY_EXIT_DELAY, ERRINJ_DOUBLE, {.dparam = 0}) \ + _(ERRINJ_VY_DELAY_PK_LOOKUP, 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 3551851694..4ef7e887c1 100644 --- a/test/box/errinj.result +++ b/test/box/errinj.result @@ -30,6 +30,8 @@ errinj.info() state: false ERRINJ_VYRUN_INDEX_GARBAGE: state: false + ERRINJ_VY_DELAY_PK_LOOKUP: + state: false ERRINJ_VY_TASK_COMPLETE: state: false ERRINJ_PORT_DUMP: diff --git a/test/vinyl/errinj.result b/test/vinyl/errinj.result index 8aaa47457d..5e4037cfda 100644 --- a/test/vinyl/errinj.result +++ b/test/vinyl/errinj.result @@ -1194,3 +1194,68 @@ box.commit() s:drop() --- ... +-- +-- gh-2442: secondary index cursor must skip key update, made +-- after the secondary index scan, but before a primary index +-- lookup. It is ok, and the test checks this. +-- +s = box.schema.create_space('test', {engine = 'vinyl'}) +--- +... +pk = s:create_index('pk') +--- +... +sk = s:create_index('sk', {parts = {{2, 'unsigned'}}}) +--- +... +s:replace{1, 1} +--- +- [1, 1] +... +s:replace{3, 3} +--- +- [3, 3] +... +box.snapshot() +--- +- ok +... +ret = nil +--- +... +function do_read() ret = sk:select({2}, {iterator = 'GE'}) end +--- +... +errinj.set("ERRINJ_VY_DELAY_PK_LOOKUP", true) +--- +- ok +... +f = fiber.create(do_read) +--- +... +f:status() +--- +- suspended +... +ret +--- +- null +... +s:replace{2, 2} +--- +- [2, 2] +... +errinj.set("ERRINJ_VY_DELAY_PK_LOOKUP", false) +--- +- ok +... +while ret == nil do fiber.sleep(0.01) end +--- +... +ret +--- +- - [3, 3] +... +s:drop() +--- +... diff --git a/test/vinyl/errinj.test.lua b/test/vinyl/errinj.test.lua index 45eed72eba..bbfb44abda 100644 --- a/test/vinyl/errinj.test.lua +++ b/test/vinyl/errinj.test.lua @@ -466,3 +466,26 @@ value box.commit() s:drop() + +-- +-- gh-2442: secondary index cursor must skip key update, made +-- after the secondary index scan, but before a primary index +-- lookup. It is ok, and the test checks this. +-- +s = box.schema.create_space('test', {engine = 'vinyl'}) +pk = s:create_index('pk') +sk = s:create_index('sk', {parts = {{2, 'unsigned'}}}) +s:replace{1, 1} +s:replace{3, 3} +box.snapshot() +ret = nil +function do_read() ret = sk:select({2}, {iterator = 'GE'}) end +errinj.set("ERRINJ_VY_DELAY_PK_LOOKUP", true) +f = fiber.create(do_read) +f:status() +ret +s:replace{2, 2} +errinj.set("ERRINJ_VY_DELAY_PK_LOOKUP", false) +while ret == nil do fiber.sleep(0.01) end +ret +s:drop() -- GitLab