From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 26D9028DEC for ; Tue, 17 Apr 2018 03:39:33 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6qaPD7RmHnNZ for ; Tue, 17 Apr 2018 03:39:33 -0400 (EDT) Received: from smtp40.i.mail.ru (smtp40.i.mail.ru [94.100.177.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 80B5028D66 for ; Tue, 17 Apr 2018 03:39:32 -0400 (EDT) From: Ilya Markov Subject: [tarantool-patches] [wal 1/1] wal: Update request header after sequence update Date: Tue, 17 Apr 2018 10:39:16 +0300 Message-Id: Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: georgy@tarantool.org Cc: tarantool-patches@freelists.org When tuple in insert/replace request has NULL value in the field incremented by sequence, request body is changed, NULL is replaced by value taken from sequence. But request header is not updated. So Redo log, which takes body from header if header exists, writes the old version of request to wal. Fixed this with updating header value after handling the sequence. Closes #3247 --- branch gh-3247-wrong-sequence-primary-index src/box/request.c | 7 +++++ test/replication/misc.result | 66 ++++++++++++++++++++++++++++++++++++++++++ test/replication/misc.test.lua | 21 ++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/src/box/request.c b/src/box/request.c index 646da42..0b3c5fb 100644 --- a/src/box/request.c +++ b/src/box/request.c @@ -195,5 +195,12 @@ request_handle_sequence(struct request *request, struct space *space) if (likely(mp_read_int64(&key, &value) == 0)) return sequence_update(seq, value); } + /* + * As the request body was changed, we have to update body in header. + */ + if (request->header != NULL) { + request->header->bodycnt = + xrow_encode_dml(request, request->header->body); + } return 0; } diff --git a/test/replication/misc.result b/test/replication/misc.result index 879c7fe..3d1089d 100644 --- a/test/replication/misc.result +++ b/test/replication/misc.result @@ -139,6 +139,72 @@ test_run:cmd("switch default") --- - true ... +-- gh-3247 wrong sequence replication +test_run:cmd("switch autobootstrap1") +--- +- true +... +net_box = require('net.box') +--- +... +engine = test_run:get_cfg('engine') +--- +... +_ = box.schema.space.create("space1", {engine=engine}) +--- +... +_ = box.schema.sequence.create('seq') +--- +... +_ = box.space.space1:create_index('primary', {sequence='seq'} ) +--- +... +_ = box.space.space1:create_index('idx', { type = 'tree', unique = false, parts = {2, 'number'} }) +--- +... +box.schema.user.grant('guest', "read,write", "space", 'space1') +--- +... +box.schema.user.grant('guest', "read,write", "sequence", 'seq') +--- +... +c = net_box.connect(box.cfg.listen) +--- +... +c.space.space1:insert{box.NULL, "data"} +--- +- error: 'Tuple field 2 type does not match one required by operation: expected number' +... +c.space.space1:insert{box.NULL, 1, "data"} +--- +- [2, 1, 'data'] +... +box.space.space1:select{} +--- +- - [2, 1, 'data'] +... +test_run:cmd("switch autobootstrap2") +--- +- true +... +box.space.space1:select{} +--- +- - [2, 1, 'data'] +... +test_run:cmd("switch autobootstrap1") +--- +- true +... +box.space.space1:drop() +--- +... +box.sequence.seq:drop() +--- +... +test_run:cmd("switch default") +--- +- true +... test_run:drop_cluster(SERVERS) --- ... diff --git a/test/replication/misc.test.lua b/test/replication/misc.test.lua index 8752182..b00154e 100644 --- a/test/replication/misc.test.lua +++ b/test/replication/misc.test.lua @@ -56,6 +56,27 @@ end ; test_run:cmd("setopt delimiter ''"); test_timeout() test_run:cmd("switch default") +-- gh-3247 wrong sequence replication +test_run:cmd("switch autobootstrap1") +net_box = require('net.box') +engine = test_run:get_cfg('engine') +_ = box.schema.space.create("space1", {engine=engine}) +_ = box.schema.sequence.create('seq') +_ = box.space.space1:create_index('primary', {sequence='seq'} ) +_ = box.space.space1:create_index('idx', { type = 'tree', unique = false, parts = {2, 'number'} }) +box.schema.user.grant('guest', "read,write", "space", 'space1') +box.schema.user.grant('guest', "read,write", "sequence", 'seq') +c = net_box.connect(box.cfg.listen) +c.space.space1:insert{box.NULL, "data"} +c.space.space1:insert{box.NULL, 1, "data"} +box.space.space1:select{} +test_run:cmd("switch autobootstrap2") +box.space.space1:select{} +test_run:cmd("switch autobootstrap1") +box.space.space1:drop() +box.sequence.seq:drop() + +test_run:cmd("switch default") test_run:drop_cluster(SERVERS) box.schema.user.revoke('guest', 'replication') -- 2.7.4