[PATCH 07/10] vinyl: don't access last vylog signature outside vylog implementation

Vladimir Davydov vdavydov.dev at gmail.com
Fri May 17 17:52:41 MSK 2019


Currently, it's updated in the tx thread under the vylog latch. Once we
remove the vylog latch, we'll have to update it from the vylog thread,
which would make it unsafe to access this variable from the tx thread.
Actually, we don't really need to access it from tx. We use it in two
places outside vylog. First, to load the last vylog for garbage
collection, but we can simply pass a special signature value (-1) and
let vylog thread lookup the last vylog file for us. Second, we use it in
the scheduler to collect compacted runs, but there we can use the
signature provided by the general gc infrastructure.
---
 src/box/vinyl.c        |  2 +-
 src/box/vy_log.c       | 11 ++++-------
 src/box/vy_log.h       |  9 ++-------
 src/box/vy_scheduler.c | 12 +++++++++++-
 4 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index d4929a37..36bdba36 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -3464,7 +3464,7 @@ vinyl_engine_collect_garbage(struct engine *engine, const struct vclock *vclock)
 	vy_log_collect_garbage(vclock);
 
 	/* Cleanup run files. */
-	struct vy_recovery *recovery = vy_recovery_new(vy_log_signature(), 0);
+	struct vy_recovery *recovery = vy_recovery_new(-1, 0);
 	if (recovery == NULL) {
 		say_error("failed to recover vylog for garbage collection");
 		return;
diff --git a/src/box/vy_log.c b/src/box/vy_log.c
index 1bc35e82..31bc5c63 100644
--- a/src/box/vy_log.c
+++ b/src/box/vy_log.c
@@ -1190,12 +1190,6 @@ vy_log_collect_garbage(const struct vclock *vclock)
 	xdir_collect_garbage(&vy_log.dir, vclock_sum(vclock), XDIR_GC_ASYNC);
 }
 
-int64_t
-vy_log_signature(void)
-{
-	return vclock_sum(&vy_log.last_checkpoint);
-}
-
 const char *
 vy_log_backup_path(const struct vclock *vclock)
 {
@@ -2185,7 +2179,7 @@ vy_recovery_commit_rebootstrap(struct vy_recovery *recovery)
 			 * The files will be removed when the current
 			 * checkpoint is purged by garbage collector.
 			 */
-			lsm->drop_lsn = vy_log_signature();
+			lsm->drop_lsn = vclock_sum(&vy_log.last_checkpoint);
 		}
 	}
 }
@@ -2383,6 +2377,9 @@ vy_recovery_new_f(struct cbus_call_msg *base)
 {
 	struct vy_recovery_msg *msg = (struct vy_recovery_msg *)base;
 
+	if (msg->signature < 0)
+		msg->signature = vclock_sum(&vy_log.last_checkpoint);
+
 	msg->recovery = vy_recovery_load(msg->signature, msg->flags);
 	if (msg->recovery == NULL)
 		return -1;
diff --git a/src/box/vy_log.h b/src/box/vy_log.h
index 81f62706..bd6a4a0d 100644
--- a/src/box/vy_log.h
+++ b/src/box/vy_log.h
@@ -459,12 +459,6 @@ void
 vy_log_collect_garbage(const struct vclock *vclock);
 
 /**
- * Return the signature of the newest vylog to the time.
- */
-int64_t
-vy_log_signature(void);
-
-/**
  * Return the path to the log file that needs to be backed up
  * in order to recover to checkpoint @vclock.
  */
@@ -569,7 +563,8 @@ enum vy_recovery_flag {
 
 /**
  * Create a recovery context from the metadata log created
- * by checkpoint with the given signature.
+ * by checkpoint with the given signature. Pass -1 to load
+ * the most recent log file.
  *
  * For valid values of @flags, see vy_recovery_flag.
  *
diff --git a/src/box/vy_scheduler.c b/src/box/vy_scheduler.c
index 2d1abc2e..079438c7 100644
--- a/src/box/vy_scheduler.c
+++ b/src/box/vy_scheduler.c
@@ -50,6 +50,7 @@
 #include "txn.h"
 #include "space.h"
 #include "schema.h"
+#include "gc.h"
 #include "xrow.h"
 #include "vy_lsm.h"
 #include "vy_log.h"
@@ -198,6 +199,11 @@ struct vy_task {
 	 */
 	struct vy_slice *first_slice, *last_slice;
 	/**
+	 * For compaction tasks: signature of the last checkpoint
+	 * at the time of task creation.
+	 */
+	int64_t gc_lsn;
+	/**
 	 * Index options may be modified while a task is in
 	 * progress so we save them here to safely access them
 	 * from another thread.
@@ -1459,6 +1465,7 @@ vy_task_compaction_complete(struct vy_task *task)
 	struct vy_lsm *lsm = task->lsm;
 	struct vy_range *range = task->range;
 	struct vy_run *new_run = task->new_run;
+	int64_t gc_lsn = task->gc_lsn;
 	double compaction_time = ev_monotonic_now(loop()) - task->start_time;
 	struct vy_disk_stmt_counter compaction_output = new_run->count;
 	struct vy_disk_stmt_counter compaction_input;
@@ -1510,7 +1517,6 @@ vy_task_compaction_complete(struct vy_task *task)
 		if (slice == last_slice)
 			break;
 	}
-	int64_t gc_lsn = vy_log_signature();
 	rlist_foreach_entry(run, &unused_runs, in_unused)
 		vy_log_drop_run(run->id, gc_lsn);
 	if (new_slice != NULL) {
@@ -1709,6 +1715,10 @@ vy_task_compaction_new(struct vy_scheduler *scheduler, struct vy_worker *worker,
 
 	range->needs_compaction = false;
 
+	struct gc_checkpoint *checkpoint = gc_last_checkpoint();
+	if (checkpoint != NULL)
+		task->gc_lsn = vclock_sum(&checkpoint->vclock);
+
 	task->range = range;
 	task->new_run = new_run;
 	task->wi = wi;
-- 
2.11.0




More information about the Tarantool-patches mailing list