Skip to content

Commit beaac90

Browse files
authored
Add upgrade instruction for illegal type names issue (#3253)
Resolves #3229
1 parent 02698af commit beaac90

File tree

5 files changed

+219
-2
lines changed

5 files changed

+219
-2
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env tarantool
2+
3+
local xlog = require('xlog')
4+
local json = require('json')
5+
6+
if arg[1] == nil then
7+
print(('Usage: %s xxxxxxxxxxxxxxxxxxxx.snap'):format(arg[0]))
8+
os.exit(1)
9+
end
10+
11+
local illegal_types = {
12+
[''] = true,
13+
['n'] = true,
14+
['nu'] = true,
15+
['s'] = true,
16+
['st'] = true,
17+
}
18+
19+
local function report_field_def(name, field_def)
20+
local msg = 'A field def in a _space entry %q contains an illegal type: %s'
21+
print(msg:format(name, json.encode(field_def)))
22+
end
23+
24+
local has_broken_format = false
25+
26+
for _, record in xlog.pairs(arg[1]) do
27+
-- Filter inserts.
28+
if record.HEADER == nil or record.HEADER.type ~= 'INSERT' then
29+
goto continue
30+
end
31+
-- Filter _space records.
32+
if record.BODY == nil or record.BODY.space_id ~= 280 then
33+
goto continue
34+
end
35+
36+
local tuple = record.BODY.tuple
37+
local name = tuple[3]
38+
local format = tuple[7]
39+
40+
local is_format_broken = false
41+
for _, field_def in ipairs(format) do
42+
if illegal_types[field_def.type] ~= nil then
43+
report_field_def(name, field_def)
44+
is_format_broken = true
45+
end
46+
47+
if illegal_types[field_def[2]] ~= nil then
48+
report_field_def(name, field_def)
49+
is_format_broken = true
50+
end
51+
52+
end
53+
54+
if is_format_broken then
55+
has_broken_format = true
56+
local msg = 'The following _space entry contains illegal type(s): %s'
57+
print(msg:format(json.encode(record)))
58+
end
59+
::continue::
60+
end
61+
62+
if has_broken_format then
63+
print('')
64+
print(('%s has an illegal type in a space format'):format(arg[1]))
65+
print('It is recommended to proceed with the upgrade instruction:')
66+
print('https://github.com/tarantool/tarantool/wiki/Fix-illegal-field-type-in-a-space-format-when-upgrading-to-2.10.4')
67+
else
68+
print('Everything looks nice!')
69+
end
70+
71+
os.exit(has_broken_format and 2 or 0)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
-- Convert illegal type names in a space format that were
2+
-- allowed before tarantool 2.10.4.
3+
4+
local log = require('log')
5+
local json = require('json')
6+
7+
local transforms = {
8+
[''] = 'num',
9+
['n'] = 'num',
10+
['nu'] = 'num',
11+
['s'] = 'str',
12+
['st'] = 'str',
13+
}
14+
15+
-- The helper for before_replace().
16+
local function transform_field_def(name, field_def, field, new_type)
17+
local field_def_old_str = json.encode(field_def)
18+
field_def[field] = new_type
19+
local field_def_new_str = json.encode(field_def)
20+
21+
local msg = 'Transform a field def in a _space entry %q: %s -> %s'
22+
log.info(msg:format(name, field_def_old_str, field_def_new_str))
23+
end
24+
25+
-- _space trigger.
26+
local function before_replace(_, tuple)
27+
if tuple == nil then return tuple end
28+
29+
local name = tuple[3]
30+
local format = tuple[7]
31+
32+
-- Update format if necessary.
33+
local is_format_changed = false
34+
for i, field_def in ipairs(format) do
35+
local new_type = transforms[field_def.type]
36+
if new_type ~= nil then
37+
transform_field_def(name, field_def, 'type', new_type)
38+
is_format_changed = true
39+
end
40+
41+
local new_type = transforms[field_def[2]]
42+
if new_type ~= nil then
43+
transform_field_def(name, field_def, 2, new_type)
44+
is_format_changed = true
45+
end
46+
end
47+
48+
-- No changed: skip.
49+
if not is_format_changed then return tuple end
50+
51+
-- Rebuild the tuple.
52+
local new_tuple = tuple:transform(7, 1, format)
53+
log.info(('Transformed _space entry %s to %s'):format(
54+
json.encode(tuple), json.encode(new_tuple)))
55+
return new_tuple
56+
end
57+
58+
-- on_schema_init trigger to set before_replace().
59+
local function on_schema_init()
60+
box.space._space:before_replace(before_replace)
61+
end
62+
63+
-- Set the trigger on _space.
64+
box.ctl.on_schema_init(on_schema_init)

doc/book/admin/upgrades.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,5 @@ Version specifics
111111
upgrades/1.6-1.10
112112
upgrades/1.6-2.0-downtime
113113
upgrades/2.10.1
114+
upgrades/2.10.4
115+

doc/book/admin/upgrades/2.10.4.rst

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
.. _admin-upgrades-2.10.4_illegal_type_name:
2+
3+
Fix illegal type names when upgrading to 2.10.4
4+
===============================================
5+
6+
This is an upgrade guide for fixing one specific problem which could happen with field type names.
7+
It's only relevant when you're upgrading from a Tarantool version <=2.10.3 to >=2.10.4.
8+
9+
Before :tarantool-issue:`5940` was fixed, the empty string, ``n``, ``nu``, ``s``,
10+
and ``st`` (that is, leading parts of ``num`` and ``str``) were accepted as valid field types.
11+
Since 2.10.4, Tarantool doesn't accept these strings and they must be replaced with
12+
correct values ``num`` and ``str``.
13+
14+
This instruction is also available on `GitHub <https://github.com/tarantool/tarantool/wiki/Fix-illegal-field-type-in-a-space-format-when-upgrading-to-2.10.4>`__.
15+
16+
Check if your snapshots contain illegal type names
17+
--------------------------------------------------
18+
19+
A snapshot can be validated against the issue using the following script:
20+
21+
.. literalinclude:: ../_includes/script_check_type_names.rst
22+
:language: lua
23+
24+
If the snapshot contains the values that aren't valid in 2.10.4, you'll get
25+
an output like the following:
26+
27+
.. code-block::bash
28+
29+
$ ./verify.lua 00000000000002045336.snap
30+
A field def in a _space entry "hehe" contains an illegal type: {"name":"id","type":"st"}
31+
The following _space entry contains illegal type(s): {"HEADER":{"lsn":342,"type":"INSERT","timestamp":1662160874.6816},"BODY":{"space_id":280,"tuple":[589,1,"hehe","memtx",0,{},[{"name":"id","type":"st"}]]}}
32+
33+
00000000000002045336.snap has an illegal type in a space format
34+
It is recommended to proceed with the upgrade instruction:
35+
https://github.com/tarantool/tarantool/wiki/Fix-illegal-field-type-in-a-space-format-when-upgrading-to-2.10.4
36+
37+
Fix an application file
38+
-----------------------
39+
40+
To fix the application file that contains illegal type names, add the following code in it
41+
**before** the ``box.cfg()``/``vshard.cfg()``/``cartridge.cfg()`` call.
42+
43+
.. note::
44+
45+
In Cartridge applications, the instance file is called ``init.lua``.
46+
47+
48+
.. literalinclude:: ../_includes/script_fix_type_names.rst
49+
:language: lua
50+
51+
You can delete these triggers **after** the ``box.cfg()``/``vshard.cfg()``/``cartridge.cfg()``
52+
call.
53+
54+
An example for a Cartridge application:
55+
56+
.. code-block::lua
57+
58+
-- <..define before_replace function..>
59+
-- <..define on_schema_init function..>
60+
61+
-- Set the trigger on _space.
62+
box.ctl.on_schema_init(on_schema_init)
63+
64+
-- Init cartridge. The snapshot is recovered while configuration.
65+
cartridge.cfg(<...>)
66+
67+
-- Delete the triggers.
68+
box.space._space:before_replace(nil, before_replace)
69+
box.ctl.on_schema_init(nil, on_schema_init)
70+
71+
The triggers will report the changes the make in the following form:
72+
73+
.. code-block::bash
74+
75+
I> Transform a field def in a _space entry "hehe": {"name":"id","type":"st"} -> {"name":"id","type":"str"}
76+
I> Transformed _space entry [589,1,"hehe","memtx",0,{},[{"name":"id","type":"st"}]] to [589,1,"hehe","memtx",0,{},[{"name":"id","type":"str"}]]

doc/release/2.10.4.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ features of the 2.x series.
3030
Breaking Changes
3131
----------------
3232

33-
- Now the empty string, ``n``, ``nu``, ``s``, and ``st`` (that is,
34-
leading parts of
33+
- Now the empty string, ``n``, ``nu``, ``s``, and ``st`` (that is, leading parts of
3534
``num`` and ``str``) are not accepted as valid field types (:tarantool-issue:`5940`).
35+
:ref:`This instruction <admin-upgrades-2.10.4_illegal_type_name>` will help you upgrade
36+
to Tarantool 2.10.4 and newer if you've previously used these values in field types.
3637

3738
Functionality added or changed
3839
------------------------------
@@ -144,6 +145,9 @@ Box
144145
- **[Breaking change]** Now the empty string, ``n``, ``nu``, ``s``, and
145146
``st`` (that is, leading parts of ``num`` and ``str``) are not
146147
accepted as valid field types (:tarantool-issue:`5940`).
148+
:ref:`This instruction <admin-upgrades-2.10.4_illegal_type_name>` will help you upgrade
149+
to Tarantool 2.10.4 and newer if you've previously used these values in field types.
150+
147151
- Fixed a bug when ``type = box.NULL`` in ``key_def.new()`` resulted in
148152
``type = 'unsigned'`` (:tarantool-issue:`5222`).
149153
- The ``_vfunc`` system space now has the same format as ``_func``

0 commit comments

Comments
 (0)