[Tarantool-patches] [PATCH] box: check schema version after tarantool update
Roman Khabibov
roman.habibov at tarantool.org
Wed Dec 2 03:16:17 MSK 2020
Hi! Thanks for the review.
> On Dec 1, 2020, at 12:58, Serge Petrenko <sergepetrenko at tarantool.org> wrote:
>
>
> 30.11.2020 16:43, Roman Khabibov пишет:
>> Thanks.
>>
>> Serge, could you, please, look through the patch?
>
>
> Hi! Thanks for the patch!
>
> Since you're working on this instead of Sergey now, you may add yourself to
>
> the Co-developed-by field in the commit message, like it is done here:
>
> https://github.com/tarantool/tarantool/commit/cfccfd449c890c18615185ba4895d9081e50c318
>
>
> Please see 3 more comments below.
>
>
>> commit 8b3265c1599772f5a85e47ed1a8232571ec23f8d
>> Author: Sergey Voinov <sergeiv at tarantool.org>
>> Date: Wed Dec 11 17:28:39 2019 +0300
>>
>> box: check schema version after tarantool update
>> Check schema version (stored in box.space._schema) on start and
>> print a warning if it doesn't match last available schema version.
>> It is needed because some users forget to call
>> box.schema.upgrade() after Tarantool update and get stuck with an
>> old schema version until they encounter some hard to debug
>> problems.
>> Closes #4574
>>
>> diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
>> index 76e2e92c2..451247dcf 100644
>> --- a/src/box/lua/load_cfg.lua
>> +++ b/src/box/lua/load_cfg.lua
>> @@ -702,6 +702,22 @@ local function load_cfg(cfg)
>> box_configured = nil
>> box_is_configured = true
>> +
>> + -- Check if schema version matches Tarantool version
>> + -- and print warning if it's not (in case user forgot to call box.schema.upgrade())
>> + local version = box.space._schema:get{'version'}
>
>
> 1. Version unused. You get schema version in `schema_needs_upgrade()` anyway.
>
> Also you may omit testing for nil here. You may just test schema version
> inside `schema_needs_upgrade()` and simply return false, if it is nil.
>
>
> You'll also need to update test/box/stat.result after this is done.
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index 76e2e92c2..770442052 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -702,6 +702,18 @@ local function load_cfg(cfg)
box_configured = nil
box_is_configured = true
+
+ -- Check if schema version matches Tarantool version and print
+ -- warning if it's not (in case user forgot to call
+ -- box.schema.upgrade()).
+ local needs, schema_version_str = private.schema_needs_upgrade()
+ if needs then
+ local msg = string.format(
+ 'Your schema version is %s while Tarantool %s requires a more'..
+ ' recent schema version. Please, consider using box.'..
+ 'schema.upgrade().', schema_version_str, box.info.version)
+ log.warn(msg)
+ end
end
box.cfg = locked(load_cfg)
>
>> + if version ~= nil then
>> + local needs, schema_version_str = private.schema_needs_upgrade()
>> + local tarantool_version_str = box.info.version
>> + if needs then
>> + -- Print the warning
>> + local msg = string.format(
>> + 'Your schema version is %s while Tarantool %s requires a more'..
>> + ' recent schema version. Please, consider using box.'..
>> + 'schema.upgrade().', schema_version_str, tarantool_version_str)
>> + log.warn(msg)
>> + end
>> + end
>> end
>> box.cfg = locked(load_cfg)
>>
>
>> diff --git a/test/box/cfg.test.lua b/test/box/cfg.test.lua
>> index 56018b1a0..e806c9efe 100644
>> --- a/test/box/cfg.test.lua
>> +++ b/test/box/cfg.test.lua
>> @@ -159,3 +159,21 @@ test_run:grep_log('cfg_tester7', 'set \'replication\' configuration option to',
>> test_run:grep_log('cfg_tester7', 'test%-cluster%-cookie', 1000)
>> test_run:cmd("stop server cfg_tester7")
>> test_run:cmd("cleanup server cfg_tester7")
>> +
>> +--
>> +-- gh-4574: Check schema version after Tarantool update.
>> +--
>> +test_run:cmd('create server cfg_tester8 with script = "box/lua/cfg_test8.lua", workdir="sql/upgrade/2.1.0/"')
>
>
> 2. Can you reuse `cfg_test1.lua` here?
No, I need to have "read_only = true”.
>
>> +test_run:cmd("start server cfg_tester8")
>> +--- Check that the warning is printed.
>> +version_warning = "Please, consider using box.schema.upgrade()."
>> +test_run:grep_log('cfg_tester8', version_warning, 1000) ~= nil
>
>
> 3. Better use `wait_log` instead of `grep_log`. It's not guaranteed that the
> server will print this message by the time you grep for it.
Done.
>
>> +test_run:cmd("stop server cfg_tester8")
>> +test_run:cmd("cleanup server cfg_tester8")
>> +
>> +test_run:cmd('create server cfg_tester9 with script = "box/lua/cfg_test1.lua"')
>> +test_run:cmd("start server cfg_tester9")
>> +--- Check that the warning isn't printed.
>> +test_run:grep_log('cfg_tester9', version_warning, 1000) == nil
>> +test_run:cmd("stop server cfg_tester9")
>> +test_run:cmd("cleanup server cfg_tester9")
>> diff --git a/test/box/lua/cfg_test8.lua b/test/box/lua/cfg_test8.lua
>> new file mode 100644
>> index 000000000..c61b86ae3
>> --- /dev/null
>> +++ b/test/box/lua/cfg_test8.lua
>> @@ -0,0 +1,9 @@
>> +#!/usr/bin/env tarantool
>> +os = require('os')
>> +
>> +box.cfg{
>> + listen = os.getenv("LISTEN"),
>> + read_only = true
>> +}
>> +
>> +require('console').listen(os.getenv('ADMIN'))
>
> --
> Serge Petrenko
>
commit ca9744ddab1f04663ef5fe0c1e7dc872cf6d55fd
Author: Sergey Voinov <sergeiv at tarantool.org>
Date: Wed Dec 11 17:28:39 2019 +0300
box: check schema version after tarantool update
Check schema version (stored in box.space._schema) on start and
print a warning if it doesn't match last available schema version.
It is needed because some users forget to call
box.schema.upgrade() after Tarantool update and get stuck with an
old schema version until they encounter some hard to debug
problems.
Closes #4574
Co-developed-by: Roman Khabibov <roman.habibov at tarantool.org>
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index 76e2e92c2..770442052 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -702,6 +702,18 @@ local function load_cfg(cfg)
box_configured = nil
box_is_configured = true
+
+ -- Check if schema version matches Tarantool version and print
+ -- warning if it's not (in case user forgot to call
+ -- box.schema.upgrade()).
+ local needs, schema_version_str = private.schema_needs_upgrade()
+ if needs then
+ local msg = string.format(
+ 'Your schema version is %s while Tarantool %s requires a more'..
+ ' recent schema version. Please, consider using box.'..
+ 'schema.upgrade().', schema_version_str, box.info.version)
+ log.warn(msg)
+ end
end
box.cfg = locked(load_cfg)
diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua
index add791cd7..a86a0d410 100644
--- a/src/box/lua/upgrade.lua
+++ b/src/box/lua/upgrade.lua
@@ -973,6 +973,21 @@ end
--------------------------------------------------------------------------------
+local handlers = {
+ {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},
+ {version = mkversion(1, 10, 2), func = upgrade_to_1_10_2, auto = true},
+ {version = mkversion(2, 1, 0), func = upgrade_to_2_1_0, auto = true},
+ {version = mkversion(2, 1, 1), func = upgrade_to_2_1_1, auto = true},
+ {version = mkversion(2, 1, 2), func = upgrade_to_2_1_2, auto = true},
+ {version = mkversion(2, 1, 3), func = upgrade_to_2_1_3, auto = true},
+ {version = mkversion(2, 2, 1), func = upgrade_to_2_2_1, auto = true},
+ {version = mkversion(2, 3, 0), func = upgrade_to_2_3_0, auto = true},
+ {version = mkversion(2, 3, 1), func = upgrade_to_2_3_1, auto = true},
+}
+
+-- Schema version of the snapshot.
local function get_version()
local version = box.space._schema:get{'version'}
if version == nil then
@@ -982,7 +997,19 @@ local function get_version()
local minor = version[3]
local patch = version[4] or 0
- return mkversion(major, minor, patch)
+ return mkversion(major, minor, patch),
+ string.format("%s.%s.%s", major, minor, patch)
+end
+
+local function schema_needs_upgrade()
+ -- Schema needs upgrade if current schema version is greater
+ -- than schema version of the snapshot.
+ local schema_version, schema_version_str = get_version()
+ if schema_version ~= nil and
+ handlers[#handlers].version > schema_version then
+ return true, schema_version_str
+ end
+ return false
end
local function upgrade(options)
@@ -995,20 +1022,6 @@ local function upgrade(options)
return
end
- local handlers = {
- {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},
- {version = mkversion(1, 10, 2), func = upgrade_to_1_10_2, auto = true},
- {version = mkversion(2, 1, 0), func = upgrade_to_2_1_0, auto = true},
- {version = mkversion(2, 1, 1), func = upgrade_to_2_1_1, auto = true},
- {version = mkversion(2, 1, 2), func = upgrade_to_2_1_2, auto = true},
- {version = mkversion(2, 1, 3), func = upgrade_to_2_1_3, auto = true},
- {version = mkversion(2, 2, 1), func = upgrade_to_2_2_1, auto = true},
- {version = mkversion(2, 3, 0), func = upgrade_to_2_3_0, auto = true},
- {version = mkversion(2, 3, 1), func = upgrade_to_2_3_1, auto = true},
- }
-
for _, handler in ipairs(handlers) do
if version >= handler.version then
goto continue
@@ -1047,3 +1060,4 @@ end
box.schema.upgrade = upgrade;
box.internal.bootstrap = bootstrap;
+box.internal.schema_needs_upgrade = schema_needs_upgrade;
diff --git a/test/box/cfg.result b/test/box/cfg.result
index 4ad3c6493..5ca6ce72b 100644
--- a/test/box/cfg.result
+++ b/test/box/cfg.result
@@ -656,3 +656,53 @@ test_run:cmd("cleanup server cfg_tester7")
| ---
| - true
| ...
+
+--
+-- gh-4574: Check schema version after Tarantool update.
+--
+test_run:cmd('create server cfg_tester8 with script = "box/lua/cfg_test8.lua", workdir="sql/upgrade/2.1.0/"')
+ | ---
+ | - true
+ | ...
+test_run:cmd("start server cfg_tester8")
+ | ---
+ | - true
+ | ...
+--- Check that the warning is printed.
+version_warning = "Please, consider using box.schema.upgrade()."
+ | ---
+ | ...
+test_run:wait_log('cfg_tester8', version_warning, 1000, 1.0) ~= nil
+ | ---
+ | - true
+ | ...
+test_run:cmd("stop server cfg_tester8")
+ | ---
+ | - true
+ | ...
+test_run:cmd("cleanup server cfg_tester8")
+ | ---
+ | - true
+ | ...
+
+test_run:cmd('create server cfg_tester9 with script = "box/lua/cfg_test1.lua"')
+ | ---
+ | - true
+ | ...
+test_run:cmd("start server cfg_tester9")
+ | ---
+ | - true
+ | ...
+--- Check that the warning isn't printed.
+test_run:wait_log('cfg_tester9', version_warning, 1000, 1.0) == nil
+ | ---
+ | - true
+ | ...
+test_run:cmd("stop server cfg_tester9")
+ | ---
+ | - true
+ | ...
+test_run:cmd("cleanup server cfg_tester9")
+ | ---
+ | - true
+ | ...
diff --git a/test/box/cfg.test.lua b/test/box/cfg.test.lua
index 56018b1a0..74100adaa 100644
--- a/test/box/cfg.test.lua
+++ b/test/box/cfg.test.lua
@@ -159,3 +159,21 @@ test_run:grep_log('cfg_tester7', 'set \'replication\' configuration option to',
test_run:grep_log('cfg_tester7', 'test%-cluster%-cookie', 1000)
test_run:cmd("stop server cfg_tester7")
test_run:cmd("cleanup server cfg_tester7")
+
+--
+-- gh-4574: Check schema version after Tarantool update.
+--
+test_run:cmd('create server cfg_tester8 with script = "box/lua/cfg_test8.lua", workdir="sql/upgrade/2.1.0/"')
+test_run:cmd("start server cfg_tester8")
+--- Check that the warning is printed.
+version_warning = "Please, consider using box.schema.upgrade()."
+test_run:wait_log('cfg_tester8', version_warning, 1000, 1.0) ~= nil
+test_run:cmd("stop server cfg_tester8")
+test_run:cmd("cleanup server cfg_tester8")
+
+test_run:cmd('create server cfg_tester9 with script = "box/lua/cfg_test1.lua"')
+test_run:cmd("start server cfg_tester9")
+--- Check that the warning isn't printed.
+test_run:wait_log('cfg_tester9', version_warning, 1000, 1.0) == nil
+test_run:cmd("stop server cfg_tester9")
+test_run:cmd("cleanup server cfg_tester9")
diff --git a/test/box/lua/cfg_test8.lua b/test/box/lua/cfg_test8.lua
new file mode 100644
index 000000000..c61b86ae3
--- /dev/null
+++ b/test/box/lua/cfg_test8.lua
@@ -0,0 +1,9 @@
+#!/usr/bin/env tarantool
+os = require('os')
+
+box.cfg{
+ listen = os.getenv("LISTEN"),
+ read_only = true
+}
+
+require('console').listen(os.getenv('ADMIN'))
diff --git a/test/box/stat.result b/test/box/stat.result
index 55f29fe59..1ed243410 100644
--- a/test/box/stat.result
+++ b/test/box/stat.result
@@ -24,7 +24,7 @@ box.stat.REPLACE.total
...
box.stat.SELECT.total
---
-- 1
+- 2
...
box.stat.ERROR.total
---
@@ -59,7 +59,7 @@ box.stat.REPLACE.total
...
box.stat.SELECT.total
---
-- 5
+- 6
...
-- check exceptions
space:get('Impossible value')
@@ -77,14 +77,14 @@ space:get(1)
...
box.stat.SELECT.total
---
-- 6
+- 7
...
space:get(11)
---
...
box.stat.SELECT.total
---
-- 7
+- 8
...
space:select(5)
---
@@ -92,7 +92,7 @@ space:select(5)
...
box.stat.SELECT.total
---
-- 8
+- 9
...
space:select(15)
---
@@ -100,14 +100,14 @@ space:select(15)
...
box.stat.SELECT.total
---
-- 9
+- 10
...
for _ in space:pairs() do end
---
...
box.stat.SELECT.total
---
-- 10
+- 11
...
-- reset
box.stat.reset()
@@ -157,7 +157,7 @@ box.stat.REPLACE.total
...
box.stat.SELECT.total
---
-- 1
+- 2
...
box.stat.ERROR.total
—
More information about the Tarantool-patches
mailing list