[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