Commit Diff


commit - 55e3bb3b9202bcec83dec59d6a08ff4a793f99c8
commit + e0a9aed47b2fdef34db0bccf8a81b91e4b17e65f
blob - /dev/null
blob + 8da90191e6e1675b6ae95f3e6be1f66dbdca0e02 (mode 644)
--- /dev/null
+++ 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).
blob - faca74651fff09b70dfc09cac71fe25a8dad27fd
blob + 3b4e37964c2c0147de5e887f133940001cd3fb85
--- src/box/memtx_engine.cc
+++ src/box/memtx_engine.cc
@@ -263,7 +263,7 @@ memtx_engine_recover_snapshot(struct memtx_engine *mem
 		}
 	}
 	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 *mem
 			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;
 }
 
blob - /dev/null
blob + 7dc1f61d242d67cd7db4f553b15866650f69e547 (mode 644)
Binary files /dev/null and test/box-luatest/gh_7800_data/00000000000000000000.snap differ
blob - /dev/null
blob + e4871f3b6f67b8bab925561c36fc90992df6390e (mode 644)
--- /dev/null
+++ 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