From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Vladimir Davydov Subject: [PATCH 2/4] vinyl: don't abort transactions that modify only local spaces for ro Date: Sun, 24 Mar 2019 00:07:22 +0300 Message-Id: <7add57ecaf0970eaf56dc248edbd81c3d28d64b6.1553373793.git.vdavydov.dev@gmail.com> In-Reply-To: References: In-Reply-To: References: To: kostja@tarantool.org Cc: tarantool-patches@freelists.org List-ID: Local spaces can be modified even in read-only mode hence we don't need to abort transactions that modify only local spaces when switching to read-only mode. Follow-up #4016 --- src/box/vy_tx.c | 19 +++++++++++++++++-- test/vinyl/misc.result | 38 ++++++++++++++++++++++++++++++++++++++ test/vinyl/misc.test.lua | 16 ++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/box/vy_tx.c b/src/box/vy_tx.c index 56d594e5..67a9b384 100644 --- a/src/box/vy_tx.c +++ b/src/box/vy_tx.c @@ -52,6 +52,7 @@ #include "trivia/util.h" #include "tuple.h" #include "column_mask.h" +#include "vclock.h" #include "vy_cache.h" #include "vy_lsm.h" #include "vy_mem.h" @@ -1121,8 +1122,22 @@ tx_manager_abort_writers_for_ro(struct tx_manager *xm) struct vy_tx *tx; rlist_foreach_entry(tx, &xm->writers, in_writers) { /* Applier ignores ro flag. */ - if (tx->state == VINYL_TX_READY && !tx->is_applier_session) - vy_tx_abort(tx); + if (tx->state == VINYL_TX_READY && !tx->is_applier_session) { + /* + * Don't abort transactions that modify only + * local spaces as they can be modified even + * in ro mode. + */ + struct vy_tx_space_hash_entry *entry; + struct vy_tx_space_hash_iterator it; + vy_tx_space_hash_ifirst(&tx->space_hash, &it); + while ((entry = vy_tx_space_hash_inext(&it)) != NULL) { + if (space_group_id(entry->space) != GROUP_LOCAL) { + vy_tx_abort(tx); + break; + } + } + } } } diff --git a/test/vinyl/misc.result b/test/vinyl/misc.result index 4f613cb0..751f8795 100644 --- a/test/vinyl/misc.result +++ b/test/vinyl/misc.result @@ -298,6 +298,16 @@ s:replace({1, 1}) --- - [1, 1] ... +s_local = box.schema.space.create('test_local', {engine = 'vinyl', is_local = true}) +--- +... +_ = s_local:create_index('pk') +--- +... +s_local:replace({1, 1}) +--- +- [1, 1] +... test_run:cmd("setopt delimiter ';'") --- - true @@ -334,6 +344,19 @@ _ = fiber.create(function() end); --- ... +-- Start rw transaction modifying only local spaces. +ch3 = fiber.channel(1); +--- +... +_ = fiber.create(function() + box.begin() + s_local:replace{1, 2} + ch3:get() + local status, err = pcall(box.commit) + ch3:put(status or err) +end); +--- +... test_run:cmd("setopt delimiter ''"); --- - true @@ -351,6 +374,10 @@ ch2:put(true) --- - true ... +ch3:put(true) +--- +- true +... ch1:get() --- - Can't modify data because this instance is in read-only mode. @@ -371,6 +398,10 @@ ch2:get() --- - true ... +ch3:get() +--- +- true +... -- Cleanup. box.cfg{read_only = false} --- @@ -382,3 +413,10 @@ s:select() s:drop() --- ... +s_local:select() +--- +- - [1, 2] +... +s_local:drop() +--- +... diff --git a/test/vinyl/misc.test.lua b/test/vinyl/misc.test.lua index bffaaf16..0616722f 100644 --- a/test/vinyl/misc.test.lua +++ b/test/vinyl/misc.test.lua @@ -124,6 +124,9 @@ test_run:cmd('cleanup server test') s = box.schema.space.create('test', {engine = 'vinyl'}) _ = s:create_index('pk') s:replace({1, 1}) +s_local = box.schema.space.create('test_local', {engine = 'vinyl', is_local = true}) +_ = s_local:create_index('pk') +s_local:replace({1, 1}) test_run:cmd("setopt delimiter ';'") -- Start rw transaction. ch1 = fiber.channel(1); @@ -149,18 +152,31 @@ _ = fiber.create(function() local status, err = pcall(box.commit) ch2:put(status or err) end); +-- Start rw transaction modifying only local spaces. +ch3 = fiber.channel(1); +_ = fiber.create(function() + box.begin() + s_local:replace{1, 2} + ch3:get() + local status, err = pcall(box.commit) + ch3:put(status or err) +end); test_run:cmd("setopt delimiter ''"); -- Switch to ro mode. box.cfg{read_only = true} -- Resume the transactions. ch1:put(true) ch2:put(true) +ch3:put(true) ch1:get() ch1:get() ch1:get() ch2:get() ch2:get() +ch3:get() -- Cleanup. box.cfg{read_only = false} s:select() s:drop() +s_local:select() +s_local:drop() -- 2.11.0