[tarantool-patches] [PATCH 1/2] Update lua space cache just after creation
Georgy Kirichenko
georgy at tarantool.org
Tue Aug 28 19:19:12 MSK 2018
The lua space cache (box.space.*) should be valid just after space is
created because space is ready to accept new records or does not exists
before wal would be written. So invoke a space create/drop trigger after
a space is changed and recall it in a case of rollback.
Relates: 3159
---
src/box/alter.cc | 30 ++++++-----------
test/box/errinj.result | 61 ++++++++++++++++++++++++++++++++++
test/box/errinj.test.lua | 27 +++++++++++++++
test/box/misc.result | 72 ++++++++++++++++++++++++++++++++++++++++
test/box/misc.test.lua | 34 +++++++++++++++++++
5 files changed, 205 insertions(+), 19 deletions(-)
diff --git a/src/box/alter.cc b/src/box/alter.cc
index a6299a12e..b2758a4d9 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -787,7 +787,6 @@ alter_space_commit(struct trigger *trigger, void *event)
op->commit(alter, txn->signature);
}
- trigger_run_xc(&on_alter_space, alter->new_space);
alter->new_space = NULL; /* for alter_space_delete(). */
/*
@@ -825,6 +824,7 @@ alter_space_rollback(struct trigger *trigger, void * /* event */)
struct space *new_space = space_cache_replace(alter->old_space);
assert(new_space == alter->new_space);
(void) new_space;
+ trigger_run_xc(&on_alter_space, alter->old_space);
alter_space_delete(alter);
}
@@ -1417,7 +1417,6 @@ on_drop_space_commit(struct trigger *trigger, void *event)
{
(void) event;
struct space *space = (struct space *)trigger->data;
- trigger_run_xc(&on_alter_space, space);
space_delete(space);
}
@@ -1432,16 +1431,6 @@ on_drop_space_rollback(struct trigger *trigger, void *event)
(void) event;
struct space *space = (struct space *)trigger->data;
space_cache_replace(space);
-}
-
-/**
- * Run the triggers registered on commit of a change in _space.
- */
-static void
-on_create_space_commit(struct trigger *trigger, void *event)
-{
- (void) event;
- struct space *space = (struct space *)trigger->data;
trigger_run_xc(&on_alter_space, space);
}
@@ -1460,6 +1449,7 @@ on_create_space_rollback(struct trigger *trigger, void *event)
struct space *cached = space_cache_delete(space_id(space));
(void) cached;
assert(cached == space);
+ trigger_run_xc(&on_alter_space, space);
space_delete(space);
}
@@ -1626,12 +1616,10 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
* so it's safe to simply drop the space on
* rollback.
*/
- struct trigger *on_commit =
- txn_alter_trigger_new(on_create_space_commit, space);
- txn_on_commit(txn, on_commit);
struct trigger *on_rollback =
txn_alter_trigger_new(on_create_space_rollback, space);
txn_on_rollback(txn, on_rollback);
+ trigger_run_xc(&on_alter_space, space);
} else if (new_tuple == NULL) { /* DELETE */
access_check_ddl(old_space->def->name, old_space->def->id,
old_space->def->uid, SC_SPACE, PRIV_D, true);
@@ -1674,6 +1662,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
struct trigger *on_rollback =
txn_alter_trigger_new(on_drop_space_rollback, space);
txn_on_rollback(txn, on_rollback);
+ trigger_run_xc(&on_alter_space, old_space);
} else { /* UPDATE, REPLACE */
assert(old_space != NULL && new_tuple != NULL);
struct space_def *def =
@@ -1730,6 +1719,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
(void) new UpdateSchemaVersion(alter);
alter_space_do(txn, alter);
alter_guard.is_active = false;
+ trigger_run_xc(&on_alter_space, alter->new_space);
}
}
@@ -1931,6 +1921,7 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)
(void) new UpdateSchemaVersion(alter);
alter_space_do(txn, alter);
scoped_guard.is_active = false;
+ trigger_run_xc(&on_alter_space, alter->new_space);
}
/**
@@ -3180,7 +3171,7 @@ on_replace_dd_sequence_data(struct trigger * /* trigger */, void *event)
* Run the triggers registered on commit of a change in _space.
*/
static void
-on_commit_dd_space_sequence(struct trigger *trigger, void * /* event */)
+on_rollback_dd_space_sequence(struct trigger *trigger, void * /* event */)
{
struct space *space = (struct space *) trigger->data;
trigger_run_xc(&on_alter_space, space);
@@ -3230,9 +3221,9 @@ on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event)
access_check_ddl(space->def->name, space->def->id, space->def->uid,
SC_SPACE, PRIV_A, false);
- struct trigger *on_commit =
- txn_alter_trigger_new(on_commit_dd_space_sequence, space);
- txn_on_commit(txn, on_commit);
+ struct trigger *on_rollback =
+ txn_alter_trigger_new(on_rollback_dd_space_sequence, space);
+ txn_on_rollback(txn, on_rollback);
if (stmt->new_tuple != NULL) { /* INSERT, UPDATE */
struct index *pk = index_find_xc(space, 0);
@@ -3248,6 +3239,7 @@ on_replace_dd_space_sequence(struct trigger * /* trigger */, void *event)
assert(space->sequence == seq);
space->sequence = NULL;
}
+ trigger_run_xc(&on_alter_space, space);
}
/* }}} sequence */
diff --git a/test/box/errinj.result b/test/box/errinj.result
index c7e4ce20b..1fe2c0c44 100644
--- a/test/box/errinj.result
+++ b/test/box/errinj.result
@@ -1571,3 +1571,64 @@ fio = require('fio')
box.space.test:drop()
---
...
+-- allocate a space id to prevent max space id update
+trig = box.schema.space.create('trig')
+---
+...
+trig_id = trig.id
+---
+...
+trig:drop()
+---
+...
+trig = nil
+---
+...
+fiber = require('fiber')
+---
+...
+ch = fiber.channel(1)
+---
+...
+errinj = box.error.injection
+---
+...
+test_run:cmd("setopt delimiter ';'")
+---
+- true
+...
+-- check space exists just after creation
+errinj.set("ERRINJ_WAL_WRITE", true);
+---
+- ok
+...
+_ = fiber.create(function ()
+ fiber.create(function ()
+ pcall(box.schema.space.create, 'trig', {id = trig_id})
+ ch:put(true)
+ end)
+ trig = box.space.trig
+ end);
+---
+...
+trig ~= nil;
+---
+- true
+...
+ch:get();
+---
+- true
+...
+--and not exists after rollback
+box.space.trig;
+---
+- null
+...
+test_run:cmd("setopt delimiter ''");
+---
+- true
+...
+errinj.set("ERRINJ_WAL_WRITE", false)
+---
+- ok
+...
diff --git a/test/box/errinj.test.lua b/test/box/errinj.test.lua
index a3ea659aa..32569f605 100644
--- a/test/box/errinj.test.lua
+++ b/test/box/errinj.test.lua
@@ -557,3 +557,30 @@ fio = require('fio')
#fio.glob(fio.pathjoin(box.cfg.vinyl_dir, box.space.test.id, 0, '*.index.inprogress')) == 0
box.space.test:drop()
+
+
+-- allocate a space id to prevent max space id update
+trig = box.schema.space.create('trig')
+trig_id = trig.id
+trig:drop()
+trig = nil
+fiber = require('fiber')
+ch = fiber.channel(1)
+errinj = box.error.injection
+test_run:cmd("setopt delimiter ';'")
+-- check space exists just after creation
+errinj.set("ERRINJ_WAL_WRITE", true);
+_ = fiber.create(function ()
+ fiber.create(function ()
+ pcall(box.schema.space.create, 'trig', {id = trig_id})
+ ch:put(true)
+ end)
+ trig = box.space.trig
+ end);
+trig ~= nil;
+ch:get();
+--and not exists after rollback
+box.space.trig;
+test_run:cmd("setopt delimiter ''");
+
+errinj.set("ERRINJ_WAL_WRITE", false)
diff --git a/test/box/misc.result b/test/box/misc.result
index 62376754e..e213d7964 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -1196,3 +1196,75 @@ box.cfg{too_long_threshold = too_long_threshold}
s:drop()
---
...
+-- Test if space is visible just after creation
+fiber = require('fiber')
+---
+...
+-- allocate a space id to prevent max space id update
+trig = box.schema.space.create('trig')
+---
+...
+trig_id = trig.id
+---
+...
+trig:drop()
+---
+...
+trig = nil
+---
+...
+ch = fiber.channel(1)
+---
+...
+test_run:cmd("setopt delimiter ';'")
+---
+- true
+...
+-- check space exists just after creation
+_ = fiber.create(function ()
+ fiber.create(function ()
+ box.schema.space.create('trig', {id = trig_id})
+ ch:put(true)
+ end)
+ trig = box.space.trig
+ end);
+---
+...
+trig ~= nil;
+---
+- true
+...
+ch:get();
+---
+- true
+...
+trig == box.space.trig;
+---
+- true
+...
+-- check space does not exists just after deletion
+_ = fiber.create(function ()
+ fiber.create(function ()
+ box.space.trig:drop()
+ ch:put(true)
+ end)
+ trig = box.space.trig
+ end);
+---
+...
+trig == nil;
+---
+- false
+...
+ch:get();
+---
+- true
+...
+box.space.trig;
+---
+- null
+...
+test_run:cmd("setopt delimiter ''");
+---
+- true
+...
diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua
index d6815645e..879e77930 100644
--- a/test/box/misc.test.lua
+++ b/test/box/misc.test.lua
@@ -336,3 +336,37 @@ rows == expected_rows
lsn == expected_lsn
box.cfg{too_long_threshold = too_long_threshold}
s:drop()
+
+-- Test if space is visible just after creation
+fiber = require('fiber')
+-- allocate a space id to prevent max space id update
+trig = box.schema.space.create('trig')
+trig_id = trig.id
+trig:drop()
+trig = nil
+ch = fiber.channel(1)
+test_run:cmd("setopt delimiter ';'")
+-- check space exists just after creation
+_ = fiber.create(function ()
+ fiber.create(function ()
+ box.schema.space.create('trig', {id = trig_id})
+ ch:put(true)
+ end)
+ trig = box.space.trig
+ end);
+trig ~= nil;
+ch:get();
+trig == box.space.trig;
+
+-- check space does not exists just after deletion
+_ = fiber.create(function ()
+ fiber.create(function ()
+ box.space.trig:drop()
+ ch:put(true)
+ end)
+ trig = box.space.trig
+ end);
+trig == nil;
+ch:get();
+box.space.trig;
+test_run:cmd("setopt delimiter ''");
--
2.18.0
More information about the Tarantool-patches
mailing list