From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Vladimir Davydov Subject: [PATCH 2/2] vinyl: don't compress L1 runs Date: Wed, 10 Apr 2019 17:22:54 +0300 Message-Id: <2887580c0693a777c80a64a5bffb329578f79b3f.1554905969.git.vdavydov.dev@gmail.com> In-Reply-To: <1e080cbd666aa2d8ee9038af971ee0220677da0e.1554905969.git.vdavydov.dev@gmail.com> References: <1e080cbd666aa2d8ee9038af971ee0220677da0e.1554905969.git.vdavydov.dev@gmail.com> In-Reply-To: <1e080cbd666aa2d8ee9038af971ee0220677da0e.1554905969.git.vdavydov.dev@gmail.com> References: <1e080cbd666aa2d8ee9038af971ee0220677da0e.1554905969.git.vdavydov.dev@gmail.com> To: kostja@tarantool.org Cc: tarantool-patches@freelists.org List-ID: 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