From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp44.i.mail.ru (smtp44.i.mail.ru [94.100.177.104]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 4D38B4696C3 for ; Wed, 1 Apr 2020 23:45:34 +0300 (MSK) From: Alexander Turenko Date: Wed, 1 Apr 2020 23:45:21 +0300 Message-Id: <65798b71932c21183072decd2cce8b2b0f88b884.1585773275.git.alexander.turenko@tarantool.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH] net.box: fix fetching of schema of an old version List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Vladislav Shpilevoy Cc: tarantool-patches@dev.tarantool.org After 2.2.0-633-gaa0964ae1 ('net.box: fix schema fetching from 1.10/2.1 servers') net.box expects that _vcollation system view exists on a tarantool server of 2.2.1+ version. This is however not always so: a server may be run on a new version of tarantool, but work on a schema of an old version. The situation with non last schema is usual for replication cluster in process of upgrading: all instances run on the new version of tarantool first (no auto-upgrade is performed by tarantools in a cluster). Then box.schema.upgrade() should be called, but the instances should be operable even before the call. Before the commit net.box was unable to connect a server if it is run on a schema without _vcollation system view (say, 2.1.3), but the server executable is of 2.2.1 version or newer. Follows up #4307 Fixes #4691 --- https://github.com/tarantool/tarantool/issues/4691 https://github.com/tarantool/tarantool/tree/Totktonada/gh-4691-net-box-connect-schema-2-1-3 src/box/lua/net_box.lua | 9 ++ ...4691-net-box-connect-schema-2-1-3.test.lua | 93 ++++++++++++++++++ test/box-tap/no_auto_schema_upgrade.lua | 30 ++++++ .../snap/2.1.3/00000000000000000000.snap | Bin 0 -> 4466 bytes 4 files changed, 132 insertions(+) create mode 100755 test/box-tap/gh-4691-net-box-connect-schema-2-1-3.test.lua create mode 100644 test/box-tap/no_auto_schema_upgrade.lua create mode 100644 test/box-tap/snap/2.1.3/00000000000000000000.snap diff --git a/src/box/lua/net_box.lua b/src/box/lua/net_box.lua index 3f611c027..d3ccc0fc6 100644 --- a/src/box/lua/net_box.lua +++ b/src/box/lua/net_box.lua @@ -53,6 +53,7 @@ local E_UNKNOWN = box.error.UNKNOWN local E_NO_CONNECTION = box.error.NO_CONNECTION local E_TIMEOUT = box.error.TIMEOUT local E_PROC_LUA = box.error.PROC_LUA +local E_NO_SUCH_SPACE = box.error.NO_SUCH_SPACE -- utility tables local is_final_state = {closed = 1, error = 1} @@ -779,6 +780,13 @@ local function create_transport(host, port, user, password, callback, local status = hdr[IPROTO_STATUS_KEY] local response_schema_version = hdr[IPROTO_SCHEMA_VERSION_KEY] if status ~= 0 then + -- No _vcollation space (server has an old + -- schema version). + local errno = band(status, IPROTO_ERRNO_MASK) + if id == select3_id and errno == E_NO_SUCH_SPACE then + peer_has_vcollation = false + goto continue + end local body body, body_end = decode(body_rpos) return error_sm(E_NO_CONNECTION, body[IPROTO_ERROR_KEY]) @@ -793,6 +801,7 @@ local function create_transport(host, port, user, password, callback, body, body_end = decode(body_rpos) response[id] = body[IPROTO_DATA_KEY] end + ::continue:: until response[select1_id] and response[select2_id] and (not peer_has_vcollation or response[select3_id]) -- trick: response[select3_id] is nil when the key is nil diff --git a/test/box-tap/gh-4691-net-box-connect-schema-2-1-3.test.lua b/test/box-tap/gh-4691-net-box-connect-schema-2-1-3.test.lua new file mode 100755 index 000000000..565f7da7b --- /dev/null +++ b/test/box-tap/gh-4691-net-box-connect-schema-2-1-3.test.lua @@ -0,0 +1,93 @@ +#!/usr/bin/env tarantool + +-- +-- gh-4691: net.box fails to connect to tarantool-2.2+ server with +-- a schema of version 2.1.3 or below (w/o _vcollation system +-- space). +-- +-- Tarantool does not update a schema automatically when an +-- instance is in a replication cluster, because it may break +-- instances that are run under an old tarantool version. It is +-- quite usual to have non-upgraded instances for some time, +-- because upgrade is usually performed step-by-step. +-- +-- net.box leans on a server version from greeting to determine +-- whether _vcollation system view should exist and reports an +-- error if fetching of the space fails. This causes the problem: +-- a version may be 2.2+, but _vcollation does not exists, because +-- schema upgrade is not performed yet. The fix of gh-4691 allows +-- the server to respond ER_NO_SUCH_SPACE for the query. +-- + +local test_run = require('test_run').new() +local net_box = require('net.box') +local tap = require('tap') + +local function before_all() + local opts = { + 'script = "box-tap/no_auto_schema_upgrade.lua"', + 'workdir = "box-tap/snap/2.1.3"', + 'return_listen_uri = True', + } + local opts_str = table.concat(opts, ', ') + local cmd = 'create server schema_2_1_3 with %s' + local uri = test_run:cmd(cmd:format(opts_str)) + test_run:cmd('start server schema_2_1_3') + + -- Create 'test' space with 'unicode_ci' index part. + -- + -- We need it to verify that net.box will expose collation_id + -- for an index key part when collation names information is + -- not available. + -- + -- Note: read_only = false on reconfiguration does not lead to + -- a schema upgrading. + test_run:eval('schema_2_1_3', ([[ + box.cfg{read_only = false} + box.schema.create_space('test') + box.space.test:create_index('pk', {parts = + {{field = 1, type = 'string', collation = 'unicode_ci'}}}) + box.cfg{read_only = true} + ]]):gsub('\n', ' ')) + return uri +end + +local function test_connect_schema_2_1_3(test, uri) + test:plan(3) + + local connection = net_box.connect(uri) + + -- Connection is alive. + test:ok(connection:is_connected(), 'connection is alive') + + -- Space metainfo is correct: collation_id is exposed when + -- collation name information is not available. + local key_part = connection.space.test.index[0].parts[1] + test:is(key_part.collation, nil, + 'collation names are not available') + test:is(type(key_part.collation_id), 'number', + 'collation numeric ids are exposed') + + connection:close() +end + +local function after_all() + -- Drop 'test' space. + test_run:eval('schema_2_1_3', ([[ + box.cfg{read_only = false} + box.space.test:drop() + box.cfg{read_only = true} + ]]):gsub('\n', ' ')) + + test_run:cmd('stop server schema_2_1_3') + test_run:cmd('cleanup server schema_2_1_3') + test_run:cmd('delete server schema_2_1_3') +end + +local uri = before_all() +local test = tap.test('gh-4691-net-box-connect-schema-2-1-3') +test:plan(1) +test:test('connect_schema_2_1_3', test_connect_schema_2_1_3, uri) +after_all() + +os.exit(test:check() and 0 or 1) diff --git a/test/box-tap/no_auto_schema_upgrade.lua b/test/box-tap/no_auto_schema_upgrade.lua new file mode 100644 index 000000000..b693637ac --- /dev/null +++ b/test/box-tap/no_auto_schema_upgrade.lua @@ -0,0 +1,30 @@ +#!/usr/bin/env tarantool + +-- +-- This instance is intended to be used with existing snapshot +-- from a previous tarantool version. It does not perform +-- automatic schema upgrade. +-- +-- Having tarantool in this state allows us to create test cases +-- for net.box, relay, applier connected to an instance in such +-- state or test behaviour of the instance itself. +-- +-- There are two ways to disable automatic schema upgrade: set +-- 'replication' box.cfg(<...>) option or set 'read_only' option. +-- Use the latter one, because it is simpler. +-- + +box.cfg({ + listen = os.getenv('LISTEN'), + read_only = true, +}) + +-- Give 'guest' user read/write accesses to all spaces. +-- +-- Note: reconfiguration with read_only = false does not lead to +-- schema upgrading. +box.cfg{read_only = false} +box.schema.user.grant('guest', 'read, write', 'universe') +box.cfg{read_only = true} + +require('console').listen(os.getenv('ADMIN')) diff --git a/test/box-tap/snap/2.1.3/00000000000000000000.snap b/test/box-tap/snap/2.1.3/00000000000000000000.snap new file mode 100644 index 0000000000000000000000000000000000000000..c8eecc0b4cc6b7bc0ee8634b3d51081662331da7 GIT binary patch literal 4466 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 E?c6t5<^TWy literal 0 HcmV?d00001 -- 2.25.0