[Tarantool-patches] [PATCH v2 2/2] box: allow upgrading from version 1.6

Бабин Олег olegrok at tarantool.org
Mon Aug 16 16:18:09 MSK 2021


Thanks for your patch. LGTM but consider several nits below.

  
>Пятница, 13 августа 2021, 2:35 +03:00 от Serge Petrenko via Tarantool-patches <tarantool-patches at dev.tarantool.org>:
> 
>Direct upgrade support from pre-1.7.5 versions was removed in commit
>7d3b80e78206c479cab75b4893629cfa1932252e
>(Forbid upgrade from Tarantool < 1.7.5 and refactor upgrade.lua)
>The reason for that was the mandatory space format checks introduced
>back then. With these space format checks, old schema couldn't be
>recovered on new Tarantool versions, because newer versions had
>different system space formats. So old schema couldn't be upgraded
>because it couldn't even be recovered.
>
>Actually this was rather inconvenient. One had to perform an extra
>upgrade step when upgrading from, say, 1.6 to 2.x: instead of
>performing a direct upgrade one had to do 1.6 -> 1.10 -> 2.x upgrade
>which takes twice the time.
>
>Make it possible to boot from snapshots coming from Tarantool version
>1.6.8 and above.
>
>In order to do so, introduce before_replace triggers on system spaces,
>which work during snapshot/xlog recovery. The triggers will set tuple
>formats to the ones supported by current Tarantool (2.x). This way the
>recovered data will have the correct format for a usual schema upgrade.
>
>Also add upgrade_to_1_7_5() handler, which finishes transformation of
>old schema to 1.7.5. The handler is fired together with other
>box.schema.upgrade() handlers, so there's no user-visible behaviour
>change.
>
>Side note: it would be great to use the same technique to allow booting
>from pre-1.6.8 snapshots. Unfortunately, this is not possible.
>
>Current triggers don't break the order of schema upgrades, so 1.7.1
>upgrades come before 1.7.2 and 1.7.5. This is because all the upgrades
>in these versions are replacing existing tuples and not inserting new
>ones, so the upgrades may be handled by the before_replace triggers.
>
>Upgrade to 1.6.8 requires inserting new tuples: creating sysviews, like
>_vspace, _vuser and so on. This can't be done from the before_replace
>triggers, so we would have to run triggers for 1.7.x first which would
>allow Tarantool to recover the snapshot, and then run an upgrade handler for
>1.6.8. This looks really messy.
>
>Closes #5894
>---
> src/box/lua/load_cfg.lua | 14 +
> src/box/lua/upgrade.lua | 276 +++++++++++-
> test/xlog/gh-5894-pre-1.7.7-upgrade.result | 400 ++++++++++++++++++
> test/xlog/gh-5894-pre-1.7.7-upgrade.test.lua | 77 ++++
> .../1.6.8/gh-5894-pre-1.7.7-upgrade/fill.lua | 1 +
> .../1.7.1/gh-5894-pre-1.7.7-upgrade/fill.lua | 1 +
> .../1.7.2/gh-5894-pre-1.7.7-upgrade/fill.lua | 1 +
> .../1.7.5/gh-5894-pre-1.7.7-upgrade/fill.lua | 1 +
> test/xlog/upgrade/fill.lua | 4 +
> 9 files changed, 773 insertions(+), 2 deletions(-)
> create mode 100644 test/xlog/gh-5894-pre-1.7.7-upgrade.result
> create mode 100644 test/xlog/gh-5894-pre-1.7.7-upgrade.test.lua
> create mode 120000 test/xlog/upgrade/1.6.8/gh-5894-pre-1.7.7-upgrade/fill.lua
> create mode 120000 test/xlog/upgrade/1.7.1/gh-5894-pre-1.7.7-upgrade/fill.lua
> create mode 120000 test/xlog/upgrade/1.7.2/gh-5894-pre-1.7.7-upgrade/fill.lua
> create mode 120000 test/xlog/upgrade/1.7.5/gh-5894-pre-1.7.7-upgrade/fill.lua
>
>diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
>index 4df70c210..7a8cab3fd 100644
>--- a/src/box/lua/load_cfg.lua
>+++ b/src/box/lua/load_cfg.lua
>@@ -719,9 +719,23 @@ local function load_cfg(cfg)
>             __call = locked(reload_cfg),
>         })
> 
>+ -- Check schema version of the snapshot we're about to recover, if any.
>+ -- Some schema versions (below 1.7.5) are incompatible with Tarantool 2.x
>+ -- When recovering from such an old snapshot, special recovery triggers on
>+ -- system spaces are needed in order to be able to recover and upgrade
>+ -- the schema then.
>+ local snap_dir = box.cfg.memtx_dir
>+ local snap_version = private.get_snapshot_version(snap_dir)
>+ if snap_version then
>+ private.set_recovery_triggers(snap_version)
>+ end
>+
>     -- This call either succeeds or calls panic() / exit().
>     private.cfg_load()
> 
>+ if snap_version then
>+ private.clear_recovery_triggers()
>+ end
>     -- This block does not raise an error: all necessary checks
>     -- already performed in private.cfg_check(). See <dynamic_cfg>
>     -- comment.
>diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua
>index 6abce50f4..925adab18 100644
>--- a/src/box/lua/upgrade.lua
>+++ b/src/box/lua/upgrade.lua
>@@ -1,6 +1,8 @@
> local log = require('log')
> local bit = require('bit')
> local json = require('json')
>+local fio = require('fio')
>+local xlog = require('xlog')
> 
> -- Guest user id - the default user
> local GUEST = 0
>@@ -86,6 +88,40 @@ local function set_system_triggers(val)
>     foreach_system_space(function(s) s:run_triggers(val) end)
> end
> 
>+-- Get schema version, stored in _schema system space, by reading the latest
>+-- snapshot file from the snap_dir. Useful to define schema_version before
>+-- recovering the snapshot, because some schema versions are too old and cannot
>+-- be recovered normally.
>+local function get_snapshot_version(snap_dir)
>+ local snap_pattern = snap_dir..'/'..string.rep('[0-9]', 20)..'.snap'
 
Probably we could use fio.pathjoin here
 
>+ local snap_list = fio.glob(snap_pattern)
>+ table.sort(snap_list)
>+ local snap = snap_list[#snap_list]
>+ if not snap then
>+ return nil
>+ end
>+ local version = nil
>+ for _, row in xlog.pairs(snap) do
>+ local sid = row.BODY and row.BODY.space_id
>+ if sid == box.schema.SCHEMA_ID then
>+ local tuple = row.BODY.tuple
>+ if tuple and tuple[1] == 'version' then
>+ local major, minor, patch = tuple[2], tuple[3], tuple[4] or 0
 
Could it be replaced with tuple:unpack(2, 4)?
 
>+ if major and minor and patch and type(major) == 'number' and
>+ type(minor) == 'number' and type(patch) == 'number' then
 
Here you use type() == number checks. Could it be different? In case of broken snap?
So, we should log it I assume. The same for similar places below.
 
>+ version = mkversion(major, minor, patch)
>+ break
>+ end
>+ end
>+ elseif sid and sid > box.schema.SCHEMA_ID then
>+ -- Exit early if version wasn't found in _schema space.
>+ -- Snapshot rows are ordered by space id.
>+ break
>+ end
>+ end
>+ return version
>+end
>+
> --------------------------------------------------------------------------------
> -- Bootstrap
> --------------------------------------------------------------------------------
>@@ -131,6 +167,144 @@ local function create_sysview(source_id, target_id)
>     end
> end
> 
>+--------------------------------------------------------------------------------
>+-- Tarantool 1.7.1
>+--------------------------------------------------------------------------------
>+local function user_trig_1_7_1(_, tuple)
>+ if tuple and tuple[3] == 'guest' and not tuple[5] then
 
I think it’s better to use explicit check for tuple[5] value.
If it’s a boolean value could it be box.NULL?
 
>+ local auth_method_list = {}
>+ auth_method_list["chap-sha1"] = box.schema.user.password("")
>+ tuple = tuple:update{{'=', 5, auth_method_list}}
>+ log.info("Set empty password to user 'guest'")
>+ end
>+ return tuple
>+end
>+
>+--------------------------------------------------------------------------------
>+-- Tarantool 1.7.2
>+--------------------------------------------------------------------------------
>+local function index_trig_1_7_2(_, tuple)
>+ local field_types_v16 = {
>+ num = 'unsigned',
>+ int = 'integer',
>+ str = 'string',
>+ }
>+ if not tuple then
>+ return tuple
>+ end
>+ local parts = tuple[6]
>+ local changed = false
>+ for _, part in pairs(parts) do
>+ local field_type = part[2]:lower()
>+ if field_types_v16[field_type] ~= nil then
>+ part[2] = field_types_v16[field_type]
>+ changed = true
>+ end
>+ end
>+ if changed then
>+ log.info("Update index '%s' on space '%s': set parts to %s", tuple[3],
>+ box.space[tuple[1]].name, json.encode(parts))
>+ tuple = tuple:update{{'=', 6, parts}}
>+ end
>+ return tuple
>+end
>+
>+--------------------------------------------------------------------------------
>+-- Tarantool 1.7.5
>+--------------------------------------------------------------------------------
>+local function create_truncate_space()
>+ local _truncate = box.space[box.schema.TRUNCATE_ID]
>+
>+ log.info("create space _truncate")
>+ box.space._space:insert{
>+ _truncate.id, ADMIN, '_truncate', 'memtx', 0, setmap({}),
>+ {{name = 'id', type = 'unsigned'}, {name = 'count', type = 'unsigned'}}
>+ }
>+
>+ log.info("create index primary on _truncate")
>+ box.space._index:insert{
>+ _truncate.id, 0, 'primary', 'tree', {unique = true}, {{0, 'unsigned'}}
>+ }
>+
>+ local _priv = box.space[box.schema.PRIV_ID]
>+ _priv:insert{ADMIN, PUBLIC, 'space', _truncate.id, box.priv.W}
>+end
>+
>+local function upgrade_to_1_7_5()
>+ create_truncate_space()
>+end
>+
>+local function user_trig_1_7_5(_, tuple)
>+ if tuple and not tuple[5] then
>+ tuple = tuple:update{{'=', 5, setmap({})}}
>+ log.info("Set empty password to %s '%s'", tuple[4], tuple[3])
>+ end
>+ return tuple
>+end
>+
>+local space_formats_1_7_5 = {
>+ _schema = {
>+ {name = 'key', type = 'string'},
>+ },
>+ _space = {
>+ {name = 'id', type = 'unsigned'},
>+ {name = 'owner', type = 'unsigned'},
>+ {name = 'name', type = 'string'},
>+ {name = 'engine', type = 'string'},
>+ {name = 'field_count', type = 'unsigned'},
>+ {name = 'flags', type = 'map'},
>+ {name = 'format', type = 'array'},
>+ },
>+ _index = {
>+ {name = 'id', type = 'unsigned'},
>+ {name = 'iid', type = 'unsigned'},
>+ {name = 'name', type = 'string'},
>+ {name = 'type', type = 'string'},
>+ {name = 'opts', type = 'map'},
>+ {name = 'parts', type = 'array'},
>+ },
>+ _func = {
>+ {name = 'id', type = 'unsigned'},
>+ {name = 'owner', type = 'unsigned'},
>+ {name = 'name', type = 'string'},
>+ {name = 'setuid', type = 'unsigned'},
>+ },
>+ _user = {
>+ {name = 'id', type = 'unsigned'},
>+ {name = 'owner', type = 'unsigned'},
>+ {name = 'name', type = 'string'},
>+ {name = 'type', type = 'string'},
>+ {name = 'auth', type = 'map'},
>+ },
>+ _priv = {
>+ {name = 'grantor', type = 'unsigned'},
>+ {name = 'grantee', type = 'unsigned'},
>+ {name = 'object_type', type = 'string'},
>+ {name = 'object_id', type = 'unsigned'},
>+ {name = 'privilege', type = 'unsigned'},
>+ },
>+ _cluster = {
>+ {name = 'id', type = 'unsigned'},
>+ {name = 'uuid', type = 'string'},
>+ },
>+}
>+
>+space_formats_1_7_5._vspace = space_formats_1_7_5._space
>+space_formats_1_7_5._vindex = space_formats_1_7_5._index
>+space_formats_1_7_5._vfunc = space_formats_1_7_5._func
>+space_formats_1_7_5._vuser = space_formats_1_7_5._user
>+space_formats_1_7_5._vpriv = space_formats_1_7_5._priv
>+
>+local function space_trig_1_7_5(_, tuple)
>+ if tuple and space_formats_1_7_5[tuple[3]] and
>+ not table.equals(space_formats_1_7_5[tuple[3]], tuple[7]) then
>+ tuple = tuple:update{{'=', 7, space_formats_1_7_5[tuple[3]]}}
>+ log.info("Update space '%s' format: new format %s", tuple[3],
>+ json.encode(tuple[7]))
>+ end
>+ return tuple
>+end
>+
> local function initial_1_7_5()
>     -- stick to the following convention:
>     -- prefer user id (owner id) in field #1
>@@ -452,6 +626,15 @@ local function upgrade_to_1_7_7()
>     _priv:replace({ADMIN, SUPER, 'universe', 0, 4294967295})
> end
> 
>+local function priv_trig_1_7_7(_, tuple)
>+ if tuple and tuple[2] == ADMIN and tuple[3] == 'universe' and
>+ tuple[5] ~= box.priv.ALL then
>+ tuple = tuple:update{{'=', 5, box.priv.ALL}}
>+ log.info("Grant all privileges to user 'admin'")
>+ end
>+ return tuple
>+end
>+
> --------------------------------------------------------------------------------
> --- Tarantool 1.10.0
> --------------------------------------------------------------------------------
>@@ -1021,6 +1204,7 @@ end
> --------------------------------------------------------------------------------
> 
> local handlers = {
>+ {version = mkversion(1, 7, 5), func = upgrade_to_1_7_5, auto=true},
>     {version = mkversion(1, 7, 6), func = upgrade_to_1_7_6, auto = true},
>     {version = mkversion(1, 7, 7), func = upgrade_to_1_7_7, auto = true},
>     {version = mkversion(1, 10, 0), func = upgrade_to_1_10_0, auto = true},
>@@ -1061,13 +1245,98 @@ local function schema_needs_upgrade()
>     return false
> end
> 
>+local trig_oldest_version = nil
>+
>+-- Some schema changes before version 1.7.7 make it impossible to recover from
>+-- older snapshot. The table below consists of before_replace triggers on system
>+-- spaces, which make old snapshot schema compatible with current Tarantool
>+-- (version 2.x). The triggers replace old format tuples with new ones
>+-- in-memory, thus making it possible to recover from a rather old snapshot
>+-- (up to schema version 1.6.8). Once the snapshot is recovered, a normal
>+-- upgrade procedure may set schema version to the latest one.
>+--
>+-- The triggers mostly repeat the corresponding upgrade_to_1_7_x functions,
>+-- which were used when pre-1.7.x snapshot schema was still recoverable.
>+--
>+-- When the triggers are used (i.e. when snapshot schema version is below 1.7.5,
>+-- the upgrade procedure works as follows:
>+-- * first the snapshot is recovered and 1.7.5-compatible schema is applied to
>+-- it in-memory with the help of triggers.
>+-- * then usual upgrade_to_X_X_X() handlers may be fired to turn schema into the
>+-- latest one.
>+local recovery_triggers = {
>+ {version = mkversion(1, 7, 1), tbl = {
>+ _user = user_trig_1_7_1,
>+ }},
>+ {version = mkversion(1, 7, 2), tbl = {
>+ _index = index_trig_1_7_2,
>+ }},
>+ {version = mkversion(1, 7, 5), tbl = {
>+ _space = space_trig_1_7_5,
>+ _user = user_trig_1_7_5,
>+ }},
>+ {version = mkversion(1, 7, 7), tbl = {
>+ _priv = priv_trig_1_7_7,
>+ }},
>+}
>+
>+-- Once newer schema version is recovered (say, from an xlog following the old
>+-- snapshot), the triggers helping recover the old schema should be removed.
>+local function schema_trig_last(_, tuple)
>+ if tuple and tuple[1] == 'version' then
>+ local major, minor, patch = tuple[2], tuple[3], tuple[4] or 0
>+ if major and minor and patch and type(major) == 'number' and
>+ type(minor) == 'number' and type(patch) == 'number' then
>+ local version = mkversion(major, minor, patch)
>+ log.info("Recovery trigger: recovered schema version %s. "..
>+ "Removing outdated recovery triggers.", version)
>+ box.internal.clear_recovery_triggers(version)
>+ trig_oldest_version = version
>+ end
>+ end
>+ return tuple
>+end
>+
>+recovery_triggers[#recovery_triggers].tbl['_schema'] = schema_trig_last
>+
>+local function on_init_set_recovery_triggers()
>+ log.info("Recovering snapshot with schema version %s", trig_oldest_version)
>+ for _, trig_tbl in ipairs(recovery_triggers) do
>+ if trig_tbl.version > trig_oldest_version then
>+ for space, trig in pairs(trig_tbl.tbl) do
>+ box.space[space]:before_replace(trig)
>+ log.info("Set recovery trigger on space '%s' to comply with "..
>+ "version %s format", space, trig_tbl.version)
>+ end
>+ end
>+ end
>+end
>+
>+local function set_recovery_triggers(version)
>+ trig_oldest_version = version
>+ box.ctl.on_schema_init(on_init_set_recovery_triggers)
>+end
>+
>+local function clear_recovery_triggers(version)
>+ for _, trig_tbl in ipairs(recovery_triggers) do
>+ if trig_tbl.version > trig_oldest_version and
>+ (not version or trig_tbl.version <= version) then
>+ for space, trig in pairs(trig_tbl.tbl) do
>+ box.space[space]:before_replace(nil, trig)
>+ log.info("Remove recovery trigger on space '%s' for version %s",
>+ space, trig_tbl.version)
>+ end
>+ end
>+ end
>+end
>+
> local function upgrade(options)
>     options = options or {}
>     setmetatable(options, {__index = {auto = false}})
> 
>     local version = get_version()
>- if version < mkversion(1, 7, 5) then
>- log.warn('can upgrade from 1.7.5 only')
>+ if version < mkversion(1, 6, 8) then
>+ log.warn('can upgrade from 1.6.8 only')
>         return
>     end
> 
>@@ -1110,3 +1379,6 @@ end
> box.schema.upgrade = upgrade;
> box.internal.bootstrap = bootstrap;
> box.internal.schema_needs_upgrade = schema_needs_upgrade;
>+box.internal.get_snapshot_version = get_snapshot_version;
>+box.internal.set_recovery_triggers = set_recovery_triggers;
>+box.internal.clear_recovery_triggers = clear_recovery_triggers;
>diff --git a/test/xlog/gh-5894-pre-1.7.7-upgrade.result b/test/xlog/gh-5894-pre-1.7.7-upgrade.result
>new file mode 100644
>index 000000000..aba5a56ab
>--- /dev/null
>+++ b/test/xlog/gh-5894-pre-1.7.7-upgrade.result
>@@ -0,0 +1,400 @@
>+-- test-run result file version 2
>+test_run = require('test_run').new()
>+ | ---
>+ | ...
>+
>+-- Upgrade from 1.6.8.
>+test_run:cmd('create server upgrade with script="xlog/upgrade.lua", \
>+ workdir="xlog/upgrade/1.6.8/gh-5894-pre-1.7.7-upgrade"')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('start server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+test_run:switch('upgrade')
>+ | ---
>+ | - true
>+ | ...
>+
>+assert(not box.internal.schema_needs_upgrade())
>+ | ---
>+ | - true
>+ | ...
>+box.space.distro:select{}
>+ | ---
>+ | - - ['debian', 'sarge', 31, 1118059200]
>+ | - ['debian', 'etch', 40, 1176033600]
>+ | - ['ubuntu', 'trusty', 1404, 1397736000]
>+ | - ['ubuntu', 'vivid', 1504, 1429790400]
>+ | - ['ubuntu', 'wily', 1510, 1445515200]
>+ | - ['debian', 'wheezy', 70, 1367668800]
>+ | - ['debian', 'squeeze', 60, 1296907200]
>+ | - ['debian', 'lenny', 50, 1234612800]
>+ | - ['debian', 'jessie', 80, 1430049600]
>+ | - ['ubuntu', 'precise', 1510, 1335441600]
>+ | - ['debian', 'woody', 30, 1027080000]
>+ | ...
>+box.space._index:select{box.space.distro.id}
>+ | ---
>+ | - - [512, 0, 'primary', 'hash', {'unique': true}, [[0, 'string'], [1, 'string'], [
>+ | 2, 'unsigned']]]
>+ | - [512, 1, 'codename', 'hash', {'unique': true}, [[1, 'string']]]
>+ | - [512, 2, 'time', 'tree', {'unique': false}, [[3, 'unsigned']]]
>+ | ...
>+box.space._space:format()
>+ | ---
>+ | - [{'name': 'id', 'type': 'unsigned'}, {'name': 'owner', 'type': 'unsigned'}, {'name': 'name',
>+ | 'type': 'string'}, {'name': 'engine', 'type': 'string'}, {'name': 'field_count',
>+ | 'type': 'unsigned'}, {'name': 'flags', 'type': 'map'}, {'name': 'format', 'type': 'array'}]
>+ | ...
>+box.schema.user.info('admin')
>+ | ---
>+ | - - - read,write,execute,session,usage,create,drop,alter,reference,trigger,insert,update,delete
>+ | - universe
>+ | -
>+ | ...
>+box.schema.user.info('guest')
>+ | ---
>+ | - - - execute
>+ | - role
>+ | - public
>+ | - - session,usage
>+ | - universe
>+ | -
>+ | ...
>+box.schema.user.info('someuser')
>+ | ---
>+ | - - - execute
>+ | - function
>+ | - someotherfunc
>+ | - - execute
>+ | - role
>+ | - public
>+ | - - execute
>+ | - role
>+ | - somerole
>+ | - - read,write,drop,alter
>+ | - space
>+ | - temporary
>+ | - - session,usage
>+ | - universe
>+ | -
>+ | ...
>+box.schema.role.info('somerole')
>+ | ---
>+ | - - - read,write,drop,alter
>+ | - space
>+ | - distro
>+ | ...
>+
>+test_run:switch('default')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('stop server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('delete server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+
>+-- Upgrade from 1.7.1.
>+test_run:cmd('create server upgrade with script="xlog/upgrade.lua", \
>+ workdir="xlog/upgrade/1.7.1/gh-5894-pre-1.7.7-upgrade"')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('start server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+test_run:switch('upgrade')
>+ | ---
>+ | - true
>+ | ...
>+
>+assert(not box.internal.schema_needs_upgrade())
>+ | ---
>+ | - true
>+ | ...
>+box.space.distro:select{}
>+ | ---
>+ | - - ['debian', 'etch', 40, 1176033600]
>+ | - ['debian', 'sarge', 31, 1118059200]
>+ | - ['ubuntu', 'wily', 1510, 1445515200]
>+ | - ['ubuntu', 'trusty', 1404, 1397736000]
>+ | - ['ubuntu', 'vivid', 1504, 1429790400]
>+ | - ['debian', 'wheezy', 70, 1367668800]
>+ | - ['debian', 'squeeze', 60, 1296907200]
>+ | - ['debian', 'lenny', 50, 1234612800]
>+ | - ['debian', 'jessie', 80, 1430049600]
>+ | - ['ubuntu', 'precise', 1510, 1335441600]
>+ | - ['debian', 'woody', 30, 1027080000]
>+ | ...
>+box.space._index:select{box.space.distro.id}
>+ | ---
>+ | - - [512, 0, 'primary', 'hash', {'unique': true}, [[0, 'string'], [1, 'string'], [
>+ | 2, 'unsigned']]]
>+ | - [512, 1, 'codename', 'hash', {'unique': true}, [[1, 'string']]]
>+ | - [512, 2, 'time', 'tree', {'unique': false}, [[3, 'unsigned']]]
>+ | ...
>+box.space._space:format()
>+ | ---
>+ | - [{'name': 'id', 'type': 'unsigned'}, {'name': 'owner', 'type': 'unsigned'}, {'name': 'name',
>+ | 'type': 'string'}, {'name': 'engine', 'type': 'string'}, {'name': 'field_count',
>+ | 'type': 'unsigned'}, {'name': 'flags', 'type': 'map'}, {'name': 'format', 'type': 'array'}]
>+ | ...
>+box.schema.user.info('admin')
>+ | ---
>+ | - - - read,write,execute,session,usage,create,drop,alter,reference,trigger,insert,update,delete
>+ | - universe
>+ | -
>+ | ...
>+box.schema.user.info('guest')
>+ | ---
>+ | - - - execute
>+ | - role
>+ | - public
>+ | - - session,usage
>+ | - universe
>+ | -
>+ | ...
>+box.schema.user.info('someuser')
>+ | ---
>+ | - - - execute
>+ | - function
>+ | - someotherfunc
>+ | - - execute
>+ | - role
>+ | - public
>+ | - - execute
>+ | - role
>+ | - somerole
>+ | - - read,write,drop,alter
>+ | - space
>+ | - temporary
>+ | - - session,usage
>+ | - universe
>+ | -
>+ | ...
>+box.schema.role.info('somerole')
>+ | ---
>+ | - - - read,write,drop,alter
>+ | - space
>+ | - distro
>+ | ...
>+
>+test_run:switch('default')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('stop server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('delete server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+
>+-- Upgrade from 1.7.2.
>+test_run:cmd('create server upgrade with script="xlog/upgrade.lua", \
>+ workdir="xlog/upgrade/1.7.2/gh-5894-pre-1.7.7-upgrade"')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('start server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+test_run:switch('upgrade')
>+ | ---
>+ | - true
>+ | ...
>+
>+assert(not box.internal.schema_needs_upgrade())
>+ | ---
>+ | - true
>+ | ...
>+box.space.distro:select{}
>+ | ---
>+ | - - ['debian', 'sarge', 31, 1118059200]
>+ | - ['debian', 'etch', 40, 1176033600]
>+ | - ['ubuntu', 'trusty', 1404, 1397736000]
>+ | - ['ubuntu', 'vivid', 1504, 1429790400]
>+ | - ['debian', 'lenny', 50, 1234612800]
>+ | - ['debian', 'wheezy', 70, 1367668800]
>+ | - ['debian', 'squeeze', 60, 1296907200]
>+ | - ['ubuntu', 'wily', 1510, 1445515200]
>+ | - ['debian', 'jessie', 80, 1430049600]
>+ | - ['ubuntu', 'precise', 1510, 1335441600]
>+ | - ['debian', 'woody', 30, 1027080000]
>+ | ...
>+box.space._index:select{box.space.distro.id}
>+ | ---
>+ | - - [512, 0, 'primary', 'hash', {'unique': true}, [[0, 'string'], [1, 'string'], [
>+ | 2, 'unsigned']]]
>+ | - [512, 1, 'codename', 'hash', {'unique': true}, [[1, 'string']]]
>+ | - [512, 2, 'time', 'tree', {'unique': false}, [[3, 'unsigned']]]
>+ | ...
>+box.space._space:format()
>+ | ---
>+ | - [{'name': 'id', 'type': 'unsigned'}, {'name': 'owner', 'type': 'unsigned'}, {'name': 'name',
>+ | 'type': 'string'}, {'name': 'engine', 'type': 'string'}, {'name': 'field_count',
>+ | 'type': 'unsigned'}, {'name': 'flags', 'type': 'map'}, {'name': 'format', 'type': 'array'}]
>+ | ...
>+box.schema.user.info('admin')
>+ | ---
>+ | - - - read,write,execute,session,usage,create,drop,alter,reference,trigger,insert,update,delete
>+ | - universe
>+ | -
>+ | ...
>+box.schema.user.info('guest')
>+ | ---
>+ | - - - execute
>+ | - role
>+ | - public
>+ | - - session,usage
>+ | - universe
>+ | -
>+ | ...
>+box.schema.user.info('someuser')
>+ | ---
>+ | - - - execute
>+ | - function
>+ | - someotherfunc
>+ | - - execute
>+ | - role
>+ | - public
>+ | - - execute
>+ | - role
>+ | - somerole
>+ | - - read,write,drop,alter
>+ | - space
>+ | - temporary
>+ | - - session,usage
>+ | - universe
>+ | -
>+ | ...
>+box.schema.role.info('somerole')
>+ | ---
>+ | - - - read,write,drop,alter
>+ | - space
>+ | - distro
>+ | ...
>+
>+test_run:switch('default')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('stop server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('delete server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+
>+-- Upgrade from 1.7.5.
>+test_run:cmd('create server upgrade with script="xlog/upgrade.lua", \
>+ workdir="xlog/upgrade/1.7.5/gh-5894-pre-1.7.7-upgrade"')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('start server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+test_run:switch('upgrade')
>+ | ---
>+ | - true
>+ | ...
>+
>+assert(not box.internal.schema_needs_upgrade())
>+ | ---
>+ | - true
>+ | ...
>+box.space.distro:select{}
>+ | ---
>+ | - - ['debian', 'etch', 40, 1176033600]
>+ | - ['debian', 'sarge', 31, 1118059200]
>+ | - ['debian', 'lenny', 50, 1234612800]
>+ | - ['ubuntu', 'trusty', 1404, 1397736000]
>+ | - ['ubuntu', 'vivid', 1504, 1429790400]
>+ | - ['debian', 'wheezy', 70, 1367668800]
>+ | - ['debian', 'squeeze', 60, 1296907200]
>+ | - ['ubuntu', 'wily', 1510, 1445515200]
>+ | - ['debian', 'jessie', 80, 1430049600]
>+ | - ['ubuntu', 'precise', 1510, 1335441600]
>+ | - ['debian', 'woody', 30, 1027080000]
>+ | ...
>+box.space._index:select{box.space.distro.id}
>+ | ---
>+ | - - [512, 0, 'primary', 'hash', {'unique': true}, [[0, 'string'], [1, 'string'], [
>+ | 2, 'unsigned']]]
>+ | - [512, 1, 'codename', 'hash', {'unique': true}, [[1, 'string']]]
>+ | - [512, 2, 'time', 'tree', {'unique': false}, [[3, 'unsigned']]]
>+ | ...
>+box.space._space:format()
>+ | ---
>+ | - [{'name': 'id', 'type': 'unsigned'}, {'name': 'owner', 'type': 'unsigned'}, {'name': 'name',
>+ | 'type': 'string'}, {'name': 'engine', 'type': 'string'}, {'name': 'field_count',
>+ | 'type': 'unsigned'}, {'name': 'flags', 'type': 'map'}, {'name': 'format', 'type': 'array'}]
>+ | ...
>+box.schema.user.info('admin')
>+ | ---
>+ | - - - read,write,execute,session,usage,create,drop,alter,reference,trigger,insert,update,delete
>+ | - universe
>+ | -
>+ | ...
>+box.schema.user.info('guest')
>+ | ---
>+ | - - - execute
>+ | - role
>+ | - public
>+ | - - session,usage
>+ | - universe
>+ | -
>+ | ...
>+box.schema.user.info('someuser')
>+ | ---
>+ | - - - execute
>+ | - function
>+ | - someotherfunc
>+ | - - execute
>+ | - role
>+ | - public
>+ | - - execute
>+ | - role
>+ | - somerole
>+ | - - read,write,drop,alter
>+ | - space
>+ | - temporary
>+ | - - session,usage
>+ | - universe
>+ | -
>+ | ...
>+box.schema.role.info('somerole')
>+ | ---
>+ | - - - read,write,drop,alter
>+ | - space
>+ | - distro
>+ | ...
>+
>+test_run:switch('default')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('stop server upgrade')
>+ | ---
>+ | - true
>+ | ...
>+test_run:cmd('delete server upgrade')
>+ | ---
>+ | - true
>+ | ...
>diff --git a/test/xlog/gh-5894-pre-1.7.7-upgrade.test.lua b/test/xlog/gh-5894-pre-1.7.7-upgrade.test.lua
>new file mode 100644
>index 000000000..9096bcb7a
>--- /dev/null
>+++ b/test/xlog/gh-5894-pre-1.7.7-upgrade.test.lua
>@@ -0,0 +1,77 @@
>+test_run = require('test_run').new()
>+
>+-- Upgrade from 1.6.8.
>+test_run:cmd('create server upgrade with script="xlog/upgrade.lua", \
>+ workdir="xlog/upgrade/1.6.8/gh-5894-pre-1.7.7-upgrade"')
>+test_run:cmd('start server upgrade')
>+test_run:switch('upgrade')
>+
>+assert(not box.internal.schema_needs_upgrade())
>+box.space.distro:select{}
>+box.space._index:select{box.space.distro.id}
>+box.space._space:format()
>+box.schema.user.info('admin')
>+box.schema.user.info('guest')
>+box.schema.user.info('someuser')
>+box.schema.role.info('somerole')
>+
>+test_run:switch('default')
>+test_run:cmd('stop server upgrade')
>+test_run:cmd('delete server upgrade')
>+
>+-- Upgrade from 1.7.1.
>+test_run:cmd('create server upgrade with script="xlog/upgrade.lua", \
>+ workdir="xlog/upgrade/1.7.1/gh-5894-pre-1.7.7-upgrade"')
>+test_run:cmd('start server upgrade')
>+test_run:switch('upgrade')
>+
>+assert(not box.internal.schema_needs_upgrade())
>+box.space.distro:select{}
>+box.space._index:select{box.space.distro.id}
>+box.space._space:format()
>+box.schema.user.info('admin')
>+box.schema.user.info('guest')
>+box.schema.user.info('someuser')
>+box.schema.role.info('somerole')
>+
>+test_run:switch('default')
>+test_run:cmd('stop server upgrade')
>+test_run:cmd('delete server upgrade')
>+
>+-- Upgrade from 1.7.2.
>+test_run:cmd('create server upgrade with script="xlog/upgrade.lua", \
>+ workdir="xlog/upgrade/1.7.2/gh-5894-pre-1.7.7-upgrade"')
>+test_run:cmd('start server upgrade')
>+test_run:switch('upgrade')
>+
>+assert(not box.internal.schema_needs_upgrade())
>+box.space.distro:select{}
>+box.space._index:select{box.space.distro.id}
>+box.space._space:format()
>+box.schema.user.info('admin')
>+box.schema.user.info('guest')
>+box.schema.user.info('someuser')
>+box.schema.role.info('somerole')
>+
>+test_run:switch('default')
>+test_run:cmd('stop server upgrade')
>+test_run:cmd('delete server upgrade')
>+
>+-- Upgrade from 1.7.5.
>+test_run:cmd('create server upgrade with script="xlog/upgrade.lua", \
>+ workdir="xlog/upgrade/1.7.5/gh-5894-pre-1.7.7-upgrade"')
>+test_run:cmd('start server upgrade')
>+test_run:switch('upgrade')
>+
>+assert(not box.internal.schema_needs_upgrade())
>+box.space.distro:select{}
>+box.space._index:select{box.space.distro.id}
>+box.space._space:format()
>+box.schema.user.info('admin')
>+box.schema.user.info('guest')
>+box.schema.user.info('someuser')
>+box.schema.role.info('somerole')
>+
>+test_run:switch('default')
>+test_run:cmd('stop server upgrade')
>+test_run:cmd('delete server upgrade')
>diff --git a/test/xlog/upgrade/1.6.8/gh-5894-pre-1.7.7-upgrade/fill.lua b/test/xlog/upgrade/1.6.8/gh-5894-pre-1.7.7-upgrade/fill.lua
>new file mode 120000
>index 000000000..2f2a84962
>--- /dev/null
>+++ b/test/xlog/upgrade/1.6.8/gh-5894-pre-1.7.7-upgrade/fill.lua
>@@ -0,0 +1 @@
>+../../fill.lua
>\ No newline at end of file
>diff --git a/test/xlog/upgrade/1.7.1/gh-5894-pre-1.7.7-upgrade/fill.lua b/test/xlog/upgrade/1.7.1/gh-5894-pre-1.7.7-upgrade/fill.lua
>new file mode 120000
>index 000000000..2f2a84962
>--- /dev/null
>+++ b/test/xlog/upgrade/1.7.1/gh-5894-pre-1.7.7-upgrade/fill.lua
>@@ -0,0 +1 @@
>+../../fill.lua
>\ No newline at end of file
>diff --git a/test/xlog/upgrade/1.7.2/gh-5894-pre-1.7.7-upgrade/fill.lua b/test/xlog/upgrade/1.7.2/gh-5894-pre-1.7.7-upgrade/fill.lua
>new file mode 120000
>index 000000000..2f2a84962
>--- /dev/null
>+++ b/test/xlog/upgrade/1.7.2/gh-5894-pre-1.7.7-upgrade/fill.lua
>@@ -0,0 +1 @@
>+../../fill.lua
>\ No newline at end of file
>diff --git a/test/xlog/upgrade/1.7.5/gh-5894-pre-1.7.7-upgrade/fill.lua b/test/xlog/upgrade/1.7.5/gh-5894-pre-1.7.7-upgrade/fill.lua
>new file mode 120000
>index 000000000..2f2a84962
>--- /dev/null
>+++ b/test/xlog/upgrade/1.7.5/gh-5894-pre-1.7.7-upgrade/fill.lua
>@@ -0,0 +1 @@
>+../../fill.lua
>\ No newline at end of file
>diff --git a/test/xlog/upgrade/fill.lua b/test/xlog/upgrade/fill.lua
>index 0ef1a8bb9..310c1ca72 100644
>--- a/test/xlog/upgrade/fill.lua
>+++ b/test/xlog/upgrade/fill.lua
>@@ -56,4 +56,8 @@ end
> box.schema.func.create('someotherfunc')
> box.schema.user.grant('someuser', 'execute', 'function', 'someotherfunc')
> box.schema.user.grant('someuser', 'read,write', 'space', 'temporary')
>+
>+box.schema.upgrade()
>+box.snapshot()
>+
> os.exit(0)
>--
>2.30.1 (Apple Git-130) 
 
 
--
Oleg Babin
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.tarantool.org/pipermail/tarantool-patches/attachments/20210816/69e40ce4/attachment.htm>


More information about the Tarantool-patches mailing list