[PATCH 2/2] vinyl: don't compress L1 runs

Vladimir Davydov vdavydov.dev at gmail.com
Wed Apr 10 17:22:54 MSK 2019


L1 runs are usually the most frequently read and smallest runs at the
same time so we gain nothing by compressing them.

Closes #2389
---
https://github.com/tarantool/tarantool/issues/2389
https://github.com/tarantool/tarantool/commits/dv/gh-2389-vy-disable-l1-compression

 src/box/vy_run.c            |  4 +++-
 src/box/vy_run.h            |  4 +++-
 src/box/vy_scheduler.c      | 14 +++++++++----
 src/box/xlog.c              | 16 +++++++++------
 src/box/xlog.h              |  8 ++++++++
 test/unit/vy_point_lookup.c |  2 +-
 test/vinyl/misc.result      | 50 +++++++++++++++++++++++++++++++++++++++++++++
 test/vinyl/misc.test.lua    | 18 ++++++++++++++++
 8 files changed, 103 insertions(+), 13 deletions(-)

diff --git a/src/box/vy_run.c b/src/box/vy_run.c
index faa28f47..ddb375bf 100644
--- a/src/box/vy_run.c
+++ b/src/box/vy_run.c
@@ -2089,7 +2089,7 @@ int
 vy_run_writer_create(struct vy_run_writer *writer, struct vy_run *run,
 		     const char *dirpath, uint32_t space_id, uint32_t iid,
 		     struct key_def *cmp_def, struct key_def *key_def,
-		     uint64_t page_size, double bloom_fpr)
+		     uint64_t page_size, double bloom_fpr, bool no_compression)
 {
 	memset(writer, 0, sizeof(*writer));
 	writer->run = run;
@@ -2100,6 +2100,7 @@ vy_run_writer_create(struct vy_run_writer *writer, struct vy_run *run,
 	writer->key_def = key_def;
 	writer->page_size = page_size;
 	writer->bloom_fpr = bloom_fpr;
+	writer->no_compression = no_compression;
 	if (bloom_fpr < 1) {
 		writer->bloom = tuple_bloom_builder_new(key_def->part_count);
 		if (writer->bloom == NULL)
@@ -2135,6 +2136,7 @@ vy_run_writer_create_xlog(struct vy_run_writer *writer)
 	struct xlog_opts opts = xlog_opts_default;
 	opts.rate_limit = writer->run->env->snap_io_rate_limit;
 	opts.sync_interval = VY_RUN_SYNC_INTERVAL;
+	opts.no_compression = writer->no_compression;
 	if (xlog_create(&writer->data_xlog, path, 0, &meta, &opts) != 0)
 		return -1;
 	return 0;
diff --git a/src/box/vy_run.h b/src/box/vy_run.h
index aedae959..9618d856 100644
--- a/src/box/vy_run.h
+++ b/src/box/vy_run.h
@@ -612,6 +612,8 @@ struct vy_run_writer {
 	 * Current page info capacity. Can grow with page number.
 	 */
 	uint32_t page_info_capacity;
+	/** Don't use compression while writing xlog files. */
+	bool no_compression;
 	/** Xlog to write data. */
 	struct xlog data_xlog;
 	/** Bloom filter false positive rate. */
@@ -632,7 +634,7 @@ int
 vy_run_writer_create(struct vy_run_writer *writer, struct vy_run *run,
 		     const char *dirpath, uint32_t space_id, uint32_t iid,
 		     struct key_def *cmp_def, struct key_def *key_def,
-		     uint64_t page_size, double bloom_fpr);
+		     uint64_t page_size, double bloom_fpr, bool no_compression);
 
 /**
  * Write a specified statement into a run.
diff --git a/src/box/vy_scheduler.c b/src/box/vy_scheduler.c
index 8f6279dc..d56a505a 100644
--- a/src/box/vy_scheduler.c
+++ b/src/box/vy_scheduler.c
@@ -1026,7 +1026,7 @@ vy_task_deferred_delete_iface = {
 };
 
 static int
-vy_task_write_run(struct vy_task *task)
+vy_task_write_run(struct vy_task *task, bool no_compression)
 {
 	enum { YIELD_LOOPS = 32 };
 
@@ -1047,7 +1047,8 @@ vy_task_write_run(struct vy_task *task)
 	if (vy_run_writer_create(&writer, task->new_run, lsm->env->path,
 				 lsm->space_id, lsm->index_id,
 				 task->cmp_def, task->key_def,
-				 task->page_size, task->bloom_fpr) != 0)
+				 task->page_size, task->bloom_fpr,
+				 no_compression) != 0)
 		goto fail;
 
 	if (wi->iface->start(wi) != 0)
@@ -1090,7 +1091,12 @@ fail:
 static int
 vy_task_dump_execute(struct vy_task *task)
 {
-	return vy_task_write_run(task);
+	/*
+	 * Don't compress L1 runs as they are most frequently read
+	 * and smallest runs at the same time and so we would gain
+	 * nothing by compressing them.
+	 */
+	return vy_task_write_run(task, true);
 }
 
 static int
@@ -1431,7 +1437,7 @@ vy_task_compaction_execute(struct vy_task *task)
 		while (errinj->bparam)
 			fiber_sleep(0.01);
 	}
-	return vy_task_write_run(task);
+	return vy_task_write_run(task, false);
 }
 
 static int
diff --git a/src/box/xlog.c b/src/box/xlog.c
index 1e423ecc..b70e8e25 100644
--- a/src/box/xlog.c
+++ b/src/box/xlog.c
@@ -94,6 +94,7 @@ const struct xlog_opts xlog_opts_default = {
 	.sync_interval = 0,
 	.free_cache = false,
 	.sync_is_async = false,
+	.no_compression = false,
 };
 
 /* {{{ struct xlog_meta */
@@ -772,11 +773,13 @@ xlog_init(struct xlog *xlog, const struct xlog_opts *opts)
 	xlog->is_autocommit = true;
 	obuf_create(&xlog->obuf, &cord()->slabc, XLOG_TX_AUTOCOMMIT_THRESHOLD);
 	obuf_create(&xlog->zbuf, &cord()->slabc, XLOG_TX_AUTOCOMMIT_THRESHOLD);
-	xlog->zctx = ZSTD_createCCtx();
-	if (xlog->zctx == NULL) {
-		diag_set(ClientError, ER_COMPRESSION,
-			 "failed to create context");
-		return -1;
+	if (!opts->no_compression) {
+		xlog->zctx = ZSTD_createCCtx();
+		if (xlog->zctx == NULL) {
+			diag_set(ClientError, ER_COMPRESSION,
+				 "failed to create context");
+			return -1;
+		}
 	}
 	return 0;
 }
@@ -1204,7 +1207,8 @@ xlog_tx_write(struct xlog *log)
 		return 0;
 	ssize_t written;
 
-	if (obuf_size(&log->obuf) >= XLOG_TX_COMPRESS_THRESHOLD) {
+	if (!log->opts.no_compression &&
+	    obuf_size(&log->obuf) >= XLOG_TX_COMPRESS_THRESHOLD) {
 		written = xlog_tx_write_zstd(log);
 	} else {
 		written = xlog_tx_write_plain(log);
diff --git a/src/box/xlog.h b/src/box/xlog.h
index 46826573..6539d1b0 100644
--- a/src/box/xlog.h
+++ b/src/box/xlog.h
@@ -74,6 +74,14 @@ struct xlog_opts {
 	 * block writers when an xlog is rotated.
 	 */
 	bool sync_is_async;
+	/**
+	 * If this flag is set, the xlog writer won't use zstd
+	 * compression.
+	 *
+	 * This option is useful for xlog files that are intended
+	 * to be read frequently, e.g. L1 run files in Vinyl.
+	 */
+	bool no_compression;
 };
 
 extern const struct xlog_opts xlog_opts_default;
diff --git a/test/unit/vy_point_lookup.c b/test/unit/vy_point_lookup.c
index 7471693c..9961a0f7 100644
--- a/test/unit/vy_point_lookup.c
+++ b/test/unit/vy_point_lookup.c
@@ -24,7 +24,7 @@ write_run(struct vy_run *run, const char *dir_name,
 	if (vy_run_writer_create(&writer, run, dir_name,
 				 lsm->space_id, lsm->index_id,
 				 lsm->cmp_def, lsm->key_def,
-				 4096, 0.1) != 0)
+				 4096, 0.1, false) != 0)
 		goto fail;
 
 	if (wi->iface->start(wi) != 0)
diff --git a/test/vinyl/misc.result b/test/vinyl/misc.result
index 4f613cb0..139edb55 100644
--- a/test/vinyl/misc.result
+++ b/test/vinyl/misc.result
@@ -382,3 +382,53 @@ s:select()
 s:drop()
 ---
 ...
+--
+-- gh-2389: L1 runs are not compressed.
+--
+s = box.schema.space.create('test', {engine = 'vinyl'})
+---
+...
+i = s:create_index('pk', {page_size = 100 * 1000, range_size = 1000 * 1000})
+---
+...
+pad = string.rep('x', 1000)
+---
+...
+for k = 1, 10 do s:replace{k, pad} end
+---
+...
+box.snapshot()
+---
+- ok
+...
+stat = i:stat().disk
+---
+...
+stat.bytes_compressed >= stat.bytes
+---
+- true
+...
+for k = 1, 10 do s:replace{k, pad} end
+---
+...
+box.snapshot()
+---
+- ok
+...
+i:compact()
+---
+...
+test_run:wait_cond(function() return i:stat().disk.compaction.count > 0 end)
+---
+- true
+...
+stat = i:stat().disk
+---
+...
+stat.bytes_compressed < stat.bytes / 10
+---
+- true
+...
+s:drop()
+---
+...
diff --git a/test/vinyl/misc.test.lua b/test/vinyl/misc.test.lua
index bffaaf16..f8da578d 100644
--- a/test/vinyl/misc.test.lua
+++ b/test/vinyl/misc.test.lua
@@ -164,3 +164,21 @@ ch2:get()
 box.cfg{read_only = false}
 s:select()
 s:drop()
+
+--
+-- gh-2389: L1 runs are not compressed.
+--
+s = box.schema.space.create('test', {engine = 'vinyl'})
+i = s:create_index('pk', {page_size = 100 * 1000, range_size = 1000 * 1000})
+pad = string.rep('x', 1000)
+for k = 1, 10 do s:replace{k, pad} end
+box.snapshot()
+stat = i:stat().disk
+stat.bytes_compressed >= stat.bytes
+for k = 1, 10 do s:replace{k, pad} end
+box.snapshot()
+i:compact()
+test_run:wait_cond(function() return i:stat().disk.compaction.count > 0 end)
+stat = i:stat().disk
+stat.bytes_compressed < stat.bytes / 10
+s:drop()
-- 
2.11.0




More information about the Tarantool-patches mailing list