diff --git a/changelogs/unreleased/gh-7800-recover-snap-without-spaces.md b/changelogs/unreleased/gh-7800-recover-snap-without-spaces.md new file mode 100644 index 0000000000000000000000000000000000000000..8da90191e6e1675b6ae95f3e6be1f66dbdca0e02 --- /dev/null +++ b/changelogs/unreleased/gh-7800-recover-snap-without-spaces.md @@ -0,0 +1,4 @@ +## bugfix/box + +* Fixed a crash on recovery from a snapshot, which doesn't include system spaces + (gh-7800). diff --git a/src/box/memtx_engine.cc b/src/box/memtx_engine.cc index faca74651fff09b70dfc09cac71fe25a8dad27fd..3b4e37964c2c0147de5e887f133940001cd3fb85 100644 --- a/src/box/memtx_engine.cc +++ b/src/box/memtx_engine.cc @@ -263,7 +263,7 @@ memtx_engine_recover_snapshot(struct memtx_engine *memtx, } } xlog_cursor_close(&cursor, false); - if (rc < 0 || is_space_system < 0) + if (rc < 0) return -1; /** @@ -278,6 +278,13 @@ memtx_engine_recover_snapshot(struct memtx_engine *memtx, say_error("snapshot `%s' has no EOF marker", cursor.name); } + /* + * Snapshot entries are ordered by the space id, it means that if there + * are no spaces, then all system spaces are definitely missing. + */ + if (is_space_system < 0) + panic("snapshot `%s' has no system spaces", cursor.name); + return 0; } diff --git a/test/box-luatest/gh_7800_data/00000000000000000000.snap b/test/box-luatest/gh_7800_data/00000000000000000000.snap new file mode 100644 index 0000000000000000000000000000000000000000..7dc1f61d242d67cd7db4f553b15866650f69e547 Binary files /dev/null and b/test/box-luatest/gh_7800_data/00000000000000000000.snap differ diff --git a/test/box-luatest/gh_7800_recover_snap_without_spaces_test.lua b/test/box-luatest/gh_7800_recover_snap_without_spaces_test.lua new file mode 100644 index 0000000000000000000000000000000000000000..e4871f3b6f67b8bab925561c36fc90992df6390e --- /dev/null +++ b/test/box-luatest/gh_7800_recover_snap_without_spaces_test.lua @@ -0,0 +1,23 @@ +local t = require('luatest') +local g = t.group('gh-7800') + +g.before_all(function() + local server = require('test.luatest_helpers.server') + g.server = server:new({alias = 'master', + datadir = 'test/box-luatest/gh_7800_data'}) + g.server:start({wait_for_readiness = false}) +end) + +g.after_all(function() + g.server:cleanup() +end) + +g.test_recovery = function() + t.helpers.retrying({}, function() + local fio = require('fio') + local msg = "has no system spaces" + local filename = fio.pathjoin(g.server.workdir, + g.server.alias .. '.log') + t.assert(g.server:grep_log(msg, nil, {filename = filename})) + end) +end