diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 47ac2565bbb4c40727cfd2cc65ce5cf02b5c8bb8..899570258d440583c1661db2668b74af29582626 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -183,10 +183,6 @@ enum vy_stat_name { VY_STAT_TX_WRITE, VY_STAT_CURSOR, VY_STAT_CURSOR_OPS, - /* How many upsert chains was squashed */ - VY_STAT_UPSERT_SQUASHED, - /* How many upserts was applied on read */ - VY_STAT_UPSERT_APPLIED, VY_STAT_LAST, }; @@ -197,8 +193,6 @@ static const char *vy_stat_strings[] = { "tx_write", "cursor", "cursor_ops", - "upsert_squashed", - "upsert_applied" }; struct vy_stat { @@ -2683,7 +2677,6 @@ vy_index_commit_upsert(struct vy_index *index, struct vy_mem *mem, */ assert(index->id == 0); - struct vy_stat *stat = index->env->stat; const struct tuple *older; int64_t lsn = vy_stmt_lsn(stmt); uint8_t n_upserts = vy_stmt_n_upserts(stmt); @@ -2740,7 +2733,7 @@ vy_index_commit_upsert(struct vy_index *index, struct vy_mem *mem, vy_apply_upsert(stmt, older, index->key_def, index->space_format, index->upsert_format, false); - rmean_collect(stat->rmean, VY_STAT_UPSERT_APPLIED, 1); + index->stat.upsert.applied++; if (upserted == NULL) { /* OOM */ @@ -2789,7 +2782,7 @@ vy_index_commit_upsert(struct vy_index *index, struct vy_mem *mem, assert(rc == 0); (void)rc; tuple_unref(upserted); vy_mem_commit_stmt(mem, region_stmt); - rmean_collect(stat->rmean, VY_STAT_UPSERT_SQUASHED, 1); + index->stat.upsert.squashed++; } } @@ -4544,6 +4537,11 @@ vy_index_info(struct vy_index *index, struct info_handler *h) vy_info_append_stmt_counter(h, "get", &stat->get); vy_info_append_stmt_counter(h, "put", &stat->put); + info_table_begin(h, "upsert"); + info_append_int(h, "squashed", stat->upsert.squashed); + info_append_int(h, "applied", stat->upsert.applied); + info_table_end(h); + info_table_begin(h, "memory"); vy_info_append_stmt_counter(h, NULL, &stat->memory.count); info_table_begin(h, "iterator"); @@ -5256,7 +5254,6 @@ static int vy_tx_set(struct vy_tx *tx, struct vy_index *index, struct tuple *stmt) { assert(vy_stmt_type(stmt) != 0); - struct vy_stat *stat = index->env->stat; /** * A statement in write set must have and unique lsn * in order to differ it from cachable statements in mem and run. @@ -5278,11 +5275,11 @@ vy_tx_set(struct vy_tx *tx, struct vy_index *index, struct tuple *stmt) stmt = vy_apply_upsert(stmt, old->stmt, index->key_def, index->space_format, index->upsert_format, true); - rmean_collect(stat->rmean, VY_STAT_UPSERT_APPLIED, 1); + index->stat.upsert.applied++; if (stmt == NULL) return -1; assert(vy_stmt_type(stmt) != 0); - rmean_collect(stat->rmean, VY_STAT_UPSERT_SQUASHED, 1); + index->stat.upsert.squashed++; } assert(tx->write_size >= tuple_size(old->stmt)); tx->write_size -= tuple_size(old->stmt); @@ -7605,7 +7602,7 @@ vy_merge_iterator_next_lsn(struct vy_merge_iterator *itr, struct tuple **ret) static NODISCARD int vy_merge_iterator_squash_upsert(struct vy_merge_iterator *itr, struct tuple **ret, bool suppress_error, - struct vy_stat *stat) + int64_t *upserts_applied) { *ret = NULL; struct tuple *t = itr->curr_stmt; @@ -7628,8 +7625,7 @@ vy_merge_iterator_squash_upsert(struct vy_merge_iterator *itr, assert(itr->is_primary); applied = vy_apply_upsert(t, next, itr->key_def, itr->format, itr->upsert_format, suppress_error); - if (stat != NULL) - rmean_collect(stat->rmean, VY_STAT_UPSERT_APPLIED, 1); + ++*upserts_applied; tuple_unref(t); if (applied == NULL) return -1; @@ -7946,7 +7942,6 @@ vy_read_iterator_next(struct vy_read_iterator *itr, struct tuple **result) struct tuple *t = NULL; struct vy_merge_iterator *mi = &itr->merge_iterator; struct vy_index *index = itr->index; - struct vy_stat *stat = index->env->stat; int rc = 0; while (true) { if (vy_read_iterator_merge_next_key(itr, &t)) { @@ -7966,7 +7961,8 @@ vy_read_iterator_next(struct vy_read_iterator *itr, struct tuple **result) rc = 0; /* No more data. */ break; } - rc = vy_merge_iterator_squash_upsert(mi, &t, true, stat); + rc = vy_merge_iterator_squash_upsert(mi, &t, true, + &index->stat.upsert.applied); if (rc != 0) { if (rc == -1) goto clear; @@ -7991,8 +7987,7 @@ vy_read_iterator_next(struct vy_read_iterator *itr, struct tuple **result) mi->format, mi->upsert_format, true); - rmean_collect(stat->rmean, - VY_STAT_UPSERT_APPLIED, 1); + index->stat.upsert.applied++; tuple_unref(t); t = applied; assert(vy_stmt_type(t) == IPROTO_REPLACE); @@ -8601,7 +8596,6 @@ vy_squash_process(struct vy_squash *squash) struct vy_index *index = squash->index; struct vy_env *env = index->env; - struct vy_stat *stat = env->stat; struct key_def *def = index->key_def; /* Upserts enabled only in the primary index. */ @@ -8710,7 +8704,7 @@ vy_squash_process(struct vy_squash *squash) struct tuple *applied = vy_apply_upsert(mem_stmt, result, def, mem->format, mem->upsert_format, true); - rmean_collect(stat->rmean, VY_STAT_UPSERT_APPLIED, 1); + index->stat.upsert.applied++; tuple_unref(result); if (applied == NULL) return -1; @@ -8748,7 +8742,7 @@ vy_squash_process(struct vy_squash *squash) } } - rmean_collect(stat->rmean, VY_STAT_UPSERT_SQUASHED, 1); + index->stat.upsert.squashed++; /* * Insert the resulting REPLACE statement to the mem diff --git a/src/box/vy_stat.h b/src/box/vy_stat.h index b1fe1dde4c863044663ee2c0b3745afd7966303d..d844c4f197a38089d49dc1ee81fa5285a664a86a 100644 --- a/src/box/vy_stat.h +++ b/src/box/vy_stat.h @@ -117,6 +117,13 @@ struct vy_index_stat { struct vy_stmt_counter get; /** Number of statements written to this index. */ struct vy_stmt_counter put; + /** Upsert statistics. */ + struct { + /** How many upsert chains have been squashed. */ + int64_t squashed; + /** How many upserts have been applied on read. */ + int64_t applied; + } upsert; /** Memory related statistics. */ struct { /** Number of statements stored in memory. */ diff --git a/test/vinyl/upsert.result b/test/vinyl/upsert.result index 27f67251646c6878c829c4f9ddcbd8a38298aac2..4bbd183a6bd86f5f08166435d4a503d3b182b0e8 100644 --- a/test/vinyl/upsert.result +++ b/test/vinyl/upsert.result @@ -491,8 +491,8 @@ test_run:cmd("setopt delimiter ';'") ... function upsert_stat_diff(stat2, stat1) return { - squashed = stat2.upsert_squashed.total - stat1.upsert_squashed.total, - applied = stat2.upsert_applied.total - stat1.upsert_applied.total + squashed = stat2.upsert.squashed - stat1.upsert.squashed, + applied = stat2.upsert.applied - stat1.upsert.applied } end; --- @@ -501,15 +501,15 @@ test_run:cmd("setopt delimiter ''"); --- - true ... -stat1 = box.info.vinyl().performance ---- -... space = box.schema.space.create('test', { engine = 'vinyl' }) --- ... index = space:create_index('primary') --- ... +stat1 = index:info() +--- +... -- separate upserts w/o on disk data space:upsert({1, 1, 1}, {{'+', 2, 10}}) --- @@ -520,7 +520,7 @@ space:upsert({1, 1, 1}, {{'-', 2, 20}}) space:upsert({1, 1, 1}, {{'=', 2, 20}}) --- ... -stat2 = box.info.vinyl().performance +stat2 = index:info() --- ... upsert_stat_diff(stat2, stat1) @@ -531,7 +531,7 @@ upsert_stat_diff(stat2, stat1) stat1 = stat2 --- ... -space.index.primary:info().rows +stat1.rows --- - 3 ... @@ -551,7 +551,7 @@ space:upsert({2, 1, 1}, {{'=', 2, 20}}) box.commit() --- ... -stat2 = box.info.vinyl().performance +stat2 = index:info() --- ... upsert_stat_diff(stat2, stat1) @@ -562,7 +562,7 @@ upsert_stat_diff(stat2, stat1) stat1 = stat2 --- ... -space.index.primary:info().rows +stat1.rows --- - 4 ... @@ -570,7 +570,7 @@ box.snapshot() --- - ok ... -space.index.primary:info().rows +index:info().rows --- - 2 ... @@ -581,7 +581,7 @@ space:upsert({1, 1, 1}, {{'+', 2, 10}}) space:upsert({1, 1, 1}, {{'-', 2, 20}}) --- ... -stat2 = box.info.vinyl().performance +stat2 = index:info() --- ... upsert_stat_diff(stat2, stat1) @@ -592,7 +592,7 @@ upsert_stat_diff(stat2, stat1) stat1 = stat2 --- ... -space.index.primary:info().rows +stat1.rows --- - 4 ... @@ -601,7 +601,7 @@ space:get({1}) --- - [1, 10, 1] ... -stat2 = box.info.vinyl().performance +stat2 = index:info() --- ... upsert_stat_diff(stat2, stat1) @@ -616,7 +616,7 @@ space:get({2}) --- - [2, 20, 1] ... -stat2 = box.info.vinyl().performance +stat2 = index:info() --- ... upsert_stat_diff(stat2, stat1) @@ -632,7 +632,7 @@ space:select({}) - - [1, 10, 1] - [2, 20, 1] ... -stat2 = box.info.vinyl().performance +stat2 = index:info() --- ... upsert_stat_diff(stat2, stat1) @@ -647,7 +647,7 @@ stat1 = stat2 for i = 0, 999 do space:upsert({3, 0, 0}, {{'+', 2, 1}}) end --- ... -stat2 = box.info.vinyl().performance +stat2 = index:info() --- ... upsert_stat_diff(stat2, stat1) @@ -662,7 +662,7 @@ space:get{3} --- - [3, 999, 0] ... -space.index.primary:info().rows +stat1.rows --- - 1004 ... @@ -697,10 +697,7 @@ s:select() --both upserts are ignored due to primary key change -- -- gh-2520 use cache as a hint when applying upserts. -- -old_stat = box.info.vinyl().performance ---- -... -old_disk_lookup_count = s.index.test:info().disk.iterator.lookup +old_stat = s.index.test:info() --- ... -- insert the first upsert @@ -718,10 +715,7 @@ s:get{100} - [100] ... -- a lookup in a run was done to populate the cache -new_stat = box.info.vinyl().performance ---- -... -new_disk_lookup_count = s.index.test:info().disk.iterator.lookup +new_stat = s.index.test:info() --- ... upsert_stat_diff(new_stat, old_stat) @@ -729,14 +723,11 @@ upsert_stat_diff(new_stat, old_stat) - squashed: 0 applied: 1 ... -old_stat = new_stat ---- -... -new_disk_lookup_count - old_disk_lookup_count +new_stat.disk.iterator.lookup - old_stat.disk.iterator.lookup --- - 1 ... -old_disk_lookup_count = new_disk_lookup_count +old_stat = new_stat --- ... -- Add another upsert: the cached REPLACE will be used and the upsert will @@ -759,10 +750,7 @@ s:get{100} -- go no further than the latest dump to locate the latest -- value of the key -- -new_stat = box.info.vinyl().performance ---- -... -new_disk_lookup_count = s.index.test:info().disk.iterator.lookup +new_stat = s.index.test:info() --- ... upsert_stat_diff(new_stat, old_stat) @@ -770,16 +758,10 @@ upsert_stat_diff(new_stat, old_stat) - squashed: 0 applied: 0 ... -old_stat = new_stat ---- -... -new_disk_lookup_count - old_disk_lookup_count +new_stat.disk.iterator.lookup - old_stat.disk.iterator.lookup --- - 1 ... -old_disk_lookup_count = new_disk_lookup_count ---- -... s:drop() --- ... diff --git a/test/vinyl/upsert.test.lua b/test/vinyl/upsert.test.lua index 5200402c7fbeafe4741593aa3933fc7b4d78ca68..7f1acc8cd3e47b8aead7af38c94b213d4113e9ca 100644 --- a/test/vinyl/upsert.test.lua +++ b/test/vinyl/upsert.test.lua @@ -194,27 +194,27 @@ space:drop() test_run:cmd("setopt delimiter ';'") function upsert_stat_diff(stat2, stat1) return { - squashed = stat2.upsert_squashed.total - stat1.upsert_squashed.total, - applied = stat2.upsert_applied.total - stat1.upsert_applied.total + squashed = stat2.upsert.squashed - stat1.upsert.squashed, + applied = stat2.upsert.applied - stat1.upsert.applied } end; test_run:cmd("setopt delimiter ''"); -stat1 = box.info.vinyl().performance - space = box.schema.space.create('test', { engine = 'vinyl' }) index = space:create_index('primary') +stat1 = index:info() + -- separate upserts w/o on disk data space:upsert({1, 1, 1}, {{'+', 2, 10}}) space:upsert({1, 1, 1}, {{'-', 2, 20}}) space:upsert({1, 1, 1}, {{'=', 2, 20}}) -stat2 = box.info.vinyl().performance +stat2 = index:info() upsert_stat_diff(stat2, stat1) stat1 = stat2 -space.index.primary:info().rows +stat1.rows -- in-tx upserts box.begin() @@ -223,50 +223,50 @@ space:upsert({2, 1, 1}, {{'-', 2, 20}}) space:upsert({2, 1, 1}, {{'=', 2, 20}}) box.commit() -stat2 = box.info.vinyl().performance +stat2 = index:info() upsert_stat_diff(stat2, stat1) stat1 = stat2 -space.index.primary:info().rows +stat1.rows box.snapshot() -space.index.primary:info().rows +index:info().rows -- upsert with on disk data space:upsert({1, 1, 1}, {{'+', 2, 10}}) space:upsert({1, 1, 1}, {{'-', 2, 20}}) -stat2 = box.info.vinyl().performance +stat2 = index:info() upsert_stat_diff(stat2, stat1) stat1 = stat2 -space.index.primary:info().rows +stat1.rows -- count of applied apserts space:get({1}) -stat2 = box.info.vinyl().performance +stat2 = index:info() upsert_stat_diff(stat2, stat1) stat1 = stat2 space:get({2}) -stat2 = box.info.vinyl().performance +stat2 = index:info() upsert_stat_diff(stat2, stat1) stat1 = stat2 space:select({}) -stat2 = box.info.vinyl().performance +stat2 = index:info() upsert_stat_diff(stat2, stat1) stat1 = stat2 -- start upsert optimizer for i = 0, 999 do space:upsert({3, 0, 0}, {{'+', 2, 1}}) end -stat2 = box.info.vinyl().performance +stat2 = index:info() upsert_stat_diff(stat2, stat1) stat1 = stat2 space:get{3} -space.index.primary:info().rows +stat1.rows space:drop() @@ -283,8 +283,7 @@ s:select() --both upserts are ignored due to primary key change -- -- gh-2520 use cache as a hint when applying upserts. -- -old_stat = box.info.vinyl().performance -old_disk_lookup_count = s.index.test:info().disk.iterator.lookup +old_stat = s.index.test:info() -- insert the first upsert s:upsert({100}, {{'=', 2, 200}}) -- force a dump, the inserted upsert is now on disk @@ -292,12 +291,10 @@ box.snapshot() -- populate the cache s:get{100} -- a lookup in a run was done to populate the cache -new_stat = box.info.vinyl().performance -new_disk_lookup_count = s.index.test:info().disk.iterator.lookup +new_stat = s.index.test:info() upsert_stat_diff(new_stat, old_stat) +new_stat.disk.iterator.lookup - old_stat.disk.iterator.lookup old_stat = new_stat -new_disk_lookup_count - old_disk_lookup_count -old_disk_lookup_count = new_disk_lookup_count -- Add another upsert: the cached REPLACE will be used and the upsert will -- be applied immediately s:upsert({100}, {{'=', 2, 300}}) @@ -310,11 +307,8 @@ s:get{100} -- go no further than the latest dump to locate the latest -- value of the key -- -new_stat = box.info.vinyl().performance -new_disk_lookup_count = s.index.test:info().disk.iterator.lookup +new_stat = s.index.test:info() upsert_stat_diff(new_stat, old_stat) -old_stat = new_stat -new_disk_lookup_count - old_disk_lookup_count -old_disk_lookup_count = new_disk_lookup_count +new_stat.disk.iterator.lookup - old_stat.disk.iterator.lookup s:drop()