[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