diff --git a/src/box/bootstrap.snap b/src/box/bootstrap.snap index 44992b050e9d73d69608fb92782d1e965f6cdc51..641929b9ee883517c447f58a59201197a3320982 100644 Binary files a/src/box/bootstrap.snap and b/src/box/bootstrap.snap differ diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc index 580e0ea2c0cedb2f12e7e8c666643305c91eb9cd..25b7e36da952d9717a93f1fd5b766a6d2df16b42 100644 --- a/src/box/lua/space.cc +++ b/src/box/lua/space.cc @@ -518,6 +518,8 @@ box_lua_space_init(struct lua_State *L) lua_newtable(L); lua_setfield(L, -2, "schema"); lua_getfield(L, -1, "schema"); + lua_pushnumber(L, BOX_VINYL_DEFERRED_DELETE_ID); + lua_setfield(L, -2, "VINYL_DEFERRED_DELETE_ID"); lua_pushnumber(L, BOX_SCHEMA_ID); lua_setfield(L, -2, "SCHEMA_ID"); lua_pushnumber(L, BOX_SPACE_ID); diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua index ec3826399ab264bd94eb0d9046a773bf57dcc0d2..66de41fd35232277931b796ab1a522c8d27c1019 100644 --- a/src/box/lua/upgrade.lua +++ b/src/box/lua/upgrade.lua @@ -983,8 +983,23 @@ local function upgrade_priv_to_1_10_2() _vpriv.index.object:alter{parts={3, 'string', 4, 'scalar'}} end +local function create_vinyl_deferred_delete_space() + local _space = box.space[box.schema.SPACE_ID] + local _vinyl_deferred_delete = box.space[box.schema.VINYL_DEFERRED_DELETE_ID] + + local format = {} + format[1] = {name = 'space_id', type = 'unsigned'} + format[2] = {name = 'lsn', type = 'unsigned'} + format[3] = {name = 'tuple', type = 'array'} + + log.info("create space _vinyl_deferred_delete") + _space:insert{_vinyl_deferred_delete.id, ADMIN, '_vinyl_deferred_delete', + 'blackhole', 0, {group_id = 1}, format} +end + local function upgrade_to_1_10_2() upgrade_priv_to_1_10_2() + create_vinyl_deferred_delete_space() end local function get_version() diff --git a/src/box/schema.cc b/src/box/schema.cc index 4502ca6dcd4164099d1e4542aa933c7e7e38941a..7f20f36567dfc5247d5c4a022a86cb7bc85e96e6 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -37,7 +37,8 @@ #include "scoped_guard.h" #include "version.h" #include "user.h" -#include <stdio.h> +#include "vclock.h" + /** * @module Data Dictionary * @@ -351,6 +352,39 @@ schema_init() FIELD_TYPE_UNSIGNED, false, NULL, COLL_NONE); sc_space_new(BOX_INDEX_ID, "_index", key_def, &alter_space_on_replace_index, &on_stmt_begin_index); + + /* + * _vinyl_deferred_delete - blackhole that is needed + * for writing deferred DELETE statements generated by + * vinyl compaction tasks to WAL. + * + * There is an intricate ordering dependency between + * recovery of this system space and initialization of + * the vinyl engine, when we set an on_replace trigger + * on the space. To resolve this dependency, we create + * a space stub in schema_init(), then set a trigger in + * engine_begin_initial_recovery(), which is called next, + * then recover WAL rows, executing the trigger for each + * of them. + */ + { + const char *engine = "blackhole"; + const char *name = "_vinyl_deferred_delete"; + struct space_opts opts = space_opts_default; + opts.group_id = GROUP_LOCAL; + struct space_def *def; + def = space_def_new_xc(BOX_VINYL_DEFERRED_DELETE_ID, ADMIN, 0, + name, strlen(name), engine, + strlen(engine), &opts, NULL, 0); + auto def_guard = make_scoped_guard([=] { + space_def_delete(def); + }); + RLIST_HEAD(key_list); + struct space *space = space_new_xc(def, &key_list); + space_cache_replace(space); + init_system_space(space); + trigger_run_xc(&on_alter_space, space); + } } void diff --git a/src/box/schema_def.h b/src/box/schema_def.h index c0444cd11095135b05e03c57fa9eda15864589a2..df83d48d61af9a1280d98e7a8fe01da35fe24de3 100644 --- a/src/box/schema_def.h +++ b/src/box/schema_def.h @@ -66,6 +66,8 @@ static_assert(BOX_INVALID_NAME_MAX <= BOX_NAME_MAX, enum { /** Start of the reserved range of system spaces. */ BOX_SYSTEM_ID_MIN = 256, + /** Space if of _vinyl_deferred_delete. */ + BOX_VINYL_DEFERRED_DELETE_ID = 257, /** Space id of _schema. */ BOX_SCHEMA_ID = 272, /** Space id of _collation. */ diff --git a/src/box/vinyl.c b/src/box/vinyl.c index fd14d1e744aeb8d3f3a0628e77b3dcce0c11098b..18aa1ba5b6188805e4bcea1b2d79aad0b977f485 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -65,6 +65,7 @@ #include "engine.h" #include "space.h" #include "index.h" +#include "schema.h" #include "xstream.h" #include "info.h" #include "column_mask.h" @@ -256,6 +257,8 @@ static const struct engine_vtab vinyl_engine_vtab; static const struct space_vtab vinyl_space_vtab; static const struct index_vtab vinyl_index_vtab; +static struct trigger on_replace_vinyl_deferred_delete; + /** * A quick intro into Vinyl cosmology and file format * -------------------------------------------------- @@ -2771,6 +2774,20 @@ vinyl_engine_abort_checkpoint(struct engine *engine) /** {{{ Recovery */ +/** + * Install trigger on the _vinyl_deferred_delete system space. + * Called on bootstrap and recovery. Note, this function can't + * be called from engine constructor, because the latter is + * invoked before the schema is initialized. + */ +static void +vy_set_deferred_delete_trigger(void) +{ + struct space *space = space_by_id(BOX_VINYL_DEFERRED_DELETE_ID); + assert(space != NULL); + trigger_add(&space->on_replace, &on_replace_vinyl_deferred_delete); +} + static int vinyl_engine_bootstrap(struct engine *engine) { @@ -2780,6 +2797,7 @@ vinyl_engine_bootstrap(struct engine *engine) return -1; vy_quota_set_limit(&e->quota, e->memory); e->status = VINYL_ONLINE; + vy_set_deferred_delete_trigger(); return 0; } @@ -2802,6 +2820,7 @@ vinyl_engine_begin_initial_recovery(struct engine *engine, vy_quota_set_limit(&e->quota, e->memory); e->status = VINYL_INITIAL_RECOVERY_REMOTE; } + vy_set_deferred_delete_trigger(); return 0; } @@ -4265,6 +4284,21 @@ vinyl_space_build_index(struct space *src_space, struct index *new_index, /* }}} Index build */ +/* {{{ Deferred DELETE handling */ + +static void +vy_deferred_delete_on_replace(struct trigger *trigger, void *event) +{ + (void)trigger; + (void)event; +} + +static struct trigger on_replace_vinyl_deferred_delete = { + RLIST_LINK_INITIALIZER, vy_deferred_delete_on_replace, NULL, NULL +}; + +/* }}} Deferred DELETE handling */ + static const struct engine_vtab vinyl_engine_vtab = { /* .shutdown = */ vinyl_engine_shutdown, /* .create_space = */ vinyl_engine_create_space, diff --git a/test/app-tap/tarantoolctl.test.lua b/test/app-tap/tarantoolctl.test.lua index 64f2aa7e717a09f9fc53f2cbe3dca293b7c3d53c..340232ace119f2ddf418abd47d91c68ffb2cee15 100755 --- a/test/app-tap/tarantoolctl.test.lua +++ b/test/app-tap/tarantoolctl.test.lua @@ -384,7 +384,7 @@ do check_ctlcat_xlog(test_i, dir, "--from=3 --to=6 --format=json --show-system --replica 1", "\n", 3) check_ctlcat_xlog(test_i, dir, "--from=3 --to=6 --format=json --show-system --replica 1 --replica 2", "\n", 3) check_ctlcat_xlog(test_i, dir, "--from=3 --to=6 --format=json --show-system --replica 2", "\n", 0) - check_ctlcat_snap(test_i, dir, "--space=280", "---\n", 18) + check_ctlcat_snap(test_i, dir, "--space=280", "---\n", 19) check_ctlcat_snap(test_i, dir, "--space=288", "---\n", 43) end) end) diff --git a/test/box-py/bootstrap.result b/test/box-py/bootstrap.result index cf8242de51751266189a74fc1cfeb393dff694f3..11d67acbb498418ccb9939e5e30b14086ddda0b7 100644 --- a/test/box-py/bootstrap.result +++ b/test/box-py/bootstrap.result @@ -13,7 +13,10 @@ box.space._cluster:select{} ... box.space._space:select{} --- -- - [272, 1, '_schema', 'memtx', 0, {}, [{'type': 'string', 'name': 'key'}]] +- - [257, 1, '_vinyl_deferred_delete', 'blackhole', 0, {'group_id': 1}, [{'name': 'space_id', + 'type': 'unsigned'}, {'name': 'lsn', 'type': 'unsigned'}, {'name': 'tuple', + 'type': 'array'}]] + - [272, 1, '_schema', 'memtx', 0, {}, [{'type': 'string', 'name': 'key'}]] - [276, 1, '_collation', 'memtx', 0, {}, [{'name': 'id', 'type': 'unsigned'}, { 'name': 'name', 'type': 'string'}, {'name': 'owner', 'type': 'unsigned'}, {'name': 'type', 'type': 'string'}, {'name': 'locale', 'type': 'string'}, { diff --git a/test/box/access_misc.result b/test/box/access_misc.result index c1809d69aa9cdcf1641544268062653031c99fdb..7c8abeccd20c80fec3ee83862199ae80437738cf 100644 --- a/test/box/access_misc.result +++ b/test/box/access_misc.result @@ -752,7 +752,10 @@ box.space._user:select() ... box.space._space:select() --- -- - [272, 1, '_schema', 'memtx', 0, {}, [{'type': 'string', 'name': 'key'}]] +- - [257, 1, '_vinyl_deferred_delete', 'blackhole', 0, {'group_id': 1}, [{'name': 'space_id', + 'type': 'unsigned'}, {'name': 'lsn', 'type': 'unsigned'}, {'name': 'tuple', + 'type': 'array'}]] + - [272, 1, '_schema', 'memtx', 0, {}, [{'type': 'string', 'name': 'key'}]] - [276, 1, '_collation', 'memtx', 0, {}, [{'name': 'id', 'type': 'unsigned'}, { 'name': 'name', 'type': 'string'}, {'name': 'owner', 'type': 'unsigned'}, {'name': 'type', 'type': 'string'}, {'name': 'locale', 'type': 'string'}, { diff --git a/test/box/access_sysview.result b/test/box/access_sysview.result index 20efd2bbce4aaff8c216296e11bc78093f7f03a1..bc5e069fea54991aa85faf607dfc29022d4af2f5 100644 --- a/test/box/access_sysview.result +++ b/test/box/access_sysview.result @@ -230,7 +230,7 @@ box.session.su('guest') ... #box.space._vspace:select{} --- -- 19 +- 20 ... #box.space._vindex:select{} --- diff --git a/test/wal_off/alter.result b/test/wal_off/alter.result index afac1e55d41da8eccb7927492ca3c948c5af1ffb..f4703395c136be747b981d146d0a17a5976bceca 100644 --- a/test/wal_off/alter.result +++ b/test/wal_off/alter.result @@ -28,7 +28,7 @@ end; ... #spaces; --- -- 65515 +- 65513 ... -- cleanup for k, v in pairs(spaces) do diff --git a/test/xlog/upgrade.result b/test/xlog/upgrade.result index 76467baf15c45a03b533580321f008edc3d22cdc..073bab3f8afc3ec3c6a9b880cda12522a7736dfb 100644 --- a/test/xlog/upgrade.result +++ b/test/xlog/upgrade.result @@ -40,7 +40,10 @@ box.space._schema:select() ... box.space._space:select() --- -- - [272, 1, '_schema', 'memtx', 0, {}, [{'type': 'string', 'name': 'key'}]] +- - [257, 1, '_vinyl_deferred_delete', 'blackhole', 0, {'group_id': 1}, [{'name': 'space_id', + 'type': 'unsigned'}, {'name': 'lsn', 'type': 'unsigned'}, {'name': 'tuple', + 'type': 'array'}]] + - [272, 1, '_schema', 'memtx', 0, {}, [{'type': 'string', 'name': 'key'}]] - [276, 1, '_collation', 'memtx', 0, {}, [{'name': 'id', 'type': 'unsigned'}, { 'name': 'name', 'type': 'string'}, {'name': 'owner', 'type': 'unsigned'}, {'name': 'type', 'type': 'string'}, {'name': 'locale', 'type': 'string'}, {