From: Vladimir Davydov <vdavydov.dev@gmail.com> To: Konstantin Osipov <kostja@tarantool.org> Cc: tarantool-patches@freelists.org Subject: Re: [tarantool-patches] Re: [PATCH 5/9] vinyl: keep track of dumps per compaction for each LSM tree Date: Wed, 6 Feb 2019 19:54:19 +0300 [thread overview] Message-ID: <20190206165419.acqqkdjtk6gdbozg@esperanza> (raw) In-Reply-To: <20190206092003.mhklof7sqdhbym47@esperanza> On Wed, Feb 06, 2019 at 12:20:03PM +0300, Vladimir Davydov wrote: > On Tue, Feb 05, 2019 at 07:58:29PM +0300, Konstantin Osipov wrote: > > * Vladimir Davydov <vdavydov.dev@gmail.com> [19/01/21 06:58]: > > > This patch adds dumps_per_compaction metric to per index statistics. It > > > shows the number of dumps it takes to trigger a major compaction of a > > > range in a given LSM tree. We need it to automatically choose the > > > optimal number of ranges that would smooth out the load generated by > > > range compaction. > > > > I obviously like the idea of dumps_per_compaction :-), but using a > > heap to maintain the minimum sounds like a bit of an overkill. Is > > average so much less accurate? It would be much cheaper to > > maintain. > > I guess we could do that. I'll try. Had to introduce vy_lsm::sum_dumps_per_compaction for that. Here's what it looks like: From cce2fbba22eeeed78b05f76dc9e7d22ef218f3e9 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov.dev@gmail.com> Date: Wed, 6 Feb 2019 19:23:58 +0300 Subject: [PATCH] vinyl: keep track of dumps per compaction for each LSM tree This patch adds dumps_per_compaction metric to per index statistics. It shows the number of dumps it takes to trigger a major compaction of a range in a given LSM tree. We need it to automatically choose the optimal number of ranges that would smooth out the load generated by range compaction. To calculate this metric, we assign dump_count to each run. It shows how many dumps it took to create the run. If a run was created by a memory dump, it is set to 1. If a run was created by a minor compaction, it is set to the sum of dump counts of compacted ranges. If a run was created by a major compaction, it is set to the sum of dump counts of compacted ranges minus dump count of the last level run. The dump_count is stored in vylog. This allows us to estimate the number of dumps that triggers compaction in a range as dump_count of the last level run stored in the range. Finally, we report dumps_per_compaction of an LSM tree as the average dumps_per_compaction among all ranges constituting the tree. Needed for #3944 diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 065a309f..e1ff65ae 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -463,6 +463,8 @@ vinyl_index_stat(struct index *index, struct info_handler *h) info_append_int(h, "run_avg", lsm->run_count / lsm->range_count); histogram_snprint(buf, sizeof(buf), lsm->run_hist); info_append_str(h, "run_histogram", buf); + info_append_int(h, "dumps_per_compaction", + vy_lsm_dumps_per_compaction(lsm)); info_end(h); } diff --git a/src/box/vy_log.c b/src/box/vy_log.c index f94b60ff..06ab7247 100644 --- a/src/box/vy_log.c +++ b/src/box/vy_log.c @@ -84,6 +84,7 @@ enum vy_log_key { VY_LOG_KEY_MODIFY_LSN = 13, VY_LOG_KEY_DROP_LSN = 14, VY_LOG_KEY_GROUP_ID = 15, + VY_LOG_KEY_DUMP_COUNT = 16, }; /** vy_log_key -> human readable name. */ @@ -104,6 +105,7 @@ static const char *vy_log_key_name[] = { [VY_LOG_KEY_MODIFY_LSN] = "modify_lsn", [VY_LOG_KEY_DROP_LSN] = "drop_lsn", [VY_LOG_KEY_GROUP_ID] = "group_id", + [VY_LOG_KEY_DUMP_COUNT] = "dump_count", }; /** vy_log_type -> human readable name. */ @@ -285,6 +287,10 @@ vy_log_record_snprint(char *buf, int size, const struct vy_log_record *record) SNPRINT(total, snprintf, buf, size, "%s=%"PRIi64", ", vy_log_key_name[VY_LOG_KEY_GC_LSN], record->gc_lsn); + if (record->dump_count > 0) + SNPRINT(total, snprintf, buf, size, "%s=%"PRIu32", ", + vy_log_key_name[VY_LOG_KEY_DUMP_COUNT], + record->dump_count); SNPRINT(total, snprintf, buf, size, "}"); return total; } @@ -411,6 +417,11 @@ vy_log_record_encode(const struct vy_log_record *record, size += mp_sizeof_uint(record->gc_lsn); n_keys++; } + if (record->dump_count > 0) { + size += mp_sizeof_uint(VY_LOG_KEY_DUMP_COUNT); + size += mp_sizeof_uint(record->dump_count); + n_keys++; + } size += mp_sizeof_map(n_keys); /* @@ -493,6 +504,10 @@ vy_log_record_encode(const struct vy_log_record *record, pos = mp_encode_uint(pos, VY_LOG_KEY_GC_LSN); pos = mp_encode_uint(pos, record->gc_lsn); } + if (record->dump_count > 0) { + pos = mp_encode_uint(pos, VY_LOG_KEY_DUMP_COUNT); + pos = mp_encode_uint(pos, record->dump_count); + } assert(pos == tuple + size); /* @@ -621,6 +636,9 @@ vy_log_record_decode(struct vy_log_record *record, case VY_LOG_KEY_GC_LSN: record->gc_lsn = mp_decode_uint(&pos); break; + case VY_LOG_KEY_DUMP_COUNT: + record->dump_count = mp_decode_uint(&pos); + break; default: mp_next(&pos); /* unknown key, ignore */ break; @@ -1593,6 +1611,7 @@ vy_recovery_do_create_run(struct vy_recovery *recovery, int64_t run_id) run->id = run_id; run->dump_lsn = -1; run->gc_lsn = -1; + run->dump_count = 0; run->is_incomplete = false; run->is_dropped = false; run->data = NULL; @@ -1647,7 +1666,7 @@ vy_recovery_prepare_run(struct vy_recovery *recovery, int64_t lsm_id, */ static int vy_recovery_create_run(struct vy_recovery *recovery, int64_t lsm_id, - int64_t run_id, int64_t dump_lsn) + int64_t run_id, int64_t dump_lsn, uint32_t dump_count) { struct vy_lsm_recovery_info *lsm; lsm = vy_recovery_lookup_lsm(recovery, lsm_id); @@ -1672,6 +1691,7 @@ vy_recovery_create_run(struct vy_recovery *recovery, int64_t lsm_id, return -1; } run->dump_lsn = dump_lsn; + run->dump_count = dump_count; run->is_incomplete = false; rlist_move_entry(&lsm->runs, run, in_lsm); return 0; @@ -2033,7 +2053,8 @@ vy_recovery_process_record(struct vy_recovery *recovery, break; case VY_LOG_CREATE_RUN: rc = vy_recovery_create_run(recovery, record->lsm_id, - record->run_id, record->dump_lsn); + record->run_id, record->dump_lsn, + record->dump_count); break; case VY_LOG_DROP_RUN: rc = vy_recovery_drop_run(recovery, record->run_id, @@ -2383,6 +2404,7 @@ vy_log_append_lsm(struct xlog *xlog, struct vy_lsm_recovery_info *lsm) } else { record.type = VY_LOG_CREATE_RUN; record.dump_lsn = run->dump_lsn; + record.dump_count = run->dump_count; } record.lsm_id = lsm->id; record.run_id = run->id; diff --git a/src/box/vy_log.h b/src/box/vy_log.h index 70e25245..ee38c193 100644 --- a/src/box/vy_log.h +++ b/src/box/vy_log.h @@ -96,7 +96,7 @@ enum vy_log_record_type { VY_LOG_PREPARE_RUN = 4, /** * Commit a vinyl run file creation. - * Requires vy_log_record::lsm_id, run_id, dump_lsn. + * Requires vy_log_record::lsm_id, run_id, dump_lsn, dump_count. * * Written after a run file was successfully created. */ @@ -271,6 +271,8 @@ struct vy_log_record { * that uses this run. */ int64_t gc_lsn; + /** For runs: number of dumps it took to create the run. */ + uint32_t dump_count; /** Link in vy_log::tx. */ struct stailq_entry in_tx; }; @@ -389,6 +391,8 @@ struct vy_run_recovery_info { * that uses this run. */ int64_t gc_lsn; + /** Number of dumps it took to create the run. */ + uint32_t dump_count; /** * True if the run was not committed (there's * VY_LOG_PREPARE_RUN, but no VY_LOG_CREATE_RUN). @@ -710,7 +714,8 @@ vy_log_prepare_run(int64_t lsm_id, int64_t run_id) /** Helper to log a vinyl run creation. */ static inline void -vy_log_create_run(int64_t lsm_id, int64_t run_id, int64_t dump_lsn) +vy_log_create_run(int64_t lsm_id, int64_t run_id, + int64_t dump_lsn, uint32_t dump_count) { struct vy_log_record record; vy_log_record_init(&record); @@ -718,6 +723,7 @@ vy_log_create_run(int64_t lsm_id, int64_t run_id, int64_t dump_lsn) record.lsm_id = lsm_id; record.run_id = run_id; record.dump_lsn = dump_lsn; + record.dump_count = dump_count; vy_log_write(&record); } diff --git a/src/box/vy_lsm.c b/src/box/vy_lsm.c index 570e783a..6b70cd75 100644 --- a/src/box/vy_lsm.c +++ b/src/box/vy_lsm.c @@ -353,6 +353,7 @@ vy_lsm_recover_run(struct vy_lsm *lsm, struct vy_run_recovery_info *run_info, return NULL; run->dump_lsn = run_info->dump_lsn; + run->dump_count = run_info->dump_count; if (vy_run_recover(run, lsm->env->path, lsm->space_id, lsm->index_id) != 0 && (!force_recovery || @@ -638,6 +639,7 @@ vy_lsm_recover(struct vy_lsm *lsm, struct vy_recovery *recovery, (long long)range->id)); return -1; } + vy_range_update_dumps_per_compaction(range); vy_lsm_acct_range(lsm, range); } if (prev == NULL) { @@ -753,6 +755,7 @@ void vy_lsm_acct_range(struct vy_lsm *lsm, struct vy_range *range) { histogram_collect(lsm->run_hist, range->slice_count); + lsm->sum_dumps_per_compaction += range->dumps_per_compaction; vy_disk_stmt_counter_add(&lsm->stat.disk.compaction.queue, &range->compaction_queue); lsm->env->compaction_queue_size += range->compaction_queue.bytes; @@ -770,6 +773,7 @@ void vy_lsm_unacct_range(struct vy_lsm *lsm, struct vy_range *range) { histogram_discard(lsm->run_hist, range->slice_count); + lsm->sum_dumps_per_compaction -= range->dumps_per_compaction; vy_disk_stmt_counter_sub(&lsm->stat.disk.compaction.queue, &range->compaction_queue); lsm->env->compaction_queue_size -= range->compaction_queue.bytes; @@ -1078,6 +1082,7 @@ vy_lsm_split_range(struct vy_lsm *lsm, struct vy_range *range) } part->needs_compaction = range->needs_compaction; vy_range_update_compaction_priority(part, &lsm->opts); + vy_range_update_dumps_per_compaction(part); } /* @@ -1195,6 +1200,7 @@ vy_lsm_coalesce_range(struct vy_lsm *lsm, struct vy_range *range) * as it fits the configured LSM tree shape. */ vy_range_update_compaction_priority(result, &lsm->opts); + vy_range_update_dumps_per_compaction(result); vy_lsm_acct_range(lsm, result); vy_lsm_add_range(lsm, result); lsm->range_tree_version++; diff --git a/src/box/vy_lsm.h b/src/box/vy_lsm.h index 74033627..eb7cbbf0 100644 --- a/src/box/vy_lsm.h +++ b/src/box/vy_lsm.h @@ -251,6 +251,8 @@ struct vy_lsm { vy_range_tree_t *tree; /** Number of ranges in this LSM tree. */ int range_count; + /** Sum dumps_per_compaction across all ranges. */ + int sum_dumps_per_compaction; /** Heap of ranges, prioritized by compaction_priority. */ heap_t range_heap; /** @@ -351,6 +353,16 @@ vy_lsm_is_empty(struct vy_lsm *lsm) } /** + * Return the averange number of dumps it takes to trigger major + * compaction of a range in this LSM tree. + */ +static inline int +vy_lsm_dumps_per_compaction(struct vy_lsm *lsm) +{ + return lsm->sum_dumps_per_compaction / lsm->range_count; +} + +/** * Increment the reference counter of an LSM tree. * An LSM tree cannot be deleted if its reference * counter is elevated. @@ -464,8 +476,8 @@ vy_lsm_remove_range(struct vy_lsm *lsm, struct vy_range *range); * Account a range in an LSM tree. * * This function updates the following LSM tree statistics: - * - vy_lsm::run_hist after a slice is added to or removed from - * a range of the LSM tree. + * - vy_lsm::run_hist and vy_lsm::sum_dumps_per_compaction after + * a slice is added to or removed from a range of the LSM tree. * - vy_lsm::stat::disk::compaction::queue after compaction priority * of a range is updated. * - vy_lsm::stat::disk::last_level_count after a range is compacted. diff --git a/src/box/vy_range.c b/src/box/vy_range.c index 7211cfb2..19ada26b 100644 --- a/src/box/vy_range.c +++ b/src/box/vy_range.c @@ -411,6 +411,18 @@ vy_range_update_compaction_priority(struct vy_range *range, } } +void +vy_range_update_dumps_per_compaction(struct vy_range *range) +{ + if (!rlist_empty(&range->slices)) { + struct vy_slice *slice = rlist_last_entry(&range->slices, + struct vy_slice, in_range); + range->dumps_per_compaction = slice->run->dump_count; + } else { + range->dumps_per_compaction = 0; + } +} + /** * Return true and set split_key accordingly if the range needs to be * split in two. diff --git a/src/box/vy_range.h b/src/box/vy_range.h index 05195d08..0b3a78c3 100644 --- a/src/box/vy_range.h +++ b/src/box/vy_range.h @@ -119,6 +119,11 @@ struct vy_range { bool needs_compaction; /** Number of times the range was compacted. */ int n_compactions; + /** + * Number of dumps it takes to trigger major compaction in + * this range, see vy_run::dump_count for more details. + */ + int dumps_per_compaction; /** Link in vy_lsm->tree. */ rb_node(struct vy_range) tree_node; /** Link in vy_lsm->range_heap. */ @@ -243,6 +248,12 @@ vy_range_update_compaction_priority(struct vy_range *range, const struct index_opts *opts); /** + * Update the value of range->dumps_per_compaction. + */ +void +vy_range_update_dumps_per_compaction(struct vy_range *range); + +/** * Check if a range needs to be split in two. * * @param range The range. diff --git a/src/box/vy_run.h b/src/box/vy_run.h index 990daffa..28fd6a50 100644 --- a/src/box/vy_run.h +++ b/src/box/vy_run.h @@ -130,6 +130,21 @@ struct vy_run { /** Max LSN stored on disk. */ int64_t dump_lsn; /** + * Number of dumps it took to create this run. + * + * If the run was produced by a memory dump, it is 1. + * If the run was produced by a minor compaction, it + * is is the sum of dump counts of compacted runs. + * If the run was produced by a major compaction, it + * is is the sum of dump counts of compacted runs + * minus the dump count of the last (greatest) run. + * + * This way, by looking at the last level run in an LSM + * tree, we can tell how many dumps it took to compact + * it last time. + */ + uint32_t dump_count; + /** * Run reference counter, the run is deleted once it hits 0. * A new run is created with the reference counter set to 1. * A run is referenced by each slice created for it and each diff --git a/src/box/vy_scheduler.c b/src/box/vy_scheduler.c index 5ec6d171..5c53b423 100644 --- a/src/box/vy_scheduler.c +++ b/src/box/vy_scheduler.c @@ -1193,7 +1193,7 @@ vy_task_dump_complete(struct vy_task *task) * Log change in metadata. */ vy_log_tx_begin(); - vy_log_create_run(lsm->id, new_run->id, dump_lsn); + vy_log_create_run(lsm->id, new_run->id, dump_lsn, new_run->dump_count); for (range = begin_range, i = 0; range != end_range; range = vy_range_tree_next(lsm->tree, range), i++) { assert(i < lsm->range_count); @@ -1226,6 +1226,7 @@ vy_task_dump_complete(struct vy_task *task) vy_lsm_unacct_range(lsm, range); vy_range_add_slice(range, slice); vy_range_update_compaction_priority(range, &lsm->opts); + vy_range_update_dumps_per_compaction(range); vy_lsm_acct_range(lsm, range); } vy_range_heap_update_all(&lsm->range_heap); @@ -1396,6 +1397,7 @@ vy_task_dump_new(struct vy_scheduler *scheduler, struct vy_worker *worker, if (new_run == NULL) goto err_run; + new_run->dump_count = 1; new_run->dump_lsn = dump_lsn; /* @@ -1528,7 +1530,8 @@ vy_task_compaction_complete(struct vy_task *task) rlist_foreach_entry(run, &unused_runs, in_unused) vy_log_drop_run(run->id, gc_lsn); if (new_slice != NULL) { - vy_log_create_run(lsm->id, new_run->id, new_run->dump_lsn); + vy_log_create_run(lsm->id, new_run->id, new_run->dump_lsn, + new_run->dump_count); vy_log_insert_slice(range->id, new_run->id, new_slice->id, tuple_data_or_null(new_slice->begin), tuple_data_or_null(new_slice->end)); @@ -1589,6 +1592,7 @@ vy_task_compaction_complete(struct vy_task *task) } range->n_compactions++; vy_range_update_compaction_priority(range, &lsm->opts); + vy_range_update_dumps_per_compaction(range); vy_lsm_acct_range(lsm, range); vy_lsm_acct_compaction(lsm, compaction_time, &compaction_input, &compaction_output); @@ -1693,12 +1697,14 @@ vy_task_compaction_new(struct vy_scheduler *scheduler, struct vy_worker *worker, goto err_wi; struct vy_slice *slice; + int32_t dump_count = 0; int n = range->compaction_priority; rlist_foreach_entry(slice, &range->slices, in_range) { if (vy_write_iterator_new_slice(wi, slice) != 0) goto err_wi_sub; new_run->dump_lsn = MAX(new_run->dump_lsn, slice->run->dump_lsn); + dump_count += slice->run->dump_count; /* Remember the slices we are compacting. */ if (task->first_slice == NULL) task->first_slice = slice; @@ -1709,6 +1715,17 @@ vy_task_compaction_new(struct vy_scheduler *scheduler, struct vy_worker *worker, } assert(n == 0); assert(new_run->dump_lsn >= 0); + if (range->compaction_priority == range->slice_count) + dump_count -= slice->run->dump_count; + /* + * Do not update dumps_per_compaction in case compaction + * was triggered manually to avoid unexpected side effects, + * such as splitting/coalescing ranges for no good reason. + */ + if (range->needs_compaction) + new_run->dump_count = slice->run->dump_count; + else + new_run->dump_count = dump_count; range->needs_compaction = false; diff --git a/test/vinyl/layout.result b/test/vinyl/layout.result index 3be2bb91..6d58f747 100644 --- a/test/vinyl/layout.result +++ b/test/vinyl/layout.result @@ -139,7 +139,7 @@ result - HEADER: type: INSERT BODY: - tuple: [5, {2: 8, 9: 20}] + tuple: [5, {2: 8, 16: 1, 9: 20}] - HEADER: type: INSERT BODY: @@ -164,7 +164,7 @@ result - HEADER: type: INSERT BODY: - tuple: [5, {0: 2, 2: 6, 9: 20}] + tuple: [5, {0: 2, 2: 6, 16: 1, 9: 20}] - HEADER: type: INSERT BODY: @@ -204,7 +204,7 @@ result timestamp: <timestamp> type: INSERT BODY: - tuple: [5, {0: 2, 2: 10, 9: 23}] + tuple: [5, {0: 2, 2: 10, 16: 1, 9: 23}] - HEADER: timestamp: <timestamp> type: INSERT @@ -224,7 +224,7 @@ result timestamp: <timestamp> type: INSERT BODY: - tuple: [5, {2: 12, 9: 23}] + tuple: [5, {2: 12, 16: 1, 9: 23}] - HEADER: timestamp: <timestamp> type: INSERT diff --git a/test/vinyl/stat.result b/test/vinyl/stat.result index 419d3e6c..e79c32f0 100644 --- a/test/vinyl/stat.result +++ b/test/vinyl/stat.result @@ -129,7 +129,8 @@ test_run:cmd("setopt delimiter ''"); -- initially stats are empty istat() --- -- rows: 0 +- dumps_per_compaction: 0 + rows: 0 run_avg: 0 bytes: 0 upsert: @@ -294,10 +295,7 @@ wait(istat, st, 'disk.dump.count', 1) ... stat_diff(istat(), st) --- -- rows: 25 - run_avg: 1 - run_count: 1 - disk: +- disk: last_level: bytes: 26049 pages: 7 @@ -321,6 +319,10 @@ stat_diff(istat(), st) pages: 7 bytes_compressed: <bytes_compressed> bloom_size: 70 + rows: 25 + run_avg: 1 + run_count: 1 + dumps_per_compaction: 1 bytes: 26049 put: rows: 25 @@ -998,7 +1000,8 @@ box.stat.reset() ... istat() --- -- rows: 306 +- dumps_per_compaction: 1 + rows: 306 run_avg: 1 bytes: 317731 upsert: @@ -1732,6 +1735,138 @@ box.stat.vinyl().disk.data_compacted --- - 0 ... +-- +-- Number of dumps needed to trigger major compaction in +-- an LSM tree range. +-- +s = box.schema.space.create('test', {engine = 'vinyl'}) +--- +... +i = s:create_index('primary', {page_size = 128, range_size = 8192, run_count_per_level = 1, run_size_ratio = 2}) +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function dump(a, b) + for i = a, b do + s:replace{i, digest.urandom(100)} + end + box.snapshot() +end; +--- +... +function wait_compaction(count) + test_run:wait_cond(function() + return i:stat().disk.compaction.count == count + end, 10) +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +dump(1, 100) +--- +... +i:stat().dumps_per_compaction -- 1 +--- +- 1 +... +dump(1, 100) -- compaction +--- +... +dump(1, 100) -- split + compaction +--- +... +wait_compaction(3) +--- +... +i:stat().range_count -- 2 +--- +- 2 +... +i:stat().dumps_per_compaction -- 1 +--- +- 1 +... +dump(1, 10) +--- +... +dump(1, 40) -- compaction in range 1 +--- +... +wait_compaction(4) +--- +... +i:stat().dumps_per_compaction -- 1 +--- +- 1 +... +dump(90, 100) +--- +... +dump(60, 100) -- compaction in range 2 +--- +... +wait_compaction(5) +--- +... +i:stat().dumps_per_compaction -- 2 +--- +- 2 +... +-- Forcing compaction manually doesn't affect dumps_per_compaction. +dump(40, 60) +--- +... +i:compact() +--- +... +wait_compaction(7) +--- +... +i:stat().dumps_per_compaction -- 2 +--- +- 2 +... +test_run:cmd('restart server test') +fiber = require('fiber') +--- +... +digest = require('digest') +--- +... +s = box.space.test +--- +... +i = s.index.primary +--- +... +i:stat().dumps_per_compaction -- 2 +--- +- 2 +... +for i = 1, 100 do s:replace{i, digest.urandom(100)} end +--- +... +box.snapshot() +--- +- ok +... +test_run:wait_cond(function() return i:stat().disk.compaction.count == 2 end, 10) +--- +- true +... +i:stat().dumps_per_compaction -- 1 +--- +- 1 +... +s:drop() +--- +... test_run:cmd('switch default') --- - true diff --git a/test/vinyl/stat.test.lua b/test/vinyl/stat.test.lua index 4a955682..4a360f33 100644 --- a/test/vinyl/stat.test.lua +++ b/test/vinyl/stat.test.lua @@ -528,6 +528,69 @@ s:drop() box.stat.vinyl().disk.data_compacted +-- +-- Number of dumps needed to trigger major compaction in +-- an LSM tree range. +-- +s = box.schema.space.create('test', {engine = 'vinyl'}) +i = s:create_index('primary', {page_size = 128, range_size = 8192, run_count_per_level = 1, run_size_ratio = 2}) + +test_run:cmd("setopt delimiter ';'") +function dump(a, b) + for i = a, b do + s:replace{i, digest.urandom(100)} + end + box.snapshot() +end; +function wait_compaction(count) + test_run:wait_cond(function() + return i:stat().disk.compaction.count == count + end, 10) +end; +test_run:cmd("setopt delimiter ''"); + +dump(1, 100) +i:stat().dumps_per_compaction -- 1 + +dump(1, 100) -- compaction +dump(1, 100) -- split + compaction +wait_compaction(3) +i:stat().range_count -- 2 +i:stat().dumps_per_compaction -- 1 + +dump(1, 10) +dump(1, 40) -- compaction in range 1 +wait_compaction(4) +i:stat().dumps_per_compaction -- 1 + +dump(90, 100) +dump(60, 100) -- compaction in range 2 +wait_compaction(5) +i:stat().dumps_per_compaction -- 2 + +-- Forcing compaction manually doesn't affect dumps_per_compaction. +dump(40, 60) +i:compact() +wait_compaction(7) +i:stat().dumps_per_compaction -- 2 + +test_run:cmd('restart server test') + +fiber = require('fiber') +digest = require('digest') + +s = box.space.test +i = s.index.primary + +i:stat().dumps_per_compaction -- 2 +for i = 1, 100 do s:replace{i, digest.urandom(100)} end +box.snapshot() +test_run:wait_cond(function() return i:stat().disk.compaction.count == 2 end, 10) + +i:stat().dumps_per_compaction -- 1 + +s:drop() + test_run:cmd('switch default') test_run:cmd('stop server test') test_run:cmd('cleanup server test')
next prev parent reply other threads:[~2019-02-06 16:54 UTC|newest] Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-01-20 21:16 [PATCH 0/9] vinyl: compaction randomization and throttling Vladimir Davydov 2019-01-20 21:17 ` [PATCH 1/9] vinyl: update lsm->range_heap in one go on dump completion Vladimir Davydov 2019-01-24 16:55 ` Vladimir Davydov 2019-02-05 16:37 ` [tarantool-patches] " Konstantin Osipov 2019-01-20 21:17 ` [PATCH 2/9] vinyl: ignore unknown .run, .index and .vylog keys Vladimir Davydov 2019-01-24 16:56 ` Vladimir Davydov 2019-01-20 21:17 ` [PATCH 3/9] vinyl: use uncompressed run size for range split/coalesce/compaction Vladimir Davydov 2019-01-21 9:42 ` Vladimir Davydov 2019-02-05 16:49 ` [tarantool-patches] " Konstantin Osipov 2019-02-06 8:55 ` Vladimir Davydov 2019-02-06 10:46 ` Konstantin Osipov 2019-02-06 10:55 ` Vladimir Davydov 2019-02-05 16:43 ` Konstantin Osipov 2019-02-06 16:48 ` Vladimir Davydov 2019-01-20 21:17 ` [PATCH 4/9] vinyl: rename lsm->range_heap to max_compaction_priority Vladimir Davydov 2019-01-20 21:17 ` [PATCH 5/9] vinyl: keep track of dumps per compaction for each LSM tree Vladimir Davydov 2019-02-05 16:58 ` [tarantool-patches] " Konstantin Osipov 2019-02-06 9:20 ` Vladimir Davydov 2019-02-06 16:54 ` Vladimir Davydov [this message] 2019-01-20 21:17 ` [PATCH 6/9] vinyl: set range size automatically Vladimir Davydov 2019-01-22 9:17 ` Vladimir Davydov 2019-02-05 17:09 ` [tarantool-patches] " Konstantin Osipov 2019-02-06 9:23 ` Vladimir Davydov 2019-02-06 17:04 ` Vladimir Davydov 2019-01-20 21:17 ` [PATCH 7/9] vinyl: randomize range compaction to avoid IO load spikes Vladimir Davydov 2019-01-22 12:54 ` Vladimir Davydov 2019-02-05 17:39 ` [tarantool-patches] " Konstantin Osipov 2019-02-06 8:53 ` Vladimir Davydov 2019-02-06 10:44 ` Konstantin Osipov 2019-02-06 10:52 ` Vladimir Davydov 2019-02-06 11:06 ` Konstantin Osipov 2019-02-06 11:49 ` Vladimir Davydov 2019-02-06 13:43 ` Konstantin Osipov 2019-02-06 14:00 ` Vladimir Davydov 2019-02-05 17:14 ` Konstantin Osipov 2019-01-20 21:17 ` [PATCH 8/9] vinyl: introduce quota consumer types Vladimir Davydov 2019-01-20 21:17 ` [PATCH 9/9] vinyl: throttle tx to ensure compaction keeps up with dumps Vladimir Davydov 2019-01-21 14:14 ` Vladimir Davydov 2019-01-22 9:09 ` Vladimir Davydov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20190206165419.acqqkdjtk6gdbozg@esperanza \ --to=vdavydov.dev@gmail.com \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] Re: [PATCH 5/9] vinyl: keep track of dumps per compaction for each LSM tree' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox