From: Georgy Kirichenko <georgy@tarantool.org>
To: tarantool-patches@dev.tarantool.org, kostja.osipov@gmail.com
Cc: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Subject: Re: [Tarantool-patches] [PATCH 1/1] txn: don't trust group id in remote request header
Date: Thu, 16 Jan 2020 22:40:44 +0300 [thread overview]
Message-ID: <2518534.mvXUDI8C0e@localhost> (raw)
In-Reply-To: <f463bd65144de98ec3c45d58b8d2f429fe01e28e.1579123073.git.v.shpilevoy@tarantool.org>
[-- Attachment #1: Type: text/plain, Size: 7045 bytes --]
LGTM
On Thursday, 16 January 2020 00:24:53 MSK Vladislav Shpilevoy wrote:
> Transaction adds a redo log for each statement. The log is an xrow
> header. Some requests don't have a header (local requests), some
> do (from remote client, from replication).
>
> When a request had a header, it was written as is to WAL. But
> requests from remote client have an xrow header, however barely
> filled. Most of its fields are default values, usually 0.
> Including group id. Indeed, remote clients should not care about
> setting such deep system fields.
>
> That led to a problem when a space had group id local (!= 0), but
> it was ignored because in a request header from a remote client
> the group id was default (== 0). On the summary, it was possible
> to force Tarantool to replicate a replica-local space.
>
> Now group id setting is server-authoritative. Box always sets it
> regardless of what is present in an xrow header received from a
> client.
>
> Thanks Kostja Osipov (@kostja) for the diagnostics and the
> solution.
>
> Closes #4729
> ---
> Branch:
> https://github.com/tarantool/tarantool/tree/gerold103/gh-4729-iproto-group-> id Issue: https://github.com/tarantool/tarantool/issues/4729
>
> There is an alternative solution - nullify xrow_header pointer in
> tx_process1() before box_process1(), and return it back
> afterwards. Then txn.c won't look at the header. Currently there
> still is a problem, if a user, for example, sets replica_id field.
>
> Indeed, xrow_header may create a problem in tx_process1() only,
> and it is not really needed by tx thread. For iproto the only
> interesting fields here are sync and type.
>
> src/box/txn.c | 11 +-
> .../gh-4729-netbox-group-id.result | 104 ++++++++++++++++++
> .../gh-4729-netbox-group-id.test.lua | 37 +++++++
> 3 files changed, 150 insertions(+), 2 deletions(-)
> create mode 100644 test/replication/gh-4729-netbox-group-id.result
> create mode 100644 test/replication/gh-4729-netbox-group-id.test.lua
>
> diff --git a/src/box/txn.c b/src/box/txn.c
> index 963ec8eeb..bedb57449 100644
> --- a/src/box/txn.c
> +++ b/src/box/txn.c
> @@ -72,12 +72,19 @@ txn_add_redo(struct txn *txn, struct txn_stmt *stmt,
> struct request *request) /* Initialize members explicitly to save time on
> memset() */
> row->type = request->type;
> row->replica_id = 0;
> - row->group_id = stmt->space != NULL ?
> - space_group_id(stmt->space) : 0;
> row->lsn = 0;
> row->sync = 0;
> row->tm = 0;
> }
> + /*
> + * Group ID should be set both for requests not having a
> + * header, and for the ones who have it. This is because
> + * even if a request has a header, the group id could be
> + * omitted in it, and is default - 0. Even if the space's
> + * real group id is different.
> + */
> + struct space *space = stmt->space;
> + row->group_id = space != NULL ? space_group_id(space) : 0;
> row->bodycnt = xrow_encode_dml(request, &txn->region, row->body);
> if (row->bodycnt < 0)
> return -1;
> diff --git a/test/replication/gh-4729-netbox-group-id.result
> b/test/replication/gh-4729-netbox-group-id.result new file mode 100644
> index 000000000..d7189baaf
> --- /dev/null
> +++ b/test/replication/gh-4729-netbox-group-id.result
> @@ -0,0 +1,104 @@
> +-- test-run result file version 2
> +test_run = require('test_run').new()
> + | ---
> + | ...
> +--
> +-- gh-4729: box should not trust xrow header group id, received
> +-- from a remote client on DDL/DML.
> +--
> +box.schema.user.grant('guest', 'super')
> + | ---
> + | ...
> +s1 = box.schema.space.create('test_local', {is_local = true})
> + | ---
> + | ...
> +_ = s1:create_index('pk', {parts = {1, 'unsigned'}})
> + | ---
> + | ...
> +s2 = box.schema.space.create('test_normal')
> + | ---
> + | ...
> +_ = s2:create_index('pk', {parts = {1, 'unsigned'}})
> + | ---
> + | ...
> +
> +test_run:cmd('create server replica with rpl_master=default,
> script="replication/replica.lua"') + | ---
> + | - true
> + | ...
> +test_run:cmd('start server replica')
> + | ---
> + | - true
> + | ...
> +test_run:switch('replica')
> + | ---
> + | - true
> + | ...
> +
> +netbox = require('net.box')
> + | ---
> + | ...
> +c = netbox.connect(box.cfg.replication[1])
> + | ---
> + | ...
> +c.space.test_local:insert({1})
> + | ---
> + | - [1]
> + | ...
> +c.space.test_normal:insert({1})
> + | ---
> + | - [1]
> + | ...
> +c:close()
> + | ---
> + | ...
> +test_run:wait_cond(function() \
> + return box.space.test_normal ~= nil and \
> + box.space.test_normal.index.pk ~= nil and \
> + box.space.test_normal:count() == 1 \
> +end)
> + | ---
> + | - true
> + | ...
> +box.space.test_local:select{}
> + | ---
> + | - []
> + | ...
> +box.space.test_normal:select{}
> + | ---
> + | - - [1]
> + | ...
> +
> +test_run:switch('default')
> + | ---
> + | - true
> + | ...
> +test_run:cmd("stop server replica")
> + | ---
> + | - true
> + | ...
> +test_run:cmd("cleanup server replica")
> + | ---
> + | - true
> + | ...
> +test_run:cmd("delete server replica")
> + | ---
> + | - true
> + | ...
> +s1:select{}
> + | ---
> + | - - [1]
> + | ...
> +s2:select{}
> + | ---
> + | - - [1]
> + | ...
> +s1:drop()
> + | ---
> + | ...
> +s2:drop()
> + | ---
> + | ...
> +box.schema.user.revoke('guest', 'super')
> + | ---
> + | ...
> diff --git a/test/replication/gh-4729-netbox-group-id.test.lua
> b/test/replication/gh-4729-netbox-group-id.test.lua new file mode 100644
> index 000000000..3d8cef65f
> --- /dev/null
> +++ b/test/replication/gh-4729-netbox-group-id.test.lua
> @@ -0,0 +1,37 @@
> +test_run = require('test_run').new()
> +--
> +-- gh-4729: box should not trust xrow header group id, received
> +-- from a remote client on DDL/DML.
> +--
> +box.schema.user.grant('guest', 'super')
> +s1 = box.schema.space.create('test_local', {is_local = true})
> +_ = s1:create_index('pk', {parts = {1, 'unsigned'}})
> +s2 = box.schema.space.create('test_normal')
> +_ = s2:create_index('pk', {parts = {1, 'unsigned'}})
> +
> +test_run:cmd('create server replica with rpl_master=default,
> script="replication/replica.lua"') +test_run:cmd('start server replica')
> +test_run:switch('replica')
> +
> +netbox = require('net.box')
> +c = netbox.connect(box.cfg.replication[1])
> +c.space.test_local:insert({1})
> +c.space.test_normal:insert({1})
> +c:close()
> +test_run:wait_cond(function() \
> + return box.space.test_normal ~= nil and \
> + box.space.test_normal.index.pk ~= nil and \
> + box.space.test_normal:count() == 1 \
> +end)
> +box.space.test_local:select{}
> +box.space.test_normal:select{}
> +
> +test_run:switch('default')
> +test_run:cmd("stop server replica")
> +test_run:cmd("cleanup server replica")
> +test_run:cmd("delete server replica")
> +s1:select{}
> +s2:select{}
> +s1:drop()
> +s2:drop()
> +box.schema.user.revoke('guest', 'super')
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
next prev parent reply other threads:[~2020-01-16 19:40 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-15 21:24 Vladislav Shpilevoy
2020-01-16 19:40 ` Georgy Kirichenko [this message]
2020-01-21 12:39 ` Kirill Yukhin
2020-01-21 20:34 ` Vladislav Shpilevoy
2020-01-23 6:55 ` Kirill Yukhin
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=2518534.mvXUDI8C0e@localhost \
--to=georgy@tarantool.org \
--cc=kostja.osipov@gmail.com \
--cc=tarantool-patches@dev.tarantool.org \
--cc=v.shpilevoy@tarantool.org \
--subject='Re: [Tarantool-patches] [PATCH 1/1] txn: don'\''t trust group id in remote request header' \
/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