[PATCH 2/2] vinyl: apply box.cfg.snap_io_rate_limit to dump/compaction
Vladimir Davydov
vdavydov.dev at gmail.com
Tue May 29 18:19:37 MSK 2018
Vinyl worker threads can consume all disk bandwidth while performing
dump or compaction, thus stalling DML requests, which also need some
disk bandwidth for WAL. Memtx has a similar problem - it needs to write
snapshot files. In case of memtx, we cope with this problem by limiting
the write rate with box.cfg.snap_io_rate_limit option. Let's reuse this
option for limiting vinyl dump/compaction rate.
Closes #3220
---
src/box/box.cc | 5 +++
src/box/vinyl.c | 6 +++
src/box/vinyl.h | 6 +++
src/box/vy_run.c | 7 +++-
src/box/vy_run.h | 2 +
test/vinyl/snap_io_rate.result | 85 ++++++++++++++++++++++++++++++++++++++++
test/vinyl/snap_io_rate.test.lua | 38 ++++++++++++++++++
7 files changed, 148 insertions(+), 1 deletion(-)
create mode 100644 test/vinyl/snap_io_rate.result
create mode 100644 test/vinyl/snap_io_rate.test.lua
diff --git a/src/box/box.cc b/src/box/box.cc
index ac30eb4d..91c5f9f2 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -698,6 +698,11 @@ box_set_snap_io_rate_limit(void)
assert(memtx != NULL);
memtx_engine_set_snap_io_rate_limit(memtx,
cfg_getd("snap_io_rate_limit"));
+ struct vinyl_engine *vinyl;
+ vinyl = (struct vinyl_engine *)engine_by_name("vinyl");
+ assert(vinyl != NULL);
+ vinyl_engine_set_snap_io_rate_limit(vinyl,
+ cfg_getd("snap_io_rate_limit"));
}
void
diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index f0d26874..2abe5696 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -2787,6 +2787,12 @@ vinyl_engine_set_too_long_threshold(struct vinyl_engine *vinyl,
vinyl->env->lsm_env.too_long_threshold = too_long_threshold;
}
+void
+vinyl_engine_set_snap_io_rate_limit(struct vinyl_engine *vinyl, double limit)
+{
+ vinyl->env->run_env.snap_io_rate_limit = limit * 1024 * 1024;
+}
+
/** }}} Environment */
/* {{{ Checkpoint */
diff --git a/src/box/vinyl.h b/src/box/vinyl.h
index ac7afefb..9fec3d0a 100644
--- a/src/box/vinyl.h
+++ b/src/box/vinyl.h
@@ -76,6 +76,12 @@ void
vinyl_engine_set_too_long_threshold(struct vinyl_engine *vinyl,
double too_long_threshold);
+/**
+ * Update snap_io_rate_limit.
+ */
+void
+vinyl_engine_set_snap_io_rate_limit(struct vinyl_engine *vinyl, double limit);
+
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/box/vy_run.c b/src/box/vy_run.c
index 1011abce..e2edbcaa 100644
--- a/src/box/vy_run.c
+++ b/src/box/vy_run.c
@@ -1956,6 +1956,8 @@ vy_run_write_index(struct vy_run *run, const char *dirpath,
if (xlog_create(&index_xlog, path, 0, &meta) < 0)
return -1;
+ index_xlog.rate_limit = run->env->snap_io_rate_limit;
+
xlog_tx_begin(&index_xlog);
struct xrow_header xrow;
@@ -2035,7 +2037,10 @@ vy_run_writer_create_xlog(struct vy_run_writer *writer)
.filetype = XLOG_META_TYPE_RUN,
.instance_uuid = INSTANCE_UUID,
};
- return xlog_create(&writer->data_xlog, path, 0, &meta);
+ if (xlog_create(&writer->data_xlog, path, 0, &meta) != 0)
+ return -1;
+ writer->data_xlog.rate_limit = writer->run->env->snap_io_rate_limit;
+ return 0;
}
/**
diff --git a/src/box/vy_run.h b/src/box/vy_run.h
index 6551191b..7bafffec 100644
--- a/src/box/vy_run.h
+++ b/src/box/vy_run.h
@@ -54,6 +54,8 @@ struct vy_run_reader;
/** Part of vinyl environment for run read/write */
struct vy_run_env {
+ /** Write rate limit, in bytes per second. */
+ uint64_t snap_io_rate_limit;
/** Mempool for struct vy_page_read_task */
struct mempool read_task_pool;
/** Key for thread-local ZSTD context */
diff --git a/test/vinyl/snap_io_rate.result b/test/vinyl/snap_io_rate.result
new file mode 100644
index 00000000..ecc8d35c
--- /dev/null
+++ b/test/vinyl/snap_io_rate.result
@@ -0,0 +1,85 @@
+fiber = require('fiber')
+---
+...
+digest = require('digest')
+---
+...
+test_run = require('test_run').new()
+---
+...
+MB = 1024 * 1024
+---
+...
+TUPLE_SIZE = 1024
+---
+...
+TUPLE_COUNT = 100
+---
+...
+snap_io_rate_limit = box.cfg.snap_io_rate_limit
+---
+...
+box.cfg{snap_io_rate_limit = 0.1}
+---
+...
+s = box.schema.space.create('test', {engine = 'vinyl'})
+---
+...
+_ = s:create_index('primary', {page_size = TUPLE_SIZE, run_count_per_level = 1, run_size_ratio = 10})
+---
+...
+function fill() for i = 1, TUPLE_COUNT do s:replace{i, digest.urandom(TUPLE_SIZE)} end end
+---
+...
+-- check that snap_io_rate_limit is applied to dump
+fill()
+---
+...
+t1 = fiber.time()
+---
+...
+box.snapshot()
+---
+- ok
+...
+t2 = fiber.time()
+---
+...
+rate = TUPLE_SIZE * TUPLE_COUNT / (t2 - t1) / MB
+---
+...
+rate < box.cfg.snap_io_rate_limit or rate
+---
+- true
+...
+-- check that snap_io_rate_limit is applied to compaction
+fill()
+---
+...
+t1 = fiber.time()
+---
+...
+box.snapshot()
+---
+- ok
+...
+while s.index.primary:info().disk.compact.count == 0 do fiber.sleep(0.001) end
+---
+...
+t2 = fiber.time()
+---
+...
+-- dump + compaction => multiply by 2
+rate = 2 * TUPLE_SIZE * TUPLE_COUNT / (t2 - t1) / MB
+---
+...
+rate < box.cfg.snap_io_rate_limit or rate
+---
+- true
+...
+s:drop()
+---
+...
+box.cfg{snap_io_rate_limit = snap_io_rate_limit}
+---
+...
diff --git a/test/vinyl/snap_io_rate.test.lua b/test/vinyl/snap_io_rate.test.lua
new file mode 100644
index 00000000..836bf537
--- /dev/null
+++ b/test/vinyl/snap_io_rate.test.lua
@@ -0,0 +1,38 @@
+fiber = require('fiber')
+digest = require('digest')
+test_run = require('test_run').new()
+
+MB = 1024 * 1024
+TUPLE_SIZE = 1024
+TUPLE_COUNT = 100
+
+snap_io_rate_limit = box.cfg.snap_io_rate_limit
+box.cfg{snap_io_rate_limit = 0.1}
+
+s = box.schema.space.create('test', {engine = 'vinyl'})
+_ = s:create_index('primary', {page_size = TUPLE_SIZE, run_count_per_level = 1, run_size_ratio = 10})
+
+function fill() for i = 1, TUPLE_COUNT do s:replace{i, digest.urandom(TUPLE_SIZE)} end end
+
+-- check that snap_io_rate_limit is applied to dump
+fill()
+t1 = fiber.time()
+box.snapshot()
+t2 = fiber.time()
+
+rate = TUPLE_SIZE * TUPLE_COUNT / (t2 - t1) / MB
+rate < box.cfg.snap_io_rate_limit or rate
+
+-- check that snap_io_rate_limit is applied to compaction
+fill()
+t1 = fiber.time()
+box.snapshot()
+while s.index.primary:info().disk.compact.count == 0 do fiber.sleep(0.001) end
+t2 = fiber.time()
+
+-- dump + compaction => multiply by 2
+rate = 2 * TUPLE_SIZE * TUPLE_COUNT / (t2 - t1) / MB
+rate < box.cfg.snap_io_rate_limit or rate
+
+s:drop()
+box.cfg{snap_io_rate_limit = snap_io_rate_limit}
--
2.11.0
More information about the Tarantool-patches
mailing list