diff --git a/.travis.mk b/.travis.mk index 1b7d0514972aee96fe196fb2fbe732040b672bb5..edd94cd7d0a5e9f45e1a111b87dc53c75a52cca0 100644 --- a/.travis.mk +++ b/.travis.mk @@ -85,8 +85,20 @@ source: git clone https://github.com/packpack/packpack.git packpack TARBALL_COMPRESSOR=gz packpack/packpack tarball +# Push alpha and beta versions to <major>x bucket (say, 2x), +# stable to <major>.<minor> bucket (say, 2.2). +MAJOR_VERSION=$(word 1,$(subst ., ,$(TRAVIS_BRANCH))) +MINOR_VERSION=$(word 2,$(subst ., ,$(TRAVIS_BRANCH))) +BUCKET=tarantool.$(MAJOR_VERSION).$(MINOR_VERSION).src +ifeq ($(MINOR_VERSION),0) +BUCKET=tarantool.$(MAJOR_VERSION)x.src +endif +ifeq ($(MINOR_VERSION),1) +BUCKET=tarantool.$(MAJOR_VERSION)x.src +endif + source_deploy: pip install awscli --user aws --endpoint-url "${AWS_S3_ENDPOINT_URL}" s3 \ - cp build/*.tar.gz "s3://tarantool-${TRAVIS_BRANCH}-src/" \ + cp build/*.tar.gz "s3://${BUCKET}/" \ --acl public-read diff --git a/CMakeLists.txt b/CMakeLists.txt index 491ccaf0b63eedec5daa70cb60ab8e21f2713aad..2b43e0c6c9a2653f8d232145cfe164e0a608556d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,7 @@ check_symbol_exists(fdatasync unistd.h HAVE_FDATASYNC) check_symbol_exists(pthread_yield pthread.h HAVE_PTHREAD_YIELD) check_symbol_exists(sched_yield sched.h HAVE_SCHED_YIELD) check_symbol_exists(posix_fadvise fcntl.h HAVE_POSIX_FADVISE) +check_symbol_exists(posix_fallocate fcntl.h HAVE_POSIX_FALLOCATE) check_symbol_exists(mremap sys/mman.h HAVE_MREMAP) check_function_exists(sync_file_range HAVE_SYNC_FILE_RANGE) diff --git a/src/box/alter.cc b/src/box/alter.cc index de3943cb79d80cfeae3ad6eb9bba3a51862b7f5e..986d4daf7f85fe96bcf59c1b5f4b117d516496aa 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -810,9 +810,7 @@ alter_space_rollback(struct trigger *trigger, void * /* event */) */ space_swap_triggers(alter->new_space, alter->old_space); space_swap_fkeys(alter->new_space, alter->old_space); - struct space *new_space = space_cache_replace(alter->old_space); - assert(new_space == alter->new_space); - (void) new_space; + space_cache_replace(alter->new_space, alter->old_space); alter_space_delete(alter); } @@ -913,9 +911,7 @@ alter_space_do(struct txn *txn, struct alter_space *alter) * The new space is ready. Time to update the space * cache with it. */ - struct space *old_space = space_cache_replace(alter->new_space); - (void) old_space; - assert(old_space == alter->old_space); + space_cache_replace(alter->old_space, alter->new_space); /* * Install transaction commit/rollback triggers to either @@ -1421,7 +1417,7 @@ on_drop_space_rollback(struct trigger *trigger, void *event) { (void) event; struct space *space = (struct space *)trigger->data; - space_cache_replace(space); + space_cache_replace(NULL, space); } /** @@ -1447,9 +1443,7 @@ on_create_space_rollback(struct trigger *trigger, void *event) { (void) event; struct space *space = (struct space *)trigger->data; - struct space *cached = space_cache_delete(space_id(space)); - (void) cached; - assert(cached == space); + space_cache_replace(space, NULL); space_delete(space); } @@ -1608,10 +1602,7 @@ on_drop_view_rollback(struct trigger *trigger, void *event) * Generally, whenever a data dictionary change occurs * 2 things should be done: * - * - space cache should be updated, and changes in the space - * cache should be reflected in Lua bindings - * (this is done in space_cache_replace() and - * space_cache_delete()) + * - space cache should be updated * * - the space which is changed should be rebuilt according * to the nature of the modification, i.e. indexes added/dropped, @@ -1695,7 +1686,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) * cache right away to achieve linearisable * execution on a replica. */ - (void) space_cache_replace(space); + space_cache_replace(NULL, space); /* * Do not forget to update schema_version right after * inserting the space to the space_cache, since no @@ -1787,7 +1778,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) * cache right away to achieve linearisable * execution on a replica. */ - struct space *space = space_cache_delete(space_id(old_space)); + space_cache_replace(old_space, NULL); /* * Do not forget to update schema_version right after * deleting the space from the space_cache, since no @@ -1795,7 +1786,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) */ ++schema_version; struct trigger *on_commit = - txn_alter_trigger_new(on_drop_space_commit, space); + txn_alter_trigger_new(on_drop_space_commit, old_space); txn_on_commit(txn, on_commit); if (old_space->def->opts.is_view) { struct Select *select = @@ -1817,7 +1808,8 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) select_guard.is_active = false; } struct trigger *on_rollback = - txn_alter_trigger_new(on_drop_space_rollback, space); + txn_alter_trigger_new(on_drop_space_rollback, + old_space); txn_on_rollback(txn, on_rollback); } else { /* UPDATE, REPLACE */ assert(old_space != NULL && new_tuple != NULL); diff --git a/src/box/applier.cc b/src/box/applier.cc index 7da278e68d89699551d6b295e0a471b2382a78c0..ff4af95e5b8f12a6051b6694e93d18a9ec65126c 100644 --- a/src/box/applier.cc +++ b/src/box/applier.cc @@ -309,11 +309,14 @@ applier_join(struct applier *applier) * Receive initial data. */ assert(applier->join_stream != NULL); + uint64_t row_count = 0; while (true) { coio_read_xrow(coio, ibuf, &row); applier->last_row_time = ev_monotonic_now(loop()); if (iproto_type_is_dml(row.type)) { xstream_write_xc(applier->join_stream, &row); + if (++row_count % 100000 == 0) + say_info("%.1fM rows received", row_count / 1e6); } else if (row.type == IPROTO_OK) { if (applier->version_id < version_id(1, 7, 0)) { /* @@ -354,6 +357,8 @@ applier_join(struct applier *applier) if (iproto_type_is_dml(row.type)) { vclock_follow_xrow(&replicaset.vclock, &row); xstream_write_xc(applier->subscribe_stream, &row); + if (++row_count % 100000 == 0) + say_info("%.1fM rows received", row_count / 1e6); } else if (row.type == IPROTO_OK) { /* * Current vclock. This is not used now, diff --git a/src/box/blackhole.c b/src/box/blackhole.c index aafbfbf6592fc726a01f421f4e7f5085804b2825..88dab3fbebec4d95d50bdbb1ff0f48d02a645961 100644 --- a/src/box/blackhole.c +++ b/src/box/blackhole.c @@ -154,7 +154,7 @@ blackhole_engine_create_space(struct engine *engine, struct space_def *def, /* Allocate tuples on runtime arena, but check space format. */ struct tuple_format *format; - format = tuple_format_new(&tuple_format_runtime->vtab, NULL, 0, 0, + format = tuple_format_new(&tuple_format_runtime->vtab, NULL, 0, def->fields, def->field_count, def->dict); if (format == NULL) { free(space); diff --git a/src/box/box.cc b/src/box/box.cc index c32f731b04032c1054f92f165c5cb58a6eef4a4e..4ddb2fbfe2422984dca5493df8c4118ba5d209d2 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -2110,14 +2110,19 @@ box_cfg_xc(void) } } + struct gc_checkpoint *first_checkpoint = gc_first_checkpoint(); + assert(first_checkpoint != NULL); + /* Start WAL writer */ int64_t wal_max_rows = box_check_wal_max_rows(cfg_geti64("rows_per_wal")); int64_t wal_max_size = box_check_wal_max_size(cfg_geti64("wal_max_size")); enum wal_mode wal_mode = box_check_wal_mode(cfg_gets("wal_mode")); - if (wal_init(wal_mode, cfg_gets("wal_dir"), &INSTANCE_UUID, - &replicaset.vclock, wal_max_rows, wal_max_size)) { + if (wal_init(wal_mode, cfg_gets("wal_dir"), wal_max_rows, + wal_max_size, &INSTANCE_UUID, &replicaset.vclock, + vclock_sum(&first_checkpoint->vclock))) { diag_raise(); } + gc_set_wal_watcher(); rmean_cleanup(rmean_box); diff --git a/src/box/gc.c b/src/box/gc.c index becb5d09da7e5a2a8d64c7f522e24de34c298c17..467eecb91e76d604500e05251f0ebf8cd4c19819 100644 --- a/src/box/gc.c +++ b/src/box/gc.c @@ -48,6 +48,7 @@ #include "say.h" #include "latch.h" #include "vclock.h" +#include "cbus.h" #include "engine.h" /* engine_collect_garbage() */ #include "wal.h" /* wal_collect_garbage() */ @@ -102,9 +103,24 @@ gc_init(void) latch_create(&gc.latch); } +static void +gc_process_wal_event(struct wal_watcher_msg *); + +void +gc_set_wal_watcher(void) +{ + wal_set_watcher(&gc.wal_watcher, "tx", gc_process_wal_event, + cbus_process, WAL_EVENT_GC); +} + void gc_free(void) { + /* + * Can't clear the WAL watcher as the event loop isn't + * running when this function is called. + */ + /* Free checkpoints. */ struct gc_checkpoint *checkpoint, *next_checkpoint; rlist_foreach_entry_safe(checkpoint, &gc.checkpoints, in_checkpoints, @@ -175,6 +191,9 @@ gc_run(void) if (!run_engine_gc && !run_wal_gc) return; /* nothing to do */ + int64_t wal_lsn = vclock_sum(vclock); + int64_t checkpoint_lsn = vclock_sum(&checkpoint->vclock); + /* * Engine callbacks may sleep, because they use coio for * removing files. Make sure we won't try to remove the @@ -191,12 +210,44 @@ gc_run(void) */ int rc = 0; if (run_engine_gc) - rc = engine_collect_garbage(vclock_sum(&checkpoint->vclock)); - if (run_wal_gc && rc == 0) - wal_collect_garbage(vclock_sum(vclock)); + rc = engine_collect_garbage(checkpoint_lsn); + /* + * Run wal_collect_garbage() even if we don't need to + * delete any WAL files, because we have to apprise + * the WAL thread of the oldest checkpoint signature. + */ + if (rc == 0) + wal_collect_garbage(wal_lsn, checkpoint_lsn); latch_unlock(&gc.latch); } +/** + * Deactivate consumers that need files deleted by the WAL thread. + */ +static void +gc_process_wal_event(struct wal_watcher_msg *msg) +{ + assert((msg->events & WAL_EVENT_GC) != 0); + + struct gc_consumer *consumer = gc_tree_first(&gc.consumers); + while (consumer != NULL && + vclock_sum(&consumer->vclock) < vclock_sum(&msg->gc_vclock)) { + struct gc_consumer *next = gc_tree_next(&gc.consumers, + consumer); + assert(!consumer->is_inactive); + consumer->is_inactive = true; + gc_tree_remove(&gc.consumers, consumer); + + char *vclock_str = vclock_to_string(&consumer->vclock); + say_crit("deactivated WAL consumer %s at %s", + consumer->name, vclock_str); + free(vclock_str); + + consumer = next; + } + gc_run(); +} + void gc_set_min_checkpoint_count(int min_checkpoint_count) { @@ -279,14 +330,19 @@ gc_consumer_register(const struct vclock *vclock, const char *format, ...) void gc_consumer_unregister(struct gc_consumer *consumer) { - gc_tree_remove(&gc.consumers, consumer); + if (!consumer->is_inactive) { + gc_tree_remove(&gc.consumers, consumer); + gc_run(); + } gc_consumer_delete(consumer); - gc_run(); } void gc_consumer_advance(struct gc_consumer *consumer, const struct vclock *vclock) { + if (consumer->is_inactive) + return; + int64_t signature = vclock_sum(vclock); int64_t prev_signature = vclock_sum(&consumer->vclock); diff --git a/src/box/gc.h b/src/box/gc.h index a5392cefad837f76650f1b2f4f8cde54503230fd..e1241baac78c11ddce6834b267e1975f9b71f75f 100644 --- a/src/box/gc.h +++ b/src/box/gc.h @@ -36,6 +36,7 @@ #include "vclock.h" #include "latch.h" +#include "wal.h" #include "trivia/util.h" #if defined(__cplusplus) @@ -89,6 +90,11 @@ struct gc_consumer { char name[GC_NAME_MAX]; /** The vclock tracked by this consumer. */ struct vclock vclock; + /** + * This flag is set if a WAL needed by this consumer was + * deleted by the WAL thread on ENOSPC. + */ + bool is_inactive; }; typedef rb_tree(struct gc_consumer) gc_tree_t; @@ -120,6 +126,11 @@ struct gc_state { * garbage collection callbacks. */ struct latch latch; + /** + * WAL event watcher. Needed to shoot off stale consumers + * when a WAL file is deleted due to ENOSPC. + */ + struct wal_watcher wal_watcher; }; extern struct gc_state gc; @@ -144,6 +155,20 @@ extern struct gc_state gc; #define gc_foreach_checkpoint_ref(ref, checkpoint) \ rlist_foreach_entry(ref, &(checkpoint)->refs, in_refs) +/** + * Return the first (oldest) checkpoint known to the garbage + * collector. If there's no checkpoint, return NULL. + */ +static inline struct gc_checkpoint * +gc_first_checkpoint(void) +{ + if (rlist_empty(&gc.checkpoints)) + return NULL; + + return rlist_first_entry(&gc.checkpoints, struct gc_checkpoint, + in_checkpoints); +} + /** * Return the last (newest) checkpoint known to the garbage * collector. If there's no checkpoint, return NULL. @@ -164,6 +189,12 @@ gc_last_checkpoint(void) void gc_init(void); +/** + * Set WAL watcher. Called after WAL is initialized. + */ +void +gc_set_wal_watcher(void); + /** * Destroy the garbage collection state. */ diff --git a/src/box/iproto_constants.c b/src/box/iproto_constants.c index 4f3510e4d90b11e943f768b64be958ad825d842f..7fd295775e742273e5b7322b281e05503a1354eb 100644 --- a/src/box/iproto_constants.c +++ b/src/box/iproto_constants.c @@ -216,6 +216,7 @@ const char *vy_run_info_key_strs[VY_RUN_INFO_KEY_MAX] = { "page count", "bloom filter legacy", "bloom filter", + "stmt stat", }; const char *vy_row_index_key_strs[VY_ROW_INDEX_KEY_MAX] = { diff --git a/src/box/iproto_constants.h b/src/box/iproto_constants.h index f571375eeccdf16b999161f25ace1ad864c81ab4..ab7db1f0d3fad61fab83d93b8bee79b6e8b9f583 100644 --- a/src/box/iproto_constants.h +++ b/src/box/iproto_constants.h @@ -354,6 +354,8 @@ enum vy_run_info_key { VY_RUN_INFO_BLOOM_LEGACY = 6, /** Bloom filter for keys. */ VY_RUN_INFO_BLOOM = 7, + /** Number of statements of each type (map). */ + VY_RUN_INFO_STMT_STAT = 8, /** The last key in this enum + 1 */ VY_RUN_INFO_KEY_MAX }; diff --git a/src/box/journal.c b/src/box/journal.c index fd4f9539a131d15793b73a07c036f5f1681ebbeb..7498ba192c2f57bd462c01d36ad4dd09fe7696b4 100644 --- a/src/box/journal.c +++ b/src/box/journal.c @@ -66,6 +66,7 @@ journal_entry_new(size_t n_rows) diag_set(OutOfMemory, size, "region", "struct journal_entry"); return NULL; } + entry->approx_len = 0; entry->n_rows = n_rows; entry->res = -1; entry->fiber = fiber(); diff --git a/src/box/journal.h b/src/box/journal.h index 1d64a7bd1d752c0fa592a8b204dac246d1b0ff3d..e52316888cad41ce467fe35813a76b48c4755662 100644 --- a/src/box/journal.h +++ b/src/box/journal.h @@ -58,6 +58,10 @@ struct journal_entry { * The fiber issuing the request. */ struct fiber *fiber; + /** + * Approximate size of this request when encoded. + */ + size_t approx_len; /** * The number of rows in the request. */ diff --git a/src/box/lua/tuple.lua b/src/box/lua/tuple.lua index 63ea73e43b1b3b6ccdc10833d5fdad0bbd73b434..8662a3a02c05c8a717fff780056bbaeaff75ce0a 100644 --- a/src/box/lua/tuple.lua +++ b/src/box/lua/tuple.lua @@ -100,7 +100,7 @@ local tuple_bless = function(tuple) -- overflow checked by tuple_bless() in C builtin.box_tuple_ref(tuple) -- must never fail: - return ffi.gc(ffi.cast(const_tuple_ref_t, tuple), tuple_gc) + return ffi.cast(const_tuple_ref_t, ffi.gc(tuple, tuple_gc)) end local tuple_check = function(tuple, usage) diff --git a/src/box/memtx_engine.c b/src/box/memtx_engine.c index 5a5e87e64f3a7e6c5b8300923772c2202feb7391..6a91d0b8ef5ba6f6ffaaa92770a5c439087e9e5c 100644 --- a/src/box/memtx_engine.c +++ b/src/box/memtx_engine.c @@ -834,7 +834,7 @@ memtx_engine_collect_garbage(struct engine *engine, int64_t lsn) * That said, we have to abort garbage collection if we * fail to delete a snap file. */ - if (xdir_collect_garbage(&memtx->snap_dir, lsn, true) != 0) + if (xdir_collect_garbage(&memtx->snap_dir, lsn, XDIR_GC_USE_COIO) != 0) return -1; return 0; @@ -1130,8 +1130,8 @@ memtx_tuple_new(struct tuple_format *format, const char *data, const char *end) struct memtx_engine *memtx = (struct memtx_engine *)format->engine; assert(mp_typeof(*data) == MP_ARRAY); size_t tuple_len = end - data; - size_t meta_size = tuple_format_meta_size(format); - size_t total = sizeof(struct memtx_tuple) + meta_size + tuple_len; + size_t total = sizeof(struct memtx_tuple) + format->field_map_size + + tuple_len; ERROR_INJECT(ERRINJ_TUPLE_ALLOC, { diag_set(OutOfMemory, total, "slab allocator", "memtx_tuple"); @@ -1166,7 +1166,7 @@ memtx_tuple_new(struct tuple_format *format, const char *data, const char *end) * tuple base, not from memtx_tuple, because the struct * tuple is not the first field of the memtx_tuple. */ - tuple->data_offset = sizeof(struct tuple) + meta_size; + tuple->data_offset = sizeof(struct tuple) + format->field_map_size; char *raw = (char *) tuple + tuple->data_offset; uint32_t *field_map = (uint32_t *) raw; memcpy(raw, data, tuple_len); @@ -1184,8 +1184,8 @@ memtx_tuple_delete(struct tuple_format *format, struct tuple *tuple) struct memtx_engine *memtx = (struct memtx_engine *)format->engine; say_debug("%s(%p)", __func__, tuple); assert(tuple->refs == 0); - size_t total = sizeof(struct memtx_tuple) + - tuple_format_meta_size(format) + tuple->bsize; + size_t total = sizeof(struct memtx_tuple) + format->field_map_size + + tuple->bsize; tuple_format_unref(format); struct memtx_tuple *memtx_tuple = container_of(tuple, struct memtx_tuple, base); diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c index 8cf2e6b94097aa6d4f172539a949a1b5dc1a8834..1a248b701fcf55663ff3d74809b82e0534c04745 100644 --- a/src/box/memtx_space.c +++ b/src/box/memtx_space.c @@ -980,7 +980,7 @@ memtx_space_new(struct memtx_engine *memtx, keys[key_count++] = index_def->key_def; struct tuple_format *format = - tuple_format_new(&memtx_tuple_format_vtab, keys, key_count, 0, + tuple_format_new(&memtx_tuple_format_vtab, keys, key_count, def->fields, def->field_count, def->dict); if (format == NULL) { free(memtx_space); diff --git a/src/box/relay.cc b/src/box/relay.cc index 0a1e95af02b239b24bc78aeb09ee8f306f63680a..0034f99a043a1a66c7711ad1f23db653e0e4536e 100644 --- a/src/box/relay.cc +++ b/src/box/relay.cc @@ -406,9 +406,12 @@ relay_schedule_pending_gc(struct relay *relay, const struct vclock *vclock) } static void -relay_process_wal_event(struct wal_watcher *watcher, unsigned events) +relay_process_wal_event(struct wal_watcher_msg *msg) { - struct relay *relay = container_of(watcher, struct relay, wal_watcher); + assert((msg->events & (WAL_EVENT_WRITE | WAL_EVENT_ROTATE)) != 0); + + struct relay *relay = container_of(msg->watcher, struct relay, + wal_watcher); if (relay->state != RELAY_FOLLOW) { /* * Do not try to send anything to the replica @@ -418,7 +421,7 @@ relay_process_wal_event(struct wal_watcher *watcher, unsigned events) } try { recover_remaining_wals(relay->r, &relay->stream, NULL, - (events & WAL_EVENT_ROTATE) != 0); + (msg->events & WAL_EVENT_ROTATE) != 0); } catch (Exception *e) { e->log(); diag_move(diag_get(), &relay->diag); @@ -504,7 +507,8 @@ relay_subscribe_f(va_list ap) }; trigger_add(&r->on_close_log, &on_close_log); wal_set_watcher(&relay->wal_watcher, cord_name(cord()), - relay_process_wal_event, cbus_process); + relay_process_wal_event, cbus_process, + WAL_EVENT_WRITE | WAL_EVENT_ROTATE); relay_set_cord_name(relay->io.fd); diff --git a/src/box/schema.cc b/src/box/schema.cc index 2d2be26ae11da216b365ba2e1361bbf55c942e36..9327322b84c607a7f3d8db80a1092c7db8828446 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -158,34 +158,33 @@ space_foreach(int (*func)(struct space *sp, void *udata), void *udata) return 0; } -/** Delete a space from the space cache and Lua. */ -struct space * -space_cache_delete(uint32_t id) -{ - mh_int_t k = mh_i32ptr_find(spaces, id, NULL); - assert(k != mh_end(spaces)); - struct space *space = (struct space *)mh_i32ptr_node(spaces, k)->val; - mh_i32ptr_del(spaces, k, NULL); - space_cache_version++; - return space; -} - -/** - * Update the space in the space cache and in Lua. Returns - * the old space instance, if any, or NULL if it's a new space. - */ -struct space * -space_cache_replace(struct space *space) +void +space_cache_replace(struct space *old_space, struct space *new_space) { - const struct mh_i32ptr_node_t node = { space_id(space), space }; - struct mh_i32ptr_node_t old, *p_old = &old; - mh_int_t k = mh_i32ptr_put(spaces, &node, &p_old, NULL); - if (k == mh_end(spaces)) { - panic_syserror("Out of memory for the data " - "dictionary cache."); + assert(new_space != NULL || old_space != NULL); + if (new_space != NULL) { + const struct mh_i32ptr_node_t node_p = { space_id(new_space), + new_space }; + struct mh_i32ptr_node_t old, *p_old = &old; + mh_int_t k = mh_i32ptr_put(spaces, &node_p, &p_old, NULL); + if (k == mh_end(spaces)) { + panic_syserror("Out of memory for the data " + "dictionary cache."); + } + struct space *old_space_by_id = p_old != NULL ? + (struct space *)p_old->val : NULL; + assert(old_space_by_id == old_space); + (void)old_space_by_id; + } else { + mh_int_t k = mh_i32ptr_find(spaces, space_id(old_space), NULL); + assert(k != mh_end(spaces)); + struct space *old_space_by_id = + (struct space *)mh_i32ptr_node(spaces, k)->val; + assert(old_space_by_id == old_space); + (void)old_space_by_id; + mh_i32ptr_del(spaces, k, NULL); } space_cache_version++; - return p_old ? (struct space *) p_old->val : NULL; } /** A wrapper around space_new() for data dictionary spaces. */ @@ -220,7 +219,7 @@ sc_space_new(uint32_t id, const char *name, rlist_create(&key_list); rlist_add_entry(&key_list, index_def, link); struct space *space = space_new_xc(def, &key_list); - (void) space_cache_replace(space); + space_cache_replace(NULL, space); if (replace_trigger) trigger_add(&space->on_replace, replace_trigger); if (stmt_begin_trigger) @@ -431,7 +430,7 @@ schema_init() }); RLIST_HEAD(key_list); struct space *space = space_new_xc(def, &key_list); - space_cache_replace(space); + space_cache_replace(NULL, space); init_system_space(space); trigger_run_xc(&on_alter_space, space); } @@ -447,7 +446,7 @@ schema_free(void) struct space *space = (struct space *) mh_i32ptr_node(spaces, i)->val; - space_cache_delete(space_id(space)); + space_cache_replace(space, NULL); space_delete(space); } mh_i32ptr_delete(spaces); diff --git a/src/box/schema.h b/src/box/schema.h index 264c16b33c2cd5c2766480b8c0e18293f660bad8..958e308452a96c2e3a1035c23deea7df6d2c43cc 100644 --- a/src/box/schema.h +++ b/src/box/schema.h @@ -132,16 +132,16 @@ space_cache_find_xc(uint32_t id) } /** - * Update contents of the space cache. Typically the new space is - * an altered version of the original space. - * Returns the old space, if any. + * Update contents of the space cache. + * + * If @old_space is NULL, insert @new_space into the cache. + * If @new_space is NULL, delete @old_space from the cache. + * If neither @old_space nor @new_space is NULL, replace + * @old_space with @new_space in the cache (both spaces must + * have the same id). */ -struct space * -space_cache_replace(struct space *space); - -/** Delete a space from the space cache. */ -struct space * -space_cache_delete(uint32_t id); +void +space_cache_replace(struct space *old_space, struct space *new_space); void schema_init(); diff --git a/src/box/tuple.c b/src/box/tuple.c index 8e6c8a078ec55e89afa17176740d7394e32a9fcd..ef4d16f39e7d9feab36acba759ff1117dfc69d15 100644 --- a/src/box/tuple.c +++ b/src/box/tuple.c @@ -97,8 +97,8 @@ runtime_tuple_new(struct tuple_format *format, const char *data, const char *end mp_tuple_assert(data, end); size_t data_len = end - data; - size_t meta_size = tuple_format_meta_size(format); - size_t total = sizeof(struct tuple) + meta_size + data_len; + size_t total = sizeof(struct tuple) + format->field_map_size + + data_len; struct tuple *tuple = (struct tuple *) smalloc(&runtime_alloc, total); if (tuple == NULL) { @@ -111,7 +111,7 @@ runtime_tuple_new(struct tuple_format *format, const char *data, const char *end tuple->bsize = data_len; tuple->format_id = tuple_format_id(format); tuple_format_ref(format); - tuple->data_offset = sizeof(struct tuple) + meta_size; + tuple->data_offset = sizeof(struct tuple) + format->field_map_size; char *raw = (char *) tuple + tuple->data_offset; uint32_t *field_map = (uint32_t *) raw; memcpy(raw, data, data_len); @@ -129,7 +129,7 @@ runtime_tuple_delete(struct tuple_format *format, struct tuple *tuple) assert(format->vtab.tuple_delete == tuple_format_runtime_vtab.tuple_delete); say_debug("%s(%p)", __func__, tuple); assert(tuple->refs == 0); - size_t total = sizeof(struct tuple) + tuple_format_meta_size(format) + + size_t total = sizeof(struct tuple) + format->field_map_size + tuple->bsize; tuple_format_unref(format); smfree(&runtime_alloc, tuple, total); @@ -223,7 +223,7 @@ tuple_init(field_name_hash_f hash) * Create a format for runtime tuples */ tuple_format_runtime = tuple_format_new(&tuple_format_runtime_vtab, - NULL, 0, 0, NULL, 0, NULL); + NULL, 0, NULL, 0, NULL); if (tuple_format_runtime == NULL) return -1; @@ -395,7 +395,7 @@ box_tuple_format_new(struct key_def **keys, uint16_t key_count) { box_tuple_format_t *format = tuple_format_new(&tuple_format_runtime_vtab, - keys, key_count, 0, NULL, 0, NULL); + keys, key_count, NULL, 0, NULL); if (format != NULL) tuple_format_ref(format); return format; diff --git a/src/box/tuple.h b/src/box/tuple.h index 2a32ee2c44495e40bb267cbe59cdf2cf95daa35d..3361b6757c0b8624e323921db32d2ebf5c80cdf6 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -289,18 +289,12 @@ box_tuple_upsert(const box_tuple_t *tuple, const char *expr, const /** * An atom of Tarantool storage. Represents MsgPack Array. * Tuple has the following structure: - * format->tuple_meta_size bsize - * +------------------------+-------------+ - * tuple_begin, ..., raw = | tuple_meta | MessagePack | - * | +------------------------+-------------+ - * | ^ - * +---------------------------------------------data_offset - * - * tuple_meta structure: - * +----------------------+-----------------------+ - * | extra_size | offset N ... offset 1 | - * +----------------------+-----------------------+ - * @sa tuple_format_new() uint32 ... uint32 + * uint32 uint32 bsize + * +-------------------+-------------+ + * tuple_begin, ..., raw = | offN | ... | off1 | MessagePack | + * | +-------------------+-------------+ + * | ^ + * +---------------------------------------data_offset * * Each 'off_i' is the offset to the i-th indexed field. */ @@ -424,18 +418,6 @@ tuple_format(const struct tuple *tuple) return format; } -/** - * Return extra data saved in tuple metadata. - * @param tuple tuple - * @return a pointer to extra data saved in tuple metadata. - */ -static inline const char * -tuple_extra(const struct tuple *tuple) -{ - struct tuple_format *format = tuple_format(tuple); - return tuple_data(tuple) - tuple_format_meta_size(format); -} - /** * Instantiate a new engine-independent tuple from raw MsgPack Array data * using runtime arena. Use this function to create a standalone tuple diff --git a/src/box/tuple_bloom.c b/src/box/tuple_bloom.c index dc40698559aaad8cbfbc83aec429c3a7e8a148b5..0ea552aa85a7573ad50fc4eeb1259a36abc511ab 100644 --- a/src/box/tuple_bloom.c +++ b/src/box/tuple_bloom.c @@ -39,7 +39,6 @@ #include <msgpuck.h> #include "diag.h" #include "errcode.h" -#include "memory.h" #include "key_def.h" #include "tuple.h" #include "tuple_hash.h" @@ -143,8 +142,7 @@ tuple_bloom_new(struct tuple_bloom_builder *builder, double fpr) for (uint32_t j = 0; j < i; j++) part_fpr /= bloom_fpr(&bloom->parts[j], count); part_fpr = MIN(part_fpr, 0.5); - if (bloom_create(&bloom->parts[i], count, - part_fpr, runtime.quota) != 0) { + if (bloom_create(&bloom->parts[i], count, part_fpr) != 0) { diag_set(OutOfMemory, 0, "bloom_create", "tuple bloom part"); tuple_bloom_delete(bloom); @@ -161,7 +159,7 @@ void tuple_bloom_delete(struct tuple_bloom *bloom) { for (uint32_t i = 0; i < bloom->part_count; i++) - bloom_destroy(&bloom->parts[i], runtime.quota); + bloom_destroy(&bloom->parts[i]); free(bloom); } @@ -251,7 +249,7 @@ tuple_bloom_decode_part(struct bloom *part, const char **data) part->hash_count = mp_decode_uint(data); size_t store_size = mp_decode_binl(data); assert(store_size == bloom_store_size(part)); - if (bloom_load_table(part, *data, runtime.quota) != 0) { + if (bloom_load_table(part, *data) != 0) { diag_set(OutOfMemory, store_size, "bloom_load_table", "tuple bloom part"); return -1; @@ -329,7 +327,7 @@ tuple_bloom_decode_legacy(const char **data) size_t store_size = mp_decode_binl(data); assert(store_size == bloom_store_size(&bloom->parts[0])); - if (bloom_load_table(&bloom->parts[0], *data, runtime.quota) != 0) { + if (bloom_load_table(&bloom->parts[0], *data) != 0) { diag_set(OutOfMemory, store_size, "bloom_load_table", "tuple bloom part"); free(bloom); diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c index c17cf7855ca1e70435a39fddb48d2537e495b44e..c19ff39fb8923d6d8b34071eec2d3d6f118ac031 100644 --- a/src/box/tuple_format.c +++ b/src/box/tuple_format.c @@ -170,7 +170,7 @@ tuple_format_create(struct tuple_format *format, struct key_def * const *keys, assert(format->fields[0].offset_slot == TUPLE_OFFSET_SLOT_NIL); size_t field_map_size = -current_slot * sizeof(uint32_t); - if (field_map_size + format->extra_size > UINT16_MAX) { + if (field_map_size > UINT16_MAX) { /** tuple->data_offset is 16 bits */ diag_set(ClientError, ER_INDEX_FIELD_COUNT_LIMIT, -current_slot); @@ -288,8 +288,7 @@ tuple_format_delete(struct tuple_format *format) struct tuple_format * tuple_format_new(struct tuple_format_vtab *vtab, struct key_def * const *keys, - uint16_t key_count, uint16_t extra_size, - const struct field_def *space_fields, + uint16_t key_count, const struct field_def *space_fields, uint32_t space_field_count, struct tuple_dictionary *dict) { struct tuple_format *format = @@ -298,7 +297,6 @@ tuple_format_new(struct tuple_format_vtab *vtab, struct key_def * const *keys, return NULL; format->vtab = *vtab; format->engine = NULL; - format->extra_size = extra_size; format->is_temporary = false; if (tuple_format_register(format) < 0) { tuple_format_destroy(format); @@ -355,28 +353,6 @@ tuple_format1_can_store_format2_tuples(const struct tuple_format *format1, return true; } -struct tuple_format * -tuple_format_dup(struct tuple_format *src) -{ - uint32_t total = sizeof(struct tuple_format) + - src->field_count * sizeof(struct tuple_field); - struct tuple_format *format = (struct tuple_format *) malloc(total); - if (format == NULL) { - diag_set(OutOfMemory, total, "malloc", "tuple format"); - return NULL; - } - memcpy(format, src, total); - tuple_dictionary_ref(format->dict); - format->id = FORMAT_ID_NIL; - format->refs = 0; - if (tuple_format_register(format) != 0) { - tuple_format_destroy(format); - free(format); - return NULL; - } - return format; -} - /** @sa declaration for details. */ int tuple_init_field_map(const struct tuple_format *format, uint32_t *field_map, diff --git a/src/box/tuple_format.h b/src/box/tuple_format.h index 8f88ff5d7122e339d40e27455792febab6ca951a..232df22b2593a788e32fb13930845faa758899a7 100644 --- a/src/box/tuple_format.h +++ b/src/box/tuple_format.h @@ -146,12 +146,6 @@ struct tuple_format { * in progress. */ bool is_temporary; - /** - * The number of extra bytes to reserve in tuples before - * field map. - * \sa struct tuple - */ - uint16_t extra_size; /** * Size of field map of tuple in bytes. * \sa struct tuple @@ -221,7 +215,6 @@ tuple_format_unref(struct tuple_format *format) * @param vtab Virtual function table for specific engines. * @param keys Array of key_defs of a space. * @param key_count The number of keys in @a keys array. - * @param extra_size Extra bytes to reserve in tuples metadata. * @param space_fields Array of fields, defined in a space format. * @param space_field_count Length of @a space_fields. * @@ -230,8 +223,7 @@ tuple_format_unref(struct tuple_format *format) */ struct tuple_format * tuple_format_new(struct tuple_format_vtab *vtab, struct key_def * const *keys, - uint16_t key_count, uint16_t extra_size, - const struct field_def *space_fields, + uint16_t key_count, const struct field_def *space_fields, uint32_t space_field_count, struct tuple_dictionary *dict); /** @@ -249,29 +241,6 @@ bool tuple_format1_can_store_format2_tuples(const struct tuple_format *format1, const struct tuple_format *format2); -/** - * Register the duplicate of the specified format. - * @param src Original format. - * - * @retval not NULL Success. - * @retval NULL Memory or format register error. - */ -struct tuple_format * -tuple_format_dup(struct tuple_format *src); - -/** - * Returns the total size of tuple metadata of this format. - * See @link struct tuple @endlink for explanation of tuple layout. - * - * @param format Tuple Format. - * @returns the total size of tuple metadata - */ -static inline uint16_t -tuple_format_meta_size(const struct tuple_format *format) -{ - return format->extra_size + format->field_map_size; -} - /** * Calculate minimal field count of tuples with specified keys and * space format. diff --git a/src/box/txn.c b/src/box/txn.c index 617ceb8a2fdcce27edbed3675823cec5a46cb36c..763e5c14baf7f0249b599870ddb24f8e2043284c 100644 --- a/src/box/txn.c +++ b/src/box/txn.c @@ -273,6 +273,7 @@ txn_write_to_wal(struct txn *txn) if (stmt->row == NULL) continue; /* A read (e.g. select) request */ *row++ = stmt->row; + req->approx_len += xrow_approx_len(stmt->row); } assert(row == req->rows + req->n_rows); diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 09b665598964849c82838b3ae30b5a14ac1aca78..b09b6ad85c2db85de967e7673484ec13b5d8d2ae 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -397,6 +397,12 @@ vinyl_index_stat(struct index *index, struct info_handler *h) info_table_begin(h, "disk"); vy_info_append_disk_stmt_counter(h, NULL, &stat->disk.count); + info_table_begin(h, "statement"); + info_append_int(h, "inserts", stat->disk.stmt.inserts); + info_append_int(h, "replaces", stat->disk.stmt.replaces); + info_append_int(h, "deletes", stat->disk.stmt.deletes); + info_append_int(h, "upserts", stat->disk.stmt.upserts); + info_table_end(h); /* statement */ info_table_begin(h, "iterator"); info_append_int(h, "lookup", stat->disk.iterator.lookup); vy_info_append_stmt_counter(h, "get", &stat->disk.iterator.get); @@ -603,7 +609,7 @@ vinyl_engine_create_space(struct engine *engine, struct space_def *def, keys[key_count++] = index_def->key_def; struct tuple_format *format = - tuple_format_new(&vy_tuple_format_vtab, keys, key_count, 0, + tuple_format_new(&vy_tuple_format_vtab, keys, key_count, def->fields, def->field_count, def->dict); if (format == NULL) { free(space); @@ -1139,8 +1145,6 @@ vinyl_space_swap_index(struct space *old_space, struct space *new_space, SWAP(old_lsm, new_lsm); SWAP(old_lsm->check_is_unique, new_lsm->check_is_unique); SWAP(old_lsm->mem_format, new_lsm->mem_format); - SWAP(old_lsm->mem_format_with_colmask, - new_lsm->mem_format_with_colmask); SWAP(old_lsm->disk_format, new_lsm->disk_format); SWAP(old_lsm->opts, new_lsm->opts); key_def_swap(old_lsm->key_def, new_lsm->key_def); @@ -1476,9 +1480,6 @@ vy_check_is_unique_secondary(struct vy_tx *tx, const struct vy_read_view **rv, if (!lsm->check_is_unique) return 0; - if (key_update_can_be_skipped(lsm->key_def->column_mask, - vy_stmt_column_mask(stmt))) - return 0; if (lsm->key_def->is_nullable && vy_tuple_key_contains_null(stmt, lsm->key_def)) return 0; @@ -1518,17 +1519,22 @@ vy_check_is_unique_secondary(struct vy_tx *tx, const struct vy_read_view **rv, /** * Check if insertion of a new tuple violates unique constraint * of any index of the space. - * @param env Vinyl environment. - * @param tx Current transaction. - * @param space Space to check. - * @param stmt New tuple. + * @param env Vinyl environment. + * @param tx Current transaction. + * @param space Space to check. + * @param stmt New tuple. + * @param column_mask Mask of columns changed by the operation. + * Used to optimize out uniqueness check in + * secondary indexes when an inserted tuple + * is a result of an UPDATE operation. * * @retval 0 Success, unique constraint is satisfied. * @retval -1 Duplicate is found or read error occurred. */ static int vy_check_is_unique(struct vy_env *env, struct vy_tx *tx, - struct space *space, struct tuple *stmt) + struct space *space, struct tuple *stmt, + uint64_t column_mask) { assert(space->index_count > 0); assert(vy_stmt_type(stmt) == IPROTO_INSERT || @@ -1561,6 +1567,9 @@ vy_check_is_unique(struct vy_env *env, struct vy_tx *tx, */ for (uint32_t i = 1; i < space->index_count; i++) { struct vy_lsm *lsm = vy_lsm(space->index[i]); + if (key_update_can_be_skipped(lsm->key_def->column_mask, + column_mask)) + continue; if (vy_check_is_unique_secondary(tx, rv, space_name(space), index_name_by_id(space, i), lsm, stmt) != 0) @@ -1708,6 +1717,54 @@ vy_check_update(struct space *space, const struct vy_lsm *pk, return 0; } +/** + * An UPDATE operation turns into a REPLACE statement in the + * primary index and into DELETE + INSERT in secondary indexes. + * This function performs an UPDATE operation in the given + * transaction write set after stmt->old_tuple and new_tuple + * have been initialized and checked. + */ +static int +vy_perform_update(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt, + struct space *space, struct vy_lsm *pk, int64_t column_mask) +{ + assert(stmt->old_tuple != NULL); + assert(stmt->new_tuple != NULL); + + if (vy_check_is_unique(env, tx, space, stmt->new_tuple, + column_mask) != 0) + return -1; + + vy_stmt_set_flags(stmt->new_tuple, VY_STMT_UPDATE); + + if (vy_tx_set_with_colmask(tx, pk, stmt->new_tuple, column_mask) != 0) + return -1; + if (space->index_count == 1) + return 0; + + struct tuple *delete = vy_stmt_new_surrogate_delete(pk->mem_format, + stmt->old_tuple); + if (delete == NULL) + return -1; + + for (uint32_t i = 1; i < space->index_count; ++i) { + struct vy_lsm *lsm = vy_lsm(space->index[i]); + if (vy_is_committed_one(env, lsm)) + continue; + if (vy_tx_set_with_colmask(tx, lsm, delete, + column_mask) != 0) + goto error; + if (vy_tx_set_with_colmask(tx, lsm, stmt->new_tuple, + column_mask) != 0) + goto error; + } + tuple_unref(delete); + return 0; +error: + tuple_unref(delete); + return -1; +} + /** * Execute UPDATE in a vinyl space. * @param env Vinyl environment. @@ -1767,55 +1824,15 @@ vy_update(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt, */ if (tuple_validate_raw(pk->mem_format, new_tuple)) return -1; - - struct tuple_format *mask_format = pk->mem_format_with_colmask; - if (space->index_count == 1) { - stmt->new_tuple = vy_stmt_new_replace(pk->mem_format, new_tuple, - new_tuple_end); - if (stmt->new_tuple == NULL) - return -1; - } else { - stmt->new_tuple = vy_stmt_new_replace(mask_format, new_tuple, - new_tuple_end); - if (stmt->new_tuple == NULL) - return -1; - vy_stmt_set_column_mask(stmt->new_tuple, column_mask); - } + stmt->new_tuple = vy_stmt_new_replace(pk->mem_format, new_tuple, + new_tuple_end); + if (stmt->new_tuple == NULL) + return -1; if (vy_check_update(space, pk, stmt->old_tuple, stmt->new_tuple, column_mask) != 0) return -1; - if (vy_check_is_unique(env, tx, space, stmt->new_tuple) != 0) - return -1; - /* - * In the primary index the tuple can be replaced without - * the old tuple deletion. - */ - if (vy_tx_set(tx, pk, stmt->new_tuple) != 0) - return -1; - if (space->index_count == 1) - return 0; - - struct tuple *delete = vy_stmt_new_surrogate_delete(mask_format, - stmt->old_tuple); - if (delete == NULL) - return -1; - vy_stmt_set_column_mask(delete, column_mask); - - for (uint32_t i = 1; i < space->index_count; ++i) { - lsm = vy_lsm(space->index[i]); - if (vy_is_committed_one(env, lsm)) - continue; - if (vy_tx_set(tx, lsm, delete) != 0) - goto error; - if (vy_tx_set(tx, lsm, stmt->new_tuple) != 0) - goto error; - } - tuple_unref(delete); - return 0; -error: - tuple_unref(delete); - return -1; + return vy_perform_update(env, tx, stmt, space, pk, column_mask); } /** @@ -1836,7 +1853,7 @@ vy_insert_first_upsert(struct vy_env *env, struct vy_tx *tx, assert(tx != NULL && tx->state == VINYL_TX_READY); assert(space->index_count > 0); assert(vy_stmt_type(stmt) == IPROTO_INSERT); - if (vy_check_is_unique(env, tx, space, stmt) != 0) + if (vy_check_is_unique(env, tx, space, stmt, COLUMN_MASK_FULL) != 0) return -1; struct vy_lsm *pk = vy_lsm(space->index[0]); assert(pk->index_id == 0); @@ -2047,19 +2064,10 @@ vy_upsert(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt, if (tuple_validate_raw(pk->mem_format, new_tuple)) return -1; new_tuple_end = new_tuple + new_size; - struct tuple_format *mask_format = pk->mem_format_with_colmask; - if (space->index_count == 1) { - stmt->new_tuple = vy_stmt_new_replace(pk->mem_format, new_tuple, - new_tuple_end); - if (stmt->new_tuple == NULL) - return -1; - } else { - stmt->new_tuple = vy_stmt_new_replace(mask_format, new_tuple, - new_tuple_end); - if (stmt->new_tuple == NULL) - return -1; - vy_stmt_set_column_mask(stmt->new_tuple, column_mask); - } + stmt->new_tuple = vy_stmt_new_replace(pk->mem_format, new_tuple, + new_tuple_end); + if (stmt->new_tuple == NULL) + return -1; if (vy_check_update(space, pk, stmt->old_tuple, stmt->new_tuple, column_mask) != 0) { diag_log(); @@ -2069,34 +2077,7 @@ vy_upsert(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt, */ return 0; } - if (vy_check_is_unique(env, tx, space, stmt->new_tuple) != 0) - return -1; - if (vy_tx_set(tx, pk, stmt->new_tuple)) - return -1; - if (space->index_count == 1) - return 0; - - /* Replace in secondary indexes works as delete insert. */ - struct tuple *delete = vy_stmt_new_surrogate_delete(mask_format, - stmt->old_tuple); - if (delete == NULL) - return -1; - vy_stmt_set_column_mask(delete, column_mask); - - for (uint32_t i = 1; i < space->index_count; ++i) { - struct vy_lsm *lsm = vy_lsm(space->index[i]); - if (vy_is_committed_one(env, lsm)) - continue; - if (vy_tx_set(tx, lsm, delete) != 0) - goto error; - if (vy_tx_set(tx, lsm, stmt->new_tuple) != 0) - goto error; - } - tuple_unref(delete); - return 0; -error: - tuple_unref(delete); - return -1; + return vy_perform_update(env, tx, stmt, space, pk, column_mask); } /** @@ -2132,7 +2113,8 @@ vy_insert(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt, request->tuple_end); if (stmt->new_tuple == NULL) return -1; - if (vy_check_is_unique(env, tx, space, stmt->new_tuple) != 0) + if (vy_check_is_unique(env, tx, space, stmt->new_tuple, + COLUMN_MASK_FULL) != 0) return -1; if (vy_tx_set(tx, pk, stmt->new_tuple) != 0) return -1; @@ -2184,7 +2166,8 @@ vy_replace(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt, request->tuple_end); if (stmt->new_tuple == NULL) return -1; - if (vy_check_is_unique(env, tx, space, stmt->new_tuple) != 0) + if (vy_check_is_unique(env, tx, space, stmt->new_tuple, + COLUMN_MASK_FULL) != 0) return -1; /* * Get the overwritten tuple from the primary index if @@ -3031,7 +3014,7 @@ vy_send_lsm(struct vy_join_ctx *ctx, struct vy_lsm_recovery_info *lsm_info) if (ctx->key_def == NULL) goto out; ctx->format = tuple_format_new(&vy_tuple_format_vtab, &ctx->key_def, - 1, 0, NULL, 0, NULL); + 1, NULL, 0, NULL); if (ctx->format == NULL) goto out_free_key_def; tuple_format_ref(ctx->format); diff --git a/src/box/vy_log.c b/src/box/vy_log.c index fc8ede598dfed2f52e8367befd8817b0b7f758d4..0615dcc289100d07f381099c4fcb1e28f651b647 100644 --- a/src/box/vy_log.c +++ b/src/box/vy_log.c @@ -1078,7 +1078,7 @@ vy_log_collect_garbage(int64_t signature) * it is still needed for backups. */ signature = vy_log_prev_checkpoint(signature); - xdir_collect_garbage(&vy_log.dir, signature, true); + xdir_collect_garbage(&vy_log.dir, signature, XDIR_GC_USE_COIO); } int64_t diff --git a/src/box/vy_lsm.c b/src/box/vy_lsm.c index de5ad3143994c2a350d1eaa02624ea446ca988f9..681b165beb4d3edfe4c918940d8ef5ac9433b577 100644 --- a/src/box/vy_lsm.c +++ b/src/box/vy_lsm.c @@ -61,7 +61,7 @@ vy_lsm_env_create(struct vy_lsm_env *env, const char *path, void *upsert_thresh_arg) { env->key_format = tuple_format_new(&vy_tuple_format_vtab, - NULL, 0, 0, NULL, 0, NULL); + NULL, 0, NULL, 0, NULL); if (env->key_format == NULL) return -1; tuple_format_ref(env->key_format); @@ -154,23 +154,12 @@ vy_lsm_new(struct vy_lsm_env *lsm_env, struct vy_cache_env *cache_env, lsm->disk_format = format; } else { lsm->disk_format = tuple_format_new(&vy_tuple_format_vtab, - &cmp_def, 1, 0, NULL, 0, - NULL); + &cmp_def, 1, NULL, 0, NULL); if (lsm->disk_format == NULL) goto fail_format; } tuple_format_ref(lsm->disk_format); - if (index_def->iid == 0) { - lsm->mem_format_with_colmask = - vy_tuple_format_new_with_colmask(format); - if (lsm->mem_format_with_colmask == NULL) - goto fail_mem_format_with_colmask; - } else { - lsm->mem_format_with_colmask = pk->mem_format_with_colmask; - } - tuple_format_ref(lsm->mem_format_with_colmask); - if (vy_lsm_stat_create(&lsm->stat) != 0) goto fail_stat; @@ -178,8 +167,8 @@ vy_lsm_new(struct vy_lsm_env *lsm_env, struct vy_cache_env *cache_env, if (lsm->run_hist == NULL) goto fail_run_hist; - lsm->mem = vy_mem_new(mem_env, *lsm->env->p_generation, - cmp_def, format, lsm->mem_format_with_colmask, + lsm->mem = vy_mem_new(mem_env, cmp_def, format, + *lsm->env->p_generation, space_cache_version); if (lsm->mem == NULL) goto fail_mem; @@ -215,8 +204,6 @@ vy_lsm_new(struct vy_lsm_env *lsm_env, struct vy_cache_env *cache_env, fail_run_hist: vy_lsm_stat_destroy(&lsm->stat); fail_stat: - tuple_format_unref(lsm->mem_format_with_colmask); -fail_mem_format_with_colmask: tuple_format_unref(lsm->disk_format); fail_format: key_def_delete(cmp_def); @@ -270,7 +257,6 @@ vy_lsm_delete(struct vy_lsm *lsm) vy_range_tree_iter(lsm->tree, NULL, vy_range_tree_free_cb, NULL); vy_range_heap_destroy(&lsm->range_heap); tuple_format_unref(lsm->disk_format); - tuple_format_unref(lsm->mem_format_with_colmask); key_def_delete(lsm->cmp_def); key_def_delete(lsm->key_def); histogram_delete(lsm->run_hist); @@ -695,6 +681,7 @@ vy_lsm_add_run(struct vy_lsm *lsm, struct vy_run *run) rlist_add_entry(&lsm->runs, run, in_lsm); lsm->run_count++; vy_disk_stmt_counter_add(&lsm->stat.disk.count, &run->count); + vy_stmt_stat_add(&lsm->stat.disk.stmt, &run->info.stmt_stat); lsm->bloom_size += bloom_size; lsm->page_index_size += page_index_size; @@ -723,6 +710,7 @@ vy_lsm_remove_run(struct vy_lsm *lsm, struct vy_run *run) rlist_del_entry(run, in_lsm); lsm->run_count--; vy_disk_stmt_counter_sub(&lsm->stat.disk.count, &run->count); + vy_stmt_stat_sub(&lsm->stat.disk.stmt, &run->info.stmt_stat); lsm->bloom_size -= bloom_size; lsm->page_index_size -= page_index_size; @@ -807,9 +795,8 @@ vy_lsm_rotate_mem(struct vy_lsm *lsm) struct vy_mem *mem; assert(lsm->mem != NULL); - mem = vy_mem_new(lsm->mem->env, *lsm->env->p_generation, - lsm->cmp_def, lsm->mem_format, - lsm->mem_format_with_colmask, space_cache_version); + mem = vy_mem_new(lsm->mem->env, lsm->cmp_def, lsm->mem_format, + *lsm->env->p_generation, space_cache_version); if (mem == NULL) return -1; @@ -857,8 +844,7 @@ vy_lsm_set(struct vy_lsm *lsm, struct vy_mem *mem, lsm->stat.memory.count.bytes += tuple_size(stmt); /* Abort transaction if format was changed by DDL */ - if (format_id != tuple_format_id(mem->format_with_colmask) && - format_id != tuple_format_id(mem->format)) { + if (format_id != tuple_format_id(mem->format)) { diag_set(ClientError, ER_TRANSACTION_CONFLICT); return -1; } diff --git a/src/box/vy_lsm.h b/src/box/vy_lsm.h index 2e026ced9ee06cec3ce143526b7a914f61f9084e..d8d9f9d07f9fdaa6d6a254ede7295c00060ec123 100644 --- a/src/box/vy_lsm.h +++ b/src/box/vy_lsm.h @@ -192,14 +192,6 @@ struct vy_lsm { struct tuple_format *disk_format; /** Tuple format of the space this LSM tree belongs to. */ struct tuple_format *mem_format; - /** - * Format for tuples of type REPLACE or DELETE which - * are a result of an UPDATE operation. Such tuples - * contain a column mask which preserves the list - * of actually changed columns. Used when creating - * tuples for vy_mem, and used only by primary key. - */ - struct tuple_format *mem_format_with_colmask; /** * If this LSM tree is for a secondary index, the following * variable points to the LSM tree of the primary index of diff --git a/src/box/vy_mem.c b/src/box/vy_mem.c index ccd079f00627a16ff228941a5928b72bf1a5f574..f8b89d4e702855ed13c513df95a08280766c8fea 100644 --- a/src/box/vy_mem.c +++ b/src/box/vy_mem.c @@ -96,9 +96,8 @@ vy_mem_tree_extent_free(void *ctx, void *p) } struct vy_mem * -vy_mem_new(struct vy_mem_env *env, int64_t generation, - struct key_def *cmp_def, struct tuple_format *format, - struct tuple_format *format_with_colmask, +vy_mem_new(struct vy_mem_env *env, struct key_def *cmp_def, + struct tuple_format *format, int64_t generation, uint32_t space_cache_version) { struct vy_mem *index = calloc(1, sizeof(*index)); @@ -114,8 +113,6 @@ vy_mem_new(struct vy_mem_env *env, int64_t generation, index->space_cache_version = space_cache_version; index->format = format; tuple_format_ref(format); - index->format_with_colmask = format_with_colmask; - tuple_format_ref(format_with_colmask); vy_mem_tree_create(&index->tree, cmp_def, vy_mem_tree_extent_alloc, vy_mem_tree_extent_free, index); @@ -129,7 +126,6 @@ vy_mem_delete(struct vy_mem *index) { index->env->tree_extent_size -= index->tree_extent_size; tuple_format_unref(index->format); - tuple_format_unref(index->format_with_colmask); fiber_cond_destroy(&index->pin_cond); TRASH(index); free(index); @@ -160,8 +156,7 @@ vy_mem_insert_upsert(struct vy_mem *mem, const struct tuple *stmt) { assert(vy_stmt_type(stmt) == IPROTO_UPSERT); /* Check if the statement can be inserted in the vy_mem. */ - assert(stmt->format_id == tuple_format_id(mem->format_with_colmask) || - stmt->format_id == tuple_format_id(mem->format)); + assert(stmt->format_id == tuple_format_id(mem->format)); /* The statement must be from a lsregion. */ assert(!vy_stmt_is_refable(stmt)); size_t size = tuple_size(stmt); @@ -220,8 +215,7 @@ vy_mem_insert(struct vy_mem *mem, const struct tuple *stmt) { assert(vy_stmt_type(stmt) != IPROTO_UPSERT); /* Check if the statement can be inserted in the vy_mem. */ - assert(stmt->format_id == tuple_format_id(mem->format_with_colmask) || - stmt->format_id == tuple_format_id(mem->format)); + assert(stmt->format_id == tuple_format_id(mem->format)); /* The statement must be from a lsregion. */ assert(!vy_stmt_is_refable(stmt)); size_t size = tuple_size(stmt); diff --git a/src/box/vy_mem.h b/src/box/vy_mem.h index d6afeed132874202fafb2b887788607326e3b815..b41c3c0bb3670d608e07a073972799646eaee5be 100644 --- a/src/box/vy_mem.h +++ b/src/box/vy_mem.h @@ -194,12 +194,12 @@ struct vy_mem { */ int64_t generation; /** - * Format of vy_mem REPLACE and DELETE tuples without - * column mask. + * Format of statements stored in this in-memory index. + * Note, the statements don't reference the format by + * themselves, instead it is referenced once by vy_mem. + * This allows us to drop vy_mem in O(1). */ struct tuple_format *format; - /** Format of vy_mem tuples with column mask. */ - struct tuple_format *format_with_colmask; /** * Number of active writers to this index. * @@ -254,19 +254,16 @@ vy_mem_wait_pinned(struct vy_mem *mem) * Instantiate a new in-memory level. * * @param env Vinyl memory environment. - * @param generation Generation of statements stored in the tree. * @param key_def key definition. * @param format Format for REPLACE and DELETE tuples. - * @param format_with_colmask Format for tuples, which have - * column mask. + * @param generation Generation of statements stored in the tree. * @param space_cache_version Data dictionary cache version * @retval new vy_mem instance on success. * @retval NULL on error, check diag. */ struct vy_mem * -vy_mem_new(struct vy_mem_env *env, int64_t generation, - struct key_def *cmp_def, struct tuple_format *format, - struct tuple_format *format_with_colmask, +vy_mem_new(struct vy_mem_env *env, struct key_def *cmp_def, + struct tuple_format *format, int64_t generation, uint32_t space_cache_version); /** diff --git a/src/box/vy_range.c b/src/box/vy_range.c index 0558098a9fcc7718d6d48e657036ca48fec1eecf..af1227ea2b2a3de16d611454468fdfc13c30cf1b 100644 --- a/src/box/vy_range.c +++ b/src/box/vy_range.c @@ -312,8 +312,6 @@ vy_range_update_compact_priority(struct vy_range *range, vy_disk_stmt_counter_reset(&total_stmt_count); /* Total number of checked runs. */ uint32_t total_run_count = 0; - /* The total size of runs checked so far. */ - uint64_t total_size = 0; /* Estimated size of a compacted run, if compaction is scheduled. */ uint64_t est_new_run_size = 0; /* The number of runs at the current level. */ @@ -335,7 +333,6 @@ vy_range_update_compact_priority(struct vy_range *range, */ if (target_run_size == 0) target_run_size = size; - total_size += size; level_run_count++; total_run_count++; vy_disk_stmt_counter_add(&total_stmt_count, &slice->count); @@ -377,7 +374,7 @@ vy_range_update_compact_priority(struct vy_range *range, */ range->compact_priority = total_run_count; range->compact_queue = total_stmt_count; - est_new_run_size = total_size; + est_new_run_size = total_stmt_count.bytes_compressed; } } } diff --git a/src/box/vy_run.c b/src/box/vy_run.c index bb5baf2c7d95355150c045191366ff56df1e90c0..c448a449d5c232a9f0f2cd5ddc5723b14cba9fb0 100644 --- a/src/box/vy_run.c +++ b/src/box/vy_run.c @@ -542,6 +542,33 @@ vy_page_info_decode(struct vy_page_info *page, const struct xrow_header *xrow, return 0; } +/** Decode statement statistics from @data and advance @data. */ +static void +vy_stmt_stat_decode(struct vy_stmt_stat *stat, const char **data) +{ + uint32_t size = mp_decode_map(data); + for (uint32_t i = 0; i < size; i++) { + uint64_t key = mp_decode_uint(data); + uint64_t value = mp_decode_uint(data); + switch (key) { + case IPROTO_INSERT: + stat->inserts = value; + break; + case IPROTO_REPLACE: + stat->replaces = value; + break; + case IPROTO_DELETE: + stat->deletes = value; + break; + case IPROTO_UPSERT: + stat->upserts = value; + break; + default: + break; + } + } +} + /** * Decode the run metadata from xrow. * @@ -603,6 +630,9 @@ vy_run_info_decode(struct vy_run_info *run_info, if (run_info->bloom == NULL) return -1; break; + case VY_RUN_INFO_STMT_STAT: + vy_stmt_stat_decode(&run_info->stmt_stat, &pos); + break; default: diag_set(ClientError, ER_INVALID_INDEX_FILE, filename, "Can't decode run info: unknown key %u", @@ -1876,6 +1906,37 @@ vy_page_info_encode(const struct vy_page_info *page_info, /** {{{ vy_run_info */ +/** Return the size of encoded statement statistics. */ +static size_t +vy_stmt_stat_sizeof(const struct vy_stmt_stat *stat) +{ + return mp_sizeof_map(4) + + mp_sizeof_uint(IPROTO_INSERT) + + mp_sizeof_uint(IPROTO_REPLACE) + + mp_sizeof_uint(IPROTO_DELETE) + + mp_sizeof_uint(IPROTO_UPSERT) + + mp_sizeof_uint(stat->inserts) + + mp_sizeof_uint(stat->replaces) + + mp_sizeof_uint(stat->deletes) + + mp_sizeof_uint(stat->upserts); +} + +/** Encode statement statistics to @buf and return advanced @buf. */ +static char * +vy_stmt_stat_encode(const struct vy_stmt_stat *stat, char *buf) +{ + buf = mp_encode_map(buf, 4); + buf = mp_encode_uint(buf, IPROTO_INSERT); + buf = mp_encode_uint(buf, stat->inserts); + buf = mp_encode_uint(buf, IPROTO_REPLACE); + buf = mp_encode_uint(buf, stat->replaces); + buf = mp_encode_uint(buf, IPROTO_DELETE); + buf = mp_encode_uint(buf, stat->deletes); + buf = mp_encode_uint(buf, IPROTO_UPSERT); + buf = mp_encode_uint(buf, stat->upserts); + return buf; +} + /** * Encode vy_run_info as xrow * Allocates using region alloc @@ -1898,7 +1959,7 @@ vy_run_info_encode(const struct vy_run_info *run_info, mp_next(&tmp); size_t max_key_size = tmp - run_info->max_key; - uint32_t key_count = 5; + uint32_t key_count = 6; if (run_info->bloom != NULL) key_count++; @@ -1914,6 +1975,8 @@ vy_run_info_encode(const struct vy_run_info *run_info, if (run_info->bloom != NULL) size += mp_sizeof_uint(VY_RUN_INFO_BLOOM) + tuple_bloom_size(run_info->bloom); + size += mp_sizeof_uint(VY_RUN_INFO_STMT_STAT) + + vy_stmt_stat_sizeof(&run_info->stmt_stat); char *pos = region_alloc(&fiber()->gc, size); if (pos == NULL) { @@ -1940,6 +2003,8 @@ vy_run_info_encode(const struct vy_run_info *run_info, pos = mp_encode_uint(pos, VY_RUN_INFO_BLOOM); pos = tuple_bloom_encode(run_info->bloom, pos); } + pos = mp_encode_uint(pos, VY_RUN_INFO_STMT_STAT); + pos = vy_stmt_stat_encode(&run_info->stmt_stat, pos); xrow->body->iov_len = (void *)pos - xrow->body->iov_base; xrow->bodycnt = 1; xrow->type = VY_INDEX_RUN_INFO; @@ -2136,6 +2201,7 @@ vy_run_writer_write_to_page(struct vy_run_writer *writer, struct tuple *stmt) int64_t lsn = vy_stmt_lsn(stmt); run->info.min_lsn = MIN(run->info.min_lsn, lsn); run->info.max_lsn = MAX(run->info.max_lsn, lsn); + vy_stmt_stat_acct(&run->info.stmt_stat, vy_stmt_type(stmt)); return 0; } @@ -2567,8 +2633,10 @@ vy_slice_stream_next(struct vy_stmt_stream *virt_stream, struct tuple **ret) if (stream->slice->end != NULL && stream->page_no >= stream->slice->last_page_no && vy_tuple_compare_with_key(tuple, stream->slice->end, - stream->cmp_def) >= 0) + stream->cmp_def) >= 0) { + tuple_unref(tuple); return 0; + } /* We definitely has the next non-null tuple. Save it in stream */ if (stream->tuple != NULL) diff --git a/src/box/vy_run.h b/src/box/vy_run.h index 4b919a8ff87c3543251bec89a1693587b5594176..990daffa1a670eccec4568129537d1ccbdeaaae9 100644 --- a/src/box/vy_run.h +++ b/src/box/vy_run.h @@ -87,6 +87,8 @@ struct vy_run_info { uint32_t page_count; /** Bloom filter of all tuples in run */ struct tuple_bloom *bloom; + /** Statement statistics. */ + struct vy_stmt_stat stmt_stat; }; /** diff --git a/src/box/vy_stat.h b/src/box/vy_stat.h index 1545115adbd3196ed17338456d38d9127a927dd9..9bb09174c2dbb6e0388941dbd279b4edf8cc47ca 100644 --- a/src/box/vy_stat.h +++ b/src/box/vy_stat.h @@ -36,11 +36,20 @@ #include "latency.h" #include "tuple.h" +#include "iproto_constants.h" #if defined(__cplusplus) extern "C" { #endif /* defined(__cplusplus) */ +/** Number of statements of each type. */ +struct vy_stmt_stat { + int64_t inserts; + int64_t replaces; + int64_t deletes; + int64_t upserts; +}; + /** Used for accounting statements stored in memory. */ struct vy_stmt_counter { /** Number of statements. */ @@ -130,6 +139,8 @@ struct vy_lsm_stat { struct { /** Number of statements stored on disk. */ struct vy_disk_stmt_counter count; + /** Statement statistics. */ + struct vy_stmt_stat stmt; /** Run iterator statistics. */ struct vy_run_iterator_stat iterator; /** Dump statistics. */ @@ -298,6 +309,54 @@ vy_disk_stmt_counter_sub(struct vy_disk_stmt_counter *c1, c1->pages -= c2->pages; } +/** + * Account a single statement of the given type in @stat. + */ +static inline void +vy_stmt_stat_acct(struct vy_stmt_stat *stat, enum iproto_type type) +{ + switch (type) { + case IPROTO_INSERT: + stat->inserts++; + break; + case IPROTO_REPLACE: + stat->replaces++; + break; + case IPROTO_DELETE: + stat->deletes++; + break; + case IPROTO_UPSERT: + stat->upserts++; + break; + default: + break; + } +} + +/** + * Add statistics accumulated in @s2 to @s1. + */ +static inline void +vy_stmt_stat_add(struct vy_stmt_stat *s1, const struct vy_stmt_stat *s2) +{ + s1->inserts += s2->inserts; + s1->replaces += s2->replaces; + s1->deletes += s2->deletes; + s1->upserts += s2->upserts; +} + +/** + * Subtract statistics accumulated in @s2 from @s1. + */ +static inline void +vy_stmt_stat_sub(struct vy_stmt_stat *s1, const struct vy_stmt_stat *s2) +{ + s1->inserts -= s2->inserts; + s1->replaces -= s2->replaces; + s1->deletes -= s2->deletes; + s1->upserts -= s2->upserts; +} + #if defined(__cplusplus) } /* extern "C" */ #endif /* defined(__cplusplus) */ diff --git a/src/box/vy_stmt.c b/src/box/vy_stmt.c index ebe64300b84d50b55c43b5a3c373e47561025c60..d83840406cc5b6c291e0b65d3ab6af82e587e957 100644 --- a/src/box/vy_stmt.c +++ b/src/box/vy_stmt.c @@ -61,6 +61,14 @@ static inline uint8_t vy_stmt_persistent_flags(const struct tuple *stmt, bool is_primary) { uint8_t mask = VY_STMT_FLAGS_ALL; + + /* + * This flag is only used by the write iterator to turn + * in-memory REPLACEs into INSERTs on dump so no need to + * persist it. + */ + mask &= ~VY_STMT_UPDATE; + if (!is_primary) { /* * Do not store VY_STMT_DEFERRED_DELETE flag in @@ -119,8 +127,8 @@ vy_tuple_delete(struct tuple_format *format, struct tuple *tuple) static struct tuple * vy_stmt_alloc(struct tuple_format *format, uint32_t bsize) { - uint32_t meta_size = tuple_format_meta_size(format); - uint32_t total_size = sizeof(struct vy_stmt) + meta_size + bsize; + uint32_t total_size = sizeof(struct vy_stmt) + format->field_map_size + + bsize; if (unlikely(total_size > vy_max_tuple_size)) { diag_set(ClientError, ER_VINYL_MAX_TUPLE_SIZE, (unsigned) total_size); @@ -133,13 +141,13 @@ vy_stmt_alloc(struct tuple_format *format, uint32_t bsize) return NULL; } say_debug("vy_stmt_alloc(format = %d %u, bsize = %zu) = %p", - format->id, tuple_format_meta_size(format), bsize, tuple); + format->id, format->field_map_size, bsize, tuple); tuple->refs = 1; tuple->format_id = tuple_format_id(format); if (cord_is_main()) tuple_format_ref(format); tuple->bsize = bsize; - tuple->data_offset = sizeof(struct vy_stmt) + meta_size;; + tuple->data_offset = sizeof(struct vy_stmt) + format->field_map_size; vy_stmt_set_lsn(tuple, 0); vy_stmt_set_type(tuple, 0); vy_stmt_set_flags(tuple, 0); @@ -740,15 +748,3 @@ vy_stmt_str(const struct tuple *stmt) return "<failed to format statement>"; return buf; } - -struct tuple_format * -vy_tuple_format_new_with_colmask(struct tuple_format *mem_format) -{ - struct tuple_format *format = tuple_format_dup(mem_format); - if (format == NULL) - return NULL; - /* + size of column mask. */ - assert(format->extra_size == 0); - format->extra_size = sizeof(uint64_t); - return format; -} diff --git a/src/box/vy_stmt.h b/src/box/vy_stmt.h index 73e18ca7ce60aad32730bef21ab4967f3dfee41e..c3381402904e120f4c21e4d71109e1d47e27661b 100644 --- a/src/box/vy_stmt.h +++ b/src/box/vy_stmt.h @@ -97,10 +97,19 @@ enum { * particular key. */ VY_STMT_SKIP_READ = 1 << 1, + /** + * This flag is set for those REPLACE statements that were + * generated by UPDATE operations. It is used by the write + * iterator to turn such REPLACEs into INSERTs in secondary + * indexes so that they can get annihilated with DELETEs on + * compaction. It is never written to disk. + */ + VY_STMT_UPDATE = 1 << 2, /** * Bit mask of all statement flags. */ - VY_STMT_FLAGS_ALL = VY_STMT_DEFERRED_DELETE | VY_STMT_SKIP_READ, + VY_STMT_FLAGS_ALL = (VY_STMT_DEFERRED_DELETE | VY_STMT_SKIP_READ | + VY_STMT_UPDATE), }; /** @@ -210,39 +219,6 @@ vy_stmt_set_n_upserts(struct tuple *stmt, uint8_t n) *((uint8_t *)stmt - 1) = n; } -/** Get the column mask of the specified tuple. */ -static inline uint64_t -vy_stmt_column_mask(const struct tuple *tuple) -{ - enum iproto_type type = vy_stmt_type(tuple); - assert(type == IPROTO_INSERT || type == IPROTO_REPLACE || - type == IPROTO_DELETE); - (void) type; - if (tuple_format(tuple)->extra_size == sizeof(uint64_t)) { - /* Tuple has column mask */ - const char *extra = tuple_extra(tuple); - return load_u64(extra); - } - return UINT64_MAX; /* return default value */ -} - -/** - * Set the column mask in the tuple. - * @param tuple Tuple to set column mask. - * @param column_mask Bitmask of the updated columns. - */ -static inline void -vy_stmt_set_column_mask(struct tuple *tuple, uint64_t column_mask) -{ - enum iproto_type type = vy_stmt_type(tuple); - assert(type == IPROTO_INSERT || type == IPROTO_REPLACE || - type == IPROTO_DELETE); - assert(tuple_format(tuple)->extra_size == sizeof(uint64_t)); - (void) type; - char *extra = (char *) tuple_extra(tuple); - store_u64(extra, column_mask); -} - /** * Free the tuple of a vinyl space. * @pre tuple->refs == 0 @@ -700,17 +676,6 @@ vy_stmt_snprint(char *buf, int size, const struct tuple *stmt); const char * vy_stmt_str(const struct tuple *stmt); -/** - * Create a tuple format with column mask of an update operation. - * @sa vy_index.column_mask, vy_can_skip_update(). - * @param mem_format A base tuple format. - * - * @retval not NULL Success. - * @retval NULL Memory or format register error. - */ -struct tuple_format * -vy_tuple_format_new_with_colmask(struct tuple_format *mem_format); - /** * Check if a key of @a tuple contains NULL. * @param tuple Tuple to check. diff --git a/src/box/vy_tx.c b/src/box/vy_tx.c index 957c87f089d86840254ece9597f6f4e4ceca3462..d1027425b28ed5156c7ebb89fe17dcaaf531dcfe 100644 --- a/src/box/vy_tx.c +++ b/src/box/vy_tx.c @@ -50,6 +50,7 @@ #include "trigger.h" #include "trivia/util.h" #include "tuple.h" +#include "column_mask.h" #include "vy_cache.h" #include "vy_lsm.h" #include "vy_mem.h" @@ -212,7 +213,8 @@ tx_manager_destroy_read_view(struct tx_manager *xm, } static struct txv * -txv_new(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) +txv_new(struct vy_tx *tx, struct vy_lsm *lsm, + struct tuple *stmt, uint64_t column_mask) { struct tx_manager *xm = tx->xm; struct txv *v = mempool_alloc(&xm->txv_mempool); @@ -226,6 +228,7 @@ txv_new(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) v->stmt = stmt; tuple_ref(stmt); v->region_stmt = NULL; + v->column_mask = column_mask; v->tx = tx; v->is_first_insert = false; v->is_overwritten = false; @@ -586,7 +589,8 @@ vy_tx_handle_deferred_delete(struct vy_tx *tx, struct txv *v) int rc = 0; for (uint32_t i = 1; i < space->index_count; i++) { struct vy_lsm *lsm = vy_lsm(space->index[i]); - struct txv *delete_txv = txv_new(tx, lsm, delete_stmt); + struct txv *delete_txv = txv_new(tx, lsm, delete_stmt, + UINT64_MAX); if (delete_txv == NULL) { rc = -1; break; @@ -651,6 +655,12 @@ vy_tx_prepare(struct vy_tx *tx) if (v->is_overwritten) continue; + /* Skip statements which don't change this secondary key. */ + if (lsm->index_id > 0 && + key_update_can_be_skipped(lsm->key_def->column_mask, + v->column_mask)) + continue; + if (lsm->index_id > 0 && repsert == NULL && delete == NULL) { /* * This statement is for a secondary index, @@ -948,7 +958,8 @@ vy_tx_track_point(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) } int -vy_tx_set(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) +vy_tx_set_with_colmask(struct vy_tx *tx, struct vy_lsm *lsm, + struct tuple *stmt, uint64_t column_mask) { assert(vy_stmt_type(stmt) != 0); /** @@ -980,7 +991,7 @@ vy_tx_set(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) } /* Allocate a MVCC container. */ - struct txv *v = txv_new(tx, lsm, stmt); + struct txv *v = txv_new(tx, lsm, stmt, column_mask); if (applied != NULL) tuple_unref(applied); if (v == NULL) @@ -998,15 +1009,12 @@ vy_tx_set(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) if (old == NULL && vy_stmt_type(stmt) == IPROTO_INSERT) v->is_first_insert = true; - if (old != NULL && vy_stmt_type(stmt) != IPROTO_UPSERT) { + if (old != NULL) { /* * Inherit the column mask of the overwritten statement - * so as not to skip both statements on dump. + * so as not to skip both statements on commit. */ - uint64_t column_mask = vy_stmt_column_mask(stmt); - if (column_mask != UINT64_MAX) - vy_stmt_set_column_mask(stmt, column_mask | - vy_stmt_column_mask(old->stmt)); + v->column_mask |= old->column_mask; } if (lsm->index_id > 0 && vy_stmt_type(stmt) == IPROTO_REPLACE && @@ -1020,7 +1028,7 @@ vy_tx_set(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) * second field, but the column mask will say it does. * * To discard DELETE statements in the write iterator - * (see optimization #6), we turn a REPLACE into an + * (see optimization #5), we turn a REPLACE into an * INSERT in case the REPLACE was generated by an * update that changed secondary key fields. So we * can't tolerate inaccuracy in a column mask. @@ -1031,10 +1039,8 @@ vy_tx_set(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) * key bits in the column mask to ensure that no REPLACE * statement will be written for this secondary key. */ - uint64_t column_mask = vy_stmt_column_mask(stmt); - if (column_mask != UINT64_MAX) - vy_stmt_set_column_mask(stmt, column_mask & - ~lsm->cmp_def->column_mask); + if (v->column_mask != UINT64_MAX) + v->column_mask &= ~lsm->cmp_def->column_mask; } v->overwritten = old; diff --git a/src/box/vy_tx.h b/src/box/vy_tx.h index b201abd73a98b1a732ad3f0db8f3cd27942bd371..87066091b7b0103a7e614ad13f4f5520f39868e9 100644 --- a/src/box/vy_tx.h +++ b/src/box/vy_tx.h @@ -85,6 +85,8 @@ struct txv { struct tuple *stmt; /** Statement allocated on vy_mem->allocator. */ const struct tuple *region_stmt; + /** Mask of columns modified by this operation. */ + uint64_t column_mask; /** Next in the transaction log. */ struct stailq_entry next_in_log; /** Member the transaction write set. */ @@ -371,7 +373,14 @@ vy_tx_track_point(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt); /** Add a statement to a transaction. */ int -vy_tx_set(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt); +vy_tx_set_with_colmask(struct vy_tx *tx, struct vy_lsm *lsm, + struct tuple *stmt, uint64_t column_mask); + +static inline int +vy_tx_set(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) +{ + return vy_tx_set_with_colmask(tx, lsm, stmt, UINT64_MAX); +} /** * Iterator over the write set of a transaction. diff --git a/src/box/vy_write_iterator.c b/src/box/vy_write_iterator.c index 1b54e5399eff37e3c350fb55b5809054c6aa3b56..7a6a206271b4f8e242b0dee6df003fa4be344237 100644 --- a/src/box/vy_write_iterator.c +++ b/src/box/vy_write_iterator.c @@ -32,7 +32,6 @@ #include "vy_mem.h" #include "vy_run.h" #include "vy_upsert.h" -#include "column_mask.h" #include "fiber.h" #define HEAP_FORWARD_DECLARATION @@ -443,6 +442,7 @@ vy_write_iterator_close(struct vy_stmt_stream *vstream) assert(vstream->iface->close == vy_write_iterator_close); struct vy_write_iterator *stream = (struct vy_write_iterator *)vstream; vy_write_iterator_stop(vstream); + vy_source_heap_destroy(&stream->src_heap); tuple_format_unref(stream->format); free(stream); } @@ -632,7 +632,7 @@ vy_write_iterator_deferred_delete(struct vy_write_iterator *stream, /** * Build the history of the current key. - * Apply optimizations 1, 2 and 3 (@sa vy_write_iterator.h). + * Apply optimizations 1 and 2 (@sa vy_write_iterator.h). * When building a history, some statements can be * skipped (e.g. multiple REPLACE statements on the same key), * but nothing can be merged yet, since we don't know the first @@ -690,22 +690,18 @@ vy_write_iterator_build_history(struct vy_write_iterator *stream, int current_rv_i = 0; int64_t current_rv_lsn = vy_write_iterator_get_vlsn(stream, 0); int64_t merge_until_lsn = vy_write_iterator_get_vlsn(stream, 1); - uint64_t key_mask = stream->cmp_def->column_mask; while (true) { *is_first_insert = vy_stmt_type(src->tuple) == IPROTO_INSERT; if (!stream->is_primary && - vy_stmt_type(src->tuple) == IPROTO_REPLACE) { + (vy_stmt_flags(src->tuple) & VY_STMT_UPDATE) != 0) { /* * If a REPLACE stored in a secondary index was * generated by an update operation, it can be * turned into an INSERT. */ - uint64_t stmt_mask = vy_stmt_column_mask(src->tuple); - if (stmt_mask != UINT64_MAX && - !key_update_can_be_skipped(stmt_mask, key_mask)) - *is_first_insert = true; + *is_first_insert = true; } /* @@ -758,6 +754,12 @@ vy_write_iterator_build_history(struct vy_write_iterator *stream, goto next_lsn; } + rc = vy_write_iterator_push_rv(stream, src->tuple, + current_rv_i); + if (rc != 0) + break; + ++*count; + /* * Optimization 2: skip statements overwritten * by a REPLACE or DELETE. @@ -765,34 +767,12 @@ vy_write_iterator_build_history(struct vy_write_iterator *stream, if (vy_stmt_type(src->tuple) == IPROTO_REPLACE || vy_stmt_type(src->tuple) == IPROTO_INSERT || vy_stmt_type(src->tuple) == IPROTO_DELETE) { - uint64_t stmt_mask = vy_stmt_column_mask(src->tuple); - /* - * Optimization 3: skip statements which - * do not change this secondary key. - */ - if (!stream->is_primary && - key_update_can_be_skipped(key_mask, stmt_mask)) - goto next_lsn; - - rc = vy_write_iterator_push_rv(stream, src->tuple, - current_rv_i); - if (rc != 0) - break; - ++*count; current_rv_i++; current_rv_lsn = merge_until_lsn; merge_until_lsn = vy_write_iterator_get_vlsn(stream, current_rv_i + 1); - goto next_lsn; } - - assert(vy_stmt_type(src->tuple) == IPROTO_UPSERT); - rc = vy_write_iterator_push_rv(stream, src->tuple, - current_rv_i); - if (rc != 0) - break; - ++*count; next_lsn: rc = vy_write_iterator_merge_step(stream); if (rc != 0) @@ -844,7 +824,7 @@ vy_read_view_merge(struct vy_write_iterator *stream, struct tuple *hint, assert(rv->history != NULL); struct vy_write_history *h = rv->history; /* - * Optimization 5: discard a DELETE statement referenced + * Optimization 4: discard a DELETE statement referenced * by a read view if it is preceded by another DELETE for * the same key. */ @@ -923,7 +903,7 @@ vy_read_view_merge(struct vy_write_iterator *stream, struct tuple *hint, } if (is_first_insert && vy_stmt_type(rv->tuple) == IPROTO_DELETE) { /* - * Optimization 6: discard the first DELETE if + * Optimization 5: discard the first DELETE if * the oldest statement for the current key among * all sources is an INSERT and hence there's no * statements for this key in older runs or the @@ -939,11 +919,11 @@ vy_read_view_merge(struct vy_write_iterator *stream, struct tuple *hint, * If the oldest statement among all sources is an * INSERT, convert the first REPLACE to an INSERT * so that if the key gets deleted later, we will - * be able invoke optimization #6 to discard the + * be able invoke optimization #5 to discard the * DELETE statement. * * Otherwise convert the first INSERT to a REPLACE - * so as not to trigger optimization #6 on the next + * so as not to trigger optimization #5 on the next * compaction. */ uint32_t size; diff --git a/src/box/vy_write_iterator.h b/src/box/vy_write_iterator.h index 3b9b535aa4bd91f3e677d0a605a091cafe94c05b..4ae3815d02f397a1fa34d2e36d5e140e4b8af857 100644 --- a/src/box/vy_write_iterator.h +++ b/src/box/vy_write_iterator.h @@ -117,27 +117,7 @@ * skip keep skip merge * * --------------------------------------------------------------- - * Optimization #3: when compacting runs of a secondary key, skip - * statements, which do not update this key. - * - * -------- - * SAME KEY - * -------- - * VLSN(i) VLSN(i+1) - * Masks | | - * intersection:| not 0 0 0 not 0 not 0 | - * | ANY DELETE REPLACE ANY ... REPLACE | - * \______/\_______________/\___________________/ - * merge skip merge - * - * Details: when UPDATE is executed by Tarantool, it is - * transformed into DELETE + REPLACE or a single REPLACE. But it - * is only necessary to write anything into the secondary key if - * such UPDATE changes any field, which is part of the key. - * All other UPDATEs can be simply skipped. - * - * --------------------------------------------------------------- - * Optimization #4: use older REPLACE/DELETE to apply UPSERTs and + * Optimization #3: use older REPLACE/DELETE to apply UPSERTs and * convert them into a single REPLACE. When compaction includes * the last level, absence of REPLACE or DELETE is equivalent * to a DELETE, and UPSERT can be converted to REPLACE as well. @@ -166,7 +146,7 @@ * vy_write_iterator_build_read_views. * * --------------------------------------------------------------- - * Optimization #5: discard a tautological DELETE statement, i.e. + * Optimization #4: discard a tautological DELETE statement, i.e. * a statement that was not removed from the history because it * is referenced by read view, but that is preceeded by another * DELETE and hence not needed. @@ -182,7 +162,7 @@ * skip keep skip discard * * --------------------------------------------------------------- - * Optimization #6: discard the first DELETE if the oldest + * Optimization #5: discard the first DELETE if the oldest * statement for the current key among all sources is an INSERT. * Rationale: if a key's history starts from an INSERT, there is * either no statements for this key in older runs or the latest diff --git a/src/box/wal.c b/src/box/wal.c index 2a1353b0fa4bd08d8b79148a989bfa6d1dea3479..673762a63d896cba960081e8b55caff581b68413 100644 --- a/src/box/wal.c +++ b/src/box/wal.c @@ -44,6 +44,17 @@ #include "coio_task.h" #include "replication.h" +enum { + /** + * Size of disk space to preallocate with xlog_fallocate(). + * Obviously, we want to call this function as infrequent as + * possible to avoid the overhead associated with a system + * call, however at the same time we do not want to call it + * to allocate too big chunks, because this may increase tx + * latency. 1 MB seems to be a well balanced choice. + */ + WAL_FALLOCATE_LEN = 1024 * 1024, +}; const char *wal_mode_STRS[] = { "none", "write", "fsync", NULL }; @@ -108,6 +119,12 @@ struct wal_writer * with this LSN and LSN becomes "real". */ struct vclock vclock; + /** + * Signature of the oldest checkpoint available on the instance. + * The WAL writer must not delete WAL files that are needed to + * recover from it even if it is running out of disk space. + */ + int64_t checkpoint_lsn; /** The current WAL file. */ struct xlog current_wal; /** @@ -126,6 +143,8 @@ struct wal_writer struct wal_msg { struct cmsg base; + /** Approximate size of this request when encoded. */ + size_t approx_len; /** Input queue, on output contains all committed requests. */ struct stailq commit; /** @@ -168,6 +187,7 @@ static void wal_msg_create(struct wal_msg *batch) { cmsg_init(&batch->base, wal_request_route); + batch->approx_len = 0; stailq_create(&batch->commit); stailq_create(&batch->rollback); } @@ -273,9 +293,9 @@ tx_schedule_rollback(struct cmsg *msg) */ static void wal_writer_create(struct wal_writer *writer, enum wal_mode wal_mode, - const char *wal_dirname, const struct tt_uuid *instance_uuid, - struct vclock *vclock, int64_t wal_max_rows, - int64_t wal_max_size) + const char *wal_dirname, int64_t wal_max_rows, + int64_t wal_max_size, const struct tt_uuid *instance_uuid, + const struct vclock *vclock, int64_t checkpoint_lsn) { writer->wal_mode = wal_mode; writer->wal_max_rows = wal_max_rows; @@ -295,6 +315,7 @@ wal_writer_create(struct wal_writer *writer, enum wal_mode wal_mode, vclock_create(&writer->vclock); vclock_copy(&writer->vclock, vclock); + writer->checkpoint_lsn = checkpoint_lsn; rlist_create(&writer->watchers); } @@ -398,16 +419,16 @@ wal_open(struct wal_writer *writer) * mode are closed. WAL thread has been started. */ int -wal_init(enum wal_mode wal_mode, const char *wal_dirname, - const struct tt_uuid *instance_uuid, struct vclock *vclock, - int64_t wal_max_rows, int64_t wal_max_size) +wal_init(enum wal_mode wal_mode, const char *wal_dirname, int64_t wal_max_rows, + int64_t wal_max_size, const struct tt_uuid *instance_uuid, + const struct vclock *vclock, int64_t first_checkpoint_lsn) { assert(wal_max_rows > 1); struct wal_writer *writer = &wal_writer_singleton; - - wal_writer_create(writer, wal_mode, wal_dirname, instance_uuid, - vclock, wal_max_rows, wal_max_size); + wal_writer_create(writer, wal_mode, wal_dirname, wal_max_rows, + wal_max_size, instance_uuid, vclock, + first_checkpoint_lsn); /* * Scan the WAL directory to build an index of all @@ -525,25 +546,29 @@ wal_checkpoint(struct vclock *vclock, bool rotate) struct wal_gc_msg { struct cbus_call_msg base; - int64_t lsn; + int64_t wal_lsn; + int64_t checkpoint_lsn; }; static int wal_collect_garbage_f(struct cbus_call_msg *data) { - int64_t lsn = ((struct wal_gc_msg *)data)->lsn; - xdir_collect_garbage(&wal_writer_singleton.wal_dir, lsn, false); + struct wal_writer *writer = &wal_writer_singleton; + struct wal_gc_msg *msg = (struct wal_gc_msg *)data; + writer->checkpoint_lsn = msg->checkpoint_lsn; + xdir_collect_garbage(&writer->wal_dir, msg->wal_lsn, 0); return 0; } void -wal_collect_garbage(int64_t lsn) +wal_collect_garbage(int64_t wal_lsn, int64_t checkpoint_lsn) { struct wal_writer *writer = &wal_writer_singleton; if (writer->wal_mode == WAL_NONE) return; struct wal_gc_msg msg; - msg.lsn = lsn; + msg.wal_lsn = wal_lsn; + msg.checkpoint_lsn = checkpoint_lsn; bool cancellable = fiber_set_cancellable(false); cbus_call(&wal_thread.wal_pipe, &wal_thread.tx_prio_pipe, &msg.base, wal_collect_garbage_f, NULL, TIMEOUT_INFINITY); @@ -603,6 +628,66 @@ wal_opt_rotate(struct wal_writer *writer) return 0; } +/** + * Make sure there's enough disk space to append @len bytes + * of data to the current WAL. + * + * If fallocate() fails with ENOSPC, delete old WAL files + * that are not needed for recovery and retry. + */ +static int +wal_fallocate(struct wal_writer *writer, size_t len) +{ + bool warn_no_space = true; + struct xlog *l = &writer->current_wal; + struct errinj *errinj = errinj(ERRINJ_WAL_FALLOCATE, ERRINJ_INT); + + /* + * The actual write size can be greater than the sum size + * of encoded rows (compression, fixheaders). Double the + * given length to get a rough upper bound estimate. + */ + len *= 2; + +retry: + if (errinj == NULL || errinj->iparam == 0) { + if (l->allocated >= len) + return 0; + if (xlog_fallocate(l, MAX(len, WAL_FALLOCATE_LEN)) == 0) + return 0; + } else { + errinj->iparam--; + diag_set(ClientError, ER_INJECTION, "xlog fallocate"); + errno = ENOSPC; + } + if (errno != ENOSPC) + goto error; + if (!xdir_has_garbage(&writer->wal_dir, writer->checkpoint_lsn)) + goto error; + + if (warn_no_space) { + say_crit("ran out of disk space, try to delete old WAL files"); + warn_no_space = false; + } + + /* Keep the original error. */ + struct diag diag; + diag_create(&diag); + diag_move(diag_get(), &diag); + if (xdir_collect_garbage(&writer->wal_dir, writer->checkpoint_lsn, + XDIR_GC_REMOVE_ONE) != 0) { + diag_move(&diag, diag_get()); + goto error; + } + diag_destroy(&diag); + + wal_notify_watchers(writer, WAL_EVENT_GC); + goto retry; +error: + diag_log(); + return -1; +} + static void wal_writer_clear_bus(struct cmsg *msg) { @@ -689,6 +774,12 @@ wal_write_to_disk(struct cmsg *msg) return wal_writer_begin_rollback(writer); } + /* Ensure there's enough disk space before writing anything. */ + if (wal_fallocate(writer, wal_msg->approx_len) != 0) { + stailq_concat(&wal_msg->rollback, &wal_msg->commit); + return wal_writer_begin_rollback(writer); + } + /* * This code tries to write queued requests (=transactions) using as * few I/O syscalls and memory copies as possible. For this reason @@ -858,6 +949,7 @@ wal_write(struct journal *journal, struct journal_entry *entry) stailq_add_tail_entry(&batch->commit, entry, fifo); cpipe_push(&wal_thread.wal_pipe, &batch->base); } + batch->approx_len += entry->approx_len; wal_thread.wal_pipe.n_input += entry->n_rows * XROW_IOVMAX; cpipe_flush_input(&wal_thread.wal_pipe); /** @@ -981,29 +1073,38 @@ wal_watcher_notify(struct wal_watcher *watcher, unsigned events) { assert(!rlist_empty(&watcher->next)); - if (watcher->msg.cmsg.route != NULL) { + struct wal_watcher_msg *msg = &watcher->msg; + struct wal_writer *writer = &wal_writer_singleton; + + events &= watcher->event_mask; + if (events == 0) { + /* The watcher isn't interested in this event. */ + return; + } + + if (msg->cmsg.route != NULL) { /* * If the notification message is still en route, * mark the watcher to resend it as soon as it * returns to WAL so as not to lose any events. */ - watcher->events |= events; + watcher->pending_events |= events; return; } - watcher->msg.events = events; - cmsg_init(&watcher->msg.cmsg, watcher->route); - cpipe_push(&watcher->watcher_pipe, &watcher->msg.cmsg); + msg->events = events; + if (xdir_first_vclock(&writer->wal_dir, &msg->gc_vclock) < 0) + vclock_copy(&msg->gc_vclock, &writer->vclock); + + cmsg_init(&msg->cmsg, watcher->route); + cpipe_push(&watcher->watcher_pipe, &msg->cmsg); } static void wal_watcher_notify_perform(struct cmsg *cmsg) { struct wal_watcher_msg *msg = (struct wal_watcher_msg *) cmsg; - struct wal_watcher *watcher = msg->watcher; - unsigned events = msg->events; - - watcher->cb(watcher, events); + msg->watcher->cb(msg); } static void @@ -1019,13 +1120,13 @@ wal_watcher_notify_complete(struct cmsg *cmsg) return; } - if (watcher->events != 0) { + if (watcher->pending_events != 0) { /* * Resend the message if we got notified while * it was en route, see wal_watcher_notify(). */ - wal_watcher_notify(watcher, watcher->events); - watcher->events = 0; + wal_watcher_notify(watcher, watcher->pending_events); + watcher->pending_events = 0; } } @@ -1056,8 +1157,9 @@ wal_watcher_detach(void *arg) void wal_set_watcher(struct wal_watcher *watcher, const char *name, - void (*watcher_cb)(struct wal_watcher *, unsigned events), - void (*process_cb)(struct cbus_endpoint *)) + void (*watcher_cb)(struct wal_watcher_msg *), + void (*process_cb)(struct cbus_endpoint *), + unsigned event_mask) { assert(journal_is_initialized(&wal_writer_singleton.base)); @@ -1066,7 +1168,8 @@ wal_set_watcher(struct wal_watcher *watcher, const char *name, watcher->msg.watcher = watcher; watcher->msg.events = 0; watcher->msg.cmsg.route = NULL; - watcher->events = 0; + watcher->pending_events = 0; + watcher->event_mask = event_mask; assert(lengthof(watcher->route) == 2); watcher->route[0] = (struct cmsg_hop) @@ -1087,6 +1190,15 @@ wal_clear_watcher(struct wal_watcher *watcher, wal_watcher_detach, watcher, process_cb); } +/** + * Notify all interested watchers about a WAL event. + * + * XXX: Note, this function iterates over all registered watchers, + * including those that are not interested in the given event. + * This is OK only as long as the number of events/watchers is + * small. If this ever changes, we should consider maintaining + * a separate watcher list per each event type. + */ static void wal_notify_watchers(struct wal_writer *writer, unsigned events) { diff --git a/src/box/wal.h b/src/box/wal.h index 8ef1fb1d80cba8841368e10d6c46d85cb61e7e80..d4a37c55bc872771ceb60498cdfaecabc46e37d0 100644 --- a/src/box/wal.h +++ b/src/box/wal.h @@ -35,9 +35,9 @@ #include "small/rlist.h" #include "cbus.h" #include "journal.h" +#include "vclock.h" struct fiber; -struct vclock; struct wal_writer; struct tt_uuid; @@ -56,17 +56,25 @@ void wal_thread_start(); int -wal_init(enum wal_mode wal_mode, const char *wal_dirname, - const struct tt_uuid *instance_uuid, struct vclock *vclock, - int64_t wal_max_rows, int64_t wal_max_size); +wal_init(enum wal_mode wal_mode, const char *wal_dirname, int64_t wal_max_rows, + int64_t wal_max_size, const struct tt_uuid *instance_uuid, + const struct vclock *vclock, int64_t first_checkpoint_lsn); void wal_thread_stop(); +/** + * A notification message sent from the WAL to a watcher + * when a WAL event occurs. + */ struct wal_watcher_msg { struct cmsg cmsg; + /** Pointer to the watcher this message is for. */ struct wal_watcher *watcher; + /** Bit mask of events, see wal_event. */ unsigned events; + /** VClock of the oldest stored WAL row. */ + struct vclock gc_vclock; }; enum wal_event { @@ -74,13 +82,18 @@ enum wal_event { WAL_EVENT_WRITE = (1 << 0), /** A new WAL is created. */ WAL_EVENT_ROTATE = (1 << 1), + /** + * The WAL thread ran out of disk space and had to delete + * one or more old WAL files. + **/ + WAL_EVENT_GC = (1 << 2), }; struct wal_watcher { /** Link in wal_writer::watchers. */ struct rlist next; /** The watcher callback function. */ - void (*cb)(struct wal_watcher *, unsigned events); + void (*cb)(struct wal_watcher_msg *); /** Pipe from the watcher to WAL. */ struct cpipe wal_pipe; /** Pipe from WAL to the watcher. */ @@ -89,13 +102,18 @@ struct wal_watcher { struct cmsg_hop route[2]; /** Message sent to notify the watcher. */ struct wal_watcher_msg msg; + /** + * Bit mask of WAL events that this watcher is + * interested in. + */ + unsigned event_mask; /** * Bit mask of WAL events that happened while * the notification message was en route. * It indicates that the message must be resend * right upon returning to WAL. */ - unsigned events; + unsigned pending_events; }; /** @@ -114,17 +132,19 @@ struct wal_watcher { * @param watcher WAL watcher to register. * @param name Name of the cbus endpoint at the caller's cord. * @param watcher_cb Callback to invoke from the caller's cord - * upon receiving a WAL event. Apart from the - * watcher itself, it takes a bit mask of events. - * Events are described in wal_event enum. + * upon receiving a WAL event. It takes an object + * of type wal_watcher_msg that stores a pointer + * to the watcher and information about the event. * @param process_cb Function called to process cbus messages * while the watcher is being attached or NULL * if the cbus loop is running elsewhere. + * @param event_mask Bit mask of events the watcher is interested in. */ void wal_set_watcher(struct wal_watcher *watcher, const char *name, - void (*watcher_cb)(struct wal_watcher *, unsigned events), - void (*process_cb)(struct cbus_endpoint *)); + void (*watcher_cb)(struct wal_watcher_msg *), + void (*process_cb)(struct cbus_endpoint *), + unsigned event_mask); /** * Unsubscribe from WAL events. @@ -155,11 +175,14 @@ int wal_checkpoint(struct vclock *vclock, bool rotate); /** - * Remove WAL files that are not needed to recover - * from snapshot with @lsn or newer. + * Remove all WAL files whose signature is less than @wal_lsn. + * Update the oldest checkpoint signature with @checkpoint_lsn. + * WAL thread will delete WAL files that are not needed to + * recover from the oldest checkpoint if it runs out of disk + * space. */ void -wal_collect_garbage(int64_t lsn); +wal_collect_garbage(int64_t wal_lsn, int64_t checkpoint_lsn); void wal_init_vy_log(); diff --git a/src/box/xlog.c b/src/box/xlog.c index 90157d8399302b7ec8526aacccfff2a7ca19e483..191fadcd411772e3160bd54cea6e86e4dce5de0a 100644 --- a/src/box/xlog.c +++ b/src/box/xlog.c @@ -653,7 +653,7 @@ xdir_format_filename(struct xdir *dir, int64_t signature, } int -xdir_collect_garbage(struct xdir *dir, int64_t signature, bool use_coio) +xdir_collect_garbage(struct xdir *dir, int64_t signature, unsigned flags) { struct vclock *vclock; while ((vclock = vclockset_first(&dir->index)) != NULL && @@ -661,7 +661,7 @@ xdir_collect_garbage(struct xdir *dir, int64_t signature, bool use_coio) char *filename = xdir_format_filename(dir, vclock_sum(vclock), NONE); int rc; - if (use_coio) + if (flags & XDIR_GC_USE_COIO) rc = coio_unlink(filename); else rc = unlink(filename); @@ -678,6 +678,9 @@ xdir_collect_garbage(struct xdir *dir, int64_t signature, bool use_coio) say_info("removed %s", filename); vclockset_remove(&dir->index, vclock); free(vclock); + + if (flags & XDIR_GC_REMOVE_ONE) + break; } return 0; } @@ -990,6 +993,26 @@ xdir_create_xlog(struct xdir *dir, struct xlog *xlog, return 0; } +ssize_t +xlog_fallocate(struct xlog *log, size_t len) +{ +#ifdef HAVE_POSIX_FALLOCATE + int rc = posix_fallocate(log->fd, log->offset + log->allocated, len); + if (rc != 0) { + errno = rc; + diag_set(SystemError, "%s: can't allocate disk space", + log->filename); + return -1; + } + log->allocated += len; + return 0; +#else + (void)log; + (void)len; + return 0; +#endif /* HAVE_POSIX_FALLOCATE */ +} + /** * Write a sequence of uncompressed xrow objects. * @@ -1179,8 +1202,13 @@ xlog_tx_write(struct xlog *log) if (lseek(log->fd, log->offset, SEEK_SET) < 0 || ftruncate(log->fd, log->offset) != 0) panic_syserror("failed to truncate xlog after write error"); + log->allocated = 0; return -1; } + if (log->allocated > (size_t)written) + log->allocated -= written; + else + log->allocated = 0; log->offset += written; log->rows += log->tx_rows; log->tx_rows = 0; @@ -1378,6 +1406,17 @@ xlog_write_eof(struct xlog *l) diag_set(ClientError, ER_INJECTION, "xlog write injection"); return -1; }); + + /* + * Free disk space preallocated with xlog_fallocate(). + * Don't write the eof marker if this fails, otherwise + * we'll get "data after eof marker" error on recovery. + */ + if (l->allocated > 0 && ftruncate(l->fd, l->offset) < 0) { + diag_set(SystemError, "ftruncate() failed"); + return -1; + } + if (fio_writen(l->fd, &eof_marker, sizeof(eof_marker)) < 0) { diag_set(SystemError, "write() failed"); return -1; @@ -1793,6 +1832,15 @@ xlog_cursor_next_tx(struct xlog_cursor *i) return -1; if (rc > 0) return 1; + if (load_u32(i->rbuf.rpos) == 0) { + /* + * Space preallocated with xlog_fallocate(). + * Treat as eof and clear the buffer. + */ + i->read_offset -= ibuf_used(&i->rbuf); + ibuf_reset(&i->rbuf); + return 1; + } if (load_u32(i->rbuf.rpos) == eof_marker) { /* eof marker found */ goto eof_found; diff --git a/src/box/xlog.h b/src/box/xlog.h index c2ac4774201dbbb396a60bbad7329c8302d2d040..7c69cc4f5840b6485e977918662207d754a17751 100644 --- a/src/box/xlog.h +++ b/src/box/xlog.h @@ -178,12 +178,41 @@ char * xdir_format_filename(struct xdir *dir, int64_t signature, enum log_suffix suffix); +/** + * Return true if the given directory index has files whose + * signature is less than specified. + * + * Supposed to be used to check if xdir_collect_garbage() can + * actually delete some files. + */ +static inline bool +xdir_has_garbage(struct xdir *dir, int64_t signature) +{ + struct vclock *vclock = vclockset_first(&dir->index); + return vclock != NULL && vclock_sum(vclock) < signature; +} + +/** + * Flags passed to xdir_collect_garbage(). + */ +enum { + /** + * Delete files in coio threads so as not to block + * the caller thread. + */ + XDIR_GC_USE_COIO = 1 << 0, + /** + * Return after removing a file. + */ + XDIR_GC_REMOVE_ONE = 1 << 1, +}; + /** * Remove files whose signature is less than specified. - * If @use_coio is set, files are deleted by coio threads. + * For possible values of @flags see XDIR_GC_*. */ int -xdir_collect_garbage(struct xdir *dir, int64_t signature, bool use_coio); +xdir_collect_garbage(struct xdir *dir, int64_t signature, unsigned flags); /** * Remove inprogress files in the specified directory. @@ -191,6 +220,21 @@ xdir_collect_garbage(struct xdir *dir, int64_t signature, bool use_coio); void xdir_collect_inprogress(struct xdir *xdir); +/** + * Return LSN and vclock (unless @vclock is NULL) of the oldest + * file in a directory or -1 if the directory is empty. + */ +static inline int64_t +xdir_first_vclock(struct xdir *xdir, struct vclock *vclock) +{ + struct vclock *first = vclockset_first(&xdir->index); + if (first == NULL) + return -1; + if (vclock != NULL) + vclock_copy(vclock, first); + return vclock_sum(first); +} + /** * Return LSN and vclock (unless @vclock is NULL) of the newest * file in a directory or -1 if the directory is empty. @@ -302,6 +346,11 @@ struct xlog { bool is_autocommit; /** The current offset in the log file, for writing. */ off_t offset; + /** + * Size of disk space preallocated at @offset with + * xlog_fallocate(). + */ + size_t allocated; /** * Output buffer, works as row accumulator for * compression. @@ -422,6 +471,17 @@ xlog_is_open(struct xlog *l) int xlog_rename(struct xlog *l); +/** + * Allocate @size bytes of disk space at the end of the given + * xlog file. + * + * Returns -1 on fallocate error and sets both diag and errno + * accordingly. On success returns 0. If the underlying OS + * does not support fallocate, this function also returns 0. + */ +ssize_t +xlog_fallocate(struct xlog *log, size_t size); + /** * Write a row to xlog, * diff --git a/src/box/xrow.h b/src/box/xrow.h index fadab64dc6c5f54c04614c80ace91a985c4b38b2..881d86080ebf048de9c9b14f3d4677c3748e525f 100644 --- a/src/box/xrow.h +++ b/src/box/xrow.h @@ -80,6 +80,19 @@ struct xrow_header { struct iovec body[XROW_BODY_IOVMAX]; }; +/** + * Return the max size which the given row is going to take when + * encoded into a binary packet. + */ +static inline size_t +xrow_approx_len(struct xrow_header *row) +{ + size_t len = XROW_HEADER_LEN_MAX; + for (int i = 0; i < row->bodycnt; i++) + len += row->body[i].iov_len; + return len; +} + /** * Encode xrow into a binary packet * diff --git a/src/errinj.h b/src/errinj.h index 84a1fbb5ef4cd7f0273ed78f6053da939d8c6fc3..50062b62470a89b1384b4e08e4cfba0da29e9851 100644 --- a/src/errinj.h +++ b/src/errinj.h @@ -79,6 +79,7 @@ struct errinj { _(ERRINJ_WAL_WRITE_DISK, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_WAL_WRITE_EOF, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_WAL_DELAY, ERRINJ_BOOL, {.bparam = false}) \ + _(ERRINJ_WAL_FALLOCATE, ERRINJ_INT, {.iparam = 0}) \ _(ERRINJ_INDEX_ALLOC, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_TUPLE_ALLOC, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_TUPLE_FIELD, ERRINJ_BOOL, {.bparam = false}) \ diff --git a/src/lib/salad/bloom.c b/src/lib/salad/bloom.c index d68692ba35b367b5828f5725e2c2f69b378a2dd9..3460465a9d1120a670cd3c6573a8a5a3c0569998 100644 --- a/src/lib/salad/bloom.c +++ b/src/lib/salad/bloom.c @@ -41,7 +41,7 @@ int bloom_create(struct bloom *bloom, uint32_t number_of_values, - double false_positive_rate, struct quota *quota) + double false_positive_rate) { /* Optimal hash_count and bit count calculation */ uint16_t hash_count = ceil(log(false_positive_rate) / log(0.5)); @@ -49,14 +49,9 @@ bloom_create(struct bloom *bloom, uint32_t number_of_values, uint32_t block_bits = CHAR_BIT * sizeof(struct bloom_block); uint32_t block_count = (bit_count + block_bits - 1) / block_bits; - if (quota_use(quota, block_count * sizeof(*bloom->table)) < 0) - return -1; - bloom->table = calloc(block_count, sizeof(*bloom->table)); - if (bloom->table == NULL) { - quota_release(quota, block_count * sizeof(*bloom->table)); + if (bloom->table == NULL) return -1; - } bloom->table_size = block_count; bloom->hash_count = hash_count; @@ -64,9 +59,8 @@ bloom_create(struct bloom *bloom, uint32_t number_of_values, } void -bloom_destroy(struct bloom *bloom, struct quota *quota) +bloom_destroy(struct bloom *bloom) { - quota_release(quota, bloom->table_size * sizeof(*bloom->table)); free(bloom->table); } @@ -98,18 +92,12 @@ bloom_store(const struct bloom *bloom, char *table) } int -bloom_load_table(struct bloom *bloom, const char *table, struct quota *quota) +bloom_load_table(struct bloom *bloom, const char *table) { size_t size = bloom->table_size * sizeof(struct bloom_block); - if (quota_use(quota, size) < 0) { - bloom->table = NULL; - return -1; - } bloom->table = malloc(size); - if (bloom->table == NULL) { - quota_release(quota, size); + if (bloom->table == NULL) return -1; - } memcpy(bloom->table, table, size); return 0; } diff --git a/src/lib/salad/bloom.h b/src/lib/salad/bloom.h index 32deb81ab458e22f7b8c8b10b40cb5c0f5f1829d..c5f9e02985361a4f1d97dde2bbaad2fa513a6a54 100644 --- a/src/lib/salad/bloom.h +++ b/src/lib/salad/bloom.h @@ -48,7 +48,6 @@ #include <stddef.h> #include <limits.h> #include "bit/bit.h" -#include "small/quota.h" #if defined(__cplusplus) extern "C" { @@ -88,21 +87,19 @@ struct bloom { * @param bloom - structure to initialize * @param number_of_values - estimated number of values to be added * @param false_positive_rate - desired false positive rate - * @param quota - quota for memory allocation * @return 0 - OK, -1 - memory error */ int bloom_create(struct bloom *bloom, uint32_t number_of_values, - double false_positive_rate, struct quota *quota); + double false_positive_rate); /** * Free resources of the bloom filter * * @param bloom - the bloom filter - * @param quota - quota for memory deallocation */ void -bloom_destroy(struct bloom *bloom, struct quota *quota); +bloom_destroy(struct bloom *bloom); /** * Add a value into the data set @@ -156,11 +153,10 @@ bloom_store(const struct bloom *bloom, char *table); * * @param bloom - structure to load to * @param table - data to load - * @param quota - quota for memory allocation * @return 0 - OK, -1 - memory error */ int -bloom_load_table(struct bloom *bloom, const char *table, struct quota *quota); +bloom_load_table(struct bloom *bloom, const char *table); /* }}} API declaration */ diff --git a/src/trivia/config.h.cmake b/src/trivia/config.h.cmake index 8894b4364474c1346e08d38a21051d180bc47320..53eae2fe168cc943ca29c2061b0f5bfabc78ecb4 100644 --- a/src/trivia/config.h.cmake +++ b/src/trivia/config.h.cmake @@ -166,6 +166,7 @@ #cmakedefine HAVE_PTHREAD_YIELD 1 #cmakedefine HAVE_SCHED_YIELD 1 #cmakedefine HAVE_POSIX_FADVISE 1 +#cmakedefine HAVE_POSIX_FALLOCATE 1 #cmakedefine HAVE_MREMAP 1 #cmakedefine HAVE_SYNC_FILE_RANGE 1 diff --git a/test-run b/test-run index b8764e17ccc79a26d1e661a0aaeaad90bd0aa1ea..670f330aacaf44bc8b1f969fa0cd5f811c5ceb1b 160000 --- a/test-run +++ b/test-run @@ -1 +1 @@ -Subproject commit b8764e17ccc79a26d1e661a0aaeaad90bd0aa1ea +Subproject commit 670f330aacaf44bc8b1f969fa0cd5f811c5ceb1b diff --git a/test/box-py/call.result b/test/box-py/call.result index 7453c020a73dcbfc87e8681d5b509dfbd2f1dd4d..d340ed6fa06558cd86154dadfe84dbc05f0f6465 100644 --- a/test/box-py/call.result +++ b/test/box-py/call.result @@ -21,29 +21,40 @@ f1() - null ... call f1 () -- [testing] -- [1] -- [false] -- [-1] -- [1.123] -- [true] -- [null] - +- 'testing' +- 1 +- False +- -1 +- 1.123 +- True +- None f1=nil --- ... call f1 () -error: {code: ER_NO_SUCH_PROC, reason: Procedure 'f1' is not defined} - +{ + "error": { + "code": "ER_NO_SUCH_PROC", + "reason": "Procedure 'f1' is not defined" + } +} function f1() return f1 end --- ... call f1 () -error: {code: ER_PROC_LUA, reason: unsupported Lua type 'function'} - +{ + "error": { + "code": "ER_PROC_LUA", + "reason": "unsupported Lua type 'function'" + } +} call box.error (33333, 'Hey!') -error: {code: U, reason: Unknown error} - +{ + "error": { + "code": "U", + "reason": "Unknown error" + } +} # A test case for Bug#103491 # server CALL processing bug with name path longer than two @@ -65,14 +76,11 @@ test.test.f = f --- ... call f () -- [OK] - +- 'OK' call test.f () -- [OK] - +- 'OK' call test.test.f () -- [OK] - +- 'OK' # Test for Bug #955226 # Lua Numbers are passed back wrongly as strings @@ -82,11 +90,10 @@ function foo() return 1, 2, '1', '2' end --- ... call foo () -- [1] -- [2] -- ['1'] -- ['2'] - +- 1 +- 2 +- '1' +- '2' function f1(...) return {...} end --- ... @@ -94,81 +101,60 @@ function f2(...) return f1({...}) end --- ... call f1 ('test_', 'test_') -- [test_, test_] - +- ['test_', 'test_'] call f2 ('test_', 'test_') -- [test_, test_] - +- [['test_', 'test_']] call f1 () - [] - call f2 () -- [] - +- [[]] function f3() return {{'hello'}, {'world'}} end --- ... call f3 () -- [hello] -- [world] - +- [['hello'], ['world']] function f3() return {'hello', {'world'}} end --- ... call f3 () -- - hello - - [world] - +- ['hello', ['world']] function f3() return 'hello', {{'world'}, {'canada'}} end --- ... call f3 () -- [hello] -- - [world] - - [canada] - +- 'hello' +- [['world'], ['canada']] function f3() return {}, '123', {{}, {}} end --- ... call f3 () - [] -- ['123'] -- - [] - - [] - +- '123' +- [[], []] function f3() return { {{'hello'}} } end --- ... call f3 () -- - [hello] - +- [[['hello']]] function f3() return { box.tuple.new('hello'), {'world'} } end --- ... call f3 () -- [hello] -- [world] - +- [['hello'], ['world']] function f3() return { {'world'}, box.tuple.new('hello') } end --- ... call f3 () -- [world] -- [hello] - +- [['world'], ['hello']] function f3() return { { test={1,2,3} }, { test2={1,2,3} } } end --- ... call f3 () -- - test: [1, 2, 3] - - test2: [1, 2, 3] - +- [{'test': [1, 2, 3]}, {'test2': [1, 2, 3]}] call f1 ('jason',) -- [jason] - +- ['jason'] call f1 ('jason', 1, 'test', 2, 'stewart') -- [jason, 1, test, 2, stewart] - +- ['jason', 1, 'test', 2, 'stewart'] space = box.schema.space.create('tweedledum') --- ... @@ -182,57 +168,42 @@ function myinsert(...) return space:insert{...} end --- ... call myinsert (1, 'test box delete') -- [1, test box delete] - +- [1, 'test box delete'] call space:delete (1,) -- [1, test box delete] - +- [1, 'test box delete'] call myinsert (1, 'test box delete') -- [1, test box delete] - +- [1, 'test box delete'] call space:delete (1,) -- [1, test box delete] - +- [1, 'test box delete'] call space:delete (1,) -[] call myinsert (2, 'test box delete') -- [2, test box delete] - +- [2, 'test box delete'] call space:delete (1,) -[] call space:delete (2,) -- [2, test box delete] - +- [2, 'test box delete'] call space:delete (2,) -[] space:delete{2} --- ... call myinsert (2, 'test box delete') -- [2, test box delete] - +- [2, 'test box delete'] call space:get (2,) -- [2, test box delete] - +- [2, 'test box delete'] space:delete{2} --- - [2, 'test box delete'] ... call space:get (2,) -[] call myinsert (2, 'test box.select()') -- [2, test box.select()] - +- [2, 'test box.select()'] call space:get (2,) -- [2, test box.select()] - +- [2, 'test box.select()'] call space:select (2,) -- [2, test box.select()] - +- [[2, 'test box.select()']] space:get{2} --- - [2, 'test box.select()'] @@ -249,17 +220,13 @@ space:select{1} - [] ... call myreplace (2, 'hello', 'world') -- [2, hello, world] - +- [2, 'hello', 'world'] call myreplace (2, 'goodbye', 'universe') -- [2, goodbye, universe] - +- [2, 'goodbye', 'universe'] call space:get (2,) -- [2, goodbye, universe] - +- [2, 'goodbye', 'universe'] call space:select (2,) -- [2, goodbye, universe] - +- [[2, 'goodbye', 'universe']] space:get{2} --- - [2, 'goodbye', 'universe'] @@ -270,26 +237,23 @@ space:select{2} ... call myreplace (2,) - [2] - call space:get (2,) - [2] - call space:select (2,) -- [2] - +- [[2]] call space:delete (2,) - [2] - call space:delete (2,) -[] call myinsert (3, 'old', 2) -- [3, old, 2] - +- [3, 'old', 2] call myinsert (3, 'old', 2) -error: {code: ER_TUPLE_FOUND, reason: Duplicate key exists in unique index 'primary' - in space 'tweedledum'} - +{ + "error": { + "code": "ER_TUPLE_FOUND", + "reason": "Duplicate key exists in unique index 'primary' in space 'tweedledum'" + } +} space:update({3}, {{'=', 1, 4}, {'=', 2, 'new'}}) --- - error: Attempt to modify a tuple field which is part of index 'primary' in space @@ -299,11 +263,9 @@ space:insert(space:get{3}:update{{'=', 1, 4}, {'=', 2, 'new'}}) space:delete{3} --- ... call space:get (4,) -- [4, new, 2] - +- [4, 'new', 2] call space:select (4,) -- [4, new, 2] - +- [[4, 'new', 2]] space:update({4}, {{'+', 3, 1}}) --- - [4, 'new', 3] @@ -313,23 +275,18 @@ space:update({4}, {{'-', 3, 1}}) - [4, 'new', 2] ... call space:get (4,) -- [4, new, 2] - +- [4, 'new', 2] call space:select (4,) -- [4, new, 2] - +- [[4, 'new', 2]] function field_x(key, field_index) return space:get(key)[field_index] end --- ... call field_x (4, 1) -- [4] - +- 4 call field_x (4, 2) -- [new] - +- 'new' call space:delete (4,) -- [4, new, 2] - +- [4, 'new', 2] space:drop() --- ... @@ -341,423 +298,299 @@ index = space:create_index('primary', { type = 'tree' }) ... eval (return 1)() --- -[1] - +- 1 function f(...) return 1 end --- ... call f() --- -- [1] - +- 1 eval (return 1, 2, 3)() --- -[1, 2, 3] - +- 1 +- 2 +- 3 function f(...) return 1, 2, 3 end --- ... call f() --- -- [1] -- [2] -- [3] - +- 1 +- 2 +- 3 eval (return true)() --- -[true] - +- True function f(...) return true end --- ... call f() --- -- [true] - +- True eval (return nil)() --- -[null] - +- None function f(...) return nil end --- ... call f() --- -- [null] - +- None eval (return )() --- -[] function f(...) return end --- ... call f() --- -[] eval (return {})() --- - [] - function f(...) return {} end --- ... call f() --- - [] - eval (return {1})() --- - [1] - function f(...) return {1} end --- ... call f() --- - [1] - eval (return {1, 2, 3})() --- - [1, 2, 3] - function f(...) return {1, 2, 3} end --- ... call f() --- - [1, 2, 3] - eval (return {k1 = 'v1', k2 = 'v2'})() --- -- {k1: v1, k2: v2} - +- {'k2': 'v2', 'k1': 'v1'} function f(...) return {k1 = 'v1', k2 = 'v2'} end --- ... call f() --- -- - {k1: v1, k2: v2} - +- {'k2': 'v2', 'k1': 'v1'} eval (return {k1 = 'v1', k2 = 'v2'})() --- -- {k1: v1, k2: v2} - +- {'k2': 'v2', 'k1': 'v1'} function f(...) return {k1 = 'v1', k2 = 'v2'} end --- ... call f() --- -- - {k1: v1, k2: v2} - +- {'k2': 'v2', 'k1': 'v1'} eval (return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}})() --- -- c: - '106': [1, 1428578535] - '2': [1, 1428578535] - pc: - '106': [1, 1428578535, 9243] - '2': [1, 1428578535, 9243] - s: [1, 1428578535] - u: 1428578535 - v: [] - +- {'pc': {'2': [1, 1428578535, 9243], '106': [1, 1428578535, 9243]}, 's': [1, 1428578535], 'u': 1428578535, 'c': {'2': [1, 1428578535], '106': [1, 1428578535]}, 'v': []} function f(...) return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}} end --- ... call f() --- -- - c: - '106': [1, 1428578535] - '2': [1, 1428578535] - pc: - '106': [1, 1428578535, 9243] - '2': [1, 1428578535, 9243] - s: [1, 1428578535] - u: 1428578535 - v: [] - +- {'pc': {'2': [1, 1428578535, 9243], '106': [1, 1428578535, 9243]}, 's': [1, 1428578535], 'u': 1428578535, 'c': {'2': [1, 1428578535], '106': [1, 1428578535]}, 'v': []} eval (return true, {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}})() --- -- true -- c: - '106': [1, 1428578535] - '2': [1, 1428578535] - pc: - '106': [1, 1428578535, 9243] - '2': [1, 1428578535, 9243] - s: [1, 1428578535] - u: 1428578535 - v: [] - +- True +- {'pc': {'2': [1, 1428578535, 9243], '106': [1, 1428578535, 9243]}, 's': [1, 1428578535], 'u': 1428578535, 'c': {'2': [1, 1428578535], '106': [1, 1428578535]}, 'v': []} function f(...) return true, {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}} end --- ... call f() --- -- [true] -- - c: - '106': [1, 1428578535] - '2': [1, 1428578535] - pc: - '106': [1, 1428578535, 9243] - '2': [1, 1428578535, 9243] - s: [1, 1428578535] - u: 1428578535 - v: [] - +- True +- {'pc': {'2': [1, 1428578535, 9243], '106': [1, 1428578535, 9243]}, 's': [1, 1428578535], 'u': 1428578535, 'c': {'2': [1, 1428578535], '106': [1, 1428578535]}, 'v': []} eval (return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}, true)() --- -- c: - '106': [1, 1428578535] - '2': [1, 1428578535] - pc: - '106': [1, 1428578535, 9243] - '2': [1, 1428578535, 9243] - s: [1, 1428578535] - u: 1428578535 - v: [] -- true - +- {'pc': {'2': [1, 1428578535, 9243], '106': [1, 1428578535, 9243]}, 's': [1, 1428578535], 'u': 1428578535, 'c': {'2': [1, 1428578535], '106': [1, 1428578535]}, 'v': []} +- True function f(...) return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}, true end --- ... call f() --- -- - c: - '106': [1, 1428578535] - '2': [1, 1428578535] - pc: - '106': [1, 1428578535, 9243] - '2': [1, 1428578535, 9243] - s: [1, 1428578535] - u: 1428578535 - v: [] -- [true] - +- {'pc': {'2': [1, 1428578535, 9243], '106': [1, 1428578535, 9243]}, 's': [1, 1428578535], 'u': 1428578535, 'c': {'2': [1, 1428578535], '106': [1, 1428578535]}, 'v': []} +- True t = box.tuple.new('tuple', {1, 2, 3}, { k1 = 'v', k2 = 'v2'}) --- ... eval (return t)() --- -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - +- ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}] function f(...) return t end --- ... call f() --- -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - +- ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}] eval (return t, t, t)() --- -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - +- ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}] +- ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}] +- ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}] function f(...) return t, t, t end --- ... call f() --- -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - +- ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}] +- ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}] +- ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}] eval (return {t})() --- -- - - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - +- [['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}]] function f(...) return {t} end --- ... call f() --- -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - +- [['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}]] eval (return {t, t, t})() --- -- - - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - - - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - - - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - +- [['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}], ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}], ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}]] function f(...) return {t, t, t} end --- ... call f() --- -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} -- - tuple - - [1, 2, 3] - - {k1: v, k2: v2} - +- [['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}], ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}], ['tuple', [1, 2, 3], {'k2': 'v2', 'k1': 'v'}]] eval (return error('exception'))() --- -error: {code: ER_PROC_LUA, reason: exception} - +{ + "error": { + "code": "ER_PROC_LUA", + "reason": "exception" + } +} function f(...) return error('exception') end --- ... call f() --- -error: {code: ER_PROC_LUA, reason: exception} - +{ + "error": { + "code": "ER_PROC_LUA", + "reason": "exception" + } +} eval (return box.error(0))() --- -error: {code: ER_OK, reason: Unknown error} function f(...) return box.error(0) end --- ... call f() --- -error: {code: ER_OK, reason: Unknown error} eval (return ...)() --- -[] function f(...) return ... end --- ... call f() --- -[] eval (return ...)(1,2,3) --- -[1, 2, 3] - +- 1 +- 2 +- 3 function f(...) return ... end --- ... call f(1,2,3) --- -- [1] -- [2] -- [3] - +- 1 +- 2 +- 3 eval (return ...)(None,None,None) --- -[null, null, null] - +- None +- None +- None function f(...) return ... end --- ... call f(None,None,None) --- -- [null] -- [null] -- [null] - +- None +- None +- None eval (return ...)({'k2': 'v2', 'k1': 'v1'}) --- -- {k1: v1, k2: v2} - +- {'k2': 'v2', 'k1': 'v1'} function f(...) return ... end --- ... call f({'k2': 'v2', 'k1': 'v1'}) --- -- - {k1: v1, k2: v2} - +- {'k2': 'v2', 'k1': 'v1'} eval (return space:auto_increment({"transaction"}))() --- -- [1, transaction] - +- [1, 'transaction'] function f(...) return space:auto_increment({"transaction"}) end --- ... call f() --- -- [2, transaction] - +- [2, 'transaction'] eval (return space:select{})() --- -- - [1, transaction] - - [2, transaction] - +- [[1, 'transaction'], [2, 'transaction']] function f(...) return space:select{} end --- ... call f() --- -- [1, transaction] -- [2, transaction] - +- [[1, 'transaction'], [2, 'transaction']] eval (return box.begin(), space:auto_increment({"failed"}), box.rollback())() --- -- null -- [3, failed] - +- None +- [3, 'failed'] function f(...) return box.begin(), space:auto_increment({"failed"}), box.rollback() end --- ... call f() --- -- [null] -- [3, failed] - +- None +- [3, 'failed'] eval (return space:select{})() --- -- - [1, transaction] - - [2, transaction] - +- [[1, 'transaction'], [2, 'transaction']] function f(...) return space:select{} end --- ... call f() --- -- [1, transaction] -- [2, transaction] - +- [[1, 'transaction'], [2, 'transaction']] eval (return require("fiber").sleep(0))() --- -[] function f(...) return require("fiber").sleep(0) end --- ... call f() --- -[] eval (!invalid expression)() --- -error: {code: ER_PROC_LUA, reason: 'eval:1: unexpected symbol near ''!'''} - +{ + "error": { + "code": "ER_PROC_LUA", + "reason": "eval:1: unexpected symbol near '!'" + } +} space:drop() --- ... diff --git a/test/box-py/iproto.result b/test/box-py/iproto.result index 6e1f37a00e429bdeb3613e1664730f58939ce4fa..37c0adce5b220691db183f0f1e77c0a4a77ab717 100644 --- a/test/box-py/iproto.result +++ b/test/box-py/iproto.result @@ -39,9 +39,9 @@ True IPROTO_CALL -query {'IPROTO_CODE': 6} {} +query {'IPROTO_CODE': 10} {} True -query {'IPROTO_CODE': 6} {'IPROTO_KEY': ('procname',)} +query {'IPROTO_CODE': 10} {'IPROTO_KEY': ('procname',)} True @@ -58,22 +58,14 @@ index = space:create_index('primary', { type = 'hash' }) box.schema.user.grant('guest', 'read,write,execute', 'space', 'test') --- ... -- [1, baobab] - -- [2, obbaba] - -- [1, baobab] - -- [3, occama] - -- [2, obbaba] - -- [4, ockham] - -- [1, baobab] - -- [2, obbaba] - +- [1, 'baobab'] +- [2, 'obbaba'] +- [1, 'baobab'] +- [3, 'occama'] +- [2, 'obbaba'] +- [4, 'ockham'] +- [1, 'baobab'] +- [2, 'obbaba'] space:drop() --- ... @@ -186,11 +178,8 @@ box.schema.user.grant('guest', 'read,write,execute', 'space', 'test_index_base') --- ... - [1, 0, 0, 0] - - [1, 0, 1, -1] - - [1, 0, 2, -2] - function kek() return 'kek' end --- ... @@ -198,7 +187,7 @@ box.schema.user.grant('guest', 'read,write,execute', 'universe') --- ... Sync: 100 -Retcode: [['kek']] +Retcode: ['kek'] box.schema.user.revoke('guest', 'read,write,execute', 'universe') --- ... diff --git a/test/box-py/iproto.test.py b/test/box-py/iproto.test.py index 594c6f45622006986d75cef3ccc757669e289168..81cdddb619353233900d996929157ef8d561739d 100644 --- a/test/box-py/iproto.test.py +++ b/test/box-py/iproto.test.py @@ -158,20 +158,22 @@ admin("index = space:create_index('primary', { type = 'hash', parts = {1, 'strin class RawInsert(Request): request_type = REQUEST_TYPE_INSERT + def __init__(self, conn, space_no, blob): super(RawInsert, self).__init__(conn) request_body = "\x82" + msgpack.dumps(IPROTO_SPACE_ID) + \ msgpack.dumps(space_id) + msgpack.dumps(IPROTO_TUPLE) + blob - self._bytes = self.header(len(request_body)) + request_body + self._body = request_body class RawSelect(Request): request_type = REQUEST_TYPE_SELECT + def __init__(self, conn, space_no, blob): super(RawSelect, self).__init__(conn) request_body = "\x83" + msgpack.dumps(IPROTO_SPACE_ID) + \ msgpack.dumps(space_id) + msgpack.dumps(IPROTO_KEY) + blob + \ msgpack.dumps(IPROTO_LIMIT) + msgpack.dumps(100); - self._bytes = self.header(len(request_body)) + request_body + self._body = request_body c = iproto.py_con space = c.space('test') diff --git a/test/box/errinj.result b/test/box/errinj.result index c4a1326cdb1a3b888baed4a84e5f45da61436587..62dcc6a4f3afcb4c0dde73dbed59d170b1da5ff4 100644 --- a/test/box/errinj.result +++ b/test/box/errinj.result @@ -44,8 +44,8 @@ errinj.info() state: false ERRINJ_WAL_IO: state: false - ERRINJ_VY_INDEX_FILE_RENAME: - state: false + ERRINJ_WAL_FALLOCATE: + state: 0 ERRINJ_TUPLE_ALLOC: state: false ERRINJ_VY_RUN_FILE_RENAME: @@ -54,18 +54,20 @@ errinj.info() state: false ERRINJ_RELAY_REPORT_INTERVAL: state: 0 + ERRINJ_SNAP_COMMIT_DELAY: + state: false ERRINJ_VY_READ_PAGE_TIMEOUT: state: 0 ERRINJ_XLOG_META: state: false - ERRINJ_SNAP_COMMIT_DELAY: - state: false ERRINJ_WAL_BREAK_LSN: state: -1 - ERRINJ_WAL_WRITE_DISK: - state: false ERRINJ_RELAY_BREAK_LSN: state: -1 + ERRINJ_WAL_WRITE_DISK: + state: false + ERRINJ_VY_INDEX_FILE_RENAME: + state: false ERRINJ_VY_LOG_FILE_RENAME: state: false ERRINJ_VY_RUN_WRITE: @@ -100,11 +102,11 @@ errinj.info() state: false ERRINJ_INDEX_ALLOC: state: false - ERRINJ_RELAY_TIMEOUT: + ERRINJ_VY_RUN_WRITE_TIMEOUT: state: 0 ERRINJ_TESTING: state: false - ERRINJ_VY_RUN_WRITE_TIMEOUT: + ERRINJ_RELAY_TIMEOUT: state: 0 ERRINJ_VY_SQUASH_TIMEOUT: state: 0 diff --git a/test/replication-py/cluster.test.py b/test/replication-py/cluster.test.py index e3b44f680aa3ceb3d1ac8fbc02cfe9c7e7e6a897..14598b7989775455a3434270e892fb12f385d678 100644 --- a/test/replication-py/cluster.test.py +++ b/test/replication-py/cluster.test.py @@ -42,7 +42,7 @@ print len(rows) == 1 and rows[0].return_message.find('Write access') >= 0 and \ def check_join(msg): ok = True for resp in server.iproto.py_con.join(replica_uuid): - if resp.completion_status != 0: + if resp._return_code != 0: print 'not ok', '-', msg, resp.return_message ok = False diff --git a/test/replication-py/swap.result b/test/replication-py/swap.result index 8aef0cfb4ef9294a1ca06333599dbac5495476c3..7e6e66483d4355f8630ddf10887e75f9adf7a4ed 100644 --- a/test/replication-py/swap.result +++ b/test/replication-py/swap.result @@ -25,164 +25,124 @@ index = s:create_index('primary', {type = 'tree'}) test 0 iteration box.space.memtx:insert{0, "tuple 0"} - -- [0, tuple 0] - +- [0, 'tuple 0'] box.space.memtx:insert{1, "tuple 1"} - -- [1, tuple 1] - +- [1, 'tuple 1'] box.space.memtx:insert{2, "tuple 2"} - -- [2, tuple 2] - +- [2, 'tuple 2'] box.space.memtx:insert{3, "tuple 3"} - -- [3, tuple 3] - +- [3, 'tuple 3'] box.space.memtx:insert{4, "tuple 4"} - -- [4, tuple 4] - +- [4, 'tuple 4'] box.space.vinyl:insert{0, "tuple 0"} - -- [0, tuple 0] - +- [0, 'tuple 0'] box.space.vinyl:insert{1, "tuple 1"} - -- [1, tuple 1] - +- [1, 'tuple 1'] box.space.vinyl:insert{2, "tuple 2"} - -- [2, tuple 2] - +- [2, 'tuple 2'] box.space.vinyl:insert{3, "tuple 3"} - -- [3, tuple 3] - +- [3, 'tuple 3'] box.space.vinyl:insert{4, "tuple 4"} - -- [4, tuple 4] - +- [4, 'tuple 4'] box.space.memtx:select{0} - -- [0, tuple 0] - +- [0, 'tuple 0'] box.space.memtx:select{1} - -- [1, tuple 1] - +- [1, 'tuple 1'] box.space.memtx:select{2} - -- [2, tuple 2] - +- [2, 'tuple 2'] box.space.memtx:select{3} - -- [3, tuple 3] - +- [3, 'tuple 3'] box.space.memtx:select{4} - -- [4, tuple 4] - +- [4, 'tuple 4'] box.space.vinyl:select{0} - -- [0, tuple 0] - +- [0, 'tuple 0'] box.space.vinyl:select{1} - -- [1, tuple 1] - +- [1, 'tuple 1'] box.space.vinyl:select{2} - -- [2, tuple 2] - +- [2, 'tuple 2'] box.space.vinyl:select{3} - -- [3, tuple 3] - +- [3, 'tuple 3'] box.space.vinyl:select{4} - -- [4, tuple 4] - +- [4, 'tuple 4'] box.space.memtx:insert{5, "tuple 5"} - -- [5, tuple 5] - +- [5, 'tuple 5'] box.space.memtx:insert{6, "tuple 6"} - -- [6, tuple 6] - +- [6, 'tuple 6'] box.space.memtx:insert{7, "tuple 7"} - -- [7, tuple 7] - +- [7, 'tuple 7'] box.space.memtx:insert{8, "tuple 8"} - -- [8, tuple 8] - +- [8, 'tuple 8'] box.space.memtx:insert{9, "tuple 9"} - -- [9, tuple 9] - +- [9, 'tuple 9'] box.space.vinyl:insert{5, "tuple 5"} - -- [5, tuple 5] - +- [5, 'tuple 5'] box.space.vinyl:insert{6, "tuple 6"} - -- [6, tuple 6] - +- [6, 'tuple 6'] box.space.vinyl:insert{7, "tuple 7"} - -- [7, tuple 7] - +- [7, 'tuple 7'] box.space.vinyl:insert{8, "tuple 8"} - -- [8, tuple 8] - +- [8, 'tuple 8'] box.space.vinyl:insert{9, "tuple 9"} - -- [9, tuple 9] - +- [9, 'tuple 9'] box.space.memtx:select{5} - -- [5, tuple 5] - +- [5, 'tuple 5'] box.space.memtx:select{6} - -- [6, tuple 6] - +- [6, 'tuple 6'] box.space.memtx:select{7} - -- [7, tuple 7] - +- [7, 'tuple 7'] box.space.memtx:select{8} - -- [8, tuple 8] - +- [8, 'tuple 8'] box.space.memtx:select{9} - -- [9, tuple 9] - +- [9, 'tuple 9'] box.space.vinyl:select{5} - -- [5, tuple 5] - +- [5, 'tuple 5'] box.space.vinyl:select{6} - -- [6, tuple 6] - +- [6, 'tuple 6'] box.space.vinyl:select{7} - -- [7, tuple 7] - +- [7, 'tuple 7'] box.space.vinyl:select{8} - -- [8, tuple 8] - +- [8, 'tuple 8'] box.space.vinyl:select{9} - -- [9, tuple 9] - +- [9, 'tuple 9'] swap servers switch replica to master box.cfg{replication=''} @@ -191,164 +151,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{10, "tuple 10"} - -- [10, tuple 10] - +- [10, 'tuple 10'] box.space.memtx:insert{11, "tuple 11"} - -- [11, tuple 11] - +- [11, 'tuple 11'] box.space.memtx:insert{12, "tuple 12"} - -- [12, tuple 12] - +- [12, 'tuple 12'] box.space.memtx:insert{13, "tuple 13"} - -- [13, tuple 13] - +- [13, 'tuple 13'] box.space.memtx:insert{14, "tuple 14"} - -- [14, tuple 14] - +- [14, 'tuple 14'] box.space.vinyl:insert{10, "tuple 10"} - -- [10, tuple 10] - +- [10, 'tuple 10'] box.space.vinyl:insert{11, "tuple 11"} - -- [11, tuple 11] - +- [11, 'tuple 11'] box.space.vinyl:insert{12, "tuple 12"} - -- [12, tuple 12] - +- [12, 'tuple 12'] box.space.vinyl:insert{13, "tuple 13"} - -- [13, tuple 13] - +- [13, 'tuple 13'] box.space.vinyl:insert{14, "tuple 14"} - -- [14, tuple 14] - +- [14, 'tuple 14'] box.space.memtx:select{10} - -- [10, tuple 10] - +- [10, 'tuple 10'] box.space.memtx:select{11} - -- [11, tuple 11] - +- [11, 'tuple 11'] box.space.memtx:select{12} - -- [12, tuple 12] - +- [12, 'tuple 12'] box.space.memtx:select{13} - -- [13, tuple 13] - +- [13, 'tuple 13'] box.space.memtx:select{14} - -- [14, tuple 14] - +- [14, 'tuple 14'] box.space.vinyl:select{10} - -- [10, tuple 10] - +- [10, 'tuple 10'] box.space.vinyl:select{11} - -- [11, tuple 11] - +- [11, 'tuple 11'] box.space.vinyl:select{12} - -- [12, tuple 12] - +- [12, 'tuple 12'] box.space.vinyl:select{13} - -- [13, tuple 13] - +- [13, 'tuple 13'] box.space.vinyl:select{14} - -- [14, tuple 14] - +- [14, 'tuple 14'] box.space.memtx:insert{15, "tuple 15"} - -- [15, tuple 15] - +- [15, 'tuple 15'] box.space.memtx:insert{16, "tuple 16"} - -- [16, tuple 16] - +- [16, 'tuple 16'] box.space.memtx:insert{17, "tuple 17"} - -- [17, tuple 17] - +- [17, 'tuple 17'] box.space.memtx:insert{18, "tuple 18"} - -- [18, tuple 18] - +- [18, 'tuple 18'] box.space.memtx:insert{19, "tuple 19"} - -- [19, tuple 19] - +- [19, 'tuple 19'] box.space.vinyl:insert{15, "tuple 15"} - -- [15, tuple 15] - +- [15, 'tuple 15'] box.space.vinyl:insert{16, "tuple 16"} - -- [16, tuple 16] - +- [16, 'tuple 16'] box.space.vinyl:insert{17, "tuple 17"} - -- [17, tuple 17] - +- [17, 'tuple 17'] box.space.vinyl:insert{18, "tuple 18"} - -- [18, tuple 18] - +- [18, 'tuple 18'] box.space.vinyl:insert{19, "tuple 19"} - -- [19, tuple 19] - +- [19, 'tuple 19'] box.space.memtx:select{15} - -- [15, tuple 15] - +- [15, 'tuple 15'] box.space.memtx:select{16} - -- [16, tuple 16] - +- [16, 'tuple 16'] box.space.memtx:select{17} - -- [17, tuple 17] - +- [17, 'tuple 17'] box.space.memtx:select{18} - -- [18, tuple 18] - +- [18, 'tuple 18'] box.space.memtx:select{19} - -- [19, tuple 19] - +- [19, 'tuple 19'] box.space.vinyl:select{15} - -- [15, tuple 15] - +- [15, 'tuple 15'] box.space.vinyl:select{16} - -- [16, tuple 16] - +- [16, 'tuple 16'] box.space.vinyl:select{17} - -- [17, tuple 17] - +- [17, 'tuple 17'] box.space.vinyl:select{18} - -- [18, tuple 18] - +- [18, 'tuple 18'] box.space.vinyl:select{19} - -- [19, tuple 19] - +- [19, 'tuple 19'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -358,164 +278,124 @@ switch replica to replica test 1 iteration box.space.memtx:insert{20, "tuple 20"} - -- [20, tuple 20] - +- [20, 'tuple 20'] box.space.memtx:insert{21, "tuple 21"} - -- [21, tuple 21] - +- [21, 'tuple 21'] box.space.memtx:insert{22, "tuple 22"} - -- [22, tuple 22] - +- [22, 'tuple 22'] box.space.memtx:insert{23, "tuple 23"} - -- [23, tuple 23] - +- [23, 'tuple 23'] box.space.memtx:insert{24, "tuple 24"} - -- [24, tuple 24] - +- [24, 'tuple 24'] box.space.vinyl:insert{20, "tuple 20"} - -- [20, tuple 20] - +- [20, 'tuple 20'] box.space.vinyl:insert{21, "tuple 21"} - -- [21, tuple 21] - +- [21, 'tuple 21'] box.space.vinyl:insert{22, "tuple 22"} - -- [22, tuple 22] - +- [22, 'tuple 22'] box.space.vinyl:insert{23, "tuple 23"} - -- [23, tuple 23] - +- [23, 'tuple 23'] box.space.vinyl:insert{24, "tuple 24"} - -- [24, tuple 24] - +- [24, 'tuple 24'] box.space.memtx:select{20} - -- [20, tuple 20] - +- [20, 'tuple 20'] box.space.memtx:select{21} - -- [21, tuple 21] - +- [21, 'tuple 21'] box.space.memtx:select{22} - -- [22, tuple 22] - +- [22, 'tuple 22'] box.space.memtx:select{23} - -- [23, tuple 23] - +- [23, 'tuple 23'] box.space.memtx:select{24} - -- [24, tuple 24] - +- [24, 'tuple 24'] box.space.vinyl:select{20} - -- [20, tuple 20] - +- [20, 'tuple 20'] box.space.vinyl:select{21} - -- [21, tuple 21] - +- [21, 'tuple 21'] box.space.vinyl:select{22} - -- [22, tuple 22] - +- [22, 'tuple 22'] box.space.vinyl:select{23} - -- [23, tuple 23] - +- [23, 'tuple 23'] box.space.vinyl:select{24} - -- [24, tuple 24] - +- [24, 'tuple 24'] box.space.memtx:insert{25, "tuple 25"} - -- [25, tuple 25] - +- [25, 'tuple 25'] box.space.memtx:insert{26, "tuple 26"} - -- [26, tuple 26] - +- [26, 'tuple 26'] box.space.memtx:insert{27, "tuple 27"} - -- [27, tuple 27] - +- [27, 'tuple 27'] box.space.memtx:insert{28, "tuple 28"} - -- [28, tuple 28] - +- [28, 'tuple 28'] box.space.memtx:insert{29, "tuple 29"} - -- [29, tuple 29] - +- [29, 'tuple 29'] box.space.vinyl:insert{25, "tuple 25"} - -- [25, tuple 25] - +- [25, 'tuple 25'] box.space.vinyl:insert{26, "tuple 26"} - -- [26, tuple 26] - +- [26, 'tuple 26'] box.space.vinyl:insert{27, "tuple 27"} - -- [27, tuple 27] - +- [27, 'tuple 27'] box.space.vinyl:insert{28, "tuple 28"} - -- [28, tuple 28] - +- [28, 'tuple 28'] box.space.vinyl:insert{29, "tuple 29"} - -- [29, tuple 29] - +- [29, 'tuple 29'] box.space.memtx:select{25} - -- [25, tuple 25] - +- [25, 'tuple 25'] box.space.memtx:select{26} - -- [26, tuple 26] - +- [26, 'tuple 26'] box.space.memtx:select{27} - -- [27, tuple 27] - +- [27, 'tuple 27'] box.space.memtx:select{28} - -- [28, tuple 28] - +- [28, 'tuple 28'] box.space.memtx:select{29} - -- [29, tuple 29] - +- [29, 'tuple 29'] box.space.vinyl:select{25} - -- [25, tuple 25] - +- [25, 'tuple 25'] box.space.vinyl:select{26} - -- [26, tuple 26] - +- [26, 'tuple 26'] box.space.vinyl:select{27} - -- [27, tuple 27] - +- [27, 'tuple 27'] box.space.vinyl:select{28} - -- [28, tuple 28] - +- [28, 'tuple 28'] box.space.vinyl:select{29} - -- [29, tuple 29] - +- [29, 'tuple 29'] swap servers switch replica to master box.cfg{replication=''} @@ -524,164 +404,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{30, "tuple 30"} - -- [30, tuple 30] - +- [30, 'tuple 30'] box.space.memtx:insert{31, "tuple 31"} - -- [31, tuple 31] - +- [31, 'tuple 31'] box.space.memtx:insert{32, "tuple 32"} - -- [32, tuple 32] - +- [32, 'tuple 32'] box.space.memtx:insert{33, "tuple 33"} - -- [33, tuple 33] - +- [33, 'tuple 33'] box.space.memtx:insert{34, "tuple 34"} - -- [34, tuple 34] - +- [34, 'tuple 34'] box.space.vinyl:insert{30, "tuple 30"} - -- [30, tuple 30] - +- [30, 'tuple 30'] box.space.vinyl:insert{31, "tuple 31"} - -- [31, tuple 31] - +- [31, 'tuple 31'] box.space.vinyl:insert{32, "tuple 32"} - -- [32, tuple 32] - +- [32, 'tuple 32'] box.space.vinyl:insert{33, "tuple 33"} - -- [33, tuple 33] - +- [33, 'tuple 33'] box.space.vinyl:insert{34, "tuple 34"} - -- [34, tuple 34] - +- [34, 'tuple 34'] box.space.memtx:select{30} - -- [30, tuple 30] - +- [30, 'tuple 30'] box.space.memtx:select{31} - -- [31, tuple 31] - +- [31, 'tuple 31'] box.space.memtx:select{32} - -- [32, tuple 32] - +- [32, 'tuple 32'] box.space.memtx:select{33} - -- [33, tuple 33] - +- [33, 'tuple 33'] box.space.memtx:select{34} - -- [34, tuple 34] - +- [34, 'tuple 34'] box.space.vinyl:select{30} - -- [30, tuple 30] - +- [30, 'tuple 30'] box.space.vinyl:select{31} - -- [31, tuple 31] - +- [31, 'tuple 31'] box.space.vinyl:select{32} - -- [32, tuple 32] - +- [32, 'tuple 32'] box.space.vinyl:select{33} - -- [33, tuple 33] - +- [33, 'tuple 33'] box.space.vinyl:select{34} - -- [34, tuple 34] - +- [34, 'tuple 34'] box.space.memtx:insert{35, "tuple 35"} - -- [35, tuple 35] - +- [35, 'tuple 35'] box.space.memtx:insert{36, "tuple 36"} - -- [36, tuple 36] - +- [36, 'tuple 36'] box.space.memtx:insert{37, "tuple 37"} - -- [37, tuple 37] - +- [37, 'tuple 37'] box.space.memtx:insert{38, "tuple 38"} - -- [38, tuple 38] - +- [38, 'tuple 38'] box.space.memtx:insert{39, "tuple 39"} - -- [39, tuple 39] - +- [39, 'tuple 39'] box.space.vinyl:insert{35, "tuple 35"} - -- [35, tuple 35] - +- [35, 'tuple 35'] box.space.vinyl:insert{36, "tuple 36"} - -- [36, tuple 36] - +- [36, 'tuple 36'] box.space.vinyl:insert{37, "tuple 37"} - -- [37, tuple 37] - +- [37, 'tuple 37'] box.space.vinyl:insert{38, "tuple 38"} - -- [38, tuple 38] - +- [38, 'tuple 38'] box.space.vinyl:insert{39, "tuple 39"} - -- [39, tuple 39] - +- [39, 'tuple 39'] box.space.memtx:select{35} - -- [35, tuple 35] - +- [35, 'tuple 35'] box.space.memtx:select{36} - -- [36, tuple 36] - +- [36, 'tuple 36'] box.space.memtx:select{37} - -- [37, tuple 37] - +- [37, 'tuple 37'] box.space.memtx:select{38} - -- [38, tuple 38] - +- [38, 'tuple 38'] box.space.memtx:select{39} - -- [39, tuple 39] - +- [39, 'tuple 39'] box.space.vinyl:select{35} - -- [35, tuple 35] - +- [35, 'tuple 35'] box.space.vinyl:select{36} - -- [36, tuple 36] - +- [36, 'tuple 36'] box.space.vinyl:select{37} - -- [37, tuple 37] - +- [37, 'tuple 37'] box.space.vinyl:select{38} - -- [38, tuple 38] - +- [38, 'tuple 38'] box.space.vinyl:select{39} - -- [39, tuple 39] - +- [39, 'tuple 39'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -691,164 +531,124 @@ switch replica to replica test 2 iteration box.space.memtx:insert{40, "tuple 40"} - -- [40, tuple 40] - +- [40, 'tuple 40'] box.space.memtx:insert{41, "tuple 41"} - -- [41, tuple 41] - +- [41, 'tuple 41'] box.space.memtx:insert{42, "tuple 42"} - -- [42, tuple 42] - +- [42, 'tuple 42'] box.space.memtx:insert{43, "tuple 43"} - -- [43, tuple 43] - +- [43, 'tuple 43'] box.space.memtx:insert{44, "tuple 44"} - -- [44, tuple 44] - +- [44, 'tuple 44'] box.space.vinyl:insert{40, "tuple 40"} - -- [40, tuple 40] - +- [40, 'tuple 40'] box.space.vinyl:insert{41, "tuple 41"} - -- [41, tuple 41] - +- [41, 'tuple 41'] box.space.vinyl:insert{42, "tuple 42"} - -- [42, tuple 42] - +- [42, 'tuple 42'] box.space.vinyl:insert{43, "tuple 43"} - -- [43, tuple 43] - +- [43, 'tuple 43'] box.space.vinyl:insert{44, "tuple 44"} - -- [44, tuple 44] - +- [44, 'tuple 44'] box.space.memtx:select{40} - -- [40, tuple 40] - +- [40, 'tuple 40'] box.space.memtx:select{41} - -- [41, tuple 41] - +- [41, 'tuple 41'] box.space.memtx:select{42} - -- [42, tuple 42] - +- [42, 'tuple 42'] box.space.memtx:select{43} - -- [43, tuple 43] - +- [43, 'tuple 43'] box.space.memtx:select{44} - -- [44, tuple 44] - +- [44, 'tuple 44'] box.space.vinyl:select{40} - -- [40, tuple 40] - +- [40, 'tuple 40'] box.space.vinyl:select{41} - -- [41, tuple 41] - +- [41, 'tuple 41'] box.space.vinyl:select{42} - -- [42, tuple 42] - +- [42, 'tuple 42'] box.space.vinyl:select{43} - -- [43, tuple 43] - +- [43, 'tuple 43'] box.space.vinyl:select{44} - -- [44, tuple 44] - +- [44, 'tuple 44'] box.space.memtx:insert{45, "tuple 45"} - -- [45, tuple 45] - +- [45, 'tuple 45'] box.space.memtx:insert{46, "tuple 46"} - -- [46, tuple 46] - +- [46, 'tuple 46'] box.space.memtx:insert{47, "tuple 47"} - -- [47, tuple 47] - +- [47, 'tuple 47'] box.space.memtx:insert{48, "tuple 48"} - -- [48, tuple 48] - +- [48, 'tuple 48'] box.space.memtx:insert{49, "tuple 49"} - -- [49, tuple 49] - +- [49, 'tuple 49'] box.space.vinyl:insert{45, "tuple 45"} - -- [45, tuple 45] - +- [45, 'tuple 45'] box.space.vinyl:insert{46, "tuple 46"} - -- [46, tuple 46] - +- [46, 'tuple 46'] box.space.vinyl:insert{47, "tuple 47"} - -- [47, tuple 47] - +- [47, 'tuple 47'] box.space.vinyl:insert{48, "tuple 48"} - -- [48, tuple 48] - +- [48, 'tuple 48'] box.space.vinyl:insert{49, "tuple 49"} - -- [49, tuple 49] - +- [49, 'tuple 49'] box.space.memtx:select{45} - -- [45, tuple 45] - +- [45, 'tuple 45'] box.space.memtx:select{46} - -- [46, tuple 46] - +- [46, 'tuple 46'] box.space.memtx:select{47} - -- [47, tuple 47] - +- [47, 'tuple 47'] box.space.memtx:select{48} - -- [48, tuple 48] - +- [48, 'tuple 48'] box.space.memtx:select{49} - -- [49, tuple 49] - +- [49, 'tuple 49'] box.space.vinyl:select{45} - -- [45, tuple 45] - +- [45, 'tuple 45'] box.space.vinyl:select{46} - -- [46, tuple 46] - +- [46, 'tuple 46'] box.space.vinyl:select{47} - -- [47, tuple 47] - +- [47, 'tuple 47'] box.space.vinyl:select{48} - -- [48, tuple 48] - +- [48, 'tuple 48'] box.space.vinyl:select{49} - -- [49, tuple 49] - +- [49, 'tuple 49'] swap servers switch replica to master box.cfg{replication=''} @@ -857,164 +657,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{50, "tuple 50"} - -- [50, tuple 50] - +- [50, 'tuple 50'] box.space.memtx:insert{51, "tuple 51"} - -- [51, tuple 51] - +- [51, 'tuple 51'] box.space.memtx:insert{52, "tuple 52"} - -- [52, tuple 52] - +- [52, 'tuple 52'] box.space.memtx:insert{53, "tuple 53"} - -- [53, tuple 53] - +- [53, 'tuple 53'] box.space.memtx:insert{54, "tuple 54"} - -- [54, tuple 54] - +- [54, 'tuple 54'] box.space.vinyl:insert{50, "tuple 50"} - -- [50, tuple 50] - +- [50, 'tuple 50'] box.space.vinyl:insert{51, "tuple 51"} - -- [51, tuple 51] - +- [51, 'tuple 51'] box.space.vinyl:insert{52, "tuple 52"} - -- [52, tuple 52] - +- [52, 'tuple 52'] box.space.vinyl:insert{53, "tuple 53"} - -- [53, tuple 53] - +- [53, 'tuple 53'] box.space.vinyl:insert{54, "tuple 54"} - -- [54, tuple 54] - +- [54, 'tuple 54'] box.space.memtx:select{50} - -- [50, tuple 50] - +- [50, 'tuple 50'] box.space.memtx:select{51} - -- [51, tuple 51] - +- [51, 'tuple 51'] box.space.memtx:select{52} - -- [52, tuple 52] - +- [52, 'tuple 52'] box.space.memtx:select{53} - -- [53, tuple 53] - +- [53, 'tuple 53'] box.space.memtx:select{54} - -- [54, tuple 54] - +- [54, 'tuple 54'] box.space.vinyl:select{50} - -- [50, tuple 50] - +- [50, 'tuple 50'] box.space.vinyl:select{51} - -- [51, tuple 51] - +- [51, 'tuple 51'] box.space.vinyl:select{52} - -- [52, tuple 52] - +- [52, 'tuple 52'] box.space.vinyl:select{53} - -- [53, tuple 53] - +- [53, 'tuple 53'] box.space.vinyl:select{54} - -- [54, tuple 54] - +- [54, 'tuple 54'] box.space.memtx:insert{55, "tuple 55"} - -- [55, tuple 55] - +- [55, 'tuple 55'] box.space.memtx:insert{56, "tuple 56"} - -- [56, tuple 56] - +- [56, 'tuple 56'] box.space.memtx:insert{57, "tuple 57"} - -- [57, tuple 57] - +- [57, 'tuple 57'] box.space.memtx:insert{58, "tuple 58"} - -- [58, tuple 58] - +- [58, 'tuple 58'] box.space.memtx:insert{59, "tuple 59"} - -- [59, tuple 59] - +- [59, 'tuple 59'] box.space.vinyl:insert{55, "tuple 55"} - -- [55, tuple 55] - +- [55, 'tuple 55'] box.space.vinyl:insert{56, "tuple 56"} - -- [56, tuple 56] - +- [56, 'tuple 56'] box.space.vinyl:insert{57, "tuple 57"} - -- [57, tuple 57] - +- [57, 'tuple 57'] box.space.vinyl:insert{58, "tuple 58"} - -- [58, tuple 58] - +- [58, 'tuple 58'] box.space.vinyl:insert{59, "tuple 59"} - -- [59, tuple 59] - +- [59, 'tuple 59'] box.space.memtx:select{55} - -- [55, tuple 55] - +- [55, 'tuple 55'] box.space.memtx:select{56} - -- [56, tuple 56] - +- [56, 'tuple 56'] box.space.memtx:select{57} - -- [57, tuple 57] - +- [57, 'tuple 57'] box.space.memtx:select{58} - -- [58, tuple 58] - +- [58, 'tuple 58'] box.space.memtx:select{59} - -- [59, tuple 59] - +- [59, 'tuple 59'] box.space.vinyl:select{55} - -- [55, tuple 55] - +- [55, 'tuple 55'] box.space.vinyl:select{56} - -- [56, tuple 56] - +- [56, 'tuple 56'] box.space.vinyl:select{57} - -- [57, tuple 57] - +- [57, 'tuple 57'] box.space.vinyl:select{58} - -- [58, tuple 58] - +- [58, 'tuple 58'] box.space.vinyl:select{59} - -- [59, tuple 59] - +- [59, 'tuple 59'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -1024,164 +784,124 @@ switch replica to replica test 3 iteration box.space.memtx:insert{60, "tuple 60"} - -- [60, tuple 60] - +- [60, 'tuple 60'] box.space.memtx:insert{61, "tuple 61"} - -- [61, tuple 61] - +- [61, 'tuple 61'] box.space.memtx:insert{62, "tuple 62"} - -- [62, tuple 62] - +- [62, 'tuple 62'] box.space.memtx:insert{63, "tuple 63"} - -- [63, tuple 63] - +- [63, 'tuple 63'] box.space.memtx:insert{64, "tuple 64"} - -- [64, tuple 64] - +- [64, 'tuple 64'] box.space.vinyl:insert{60, "tuple 60"} - -- [60, tuple 60] - +- [60, 'tuple 60'] box.space.vinyl:insert{61, "tuple 61"} - -- [61, tuple 61] - +- [61, 'tuple 61'] box.space.vinyl:insert{62, "tuple 62"} - -- [62, tuple 62] - +- [62, 'tuple 62'] box.space.vinyl:insert{63, "tuple 63"} - -- [63, tuple 63] - +- [63, 'tuple 63'] box.space.vinyl:insert{64, "tuple 64"} - -- [64, tuple 64] - +- [64, 'tuple 64'] box.space.memtx:select{60} - -- [60, tuple 60] - +- [60, 'tuple 60'] box.space.memtx:select{61} - -- [61, tuple 61] - +- [61, 'tuple 61'] box.space.memtx:select{62} - -- [62, tuple 62] - +- [62, 'tuple 62'] box.space.memtx:select{63} - -- [63, tuple 63] - +- [63, 'tuple 63'] box.space.memtx:select{64} - -- [64, tuple 64] - +- [64, 'tuple 64'] box.space.vinyl:select{60} - -- [60, tuple 60] - +- [60, 'tuple 60'] box.space.vinyl:select{61} - -- [61, tuple 61] - +- [61, 'tuple 61'] box.space.vinyl:select{62} - -- [62, tuple 62] - +- [62, 'tuple 62'] box.space.vinyl:select{63} - -- [63, tuple 63] - +- [63, 'tuple 63'] box.space.vinyl:select{64} - -- [64, tuple 64] - +- [64, 'tuple 64'] box.space.memtx:insert{65, "tuple 65"} - -- [65, tuple 65] - +- [65, 'tuple 65'] box.space.memtx:insert{66, "tuple 66"} - -- [66, tuple 66] - +- [66, 'tuple 66'] box.space.memtx:insert{67, "tuple 67"} - -- [67, tuple 67] - +- [67, 'tuple 67'] box.space.memtx:insert{68, "tuple 68"} - -- [68, tuple 68] - +- [68, 'tuple 68'] box.space.memtx:insert{69, "tuple 69"} - -- [69, tuple 69] - +- [69, 'tuple 69'] box.space.vinyl:insert{65, "tuple 65"} - -- [65, tuple 65] - +- [65, 'tuple 65'] box.space.vinyl:insert{66, "tuple 66"} - -- [66, tuple 66] - +- [66, 'tuple 66'] box.space.vinyl:insert{67, "tuple 67"} - -- [67, tuple 67] - +- [67, 'tuple 67'] box.space.vinyl:insert{68, "tuple 68"} - -- [68, tuple 68] - +- [68, 'tuple 68'] box.space.vinyl:insert{69, "tuple 69"} - -- [69, tuple 69] - +- [69, 'tuple 69'] box.space.memtx:select{65} - -- [65, tuple 65] - +- [65, 'tuple 65'] box.space.memtx:select{66} - -- [66, tuple 66] - +- [66, 'tuple 66'] box.space.memtx:select{67} - -- [67, tuple 67] - +- [67, 'tuple 67'] box.space.memtx:select{68} - -- [68, tuple 68] - +- [68, 'tuple 68'] box.space.memtx:select{69} - -- [69, tuple 69] - +- [69, 'tuple 69'] box.space.vinyl:select{65} - -- [65, tuple 65] - +- [65, 'tuple 65'] box.space.vinyl:select{66} - -- [66, tuple 66] - +- [66, 'tuple 66'] box.space.vinyl:select{67} - -- [67, tuple 67] - +- [67, 'tuple 67'] box.space.vinyl:select{68} - -- [68, tuple 68] - +- [68, 'tuple 68'] box.space.vinyl:select{69} - -- [69, tuple 69] - +- [69, 'tuple 69'] swap servers switch replica to master box.cfg{replication=''} @@ -1190,164 +910,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{70, "tuple 70"} - -- [70, tuple 70] - +- [70, 'tuple 70'] box.space.memtx:insert{71, "tuple 71"} - -- [71, tuple 71] - +- [71, 'tuple 71'] box.space.memtx:insert{72, "tuple 72"} - -- [72, tuple 72] - +- [72, 'tuple 72'] box.space.memtx:insert{73, "tuple 73"} - -- [73, tuple 73] - +- [73, 'tuple 73'] box.space.memtx:insert{74, "tuple 74"} - -- [74, tuple 74] - +- [74, 'tuple 74'] box.space.vinyl:insert{70, "tuple 70"} - -- [70, tuple 70] - +- [70, 'tuple 70'] box.space.vinyl:insert{71, "tuple 71"} - -- [71, tuple 71] - +- [71, 'tuple 71'] box.space.vinyl:insert{72, "tuple 72"} - -- [72, tuple 72] - +- [72, 'tuple 72'] box.space.vinyl:insert{73, "tuple 73"} - -- [73, tuple 73] - +- [73, 'tuple 73'] box.space.vinyl:insert{74, "tuple 74"} - -- [74, tuple 74] - +- [74, 'tuple 74'] box.space.memtx:select{70} - -- [70, tuple 70] - +- [70, 'tuple 70'] box.space.memtx:select{71} - -- [71, tuple 71] - +- [71, 'tuple 71'] box.space.memtx:select{72} - -- [72, tuple 72] - +- [72, 'tuple 72'] box.space.memtx:select{73} - -- [73, tuple 73] - +- [73, 'tuple 73'] box.space.memtx:select{74} - -- [74, tuple 74] - +- [74, 'tuple 74'] box.space.vinyl:select{70} - -- [70, tuple 70] - +- [70, 'tuple 70'] box.space.vinyl:select{71} - -- [71, tuple 71] - +- [71, 'tuple 71'] box.space.vinyl:select{72} - -- [72, tuple 72] - +- [72, 'tuple 72'] box.space.vinyl:select{73} - -- [73, tuple 73] - +- [73, 'tuple 73'] box.space.vinyl:select{74} - -- [74, tuple 74] - +- [74, 'tuple 74'] box.space.memtx:insert{75, "tuple 75"} - -- [75, tuple 75] - +- [75, 'tuple 75'] box.space.memtx:insert{76, "tuple 76"} - -- [76, tuple 76] - +- [76, 'tuple 76'] box.space.memtx:insert{77, "tuple 77"} - -- [77, tuple 77] - +- [77, 'tuple 77'] box.space.memtx:insert{78, "tuple 78"} - -- [78, tuple 78] - +- [78, 'tuple 78'] box.space.memtx:insert{79, "tuple 79"} - -- [79, tuple 79] - +- [79, 'tuple 79'] box.space.vinyl:insert{75, "tuple 75"} - -- [75, tuple 75] - +- [75, 'tuple 75'] box.space.vinyl:insert{76, "tuple 76"} - -- [76, tuple 76] - +- [76, 'tuple 76'] box.space.vinyl:insert{77, "tuple 77"} - -- [77, tuple 77] - +- [77, 'tuple 77'] box.space.vinyl:insert{78, "tuple 78"} - -- [78, tuple 78] - +- [78, 'tuple 78'] box.space.vinyl:insert{79, "tuple 79"} - -- [79, tuple 79] - +- [79, 'tuple 79'] box.space.memtx:select{75} - -- [75, tuple 75] - +- [75, 'tuple 75'] box.space.memtx:select{76} - -- [76, tuple 76] - +- [76, 'tuple 76'] box.space.memtx:select{77} - -- [77, tuple 77] - +- [77, 'tuple 77'] box.space.memtx:select{78} - -- [78, tuple 78] - +- [78, 'tuple 78'] box.space.memtx:select{79} - -- [79, tuple 79] - +- [79, 'tuple 79'] box.space.vinyl:select{75} - -- [75, tuple 75] - +- [75, 'tuple 75'] box.space.vinyl:select{76} - -- [76, tuple 76] - +- [76, 'tuple 76'] box.space.vinyl:select{77} - -- [77, tuple 77] - +- [77, 'tuple 77'] box.space.vinyl:select{78} - -- [78, tuple 78] - +- [78, 'tuple 78'] box.space.vinyl:select{79} - -- [79, tuple 79] - +- [79, 'tuple 79'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -1357,164 +1037,124 @@ switch replica to replica test 4 iteration box.space.memtx:insert{80, "tuple 80"} - -- [80, tuple 80] - +- [80, 'tuple 80'] box.space.memtx:insert{81, "tuple 81"} - -- [81, tuple 81] - +- [81, 'tuple 81'] box.space.memtx:insert{82, "tuple 82"} - -- [82, tuple 82] - +- [82, 'tuple 82'] box.space.memtx:insert{83, "tuple 83"} - -- [83, tuple 83] - +- [83, 'tuple 83'] box.space.memtx:insert{84, "tuple 84"} - -- [84, tuple 84] - +- [84, 'tuple 84'] box.space.vinyl:insert{80, "tuple 80"} - -- [80, tuple 80] - +- [80, 'tuple 80'] box.space.vinyl:insert{81, "tuple 81"} - -- [81, tuple 81] - +- [81, 'tuple 81'] box.space.vinyl:insert{82, "tuple 82"} - -- [82, tuple 82] - +- [82, 'tuple 82'] box.space.vinyl:insert{83, "tuple 83"} - -- [83, tuple 83] - +- [83, 'tuple 83'] box.space.vinyl:insert{84, "tuple 84"} - -- [84, tuple 84] - +- [84, 'tuple 84'] box.space.memtx:select{80} - -- [80, tuple 80] - +- [80, 'tuple 80'] box.space.memtx:select{81} - -- [81, tuple 81] - +- [81, 'tuple 81'] box.space.memtx:select{82} - -- [82, tuple 82] - +- [82, 'tuple 82'] box.space.memtx:select{83} - -- [83, tuple 83] - +- [83, 'tuple 83'] box.space.memtx:select{84} - -- [84, tuple 84] - +- [84, 'tuple 84'] box.space.vinyl:select{80} - -- [80, tuple 80] - +- [80, 'tuple 80'] box.space.vinyl:select{81} - -- [81, tuple 81] - +- [81, 'tuple 81'] box.space.vinyl:select{82} - -- [82, tuple 82] - +- [82, 'tuple 82'] box.space.vinyl:select{83} - -- [83, tuple 83] - +- [83, 'tuple 83'] box.space.vinyl:select{84} - -- [84, tuple 84] - +- [84, 'tuple 84'] box.space.memtx:insert{85, "tuple 85"} - -- [85, tuple 85] - +- [85, 'tuple 85'] box.space.memtx:insert{86, "tuple 86"} - -- [86, tuple 86] - +- [86, 'tuple 86'] box.space.memtx:insert{87, "tuple 87"} - -- [87, tuple 87] - +- [87, 'tuple 87'] box.space.memtx:insert{88, "tuple 88"} - -- [88, tuple 88] - +- [88, 'tuple 88'] box.space.memtx:insert{89, "tuple 89"} - -- [89, tuple 89] - +- [89, 'tuple 89'] box.space.vinyl:insert{85, "tuple 85"} - -- [85, tuple 85] - +- [85, 'tuple 85'] box.space.vinyl:insert{86, "tuple 86"} - -- [86, tuple 86] - +- [86, 'tuple 86'] box.space.vinyl:insert{87, "tuple 87"} - -- [87, tuple 87] - +- [87, 'tuple 87'] box.space.vinyl:insert{88, "tuple 88"} - -- [88, tuple 88] - +- [88, 'tuple 88'] box.space.vinyl:insert{89, "tuple 89"} - -- [89, tuple 89] - +- [89, 'tuple 89'] box.space.memtx:select{85} - -- [85, tuple 85] - +- [85, 'tuple 85'] box.space.memtx:select{86} - -- [86, tuple 86] - +- [86, 'tuple 86'] box.space.memtx:select{87} - -- [87, tuple 87] - +- [87, 'tuple 87'] box.space.memtx:select{88} - -- [88, tuple 88] - +- [88, 'tuple 88'] box.space.memtx:select{89} - -- [89, tuple 89] - +- [89, 'tuple 89'] box.space.vinyl:select{85} - -- [85, tuple 85] - +- [85, 'tuple 85'] box.space.vinyl:select{86} - -- [86, tuple 86] - +- [86, 'tuple 86'] box.space.vinyl:select{87} - -- [87, tuple 87] - +- [87, 'tuple 87'] box.space.vinyl:select{88} - -- [88, tuple 88] - +- [88, 'tuple 88'] box.space.vinyl:select{89} - -- [89, tuple 89] - +- [89, 'tuple 89'] swap servers switch replica to master box.cfg{replication=''} @@ -1523,164 +1163,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{90, "tuple 90"} - -- [90, tuple 90] - +- [90, 'tuple 90'] box.space.memtx:insert{91, "tuple 91"} - -- [91, tuple 91] - +- [91, 'tuple 91'] box.space.memtx:insert{92, "tuple 92"} - -- [92, tuple 92] - +- [92, 'tuple 92'] box.space.memtx:insert{93, "tuple 93"} - -- [93, tuple 93] - +- [93, 'tuple 93'] box.space.memtx:insert{94, "tuple 94"} - -- [94, tuple 94] - +- [94, 'tuple 94'] box.space.vinyl:insert{90, "tuple 90"} - -- [90, tuple 90] - +- [90, 'tuple 90'] box.space.vinyl:insert{91, "tuple 91"} - -- [91, tuple 91] - +- [91, 'tuple 91'] box.space.vinyl:insert{92, "tuple 92"} - -- [92, tuple 92] - +- [92, 'tuple 92'] box.space.vinyl:insert{93, "tuple 93"} - -- [93, tuple 93] - +- [93, 'tuple 93'] box.space.vinyl:insert{94, "tuple 94"} - -- [94, tuple 94] - +- [94, 'tuple 94'] box.space.memtx:select{90} - -- [90, tuple 90] - +- [90, 'tuple 90'] box.space.memtx:select{91} - -- [91, tuple 91] - +- [91, 'tuple 91'] box.space.memtx:select{92} - -- [92, tuple 92] - +- [92, 'tuple 92'] box.space.memtx:select{93} - -- [93, tuple 93] - +- [93, 'tuple 93'] box.space.memtx:select{94} - -- [94, tuple 94] - +- [94, 'tuple 94'] box.space.vinyl:select{90} - -- [90, tuple 90] - +- [90, 'tuple 90'] box.space.vinyl:select{91} - -- [91, tuple 91] - +- [91, 'tuple 91'] box.space.vinyl:select{92} - -- [92, tuple 92] - +- [92, 'tuple 92'] box.space.vinyl:select{93} - -- [93, tuple 93] - +- [93, 'tuple 93'] box.space.vinyl:select{94} - -- [94, tuple 94] - +- [94, 'tuple 94'] box.space.memtx:insert{95, "tuple 95"} - -- [95, tuple 95] - +- [95, 'tuple 95'] box.space.memtx:insert{96, "tuple 96"} - -- [96, tuple 96] - +- [96, 'tuple 96'] box.space.memtx:insert{97, "tuple 97"} - -- [97, tuple 97] - +- [97, 'tuple 97'] box.space.memtx:insert{98, "tuple 98"} - -- [98, tuple 98] - +- [98, 'tuple 98'] box.space.memtx:insert{99, "tuple 99"} - -- [99, tuple 99] - +- [99, 'tuple 99'] box.space.vinyl:insert{95, "tuple 95"} - -- [95, tuple 95] - +- [95, 'tuple 95'] box.space.vinyl:insert{96, "tuple 96"} - -- [96, tuple 96] - +- [96, 'tuple 96'] box.space.vinyl:insert{97, "tuple 97"} - -- [97, tuple 97] - +- [97, 'tuple 97'] box.space.vinyl:insert{98, "tuple 98"} - -- [98, tuple 98] - +- [98, 'tuple 98'] box.space.vinyl:insert{99, "tuple 99"} - -- [99, tuple 99] - +- [99, 'tuple 99'] box.space.memtx:select{95} - -- [95, tuple 95] - +- [95, 'tuple 95'] box.space.memtx:select{96} - -- [96, tuple 96] - +- [96, 'tuple 96'] box.space.memtx:select{97} - -- [97, tuple 97] - +- [97, 'tuple 97'] box.space.memtx:select{98} - -- [98, tuple 98] - +- [98, 'tuple 98'] box.space.memtx:select{99} - -- [99, tuple 99] - +- [99, 'tuple 99'] box.space.vinyl:select{95} - -- [95, tuple 95] - +- [95, 'tuple 95'] box.space.vinyl:select{96} - -- [96, tuple 96] - +- [96, 'tuple 96'] box.space.vinyl:select{97} - -- [97, tuple 97] - +- [97, 'tuple 97'] box.space.vinyl:select{98} - -- [98, tuple 98] - +- [98, 'tuple 98'] box.space.vinyl:select{99} - -- [99, tuple 99] - +- [99, 'tuple 99'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -1690,164 +1290,124 @@ switch replica to replica test 5 iteration box.space.memtx:insert{100, "tuple 100"} - -- [100, tuple 100] - +- [100, 'tuple 100'] box.space.memtx:insert{101, "tuple 101"} - -- [101, tuple 101] - +- [101, 'tuple 101'] box.space.memtx:insert{102, "tuple 102"} - -- [102, tuple 102] - +- [102, 'tuple 102'] box.space.memtx:insert{103, "tuple 103"} - -- [103, tuple 103] - +- [103, 'tuple 103'] box.space.memtx:insert{104, "tuple 104"} - -- [104, tuple 104] - +- [104, 'tuple 104'] box.space.vinyl:insert{100, "tuple 100"} - -- [100, tuple 100] - +- [100, 'tuple 100'] box.space.vinyl:insert{101, "tuple 101"} - -- [101, tuple 101] - +- [101, 'tuple 101'] box.space.vinyl:insert{102, "tuple 102"} - -- [102, tuple 102] - +- [102, 'tuple 102'] box.space.vinyl:insert{103, "tuple 103"} - -- [103, tuple 103] - +- [103, 'tuple 103'] box.space.vinyl:insert{104, "tuple 104"} - -- [104, tuple 104] - +- [104, 'tuple 104'] box.space.memtx:select{100} - -- [100, tuple 100] - +- [100, 'tuple 100'] box.space.memtx:select{101} - -- [101, tuple 101] - +- [101, 'tuple 101'] box.space.memtx:select{102} - -- [102, tuple 102] - +- [102, 'tuple 102'] box.space.memtx:select{103} - -- [103, tuple 103] - +- [103, 'tuple 103'] box.space.memtx:select{104} - -- [104, tuple 104] - +- [104, 'tuple 104'] box.space.vinyl:select{100} - -- [100, tuple 100] - +- [100, 'tuple 100'] box.space.vinyl:select{101} - -- [101, tuple 101] - +- [101, 'tuple 101'] box.space.vinyl:select{102} - -- [102, tuple 102] - +- [102, 'tuple 102'] box.space.vinyl:select{103} - -- [103, tuple 103] - +- [103, 'tuple 103'] box.space.vinyl:select{104} - -- [104, tuple 104] - +- [104, 'tuple 104'] box.space.memtx:insert{105, "tuple 105"} - -- [105, tuple 105] - +- [105, 'tuple 105'] box.space.memtx:insert{106, "tuple 106"} - -- [106, tuple 106] - +- [106, 'tuple 106'] box.space.memtx:insert{107, "tuple 107"} - -- [107, tuple 107] - +- [107, 'tuple 107'] box.space.memtx:insert{108, "tuple 108"} - -- [108, tuple 108] - +- [108, 'tuple 108'] box.space.memtx:insert{109, "tuple 109"} - -- [109, tuple 109] - +- [109, 'tuple 109'] box.space.vinyl:insert{105, "tuple 105"} - -- [105, tuple 105] - +- [105, 'tuple 105'] box.space.vinyl:insert{106, "tuple 106"} - -- [106, tuple 106] - +- [106, 'tuple 106'] box.space.vinyl:insert{107, "tuple 107"} - -- [107, tuple 107] - +- [107, 'tuple 107'] box.space.vinyl:insert{108, "tuple 108"} - -- [108, tuple 108] - +- [108, 'tuple 108'] box.space.vinyl:insert{109, "tuple 109"} - -- [109, tuple 109] - +- [109, 'tuple 109'] box.space.memtx:select{105} - -- [105, tuple 105] - +- [105, 'tuple 105'] box.space.memtx:select{106} - -- [106, tuple 106] - +- [106, 'tuple 106'] box.space.memtx:select{107} - -- [107, tuple 107] - +- [107, 'tuple 107'] box.space.memtx:select{108} - -- [108, tuple 108] - +- [108, 'tuple 108'] box.space.memtx:select{109} - -- [109, tuple 109] - +- [109, 'tuple 109'] box.space.vinyl:select{105} - -- [105, tuple 105] - +- [105, 'tuple 105'] box.space.vinyl:select{106} - -- [106, tuple 106] - +- [106, 'tuple 106'] box.space.vinyl:select{107} - -- [107, tuple 107] - +- [107, 'tuple 107'] box.space.vinyl:select{108} - -- [108, tuple 108] - +- [108, 'tuple 108'] box.space.vinyl:select{109} - -- [109, tuple 109] - +- [109, 'tuple 109'] swap servers switch replica to master box.cfg{replication=''} @@ -1856,164 +1416,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{110, "tuple 110"} - -- [110, tuple 110] - +- [110, 'tuple 110'] box.space.memtx:insert{111, "tuple 111"} - -- [111, tuple 111] - +- [111, 'tuple 111'] box.space.memtx:insert{112, "tuple 112"} - -- [112, tuple 112] - +- [112, 'tuple 112'] box.space.memtx:insert{113, "tuple 113"} - -- [113, tuple 113] - +- [113, 'tuple 113'] box.space.memtx:insert{114, "tuple 114"} - -- [114, tuple 114] - +- [114, 'tuple 114'] box.space.vinyl:insert{110, "tuple 110"} - -- [110, tuple 110] - +- [110, 'tuple 110'] box.space.vinyl:insert{111, "tuple 111"} - -- [111, tuple 111] - +- [111, 'tuple 111'] box.space.vinyl:insert{112, "tuple 112"} - -- [112, tuple 112] - +- [112, 'tuple 112'] box.space.vinyl:insert{113, "tuple 113"} - -- [113, tuple 113] - +- [113, 'tuple 113'] box.space.vinyl:insert{114, "tuple 114"} - -- [114, tuple 114] - +- [114, 'tuple 114'] box.space.memtx:select{110} - -- [110, tuple 110] - +- [110, 'tuple 110'] box.space.memtx:select{111} - -- [111, tuple 111] - +- [111, 'tuple 111'] box.space.memtx:select{112} - -- [112, tuple 112] - +- [112, 'tuple 112'] box.space.memtx:select{113} - -- [113, tuple 113] - +- [113, 'tuple 113'] box.space.memtx:select{114} - -- [114, tuple 114] - +- [114, 'tuple 114'] box.space.vinyl:select{110} - -- [110, tuple 110] - +- [110, 'tuple 110'] box.space.vinyl:select{111} - -- [111, tuple 111] - +- [111, 'tuple 111'] box.space.vinyl:select{112} - -- [112, tuple 112] - +- [112, 'tuple 112'] box.space.vinyl:select{113} - -- [113, tuple 113] - +- [113, 'tuple 113'] box.space.vinyl:select{114} - -- [114, tuple 114] - +- [114, 'tuple 114'] box.space.memtx:insert{115, "tuple 115"} - -- [115, tuple 115] - +- [115, 'tuple 115'] box.space.memtx:insert{116, "tuple 116"} - -- [116, tuple 116] - +- [116, 'tuple 116'] box.space.memtx:insert{117, "tuple 117"} - -- [117, tuple 117] - +- [117, 'tuple 117'] box.space.memtx:insert{118, "tuple 118"} - -- [118, tuple 118] - +- [118, 'tuple 118'] box.space.memtx:insert{119, "tuple 119"} - -- [119, tuple 119] - +- [119, 'tuple 119'] box.space.vinyl:insert{115, "tuple 115"} - -- [115, tuple 115] - +- [115, 'tuple 115'] box.space.vinyl:insert{116, "tuple 116"} - -- [116, tuple 116] - +- [116, 'tuple 116'] box.space.vinyl:insert{117, "tuple 117"} - -- [117, tuple 117] - +- [117, 'tuple 117'] box.space.vinyl:insert{118, "tuple 118"} - -- [118, tuple 118] - +- [118, 'tuple 118'] box.space.vinyl:insert{119, "tuple 119"} - -- [119, tuple 119] - +- [119, 'tuple 119'] box.space.memtx:select{115} - -- [115, tuple 115] - +- [115, 'tuple 115'] box.space.memtx:select{116} - -- [116, tuple 116] - +- [116, 'tuple 116'] box.space.memtx:select{117} - -- [117, tuple 117] - +- [117, 'tuple 117'] box.space.memtx:select{118} - -- [118, tuple 118] - +- [118, 'tuple 118'] box.space.memtx:select{119} - -- [119, tuple 119] - +- [119, 'tuple 119'] box.space.vinyl:select{115} - -- [115, tuple 115] - +- [115, 'tuple 115'] box.space.vinyl:select{116} - -- [116, tuple 116] - +- [116, 'tuple 116'] box.space.vinyl:select{117} - -- [117, tuple 117] - +- [117, 'tuple 117'] box.space.vinyl:select{118} - -- [118, tuple 118] - +- [118, 'tuple 118'] box.space.vinyl:select{119} - -- [119, tuple 119] - +- [119, 'tuple 119'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -2023,164 +1543,124 @@ switch replica to replica test 6 iteration box.space.memtx:insert{120, "tuple 120"} - -- [120, tuple 120] - +- [120, 'tuple 120'] box.space.memtx:insert{121, "tuple 121"} - -- [121, tuple 121] - +- [121, 'tuple 121'] box.space.memtx:insert{122, "tuple 122"} - -- [122, tuple 122] - +- [122, 'tuple 122'] box.space.memtx:insert{123, "tuple 123"} - -- [123, tuple 123] - +- [123, 'tuple 123'] box.space.memtx:insert{124, "tuple 124"} - -- [124, tuple 124] - +- [124, 'tuple 124'] box.space.vinyl:insert{120, "tuple 120"} - -- [120, tuple 120] - +- [120, 'tuple 120'] box.space.vinyl:insert{121, "tuple 121"} - -- [121, tuple 121] - +- [121, 'tuple 121'] box.space.vinyl:insert{122, "tuple 122"} - -- [122, tuple 122] - +- [122, 'tuple 122'] box.space.vinyl:insert{123, "tuple 123"} - -- [123, tuple 123] - +- [123, 'tuple 123'] box.space.vinyl:insert{124, "tuple 124"} - -- [124, tuple 124] - +- [124, 'tuple 124'] box.space.memtx:select{120} - -- [120, tuple 120] - +- [120, 'tuple 120'] box.space.memtx:select{121} - -- [121, tuple 121] - +- [121, 'tuple 121'] box.space.memtx:select{122} - -- [122, tuple 122] - +- [122, 'tuple 122'] box.space.memtx:select{123} - -- [123, tuple 123] - +- [123, 'tuple 123'] box.space.memtx:select{124} - -- [124, tuple 124] - +- [124, 'tuple 124'] box.space.vinyl:select{120} - -- [120, tuple 120] - +- [120, 'tuple 120'] box.space.vinyl:select{121} - -- [121, tuple 121] - +- [121, 'tuple 121'] box.space.vinyl:select{122} - -- [122, tuple 122] - +- [122, 'tuple 122'] box.space.vinyl:select{123} - -- [123, tuple 123] - +- [123, 'tuple 123'] box.space.vinyl:select{124} - -- [124, tuple 124] - +- [124, 'tuple 124'] box.space.memtx:insert{125, "tuple 125"} - -- [125, tuple 125] - +- [125, 'tuple 125'] box.space.memtx:insert{126, "tuple 126"} - -- [126, tuple 126] - +- [126, 'tuple 126'] box.space.memtx:insert{127, "tuple 127"} - -- [127, tuple 127] - +- [127, 'tuple 127'] box.space.memtx:insert{128, "tuple 128"} - -- [128, tuple 128] - +- [128, 'tuple 128'] box.space.memtx:insert{129, "tuple 129"} - -- [129, tuple 129] - +- [129, 'tuple 129'] box.space.vinyl:insert{125, "tuple 125"} - -- [125, tuple 125] - +- [125, 'tuple 125'] box.space.vinyl:insert{126, "tuple 126"} - -- [126, tuple 126] - +- [126, 'tuple 126'] box.space.vinyl:insert{127, "tuple 127"} - -- [127, tuple 127] - +- [127, 'tuple 127'] box.space.vinyl:insert{128, "tuple 128"} - -- [128, tuple 128] - +- [128, 'tuple 128'] box.space.vinyl:insert{129, "tuple 129"} - -- [129, tuple 129] - +- [129, 'tuple 129'] box.space.memtx:select{125} - -- [125, tuple 125] - +- [125, 'tuple 125'] box.space.memtx:select{126} - -- [126, tuple 126] - +- [126, 'tuple 126'] box.space.memtx:select{127} - -- [127, tuple 127] - +- [127, 'tuple 127'] box.space.memtx:select{128} - -- [128, tuple 128] - +- [128, 'tuple 128'] box.space.memtx:select{129} - -- [129, tuple 129] - +- [129, 'tuple 129'] box.space.vinyl:select{125} - -- [125, tuple 125] - +- [125, 'tuple 125'] box.space.vinyl:select{126} - -- [126, tuple 126] - +- [126, 'tuple 126'] box.space.vinyl:select{127} - -- [127, tuple 127] - +- [127, 'tuple 127'] box.space.vinyl:select{128} - -- [128, tuple 128] - +- [128, 'tuple 128'] box.space.vinyl:select{129} - -- [129, tuple 129] - +- [129, 'tuple 129'] swap servers switch replica to master box.cfg{replication=''} @@ -2189,164 +1669,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{130, "tuple 130"} - -- [130, tuple 130] - +- [130, 'tuple 130'] box.space.memtx:insert{131, "tuple 131"} - -- [131, tuple 131] - +- [131, 'tuple 131'] box.space.memtx:insert{132, "tuple 132"} - -- [132, tuple 132] - +- [132, 'tuple 132'] box.space.memtx:insert{133, "tuple 133"} - -- [133, tuple 133] - +- [133, 'tuple 133'] box.space.memtx:insert{134, "tuple 134"} - -- [134, tuple 134] - +- [134, 'tuple 134'] box.space.vinyl:insert{130, "tuple 130"} - -- [130, tuple 130] - +- [130, 'tuple 130'] box.space.vinyl:insert{131, "tuple 131"} - -- [131, tuple 131] - +- [131, 'tuple 131'] box.space.vinyl:insert{132, "tuple 132"} - -- [132, tuple 132] - +- [132, 'tuple 132'] box.space.vinyl:insert{133, "tuple 133"} - -- [133, tuple 133] - +- [133, 'tuple 133'] box.space.vinyl:insert{134, "tuple 134"} - -- [134, tuple 134] - +- [134, 'tuple 134'] box.space.memtx:select{130} - -- [130, tuple 130] - +- [130, 'tuple 130'] box.space.memtx:select{131} - -- [131, tuple 131] - +- [131, 'tuple 131'] box.space.memtx:select{132} - -- [132, tuple 132] - +- [132, 'tuple 132'] box.space.memtx:select{133} - -- [133, tuple 133] - +- [133, 'tuple 133'] box.space.memtx:select{134} - -- [134, tuple 134] - +- [134, 'tuple 134'] box.space.vinyl:select{130} - -- [130, tuple 130] - +- [130, 'tuple 130'] box.space.vinyl:select{131} - -- [131, tuple 131] - +- [131, 'tuple 131'] box.space.vinyl:select{132} - -- [132, tuple 132] - +- [132, 'tuple 132'] box.space.vinyl:select{133} - -- [133, tuple 133] - +- [133, 'tuple 133'] box.space.vinyl:select{134} - -- [134, tuple 134] - +- [134, 'tuple 134'] box.space.memtx:insert{135, "tuple 135"} - -- [135, tuple 135] - +- [135, 'tuple 135'] box.space.memtx:insert{136, "tuple 136"} - -- [136, tuple 136] - +- [136, 'tuple 136'] box.space.memtx:insert{137, "tuple 137"} - -- [137, tuple 137] - +- [137, 'tuple 137'] box.space.memtx:insert{138, "tuple 138"} - -- [138, tuple 138] - +- [138, 'tuple 138'] box.space.memtx:insert{139, "tuple 139"} - -- [139, tuple 139] - +- [139, 'tuple 139'] box.space.vinyl:insert{135, "tuple 135"} - -- [135, tuple 135] - +- [135, 'tuple 135'] box.space.vinyl:insert{136, "tuple 136"} - -- [136, tuple 136] - +- [136, 'tuple 136'] box.space.vinyl:insert{137, "tuple 137"} - -- [137, tuple 137] - +- [137, 'tuple 137'] box.space.vinyl:insert{138, "tuple 138"} - -- [138, tuple 138] - +- [138, 'tuple 138'] box.space.vinyl:insert{139, "tuple 139"} - -- [139, tuple 139] - +- [139, 'tuple 139'] box.space.memtx:select{135} - -- [135, tuple 135] - +- [135, 'tuple 135'] box.space.memtx:select{136} - -- [136, tuple 136] - +- [136, 'tuple 136'] box.space.memtx:select{137} - -- [137, tuple 137] - +- [137, 'tuple 137'] box.space.memtx:select{138} - -- [138, tuple 138] - +- [138, 'tuple 138'] box.space.memtx:select{139} - -- [139, tuple 139] - +- [139, 'tuple 139'] box.space.vinyl:select{135} - -- [135, tuple 135] - +- [135, 'tuple 135'] box.space.vinyl:select{136} - -- [136, tuple 136] - +- [136, 'tuple 136'] box.space.vinyl:select{137} - -- [137, tuple 137] - +- [137, 'tuple 137'] box.space.vinyl:select{138} - -- [138, tuple 138] - +- [138, 'tuple 138'] box.space.vinyl:select{139} - -- [139, tuple 139] - +- [139, 'tuple 139'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -2356,164 +1796,124 @@ switch replica to replica test 7 iteration box.space.memtx:insert{140, "tuple 140"} - -- [140, tuple 140] - +- [140, 'tuple 140'] box.space.memtx:insert{141, "tuple 141"} - -- [141, tuple 141] - +- [141, 'tuple 141'] box.space.memtx:insert{142, "tuple 142"} - -- [142, tuple 142] - +- [142, 'tuple 142'] box.space.memtx:insert{143, "tuple 143"} - -- [143, tuple 143] - +- [143, 'tuple 143'] box.space.memtx:insert{144, "tuple 144"} - -- [144, tuple 144] - +- [144, 'tuple 144'] box.space.vinyl:insert{140, "tuple 140"} - -- [140, tuple 140] - +- [140, 'tuple 140'] box.space.vinyl:insert{141, "tuple 141"} - -- [141, tuple 141] - +- [141, 'tuple 141'] box.space.vinyl:insert{142, "tuple 142"} - -- [142, tuple 142] - +- [142, 'tuple 142'] box.space.vinyl:insert{143, "tuple 143"} - -- [143, tuple 143] - +- [143, 'tuple 143'] box.space.vinyl:insert{144, "tuple 144"} - -- [144, tuple 144] - +- [144, 'tuple 144'] box.space.memtx:select{140} - -- [140, tuple 140] - +- [140, 'tuple 140'] box.space.memtx:select{141} - -- [141, tuple 141] - +- [141, 'tuple 141'] box.space.memtx:select{142} - -- [142, tuple 142] - +- [142, 'tuple 142'] box.space.memtx:select{143} - -- [143, tuple 143] - +- [143, 'tuple 143'] box.space.memtx:select{144} - -- [144, tuple 144] - +- [144, 'tuple 144'] box.space.vinyl:select{140} - -- [140, tuple 140] - +- [140, 'tuple 140'] box.space.vinyl:select{141} - -- [141, tuple 141] - +- [141, 'tuple 141'] box.space.vinyl:select{142} - -- [142, tuple 142] - +- [142, 'tuple 142'] box.space.vinyl:select{143} - -- [143, tuple 143] - +- [143, 'tuple 143'] box.space.vinyl:select{144} - -- [144, tuple 144] - +- [144, 'tuple 144'] box.space.memtx:insert{145, "tuple 145"} - -- [145, tuple 145] - +- [145, 'tuple 145'] box.space.memtx:insert{146, "tuple 146"} - -- [146, tuple 146] - +- [146, 'tuple 146'] box.space.memtx:insert{147, "tuple 147"} - -- [147, tuple 147] - +- [147, 'tuple 147'] box.space.memtx:insert{148, "tuple 148"} - -- [148, tuple 148] - +- [148, 'tuple 148'] box.space.memtx:insert{149, "tuple 149"} - -- [149, tuple 149] - +- [149, 'tuple 149'] box.space.vinyl:insert{145, "tuple 145"} - -- [145, tuple 145] - +- [145, 'tuple 145'] box.space.vinyl:insert{146, "tuple 146"} - -- [146, tuple 146] - +- [146, 'tuple 146'] box.space.vinyl:insert{147, "tuple 147"} - -- [147, tuple 147] - +- [147, 'tuple 147'] box.space.vinyl:insert{148, "tuple 148"} - -- [148, tuple 148] - +- [148, 'tuple 148'] box.space.vinyl:insert{149, "tuple 149"} - -- [149, tuple 149] - +- [149, 'tuple 149'] box.space.memtx:select{145} - -- [145, tuple 145] - +- [145, 'tuple 145'] box.space.memtx:select{146} - -- [146, tuple 146] - +- [146, 'tuple 146'] box.space.memtx:select{147} - -- [147, tuple 147] - +- [147, 'tuple 147'] box.space.memtx:select{148} - -- [148, tuple 148] - +- [148, 'tuple 148'] box.space.memtx:select{149} - -- [149, tuple 149] - +- [149, 'tuple 149'] box.space.vinyl:select{145} - -- [145, tuple 145] - +- [145, 'tuple 145'] box.space.vinyl:select{146} - -- [146, tuple 146] - +- [146, 'tuple 146'] box.space.vinyl:select{147} - -- [147, tuple 147] - +- [147, 'tuple 147'] box.space.vinyl:select{148} - -- [148, tuple 148] - +- [148, 'tuple 148'] box.space.vinyl:select{149} - -- [149, tuple 149] - +- [149, 'tuple 149'] swap servers switch replica to master box.cfg{replication=''} @@ -2522,164 +1922,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{150, "tuple 150"} - -- [150, tuple 150] - +- [150, 'tuple 150'] box.space.memtx:insert{151, "tuple 151"} - -- [151, tuple 151] - +- [151, 'tuple 151'] box.space.memtx:insert{152, "tuple 152"} - -- [152, tuple 152] - +- [152, 'tuple 152'] box.space.memtx:insert{153, "tuple 153"} - -- [153, tuple 153] - +- [153, 'tuple 153'] box.space.memtx:insert{154, "tuple 154"} - -- [154, tuple 154] - +- [154, 'tuple 154'] box.space.vinyl:insert{150, "tuple 150"} - -- [150, tuple 150] - +- [150, 'tuple 150'] box.space.vinyl:insert{151, "tuple 151"} - -- [151, tuple 151] - +- [151, 'tuple 151'] box.space.vinyl:insert{152, "tuple 152"} - -- [152, tuple 152] - +- [152, 'tuple 152'] box.space.vinyl:insert{153, "tuple 153"} - -- [153, tuple 153] - +- [153, 'tuple 153'] box.space.vinyl:insert{154, "tuple 154"} - -- [154, tuple 154] - +- [154, 'tuple 154'] box.space.memtx:select{150} - -- [150, tuple 150] - +- [150, 'tuple 150'] box.space.memtx:select{151} - -- [151, tuple 151] - +- [151, 'tuple 151'] box.space.memtx:select{152} - -- [152, tuple 152] - +- [152, 'tuple 152'] box.space.memtx:select{153} - -- [153, tuple 153] - +- [153, 'tuple 153'] box.space.memtx:select{154} - -- [154, tuple 154] - +- [154, 'tuple 154'] box.space.vinyl:select{150} - -- [150, tuple 150] - +- [150, 'tuple 150'] box.space.vinyl:select{151} - -- [151, tuple 151] - +- [151, 'tuple 151'] box.space.vinyl:select{152} - -- [152, tuple 152] - +- [152, 'tuple 152'] box.space.vinyl:select{153} - -- [153, tuple 153] - +- [153, 'tuple 153'] box.space.vinyl:select{154} - -- [154, tuple 154] - +- [154, 'tuple 154'] box.space.memtx:insert{155, "tuple 155"} - -- [155, tuple 155] - +- [155, 'tuple 155'] box.space.memtx:insert{156, "tuple 156"} - -- [156, tuple 156] - +- [156, 'tuple 156'] box.space.memtx:insert{157, "tuple 157"} - -- [157, tuple 157] - +- [157, 'tuple 157'] box.space.memtx:insert{158, "tuple 158"} - -- [158, tuple 158] - +- [158, 'tuple 158'] box.space.memtx:insert{159, "tuple 159"} - -- [159, tuple 159] - +- [159, 'tuple 159'] box.space.vinyl:insert{155, "tuple 155"} - -- [155, tuple 155] - +- [155, 'tuple 155'] box.space.vinyl:insert{156, "tuple 156"} - -- [156, tuple 156] - +- [156, 'tuple 156'] box.space.vinyl:insert{157, "tuple 157"} - -- [157, tuple 157] - +- [157, 'tuple 157'] box.space.vinyl:insert{158, "tuple 158"} - -- [158, tuple 158] - +- [158, 'tuple 158'] box.space.vinyl:insert{159, "tuple 159"} - -- [159, tuple 159] - +- [159, 'tuple 159'] box.space.memtx:select{155} - -- [155, tuple 155] - +- [155, 'tuple 155'] box.space.memtx:select{156} - -- [156, tuple 156] - +- [156, 'tuple 156'] box.space.memtx:select{157} - -- [157, tuple 157] - +- [157, 'tuple 157'] box.space.memtx:select{158} - -- [158, tuple 158] - +- [158, 'tuple 158'] box.space.memtx:select{159} - -- [159, tuple 159] - +- [159, 'tuple 159'] box.space.vinyl:select{155} - -- [155, tuple 155] - +- [155, 'tuple 155'] box.space.vinyl:select{156} - -- [156, tuple 156] - +- [156, 'tuple 156'] box.space.vinyl:select{157} - -- [157, tuple 157] - +- [157, 'tuple 157'] box.space.vinyl:select{158} - -- [158, tuple 158] - +- [158, 'tuple 158'] box.space.vinyl:select{159} - -- [159, tuple 159] - +- [159, 'tuple 159'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -2689,164 +2049,124 @@ switch replica to replica test 8 iteration box.space.memtx:insert{160, "tuple 160"} - -- [160, tuple 160] - +- [160, 'tuple 160'] box.space.memtx:insert{161, "tuple 161"} - -- [161, tuple 161] - +- [161, 'tuple 161'] box.space.memtx:insert{162, "tuple 162"} - -- [162, tuple 162] - +- [162, 'tuple 162'] box.space.memtx:insert{163, "tuple 163"} - -- [163, tuple 163] - +- [163, 'tuple 163'] box.space.memtx:insert{164, "tuple 164"} - -- [164, tuple 164] - +- [164, 'tuple 164'] box.space.vinyl:insert{160, "tuple 160"} - -- [160, tuple 160] - +- [160, 'tuple 160'] box.space.vinyl:insert{161, "tuple 161"} - -- [161, tuple 161] - +- [161, 'tuple 161'] box.space.vinyl:insert{162, "tuple 162"} - -- [162, tuple 162] - +- [162, 'tuple 162'] box.space.vinyl:insert{163, "tuple 163"} - -- [163, tuple 163] - +- [163, 'tuple 163'] box.space.vinyl:insert{164, "tuple 164"} - -- [164, tuple 164] - +- [164, 'tuple 164'] box.space.memtx:select{160} - -- [160, tuple 160] - +- [160, 'tuple 160'] box.space.memtx:select{161} - -- [161, tuple 161] - +- [161, 'tuple 161'] box.space.memtx:select{162} - -- [162, tuple 162] - +- [162, 'tuple 162'] box.space.memtx:select{163} - -- [163, tuple 163] - +- [163, 'tuple 163'] box.space.memtx:select{164} - -- [164, tuple 164] - +- [164, 'tuple 164'] box.space.vinyl:select{160} - -- [160, tuple 160] - +- [160, 'tuple 160'] box.space.vinyl:select{161} - -- [161, tuple 161] - +- [161, 'tuple 161'] box.space.vinyl:select{162} - -- [162, tuple 162] - +- [162, 'tuple 162'] box.space.vinyl:select{163} - -- [163, tuple 163] - +- [163, 'tuple 163'] box.space.vinyl:select{164} - -- [164, tuple 164] - +- [164, 'tuple 164'] box.space.memtx:insert{165, "tuple 165"} - -- [165, tuple 165] - +- [165, 'tuple 165'] box.space.memtx:insert{166, "tuple 166"} - -- [166, tuple 166] - +- [166, 'tuple 166'] box.space.memtx:insert{167, "tuple 167"} - -- [167, tuple 167] - +- [167, 'tuple 167'] box.space.memtx:insert{168, "tuple 168"} - -- [168, tuple 168] - +- [168, 'tuple 168'] box.space.memtx:insert{169, "tuple 169"} - -- [169, tuple 169] - +- [169, 'tuple 169'] box.space.vinyl:insert{165, "tuple 165"} - -- [165, tuple 165] - +- [165, 'tuple 165'] box.space.vinyl:insert{166, "tuple 166"} - -- [166, tuple 166] - +- [166, 'tuple 166'] box.space.vinyl:insert{167, "tuple 167"} - -- [167, tuple 167] - +- [167, 'tuple 167'] box.space.vinyl:insert{168, "tuple 168"} - -- [168, tuple 168] - +- [168, 'tuple 168'] box.space.vinyl:insert{169, "tuple 169"} - -- [169, tuple 169] - +- [169, 'tuple 169'] box.space.memtx:select{165} - -- [165, tuple 165] - +- [165, 'tuple 165'] box.space.memtx:select{166} - -- [166, tuple 166] - +- [166, 'tuple 166'] box.space.memtx:select{167} - -- [167, tuple 167] - +- [167, 'tuple 167'] box.space.memtx:select{168} - -- [168, tuple 168] - +- [168, 'tuple 168'] box.space.memtx:select{169} - -- [169, tuple 169] - +- [169, 'tuple 169'] box.space.vinyl:select{165} - -- [165, tuple 165] - +- [165, 'tuple 165'] box.space.vinyl:select{166} - -- [166, tuple 166] - +- [166, 'tuple 166'] box.space.vinyl:select{167} - -- [167, tuple 167] - +- [167, 'tuple 167'] box.space.vinyl:select{168} - -- [168, tuple 168] - +- [168, 'tuple 168'] box.space.vinyl:select{169} - -- [169, tuple 169] - +- [169, 'tuple 169'] swap servers switch replica to master box.cfg{replication=''} @@ -2855,164 +2175,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{170, "tuple 170"} - -- [170, tuple 170] - +- [170, 'tuple 170'] box.space.memtx:insert{171, "tuple 171"} - -- [171, tuple 171] - +- [171, 'tuple 171'] box.space.memtx:insert{172, "tuple 172"} - -- [172, tuple 172] - +- [172, 'tuple 172'] box.space.memtx:insert{173, "tuple 173"} - -- [173, tuple 173] - +- [173, 'tuple 173'] box.space.memtx:insert{174, "tuple 174"} - -- [174, tuple 174] - +- [174, 'tuple 174'] box.space.vinyl:insert{170, "tuple 170"} - -- [170, tuple 170] - +- [170, 'tuple 170'] box.space.vinyl:insert{171, "tuple 171"} - -- [171, tuple 171] - +- [171, 'tuple 171'] box.space.vinyl:insert{172, "tuple 172"} - -- [172, tuple 172] - +- [172, 'tuple 172'] box.space.vinyl:insert{173, "tuple 173"} - -- [173, tuple 173] - +- [173, 'tuple 173'] box.space.vinyl:insert{174, "tuple 174"} - -- [174, tuple 174] - +- [174, 'tuple 174'] box.space.memtx:select{170} - -- [170, tuple 170] - +- [170, 'tuple 170'] box.space.memtx:select{171} - -- [171, tuple 171] - +- [171, 'tuple 171'] box.space.memtx:select{172} - -- [172, tuple 172] - +- [172, 'tuple 172'] box.space.memtx:select{173} - -- [173, tuple 173] - +- [173, 'tuple 173'] box.space.memtx:select{174} - -- [174, tuple 174] - +- [174, 'tuple 174'] box.space.vinyl:select{170} - -- [170, tuple 170] - +- [170, 'tuple 170'] box.space.vinyl:select{171} - -- [171, tuple 171] - +- [171, 'tuple 171'] box.space.vinyl:select{172} - -- [172, tuple 172] - +- [172, 'tuple 172'] box.space.vinyl:select{173} - -- [173, tuple 173] - +- [173, 'tuple 173'] box.space.vinyl:select{174} - -- [174, tuple 174] - +- [174, 'tuple 174'] box.space.memtx:insert{175, "tuple 175"} - -- [175, tuple 175] - +- [175, 'tuple 175'] box.space.memtx:insert{176, "tuple 176"} - -- [176, tuple 176] - +- [176, 'tuple 176'] box.space.memtx:insert{177, "tuple 177"} - -- [177, tuple 177] - +- [177, 'tuple 177'] box.space.memtx:insert{178, "tuple 178"} - -- [178, tuple 178] - +- [178, 'tuple 178'] box.space.memtx:insert{179, "tuple 179"} - -- [179, tuple 179] - +- [179, 'tuple 179'] box.space.vinyl:insert{175, "tuple 175"} - -- [175, tuple 175] - +- [175, 'tuple 175'] box.space.vinyl:insert{176, "tuple 176"} - -- [176, tuple 176] - +- [176, 'tuple 176'] box.space.vinyl:insert{177, "tuple 177"} - -- [177, tuple 177] - +- [177, 'tuple 177'] box.space.vinyl:insert{178, "tuple 178"} - -- [178, tuple 178] - +- [178, 'tuple 178'] box.space.vinyl:insert{179, "tuple 179"} - -- [179, tuple 179] - +- [179, 'tuple 179'] box.space.memtx:select{175} - -- [175, tuple 175] - +- [175, 'tuple 175'] box.space.memtx:select{176} - -- [176, tuple 176] - +- [176, 'tuple 176'] box.space.memtx:select{177} - -- [177, tuple 177] - +- [177, 'tuple 177'] box.space.memtx:select{178} - -- [178, tuple 178] - +- [178, 'tuple 178'] box.space.memtx:select{179} - -- [179, tuple 179] - +- [179, 'tuple 179'] box.space.vinyl:select{175} - -- [175, tuple 175] - +- [175, 'tuple 175'] box.space.vinyl:select{176} - -- [176, tuple 176] - +- [176, 'tuple 176'] box.space.vinyl:select{177} - -- [177, tuple 177] - +- [177, 'tuple 177'] box.space.vinyl:select{178} - -- [178, tuple 178] - +- [178, 'tuple 178'] box.space.vinyl:select{179} - -- [179, tuple 179] - +- [179, 'tuple 179'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -3022,164 +2302,124 @@ switch replica to replica test 9 iteration box.space.memtx:insert{180, "tuple 180"} - -- [180, tuple 180] - +- [180, 'tuple 180'] box.space.memtx:insert{181, "tuple 181"} - -- [181, tuple 181] - +- [181, 'tuple 181'] box.space.memtx:insert{182, "tuple 182"} - -- [182, tuple 182] - +- [182, 'tuple 182'] box.space.memtx:insert{183, "tuple 183"} - -- [183, tuple 183] - +- [183, 'tuple 183'] box.space.memtx:insert{184, "tuple 184"} - -- [184, tuple 184] - +- [184, 'tuple 184'] box.space.vinyl:insert{180, "tuple 180"} - -- [180, tuple 180] - +- [180, 'tuple 180'] box.space.vinyl:insert{181, "tuple 181"} - -- [181, tuple 181] - +- [181, 'tuple 181'] box.space.vinyl:insert{182, "tuple 182"} - -- [182, tuple 182] - +- [182, 'tuple 182'] box.space.vinyl:insert{183, "tuple 183"} - -- [183, tuple 183] - +- [183, 'tuple 183'] box.space.vinyl:insert{184, "tuple 184"} - -- [184, tuple 184] - +- [184, 'tuple 184'] box.space.memtx:select{180} - -- [180, tuple 180] - +- [180, 'tuple 180'] box.space.memtx:select{181} - -- [181, tuple 181] - +- [181, 'tuple 181'] box.space.memtx:select{182} - -- [182, tuple 182] - +- [182, 'tuple 182'] box.space.memtx:select{183} - -- [183, tuple 183] - +- [183, 'tuple 183'] box.space.memtx:select{184} - -- [184, tuple 184] - +- [184, 'tuple 184'] box.space.vinyl:select{180} - -- [180, tuple 180] - +- [180, 'tuple 180'] box.space.vinyl:select{181} - -- [181, tuple 181] - +- [181, 'tuple 181'] box.space.vinyl:select{182} - -- [182, tuple 182] - +- [182, 'tuple 182'] box.space.vinyl:select{183} - -- [183, tuple 183] - +- [183, 'tuple 183'] box.space.vinyl:select{184} - -- [184, tuple 184] - +- [184, 'tuple 184'] box.space.memtx:insert{185, "tuple 185"} - -- [185, tuple 185] - +- [185, 'tuple 185'] box.space.memtx:insert{186, "tuple 186"} - -- [186, tuple 186] - +- [186, 'tuple 186'] box.space.memtx:insert{187, "tuple 187"} - -- [187, tuple 187] - +- [187, 'tuple 187'] box.space.memtx:insert{188, "tuple 188"} - -- [188, tuple 188] - +- [188, 'tuple 188'] box.space.memtx:insert{189, "tuple 189"} - -- [189, tuple 189] - +- [189, 'tuple 189'] box.space.vinyl:insert{185, "tuple 185"} - -- [185, tuple 185] - +- [185, 'tuple 185'] box.space.vinyl:insert{186, "tuple 186"} - -- [186, tuple 186] - +- [186, 'tuple 186'] box.space.vinyl:insert{187, "tuple 187"} - -- [187, tuple 187] - +- [187, 'tuple 187'] box.space.vinyl:insert{188, "tuple 188"} - -- [188, tuple 188] - +- [188, 'tuple 188'] box.space.vinyl:insert{189, "tuple 189"} - -- [189, tuple 189] - +- [189, 'tuple 189'] box.space.memtx:select{185} - -- [185, tuple 185] - +- [185, 'tuple 185'] box.space.memtx:select{186} - -- [186, tuple 186] - +- [186, 'tuple 186'] box.space.memtx:select{187} - -- [187, tuple 187] - +- [187, 'tuple 187'] box.space.memtx:select{188} - -- [188, tuple 188] - +- [188, 'tuple 188'] box.space.memtx:select{189} - -- [189, tuple 189] - +- [189, 'tuple 189'] box.space.vinyl:select{185} - -- [185, tuple 185] - +- [185, 'tuple 185'] box.space.vinyl:select{186} - -- [186, tuple 186] - +- [186, 'tuple 186'] box.space.vinyl:select{187} - -- [187, tuple 187] - +- [187, 'tuple 187'] box.space.vinyl:select{188} - -- [188, tuple 188] - +- [188, 'tuple 188'] box.space.vinyl:select{189} - -- [189, tuple 189] - +- [189, 'tuple 189'] swap servers switch replica to master box.cfg{replication=''} @@ -3188,164 +2428,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{190, "tuple 190"} - -- [190, tuple 190] - +- [190, 'tuple 190'] box.space.memtx:insert{191, "tuple 191"} - -- [191, tuple 191] - +- [191, 'tuple 191'] box.space.memtx:insert{192, "tuple 192"} - -- [192, tuple 192] - +- [192, 'tuple 192'] box.space.memtx:insert{193, "tuple 193"} - -- [193, tuple 193] - +- [193, 'tuple 193'] box.space.memtx:insert{194, "tuple 194"} - -- [194, tuple 194] - +- [194, 'tuple 194'] box.space.vinyl:insert{190, "tuple 190"} - -- [190, tuple 190] - +- [190, 'tuple 190'] box.space.vinyl:insert{191, "tuple 191"} - -- [191, tuple 191] - +- [191, 'tuple 191'] box.space.vinyl:insert{192, "tuple 192"} - -- [192, tuple 192] - +- [192, 'tuple 192'] box.space.vinyl:insert{193, "tuple 193"} - -- [193, tuple 193] - +- [193, 'tuple 193'] box.space.vinyl:insert{194, "tuple 194"} - -- [194, tuple 194] - +- [194, 'tuple 194'] box.space.memtx:select{190} - -- [190, tuple 190] - +- [190, 'tuple 190'] box.space.memtx:select{191} - -- [191, tuple 191] - +- [191, 'tuple 191'] box.space.memtx:select{192} - -- [192, tuple 192] - +- [192, 'tuple 192'] box.space.memtx:select{193} - -- [193, tuple 193] - +- [193, 'tuple 193'] box.space.memtx:select{194} - -- [194, tuple 194] - +- [194, 'tuple 194'] box.space.vinyl:select{190} - -- [190, tuple 190] - +- [190, 'tuple 190'] box.space.vinyl:select{191} - -- [191, tuple 191] - +- [191, 'tuple 191'] box.space.vinyl:select{192} - -- [192, tuple 192] - +- [192, 'tuple 192'] box.space.vinyl:select{193} - -- [193, tuple 193] - +- [193, 'tuple 193'] box.space.vinyl:select{194} - -- [194, tuple 194] - +- [194, 'tuple 194'] box.space.memtx:insert{195, "tuple 195"} - -- [195, tuple 195] - +- [195, 'tuple 195'] box.space.memtx:insert{196, "tuple 196"} - -- [196, tuple 196] - +- [196, 'tuple 196'] box.space.memtx:insert{197, "tuple 197"} - -- [197, tuple 197] - +- [197, 'tuple 197'] box.space.memtx:insert{198, "tuple 198"} - -- [198, tuple 198] - +- [198, 'tuple 198'] box.space.memtx:insert{199, "tuple 199"} - -- [199, tuple 199] - +- [199, 'tuple 199'] box.space.vinyl:insert{195, "tuple 195"} - -- [195, tuple 195] - +- [195, 'tuple 195'] box.space.vinyl:insert{196, "tuple 196"} - -- [196, tuple 196] - +- [196, 'tuple 196'] box.space.vinyl:insert{197, "tuple 197"} - -- [197, tuple 197] - +- [197, 'tuple 197'] box.space.vinyl:insert{198, "tuple 198"} - -- [198, tuple 198] - +- [198, 'tuple 198'] box.space.vinyl:insert{199, "tuple 199"} - -- [199, tuple 199] - +- [199, 'tuple 199'] box.space.memtx:select{195} - -- [195, tuple 195] - +- [195, 'tuple 195'] box.space.memtx:select{196} - -- [196, tuple 196] - +- [196, 'tuple 196'] box.space.memtx:select{197} - -- [197, tuple 197] - +- [197, 'tuple 197'] box.space.memtx:select{198} - -- [198, tuple 198] - +- [198, 'tuple 198'] box.space.memtx:select{199} - -- [199, tuple 199] - +- [199, 'tuple 199'] box.space.vinyl:select{195} - -- [195, tuple 195] - +- [195, 'tuple 195'] box.space.vinyl:select{196} - -- [196, tuple 196] - +- [196, 'tuple 196'] box.space.vinyl:select{197} - -- [197, tuple 197] - +- [197, 'tuple 197'] box.space.vinyl:select{198} - -- [198, tuple 198] - +- [198, 'tuple 198'] box.space.vinyl:select{199} - -- [199, tuple 199] - +- [199, 'tuple 199'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -3355,164 +2555,124 @@ switch replica to replica test 10 iteration box.space.memtx:insert{200, "tuple 200"} - -- [200, tuple 200] - +- [200, 'tuple 200'] box.space.memtx:insert{201, "tuple 201"} - -- [201, tuple 201] - +- [201, 'tuple 201'] box.space.memtx:insert{202, "tuple 202"} - -- [202, tuple 202] - +- [202, 'tuple 202'] box.space.memtx:insert{203, "tuple 203"} - -- [203, tuple 203] - +- [203, 'tuple 203'] box.space.memtx:insert{204, "tuple 204"} - -- [204, tuple 204] - +- [204, 'tuple 204'] box.space.vinyl:insert{200, "tuple 200"} - -- [200, tuple 200] - +- [200, 'tuple 200'] box.space.vinyl:insert{201, "tuple 201"} - -- [201, tuple 201] - +- [201, 'tuple 201'] box.space.vinyl:insert{202, "tuple 202"} - -- [202, tuple 202] - +- [202, 'tuple 202'] box.space.vinyl:insert{203, "tuple 203"} - -- [203, tuple 203] - +- [203, 'tuple 203'] box.space.vinyl:insert{204, "tuple 204"} - -- [204, tuple 204] - +- [204, 'tuple 204'] box.space.memtx:select{200} - -- [200, tuple 200] - +- [200, 'tuple 200'] box.space.memtx:select{201} - -- [201, tuple 201] - +- [201, 'tuple 201'] box.space.memtx:select{202} - -- [202, tuple 202] - +- [202, 'tuple 202'] box.space.memtx:select{203} - -- [203, tuple 203] - +- [203, 'tuple 203'] box.space.memtx:select{204} - -- [204, tuple 204] - +- [204, 'tuple 204'] box.space.vinyl:select{200} - -- [200, tuple 200] - +- [200, 'tuple 200'] box.space.vinyl:select{201} - -- [201, tuple 201] - +- [201, 'tuple 201'] box.space.vinyl:select{202} - -- [202, tuple 202] - +- [202, 'tuple 202'] box.space.vinyl:select{203} - -- [203, tuple 203] - +- [203, 'tuple 203'] box.space.vinyl:select{204} - -- [204, tuple 204] - +- [204, 'tuple 204'] box.space.memtx:insert{205, "tuple 205"} - -- [205, tuple 205] - +- [205, 'tuple 205'] box.space.memtx:insert{206, "tuple 206"} - -- [206, tuple 206] - +- [206, 'tuple 206'] box.space.memtx:insert{207, "tuple 207"} - -- [207, tuple 207] - +- [207, 'tuple 207'] box.space.memtx:insert{208, "tuple 208"} - -- [208, tuple 208] - +- [208, 'tuple 208'] box.space.memtx:insert{209, "tuple 209"} - -- [209, tuple 209] - +- [209, 'tuple 209'] box.space.vinyl:insert{205, "tuple 205"} - -- [205, tuple 205] - +- [205, 'tuple 205'] box.space.vinyl:insert{206, "tuple 206"} - -- [206, tuple 206] - +- [206, 'tuple 206'] box.space.vinyl:insert{207, "tuple 207"} - -- [207, tuple 207] - +- [207, 'tuple 207'] box.space.vinyl:insert{208, "tuple 208"} - -- [208, tuple 208] - +- [208, 'tuple 208'] box.space.vinyl:insert{209, "tuple 209"} - -- [209, tuple 209] - +- [209, 'tuple 209'] box.space.memtx:select{205} - -- [205, tuple 205] - +- [205, 'tuple 205'] box.space.memtx:select{206} - -- [206, tuple 206] - +- [206, 'tuple 206'] box.space.memtx:select{207} - -- [207, tuple 207] - +- [207, 'tuple 207'] box.space.memtx:select{208} - -- [208, tuple 208] - +- [208, 'tuple 208'] box.space.memtx:select{209} - -- [209, tuple 209] - +- [209, 'tuple 209'] box.space.vinyl:select{205} - -- [205, tuple 205] - +- [205, 'tuple 205'] box.space.vinyl:select{206} - -- [206, tuple 206] - +- [206, 'tuple 206'] box.space.vinyl:select{207} - -- [207, tuple 207] - +- [207, 'tuple 207'] box.space.vinyl:select{208} - -- [208, tuple 208] - +- [208, 'tuple 208'] box.space.vinyl:select{209} - -- [209, tuple 209] - +- [209, 'tuple 209'] swap servers switch replica to master box.cfg{replication=''} @@ -3521,164 +2681,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{210, "tuple 210"} - -- [210, tuple 210] - +- [210, 'tuple 210'] box.space.memtx:insert{211, "tuple 211"} - -- [211, tuple 211] - +- [211, 'tuple 211'] box.space.memtx:insert{212, "tuple 212"} - -- [212, tuple 212] - +- [212, 'tuple 212'] box.space.memtx:insert{213, "tuple 213"} - -- [213, tuple 213] - +- [213, 'tuple 213'] box.space.memtx:insert{214, "tuple 214"} - -- [214, tuple 214] - +- [214, 'tuple 214'] box.space.vinyl:insert{210, "tuple 210"} - -- [210, tuple 210] - +- [210, 'tuple 210'] box.space.vinyl:insert{211, "tuple 211"} - -- [211, tuple 211] - +- [211, 'tuple 211'] box.space.vinyl:insert{212, "tuple 212"} - -- [212, tuple 212] - +- [212, 'tuple 212'] box.space.vinyl:insert{213, "tuple 213"} - -- [213, tuple 213] - +- [213, 'tuple 213'] box.space.vinyl:insert{214, "tuple 214"} - -- [214, tuple 214] - +- [214, 'tuple 214'] box.space.memtx:select{210} - -- [210, tuple 210] - +- [210, 'tuple 210'] box.space.memtx:select{211} - -- [211, tuple 211] - +- [211, 'tuple 211'] box.space.memtx:select{212} - -- [212, tuple 212] - +- [212, 'tuple 212'] box.space.memtx:select{213} - -- [213, tuple 213] - +- [213, 'tuple 213'] box.space.memtx:select{214} - -- [214, tuple 214] - +- [214, 'tuple 214'] box.space.vinyl:select{210} - -- [210, tuple 210] - +- [210, 'tuple 210'] box.space.vinyl:select{211} - -- [211, tuple 211] - +- [211, 'tuple 211'] box.space.vinyl:select{212} - -- [212, tuple 212] - +- [212, 'tuple 212'] box.space.vinyl:select{213} - -- [213, tuple 213] - +- [213, 'tuple 213'] box.space.vinyl:select{214} - -- [214, tuple 214] - +- [214, 'tuple 214'] box.space.memtx:insert{215, "tuple 215"} - -- [215, tuple 215] - +- [215, 'tuple 215'] box.space.memtx:insert{216, "tuple 216"} - -- [216, tuple 216] - +- [216, 'tuple 216'] box.space.memtx:insert{217, "tuple 217"} - -- [217, tuple 217] - +- [217, 'tuple 217'] box.space.memtx:insert{218, "tuple 218"} - -- [218, tuple 218] - +- [218, 'tuple 218'] box.space.memtx:insert{219, "tuple 219"} - -- [219, tuple 219] - +- [219, 'tuple 219'] box.space.vinyl:insert{215, "tuple 215"} - -- [215, tuple 215] - +- [215, 'tuple 215'] box.space.vinyl:insert{216, "tuple 216"} - -- [216, tuple 216] - +- [216, 'tuple 216'] box.space.vinyl:insert{217, "tuple 217"} - -- [217, tuple 217] - +- [217, 'tuple 217'] box.space.vinyl:insert{218, "tuple 218"} - -- [218, tuple 218] - +- [218, 'tuple 218'] box.space.vinyl:insert{219, "tuple 219"} - -- [219, tuple 219] - +- [219, 'tuple 219'] box.space.memtx:select{215} - -- [215, tuple 215] - +- [215, 'tuple 215'] box.space.memtx:select{216} - -- [216, tuple 216] - +- [216, 'tuple 216'] box.space.memtx:select{217} - -- [217, tuple 217] - +- [217, 'tuple 217'] box.space.memtx:select{218} - -- [218, tuple 218] - +- [218, 'tuple 218'] box.space.memtx:select{219} - -- [219, tuple 219] - +- [219, 'tuple 219'] box.space.vinyl:select{215} - -- [215, tuple 215] - +- [215, 'tuple 215'] box.space.vinyl:select{216} - -- [216, tuple 216] - +- [216, 'tuple 216'] box.space.vinyl:select{217} - -- [217, tuple 217] - +- [217, 'tuple 217'] box.space.vinyl:select{218} - -- [218, tuple 218] - +- [218, 'tuple 218'] box.space.vinyl:select{219} - -- [219, tuple 219] - +- [219, 'tuple 219'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -3688,164 +2808,124 @@ switch replica to replica test 11 iteration box.space.memtx:insert{220, "tuple 220"} - -- [220, tuple 220] - +- [220, 'tuple 220'] box.space.memtx:insert{221, "tuple 221"} - -- [221, tuple 221] - +- [221, 'tuple 221'] box.space.memtx:insert{222, "tuple 222"} - -- [222, tuple 222] - +- [222, 'tuple 222'] box.space.memtx:insert{223, "tuple 223"} - -- [223, tuple 223] - +- [223, 'tuple 223'] box.space.memtx:insert{224, "tuple 224"} - -- [224, tuple 224] - +- [224, 'tuple 224'] box.space.vinyl:insert{220, "tuple 220"} - -- [220, tuple 220] - +- [220, 'tuple 220'] box.space.vinyl:insert{221, "tuple 221"} - -- [221, tuple 221] - +- [221, 'tuple 221'] box.space.vinyl:insert{222, "tuple 222"} - -- [222, tuple 222] - +- [222, 'tuple 222'] box.space.vinyl:insert{223, "tuple 223"} - -- [223, tuple 223] - +- [223, 'tuple 223'] box.space.vinyl:insert{224, "tuple 224"} - -- [224, tuple 224] - +- [224, 'tuple 224'] box.space.memtx:select{220} - -- [220, tuple 220] - +- [220, 'tuple 220'] box.space.memtx:select{221} - -- [221, tuple 221] - +- [221, 'tuple 221'] box.space.memtx:select{222} - -- [222, tuple 222] - +- [222, 'tuple 222'] box.space.memtx:select{223} - -- [223, tuple 223] - +- [223, 'tuple 223'] box.space.memtx:select{224} - -- [224, tuple 224] - +- [224, 'tuple 224'] box.space.vinyl:select{220} - -- [220, tuple 220] - +- [220, 'tuple 220'] box.space.vinyl:select{221} - -- [221, tuple 221] - +- [221, 'tuple 221'] box.space.vinyl:select{222} - -- [222, tuple 222] - +- [222, 'tuple 222'] box.space.vinyl:select{223} - -- [223, tuple 223] - +- [223, 'tuple 223'] box.space.vinyl:select{224} - -- [224, tuple 224] - +- [224, 'tuple 224'] box.space.memtx:insert{225, "tuple 225"} - -- [225, tuple 225] - +- [225, 'tuple 225'] box.space.memtx:insert{226, "tuple 226"} - -- [226, tuple 226] - +- [226, 'tuple 226'] box.space.memtx:insert{227, "tuple 227"} - -- [227, tuple 227] - +- [227, 'tuple 227'] box.space.memtx:insert{228, "tuple 228"} - -- [228, tuple 228] - +- [228, 'tuple 228'] box.space.memtx:insert{229, "tuple 229"} - -- [229, tuple 229] - +- [229, 'tuple 229'] box.space.vinyl:insert{225, "tuple 225"} - -- [225, tuple 225] - +- [225, 'tuple 225'] box.space.vinyl:insert{226, "tuple 226"} - -- [226, tuple 226] - +- [226, 'tuple 226'] box.space.vinyl:insert{227, "tuple 227"} - -- [227, tuple 227] - +- [227, 'tuple 227'] box.space.vinyl:insert{228, "tuple 228"} - -- [228, tuple 228] - +- [228, 'tuple 228'] box.space.vinyl:insert{229, "tuple 229"} - -- [229, tuple 229] - +- [229, 'tuple 229'] box.space.memtx:select{225} - -- [225, tuple 225] - +- [225, 'tuple 225'] box.space.memtx:select{226} - -- [226, tuple 226] - +- [226, 'tuple 226'] box.space.memtx:select{227} - -- [227, tuple 227] - +- [227, 'tuple 227'] box.space.memtx:select{228} - -- [228, tuple 228] - +- [228, 'tuple 228'] box.space.memtx:select{229} - -- [229, tuple 229] - +- [229, 'tuple 229'] box.space.vinyl:select{225} - -- [225, tuple 225] - +- [225, 'tuple 225'] box.space.vinyl:select{226} - -- [226, tuple 226] - +- [226, 'tuple 226'] box.space.vinyl:select{227} - -- [227, tuple 227] - +- [227, 'tuple 227'] box.space.vinyl:select{228} - -- [228, tuple 228] - +- [228, 'tuple 228'] box.space.vinyl:select{229} - -- [229, tuple 229] - +- [229, 'tuple 229'] swap servers switch replica to master box.cfg{replication=''} @@ -3854,164 +2934,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{230, "tuple 230"} - -- [230, tuple 230] - +- [230, 'tuple 230'] box.space.memtx:insert{231, "tuple 231"} - -- [231, tuple 231] - +- [231, 'tuple 231'] box.space.memtx:insert{232, "tuple 232"} - -- [232, tuple 232] - +- [232, 'tuple 232'] box.space.memtx:insert{233, "tuple 233"} - -- [233, tuple 233] - +- [233, 'tuple 233'] box.space.memtx:insert{234, "tuple 234"} - -- [234, tuple 234] - +- [234, 'tuple 234'] box.space.vinyl:insert{230, "tuple 230"} - -- [230, tuple 230] - +- [230, 'tuple 230'] box.space.vinyl:insert{231, "tuple 231"} - -- [231, tuple 231] - +- [231, 'tuple 231'] box.space.vinyl:insert{232, "tuple 232"} - -- [232, tuple 232] - +- [232, 'tuple 232'] box.space.vinyl:insert{233, "tuple 233"} - -- [233, tuple 233] - +- [233, 'tuple 233'] box.space.vinyl:insert{234, "tuple 234"} - -- [234, tuple 234] - +- [234, 'tuple 234'] box.space.memtx:select{230} - -- [230, tuple 230] - +- [230, 'tuple 230'] box.space.memtx:select{231} - -- [231, tuple 231] - +- [231, 'tuple 231'] box.space.memtx:select{232} - -- [232, tuple 232] - +- [232, 'tuple 232'] box.space.memtx:select{233} - -- [233, tuple 233] - +- [233, 'tuple 233'] box.space.memtx:select{234} - -- [234, tuple 234] - +- [234, 'tuple 234'] box.space.vinyl:select{230} - -- [230, tuple 230] - +- [230, 'tuple 230'] box.space.vinyl:select{231} - -- [231, tuple 231] - +- [231, 'tuple 231'] box.space.vinyl:select{232} - -- [232, tuple 232] - +- [232, 'tuple 232'] box.space.vinyl:select{233} - -- [233, tuple 233] - +- [233, 'tuple 233'] box.space.vinyl:select{234} - -- [234, tuple 234] - +- [234, 'tuple 234'] box.space.memtx:insert{235, "tuple 235"} - -- [235, tuple 235] - +- [235, 'tuple 235'] box.space.memtx:insert{236, "tuple 236"} - -- [236, tuple 236] - +- [236, 'tuple 236'] box.space.memtx:insert{237, "tuple 237"} - -- [237, tuple 237] - +- [237, 'tuple 237'] box.space.memtx:insert{238, "tuple 238"} - -- [238, tuple 238] - +- [238, 'tuple 238'] box.space.memtx:insert{239, "tuple 239"} - -- [239, tuple 239] - +- [239, 'tuple 239'] box.space.vinyl:insert{235, "tuple 235"} - -- [235, tuple 235] - +- [235, 'tuple 235'] box.space.vinyl:insert{236, "tuple 236"} - -- [236, tuple 236] - +- [236, 'tuple 236'] box.space.vinyl:insert{237, "tuple 237"} - -- [237, tuple 237] - +- [237, 'tuple 237'] box.space.vinyl:insert{238, "tuple 238"} - -- [238, tuple 238] - +- [238, 'tuple 238'] box.space.vinyl:insert{239, "tuple 239"} - -- [239, tuple 239] - +- [239, 'tuple 239'] box.space.memtx:select{235} - -- [235, tuple 235] - +- [235, 'tuple 235'] box.space.memtx:select{236} - -- [236, tuple 236] - +- [236, 'tuple 236'] box.space.memtx:select{237} - -- [237, tuple 237] - +- [237, 'tuple 237'] box.space.memtx:select{238} - -- [238, tuple 238] - +- [238, 'tuple 238'] box.space.memtx:select{239} - -- [239, tuple 239] - +- [239, 'tuple 239'] box.space.vinyl:select{235} - -- [235, tuple 235] - +- [235, 'tuple 235'] box.space.vinyl:select{236} - -- [236, tuple 236] - +- [236, 'tuple 236'] box.space.vinyl:select{237} - -- [237, tuple 237] - +- [237, 'tuple 237'] box.space.vinyl:select{238} - -- [238, tuple 238] - +- [238, 'tuple 238'] box.space.vinyl:select{239} - -- [239, tuple 239] - +- [239, 'tuple 239'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -4021,164 +3061,124 @@ switch replica to replica test 12 iteration box.space.memtx:insert{240, "tuple 240"} - -- [240, tuple 240] - +- [240, 'tuple 240'] box.space.memtx:insert{241, "tuple 241"} - -- [241, tuple 241] - +- [241, 'tuple 241'] box.space.memtx:insert{242, "tuple 242"} - -- [242, tuple 242] - +- [242, 'tuple 242'] box.space.memtx:insert{243, "tuple 243"} - -- [243, tuple 243] - +- [243, 'tuple 243'] box.space.memtx:insert{244, "tuple 244"} - -- [244, tuple 244] - +- [244, 'tuple 244'] box.space.vinyl:insert{240, "tuple 240"} - -- [240, tuple 240] - +- [240, 'tuple 240'] box.space.vinyl:insert{241, "tuple 241"} - -- [241, tuple 241] - +- [241, 'tuple 241'] box.space.vinyl:insert{242, "tuple 242"} - -- [242, tuple 242] - +- [242, 'tuple 242'] box.space.vinyl:insert{243, "tuple 243"} - -- [243, tuple 243] - +- [243, 'tuple 243'] box.space.vinyl:insert{244, "tuple 244"} - -- [244, tuple 244] - +- [244, 'tuple 244'] box.space.memtx:select{240} - -- [240, tuple 240] - +- [240, 'tuple 240'] box.space.memtx:select{241} - -- [241, tuple 241] - +- [241, 'tuple 241'] box.space.memtx:select{242} - -- [242, tuple 242] - +- [242, 'tuple 242'] box.space.memtx:select{243} - -- [243, tuple 243] - +- [243, 'tuple 243'] box.space.memtx:select{244} - -- [244, tuple 244] - +- [244, 'tuple 244'] box.space.vinyl:select{240} - -- [240, tuple 240] - +- [240, 'tuple 240'] box.space.vinyl:select{241} - -- [241, tuple 241] - +- [241, 'tuple 241'] box.space.vinyl:select{242} - -- [242, tuple 242] - +- [242, 'tuple 242'] box.space.vinyl:select{243} - -- [243, tuple 243] - +- [243, 'tuple 243'] box.space.vinyl:select{244} - -- [244, tuple 244] - +- [244, 'tuple 244'] box.space.memtx:insert{245, "tuple 245"} - -- [245, tuple 245] - +- [245, 'tuple 245'] box.space.memtx:insert{246, "tuple 246"} - -- [246, tuple 246] - +- [246, 'tuple 246'] box.space.memtx:insert{247, "tuple 247"} - -- [247, tuple 247] - +- [247, 'tuple 247'] box.space.memtx:insert{248, "tuple 248"} - -- [248, tuple 248] - +- [248, 'tuple 248'] box.space.memtx:insert{249, "tuple 249"} - -- [249, tuple 249] - +- [249, 'tuple 249'] box.space.vinyl:insert{245, "tuple 245"} - -- [245, tuple 245] - +- [245, 'tuple 245'] box.space.vinyl:insert{246, "tuple 246"} - -- [246, tuple 246] - +- [246, 'tuple 246'] box.space.vinyl:insert{247, "tuple 247"} - -- [247, tuple 247] - +- [247, 'tuple 247'] box.space.vinyl:insert{248, "tuple 248"} - -- [248, tuple 248] - +- [248, 'tuple 248'] box.space.vinyl:insert{249, "tuple 249"} - -- [249, tuple 249] - +- [249, 'tuple 249'] box.space.memtx:select{245} - -- [245, tuple 245] - +- [245, 'tuple 245'] box.space.memtx:select{246} - -- [246, tuple 246] - +- [246, 'tuple 246'] box.space.memtx:select{247} - -- [247, tuple 247] - +- [247, 'tuple 247'] box.space.memtx:select{248} - -- [248, tuple 248] - +- [248, 'tuple 248'] box.space.memtx:select{249} - -- [249, tuple 249] - +- [249, 'tuple 249'] box.space.vinyl:select{245} - -- [245, tuple 245] - +- [245, 'tuple 245'] box.space.vinyl:select{246} - -- [246, tuple 246] - +- [246, 'tuple 246'] box.space.vinyl:select{247} - -- [247, tuple 247] - +- [247, 'tuple 247'] box.space.vinyl:select{248} - -- [248, tuple 248] - +- [248, 'tuple 248'] box.space.vinyl:select{249} - -- [249, tuple 249] - +- [249, 'tuple 249'] swap servers switch replica to master box.cfg{replication=''} @@ -4187,164 +3187,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{250, "tuple 250"} - -- [250, tuple 250] - +- [250, 'tuple 250'] box.space.memtx:insert{251, "tuple 251"} - -- [251, tuple 251] - +- [251, 'tuple 251'] box.space.memtx:insert{252, "tuple 252"} - -- [252, tuple 252] - +- [252, 'tuple 252'] box.space.memtx:insert{253, "tuple 253"} - -- [253, tuple 253] - +- [253, 'tuple 253'] box.space.memtx:insert{254, "tuple 254"} - -- [254, tuple 254] - +- [254, 'tuple 254'] box.space.vinyl:insert{250, "tuple 250"} - -- [250, tuple 250] - +- [250, 'tuple 250'] box.space.vinyl:insert{251, "tuple 251"} - -- [251, tuple 251] - +- [251, 'tuple 251'] box.space.vinyl:insert{252, "tuple 252"} - -- [252, tuple 252] - +- [252, 'tuple 252'] box.space.vinyl:insert{253, "tuple 253"} - -- [253, tuple 253] - +- [253, 'tuple 253'] box.space.vinyl:insert{254, "tuple 254"} - -- [254, tuple 254] - +- [254, 'tuple 254'] box.space.memtx:select{250} - -- [250, tuple 250] - +- [250, 'tuple 250'] box.space.memtx:select{251} - -- [251, tuple 251] - +- [251, 'tuple 251'] box.space.memtx:select{252} - -- [252, tuple 252] - +- [252, 'tuple 252'] box.space.memtx:select{253} - -- [253, tuple 253] - +- [253, 'tuple 253'] box.space.memtx:select{254} - -- [254, tuple 254] - +- [254, 'tuple 254'] box.space.vinyl:select{250} - -- [250, tuple 250] - +- [250, 'tuple 250'] box.space.vinyl:select{251} - -- [251, tuple 251] - +- [251, 'tuple 251'] box.space.vinyl:select{252} - -- [252, tuple 252] - +- [252, 'tuple 252'] box.space.vinyl:select{253} - -- [253, tuple 253] - +- [253, 'tuple 253'] box.space.vinyl:select{254} - -- [254, tuple 254] - +- [254, 'tuple 254'] box.space.memtx:insert{255, "tuple 255"} - -- [255, tuple 255] - +- [255, 'tuple 255'] box.space.memtx:insert{256, "tuple 256"} - -- [256, tuple 256] - +- [256, 'tuple 256'] box.space.memtx:insert{257, "tuple 257"} - -- [257, tuple 257] - +- [257, 'tuple 257'] box.space.memtx:insert{258, "tuple 258"} - -- [258, tuple 258] - +- [258, 'tuple 258'] box.space.memtx:insert{259, "tuple 259"} - -- [259, tuple 259] - +- [259, 'tuple 259'] box.space.vinyl:insert{255, "tuple 255"} - -- [255, tuple 255] - +- [255, 'tuple 255'] box.space.vinyl:insert{256, "tuple 256"} - -- [256, tuple 256] - +- [256, 'tuple 256'] box.space.vinyl:insert{257, "tuple 257"} - -- [257, tuple 257] - +- [257, 'tuple 257'] box.space.vinyl:insert{258, "tuple 258"} - -- [258, tuple 258] - +- [258, 'tuple 258'] box.space.vinyl:insert{259, "tuple 259"} - -- [259, tuple 259] - +- [259, 'tuple 259'] box.space.memtx:select{255} - -- [255, tuple 255] - +- [255, 'tuple 255'] box.space.memtx:select{256} - -- [256, tuple 256] - +- [256, 'tuple 256'] box.space.memtx:select{257} - -- [257, tuple 257] - +- [257, 'tuple 257'] box.space.memtx:select{258} - -- [258, tuple 258] - +- [258, 'tuple 258'] box.space.memtx:select{259} - -- [259, tuple 259] - +- [259, 'tuple 259'] box.space.vinyl:select{255} - -- [255, tuple 255] - +- [255, 'tuple 255'] box.space.vinyl:select{256} - -- [256, tuple 256] - +- [256, 'tuple 256'] box.space.vinyl:select{257} - -- [257, tuple 257] - +- [257, 'tuple 257'] box.space.vinyl:select{258} - -- [258, tuple 258] - +- [258, 'tuple 258'] box.space.vinyl:select{259} - -- [259, tuple 259] - +- [259, 'tuple 259'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -4354,164 +3314,124 @@ switch replica to replica test 13 iteration box.space.memtx:insert{260, "tuple 260"} - -- [260, tuple 260] - +- [260, 'tuple 260'] box.space.memtx:insert{261, "tuple 261"} - -- [261, tuple 261] - +- [261, 'tuple 261'] box.space.memtx:insert{262, "tuple 262"} - -- [262, tuple 262] - +- [262, 'tuple 262'] box.space.memtx:insert{263, "tuple 263"} - -- [263, tuple 263] - +- [263, 'tuple 263'] box.space.memtx:insert{264, "tuple 264"} - -- [264, tuple 264] - +- [264, 'tuple 264'] box.space.vinyl:insert{260, "tuple 260"} - -- [260, tuple 260] - +- [260, 'tuple 260'] box.space.vinyl:insert{261, "tuple 261"} - -- [261, tuple 261] - +- [261, 'tuple 261'] box.space.vinyl:insert{262, "tuple 262"} - -- [262, tuple 262] - +- [262, 'tuple 262'] box.space.vinyl:insert{263, "tuple 263"} - -- [263, tuple 263] - +- [263, 'tuple 263'] box.space.vinyl:insert{264, "tuple 264"} - -- [264, tuple 264] - +- [264, 'tuple 264'] box.space.memtx:select{260} - -- [260, tuple 260] - +- [260, 'tuple 260'] box.space.memtx:select{261} - -- [261, tuple 261] - +- [261, 'tuple 261'] box.space.memtx:select{262} - -- [262, tuple 262] - +- [262, 'tuple 262'] box.space.memtx:select{263} - -- [263, tuple 263] - +- [263, 'tuple 263'] box.space.memtx:select{264} - -- [264, tuple 264] - +- [264, 'tuple 264'] box.space.vinyl:select{260} - -- [260, tuple 260] - +- [260, 'tuple 260'] box.space.vinyl:select{261} - -- [261, tuple 261] - +- [261, 'tuple 261'] box.space.vinyl:select{262} - -- [262, tuple 262] - +- [262, 'tuple 262'] box.space.vinyl:select{263} - -- [263, tuple 263] - +- [263, 'tuple 263'] box.space.vinyl:select{264} - -- [264, tuple 264] - +- [264, 'tuple 264'] box.space.memtx:insert{265, "tuple 265"} - -- [265, tuple 265] - +- [265, 'tuple 265'] box.space.memtx:insert{266, "tuple 266"} - -- [266, tuple 266] - +- [266, 'tuple 266'] box.space.memtx:insert{267, "tuple 267"} - -- [267, tuple 267] - +- [267, 'tuple 267'] box.space.memtx:insert{268, "tuple 268"} - -- [268, tuple 268] - +- [268, 'tuple 268'] box.space.memtx:insert{269, "tuple 269"} - -- [269, tuple 269] - +- [269, 'tuple 269'] box.space.vinyl:insert{265, "tuple 265"} - -- [265, tuple 265] - +- [265, 'tuple 265'] box.space.vinyl:insert{266, "tuple 266"} - -- [266, tuple 266] - +- [266, 'tuple 266'] box.space.vinyl:insert{267, "tuple 267"} - -- [267, tuple 267] - +- [267, 'tuple 267'] box.space.vinyl:insert{268, "tuple 268"} - -- [268, tuple 268] - +- [268, 'tuple 268'] box.space.vinyl:insert{269, "tuple 269"} - -- [269, tuple 269] - +- [269, 'tuple 269'] box.space.memtx:select{265} - -- [265, tuple 265] - +- [265, 'tuple 265'] box.space.memtx:select{266} - -- [266, tuple 266] - +- [266, 'tuple 266'] box.space.memtx:select{267} - -- [267, tuple 267] - +- [267, 'tuple 267'] box.space.memtx:select{268} - -- [268, tuple 268] - +- [268, 'tuple 268'] box.space.memtx:select{269} - -- [269, tuple 269] - +- [269, 'tuple 269'] box.space.vinyl:select{265} - -- [265, tuple 265] - +- [265, 'tuple 265'] box.space.vinyl:select{266} - -- [266, tuple 266] - +- [266, 'tuple 266'] box.space.vinyl:select{267} - -- [267, tuple 267] - +- [267, 'tuple 267'] box.space.vinyl:select{268} - -- [268, tuple 268] - +- [268, 'tuple 268'] box.space.vinyl:select{269} - -- [269, tuple 269] - +- [269, 'tuple 269'] swap servers switch replica to master box.cfg{replication=''} @@ -4520,164 +3440,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{270, "tuple 270"} - -- [270, tuple 270] - +- [270, 'tuple 270'] box.space.memtx:insert{271, "tuple 271"} - -- [271, tuple 271] - +- [271, 'tuple 271'] box.space.memtx:insert{272, "tuple 272"} - -- [272, tuple 272] - +- [272, 'tuple 272'] box.space.memtx:insert{273, "tuple 273"} - -- [273, tuple 273] - +- [273, 'tuple 273'] box.space.memtx:insert{274, "tuple 274"} - -- [274, tuple 274] - +- [274, 'tuple 274'] box.space.vinyl:insert{270, "tuple 270"} - -- [270, tuple 270] - +- [270, 'tuple 270'] box.space.vinyl:insert{271, "tuple 271"} - -- [271, tuple 271] - +- [271, 'tuple 271'] box.space.vinyl:insert{272, "tuple 272"} - -- [272, tuple 272] - +- [272, 'tuple 272'] box.space.vinyl:insert{273, "tuple 273"} - -- [273, tuple 273] - +- [273, 'tuple 273'] box.space.vinyl:insert{274, "tuple 274"} - -- [274, tuple 274] - +- [274, 'tuple 274'] box.space.memtx:select{270} - -- [270, tuple 270] - +- [270, 'tuple 270'] box.space.memtx:select{271} - -- [271, tuple 271] - +- [271, 'tuple 271'] box.space.memtx:select{272} - -- [272, tuple 272] - +- [272, 'tuple 272'] box.space.memtx:select{273} - -- [273, tuple 273] - +- [273, 'tuple 273'] box.space.memtx:select{274} - -- [274, tuple 274] - +- [274, 'tuple 274'] box.space.vinyl:select{270} - -- [270, tuple 270] - +- [270, 'tuple 270'] box.space.vinyl:select{271} - -- [271, tuple 271] - +- [271, 'tuple 271'] box.space.vinyl:select{272} - -- [272, tuple 272] - +- [272, 'tuple 272'] box.space.vinyl:select{273} - -- [273, tuple 273] - +- [273, 'tuple 273'] box.space.vinyl:select{274} - -- [274, tuple 274] - +- [274, 'tuple 274'] box.space.memtx:insert{275, "tuple 275"} - -- [275, tuple 275] - +- [275, 'tuple 275'] box.space.memtx:insert{276, "tuple 276"} - -- [276, tuple 276] - +- [276, 'tuple 276'] box.space.memtx:insert{277, "tuple 277"} - -- [277, tuple 277] - +- [277, 'tuple 277'] box.space.memtx:insert{278, "tuple 278"} - -- [278, tuple 278] - +- [278, 'tuple 278'] box.space.memtx:insert{279, "tuple 279"} - -- [279, tuple 279] - +- [279, 'tuple 279'] box.space.vinyl:insert{275, "tuple 275"} - -- [275, tuple 275] - +- [275, 'tuple 275'] box.space.vinyl:insert{276, "tuple 276"} - -- [276, tuple 276] - +- [276, 'tuple 276'] box.space.vinyl:insert{277, "tuple 277"} - -- [277, tuple 277] - +- [277, 'tuple 277'] box.space.vinyl:insert{278, "tuple 278"} - -- [278, tuple 278] - +- [278, 'tuple 278'] box.space.vinyl:insert{279, "tuple 279"} - -- [279, tuple 279] - +- [279, 'tuple 279'] box.space.memtx:select{275} - -- [275, tuple 275] - +- [275, 'tuple 275'] box.space.memtx:select{276} - -- [276, tuple 276] - +- [276, 'tuple 276'] box.space.memtx:select{277} - -- [277, tuple 277] - +- [277, 'tuple 277'] box.space.memtx:select{278} - -- [278, tuple 278] - +- [278, 'tuple 278'] box.space.memtx:select{279} - -- [279, tuple 279] - +- [279, 'tuple 279'] box.space.vinyl:select{275} - -- [275, tuple 275] - +- [275, 'tuple 275'] box.space.vinyl:select{276} - -- [276, tuple 276] - +- [276, 'tuple 276'] box.space.vinyl:select{277} - -- [277, tuple 277] - +- [277, 'tuple 277'] box.space.vinyl:select{278} - -- [278, tuple 278] - +- [278, 'tuple 278'] box.space.vinyl:select{279} - -- [279, tuple 279] - +- [279, 'tuple 279'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -4687,164 +3567,124 @@ switch replica to replica test 14 iteration box.space.memtx:insert{280, "tuple 280"} - -- [280, tuple 280] - +- [280, 'tuple 280'] box.space.memtx:insert{281, "tuple 281"} - -- [281, tuple 281] - +- [281, 'tuple 281'] box.space.memtx:insert{282, "tuple 282"} - -- [282, tuple 282] - +- [282, 'tuple 282'] box.space.memtx:insert{283, "tuple 283"} - -- [283, tuple 283] - +- [283, 'tuple 283'] box.space.memtx:insert{284, "tuple 284"} - -- [284, tuple 284] - +- [284, 'tuple 284'] box.space.vinyl:insert{280, "tuple 280"} - -- [280, tuple 280] - +- [280, 'tuple 280'] box.space.vinyl:insert{281, "tuple 281"} - -- [281, tuple 281] - +- [281, 'tuple 281'] box.space.vinyl:insert{282, "tuple 282"} - -- [282, tuple 282] - +- [282, 'tuple 282'] box.space.vinyl:insert{283, "tuple 283"} - -- [283, tuple 283] - +- [283, 'tuple 283'] box.space.vinyl:insert{284, "tuple 284"} - -- [284, tuple 284] - +- [284, 'tuple 284'] box.space.memtx:select{280} - -- [280, tuple 280] - +- [280, 'tuple 280'] box.space.memtx:select{281} - -- [281, tuple 281] - +- [281, 'tuple 281'] box.space.memtx:select{282} - -- [282, tuple 282] - +- [282, 'tuple 282'] box.space.memtx:select{283} - -- [283, tuple 283] - +- [283, 'tuple 283'] box.space.memtx:select{284} - -- [284, tuple 284] - +- [284, 'tuple 284'] box.space.vinyl:select{280} - -- [280, tuple 280] - +- [280, 'tuple 280'] box.space.vinyl:select{281} - -- [281, tuple 281] - +- [281, 'tuple 281'] box.space.vinyl:select{282} - -- [282, tuple 282] - +- [282, 'tuple 282'] box.space.vinyl:select{283} - -- [283, tuple 283] - +- [283, 'tuple 283'] box.space.vinyl:select{284} - -- [284, tuple 284] - +- [284, 'tuple 284'] box.space.memtx:insert{285, "tuple 285"} - -- [285, tuple 285] - +- [285, 'tuple 285'] box.space.memtx:insert{286, "tuple 286"} - -- [286, tuple 286] - +- [286, 'tuple 286'] box.space.memtx:insert{287, "tuple 287"} - -- [287, tuple 287] - +- [287, 'tuple 287'] box.space.memtx:insert{288, "tuple 288"} - -- [288, tuple 288] - +- [288, 'tuple 288'] box.space.memtx:insert{289, "tuple 289"} - -- [289, tuple 289] - +- [289, 'tuple 289'] box.space.vinyl:insert{285, "tuple 285"} - -- [285, tuple 285] - +- [285, 'tuple 285'] box.space.vinyl:insert{286, "tuple 286"} - -- [286, tuple 286] - +- [286, 'tuple 286'] box.space.vinyl:insert{287, "tuple 287"} - -- [287, tuple 287] - +- [287, 'tuple 287'] box.space.vinyl:insert{288, "tuple 288"} - -- [288, tuple 288] - +- [288, 'tuple 288'] box.space.vinyl:insert{289, "tuple 289"} - -- [289, tuple 289] - +- [289, 'tuple 289'] box.space.memtx:select{285} - -- [285, tuple 285] - +- [285, 'tuple 285'] box.space.memtx:select{286} - -- [286, tuple 286] - +- [286, 'tuple 286'] box.space.memtx:select{287} - -- [287, tuple 287] - +- [287, 'tuple 287'] box.space.memtx:select{288} - -- [288, tuple 288] - +- [288, 'tuple 288'] box.space.memtx:select{289} - -- [289, tuple 289] - +- [289, 'tuple 289'] box.space.vinyl:select{285} - -- [285, tuple 285] - +- [285, 'tuple 285'] box.space.vinyl:select{286} - -- [286, tuple 286] - +- [286, 'tuple 286'] box.space.vinyl:select{287} - -- [287, tuple 287] - +- [287, 'tuple 287'] box.space.vinyl:select{288} - -- [288, tuple 288] - +- [288, 'tuple 288'] box.space.vinyl:select{289} - -- [289, tuple 289] - +- [289, 'tuple 289'] swap servers switch replica to master box.cfg{replication=''} @@ -4853,164 +3693,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{290, "tuple 290"} - -- [290, tuple 290] - +- [290, 'tuple 290'] box.space.memtx:insert{291, "tuple 291"} - -- [291, tuple 291] - +- [291, 'tuple 291'] box.space.memtx:insert{292, "tuple 292"} - -- [292, tuple 292] - +- [292, 'tuple 292'] box.space.memtx:insert{293, "tuple 293"} - -- [293, tuple 293] - +- [293, 'tuple 293'] box.space.memtx:insert{294, "tuple 294"} - -- [294, tuple 294] - +- [294, 'tuple 294'] box.space.vinyl:insert{290, "tuple 290"} - -- [290, tuple 290] - +- [290, 'tuple 290'] box.space.vinyl:insert{291, "tuple 291"} - -- [291, tuple 291] - +- [291, 'tuple 291'] box.space.vinyl:insert{292, "tuple 292"} - -- [292, tuple 292] - +- [292, 'tuple 292'] box.space.vinyl:insert{293, "tuple 293"} - -- [293, tuple 293] - +- [293, 'tuple 293'] box.space.vinyl:insert{294, "tuple 294"} - -- [294, tuple 294] - +- [294, 'tuple 294'] box.space.memtx:select{290} - -- [290, tuple 290] - +- [290, 'tuple 290'] box.space.memtx:select{291} - -- [291, tuple 291] - +- [291, 'tuple 291'] box.space.memtx:select{292} - -- [292, tuple 292] - +- [292, 'tuple 292'] box.space.memtx:select{293} - -- [293, tuple 293] - +- [293, 'tuple 293'] box.space.memtx:select{294} - -- [294, tuple 294] - +- [294, 'tuple 294'] box.space.vinyl:select{290} - -- [290, tuple 290] - +- [290, 'tuple 290'] box.space.vinyl:select{291} - -- [291, tuple 291] - +- [291, 'tuple 291'] box.space.vinyl:select{292} - -- [292, tuple 292] - +- [292, 'tuple 292'] box.space.vinyl:select{293} - -- [293, tuple 293] - +- [293, 'tuple 293'] box.space.vinyl:select{294} - -- [294, tuple 294] - +- [294, 'tuple 294'] box.space.memtx:insert{295, "tuple 295"} - -- [295, tuple 295] - +- [295, 'tuple 295'] box.space.memtx:insert{296, "tuple 296"} - -- [296, tuple 296] - +- [296, 'tuple 296'] box.space.memtx:insert{297, "tuple 297"} - -- [297, tuple 297] - +- [297, 'tuple 297'] box.space.memtx:insert{298, "tuple 298"} - -- [298, tuple 298] - +- [298, 'tuple 298'] box.space.memtx:insert{299, "tuple 299"} - -- [299, tuple 299] - +- [299, 'tuple 299'] box.space.vinyl:insert{295, "tuple 295"} - -- [295, tuple 295] - +- [295, 'tuple 295'] box.space.vinyl:insert{296, "tuple 296"} - -- [296, tuple 296] - +- [296, 'tuple 296'] box.space.vinyl:insert{297, "tuple 297"} - -- [297, tuple 297] - +- [297, 'tuple 297'] box.space.vinyl:insert{298, "tuple 298"} - -- [298, tuple 298] - +- [298, 'tuple 298'] box.space.vinyl:insert{299, "tuple 299"} - -- [299, tuple 299] - +- [299, 'tuple 299'] box.space.memtx:select{295} - -- [295, tuple 295] - +- [295, 'tuple 295'] box.space.memtx:select{296} - -- [296, tuple 296] - +- [296, 'tuple 296'] box.space.memtx:select{297} - -- [297, tuple 297] - +- [297, 'tuple 297'] box.space.memtx:select{298} - -- [298, tuple 298] - +- [298, 'tuple 298'] box.space.memtx:select{299} - -- [299, tuple 299] - +- [299, 'tuple 299'] box.space.vinyl:select{295} - -- [295, tuple 295] - +- [295, 'tuple 295'] box.space.vinyl:select{296} - -- [296, tuple 296] - +- [296, 'tuple 296'] box.space.vinyl:select{297} - -- [297, tuple 297] - +- [297, 'tuple 297'] box.space.vinyl:select{298} - -- [298, tuple 298] - +- [298, 'tuple 298'] box.space.vinyl:select{299} - -- [299, tuple 299] - +- [299, 'tuple 299'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -5020,164 +3820,124 @@ switch replica to replica test 15 iteration box.space.memtx:insert{300, "tuple 300"} - -- [300, tuple 300] - +- [300, 'tuple 300'] box.space.memtx:insert{301, "tuple 301"} - -- [301, tuple 301] - +- [301, 'tuple 301'] box.space.memtx:insert{302, "tuple 302"} - -- [302, tuple 302] - +- [302, 'tuple 302'] box.space.memtx:insert{303, "tuple 303"} - -- [303, tuple 303] - +- [303, 'tuple 303'] box.space.memtx:insert{304, "tuple 304"} - -- [304, tuple 304] - +- [304, 'tuple 304'] box.space.vinyl:insert{300, "tuple 300"} - -- [300, tuple 300] - +- [300, 'tuple 300'] box.space.vinyl:insert{301, "tuple 301"} - -- [301, tuple 301] - +- [301, 'tuple 301'] box.space.vinyl:insert{302, "tuple 302"} - -- [302, tuple 302] - +- [302, 'tuple 302'] box.space.vinyl:insert{303, "tuple 303"} - -- [303, tuple 303] - +- [303, 'tuple 303'] box.space.vinyl:insert{304, "tuple 304"} - -- [304, tuple 304] - +- [304, 'tuple 304'] box.space.memtx:select{300} - -- [300, tuple 300] - +- [300, 'tuple 300'] box.space.memtx:select{301} - -- [301, tuple 301] - +- [301, 'tuple 301'] box.space.memtx:select{302} - -- [302, tuple 302] - +- [302, 'tuple 302'] box.space.memtx:select{303} - -- [303, tuple 303] - +- [303, 'tuple 303'] box.space.memtx:select{304} - -- [304, tuple 304] - +- [304, 'tuple 304'] box.space.vinyl:select{300} - -- [300, tuple 300] - +- [300, 'tuple 300'] box.space.vinyl:select{301} - -- [301, tuple 301] - +- [301, 'tuple 301'] box.space.vinyl:select{302} - -- [302, tuple 302] - +- [302, 'tuple 302'] box.space.vinyl:select{303} - -- [303, tuple 303] - +- [303, 'tuple 303'] box.space.vinyl:select{304} - -- [304, tuple 304] - +- [304, 'tuple 304'] box.space.memtx:insert{305, "tuple 305"} - -- [305, tuple 305] - +- [305, 'tuple 305'] box.space.memtx:insert{306, "tuple 306"} - -- [306, tuple 306] - +- [306, 'tuple 306'] box.space.memtx:insert{307, "tuple 307"} - -- [307, tuple 307] - +- [307, 'tuple 307'] box.space.memtx:insert{308, "tuple 308"} - -- [308, tuple 308] - +- [308, 'tuple 308'] box.space.memtx:insert{309, "tuple 309"} - -- [309, tuple 309] - +- [309, 'tuple 309'] box.space.vinyl:insert{305, "tuple 305"} - -- [305, tuple 305] - +- [305, 'tuple 305'] box.space.vinyl:insert{306, "tuple 306"} - -- [306, tuple 306] - +- [306, 'tuple 306'] box.space.vinyl:insert{307, "tuple 307"} - -- [307, tuple 307] - +- [307, 'tuple 307'] box.space.vinyl:insert{308, "tuple 308"} - -- [308, tuple 308] - +- [308, 'tuple 308'] box.space.vinyl:insert{309, "tuple 309"} - -- [309, tuple 309] - +- [309, 'tuple 309'] box.space.memtx:select{305} - -- [305, tuple 305] - +- [305, 'tuple 305'] box.space.memtx:select{306} - -- [306, tuple 306] - +- [306, 'tuple 306'] box.space.memtx:select{307} - -- [307, tuple 307] - +- [307, 'tuple 307'] box.space.memtx:select{308} - -- [308, tuple 308] - +- [308, 'tuple 308'] box.space.memtx:select{309} - -- [309, tuple 309] - +- [309, 'tuple 309'] box.space.vinyl:select{305} - -- [305, tuple 305] - +- [305, 'tuple 305'] box.space.vinyl:select{306} - -- [306, tuple 306] - +- [306, 'tuple 306'] box.space.vinyl:select{307} - -- [307, tuple 307] - +- [307, 'tuple 307'] box.space.vinyl:select{308} - -- [308, tuple 308] - +- [308, 'tuple 308'] box.space.vinyl:select{309} - -- [309, tuple 309] - +- [309, 'tuple 309'] swap servers switch replica to master box.cfg{replication=''} @@ -5186,164 +3946,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{310, "tuple 310"} - -- [310, tuple 310] - +- [310, 'tuple 310'] box.space.memtx:insert{311, "tuple 311"} - -- [311, tuple 311] - +- [311, 'tuple 311'] box.space.memtx:insert{312, "tuple 312"} - -- [312, tuple 312] - +- [312, 'tuple 312'] box.space.memtx:insert{313, "tuple 313"} - -- [313, tuple 313] - +- [313, 'tuple 313'] box.space.memtx:insert{314, "tuple 314"} - -- [314, tuple 314] - +- [314, 'tuple 314'] box.space.vinyl:insert{310, "tuple 310"} - -- [310, tuple 310] - +- [310, 'tuple 310'] box.space.vinyl:insert{311, "tuple 311"} - -- [311, tuple 311] - +- [311, 'tuple 311'] box.space.vinyl:insert{312, "tuple 312"} - -- [312, tuple 312] - +- [312, 'tuple 312'] box.space.vinyl:insert{313, "tuple 313"} - -- [313, tuple 313] - +- [313, 'tuple 313'] box.space.vinyl:insert{314, "tuple 314"} - -- [314, tuple 314] - +- [314, 'tuple 314'] box.space.memtx:select{310} - -- [310, tuple 310] - +- [310, 'tuple 310'] box.space.memtx:select{311} - -- [311, tuple 311] - +- [311, 'tuple 311'] box.space.memtx:select{312} - -- [312, tuple 312] - +- [312, 'tuple 312'] box.space.memtx:select{313} - -- [313, tuple 313] - +- [313, 'tuple 313'] box.space.memtx:select{314} - -- [314, tuple 314] - +- [314, 'tuple 314'] box.space.vinyl:select{310} - -- [310, tuple 310] - +- [310, 'tuple 310'] box.space.vinyl:select{311} - -- [311, tuple 311] - +- [311, 'tuple 311'] box.space.vinyl:select{312} - -- [312, tuple 312] - +- [312, 'tuple 312'] box.space.vinyl:select{313} - -- [313, tuple 313] - +- [313, 'tuple 313'] box.space.vinyl:select{314} - -- [314, tuple 314] - +- [314, 'tuple 314'] box.space.memtx:insert{315, "tuple 315"} - -- [315, tuple 315] - +- [315, 'tuple 315'] box.space.memtx:insert{316, "tuple 316"} - -- [316, tuple 316] - +- [316, 'tuple 316'] box.space.memtx:insert{317, "tuple 317"} - -- [317, tuple 317] - +- [317, 'tuple 317'] box.space.memtx:insert{318, "tuple 318"} - -- [318, tuple 318] - +- [318, 'tuple 318'] box.space.memtx:insert{319, "tuple 319"} - -- [319, tuple 319] - +- [319, 'tuple 319'] box.space.vinyl:insert{315, "tuple 315"} - -- [315, tuple 315] - +- [315, 'tuple 315'] box.space.vinyl:insert{316, "tuple 316"} - -- [316, tuple 316] - +- [316, 'tuple 316'] box.space.vinyl:insert{317, "tuple 317"} - -- [317, tuple 317] - +- [317, 'tuple 317'] box.space.vinyl:insert{318, "tuple 318"} - -- [318, tuple 318] - +- [318, 'tuple 318'] box.space.vinyl:insert{319, "tuple 319"} - -- [319, tuple 319] - +- [319, 'tuple 319'] box.space.memtx:select{315} - -- [315, tuple 315] - +- [315, 'tuple 315'] box.space.memtx:select{316} - -- [316, tuple 316] - +- [316, 'tuple 316'] box.space.memtx:select{317} - -- [317, tuple 317] - +- [317, 'tuple 317'] box.space.memtx:select{318} - -- [318, tuple 318] - +- [318, 'tuple 318'] box.space.memtx:select{319} - -- [319, tuple 319] - +- [319, 'tuple 319'] box.space.vinyl:select{315} - -- [315, tuple 315] - +- [315, 'tuple 315'] box.space.vinyl:select{316} - -- [316, tuple 316] - +- [316, 'tuple 316'] box.space.vinyl:select{317} - -- [317, tuple 317] - +- [317, 'tuple 317'] box.space.vinyl:select{318} - -- [318, tuple 318] - +- [318, 'tuple 318'] box.space.vinyl:select{319} - -- [319, tuple 319] - +- [319, 'tuple 319'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -5353,164 +4073,124 @@ switch replica to replica test 16 iteration box.space.memtx:insert{320, "tuple 320"} - -- [320, tuple 320] - +- [320, 'tuple 320'] box.space.memtx:insert{321, "tuple 321"} - -- [321, tuple 321] - +- [321, 'tuple 321'] box.space.memtx:insert{322, "tuple 322"} - -- [322, tuple 322] - +- [322, 'tuple 322'] box.space.memtx:insert{323, "tuple 323"} - -- [323, tuple 323] - +- [323, 'tuple 323'] box.space.memtx:insert{324, "tuple 324"} - -- [324, tuple 324] - +- [324, 'tuple 324'] box.space.vinyl:insert{320, "tuple 320"} - -- [320, tuple 320] - +- [320, 'tuple 320'] box.space.vinyl:insert{321, "tuple 321"} - -- [321, tuple 321] - +- [321, 'tuple 321'] box.space.vinyl:insert{322, "tuple 322"} - -- [322, tuple 322] - +- [322, 'tuple 322'] box.space.vinyl:insert{323, "tuple 323"} - -- [323, tuple 323] - +- [323, 'tuple 323'] box.space.vinyl:insert{324, "tuple 324"} - -- [324, tuple 324] - +- [324, 'tuple 324'] box.space.memtx:select{320} - -- [320, tuple 320] - +- [320, 'tuple 320'] box.space.memtx:select{321} - -- [321, tuple 321] - +- [321, 'tuple 321'] box.space.memtx:select{322} - -- [322, tuple 322] - +- [322, 'tuple 322'] box.space.memtx:select{323} - -- [323, tuple 323] - +- [323, 'tuple 323'] box.space.memtx:select{324} - -- [324, tuple 324] - +- [324, 'tuple 324'] box.space.vinyl:select{320} - -- [320, tuple 320] - +- [320, 'tuple 320'] box.space.vinyl:select{321} - -- [321, tuple 321] - +- [321, 'tuple 321'] box.space.vinyl:select{322} - -- [322, tuple 322] - +- [322, 'tuple 322'] box.space.vinyl:select{323} - -- [323, tuple 323] - +- [323, 'tuple 323'] box.space.vinyl:select{324} - -- [324, tuple 324] - +- [324, 'tuple 324'] box.space.memtx:insert{325, "tuple 325"} - -- [325, tuple 325] - +- [325, 'tuple 325'] box.space.memtx:insert{326, "tuple 326"} - -- [326, tuple 326] - +- [326, 'tuple 326'] box.space.memtx:insert{327, "tuple 327"} - -- [327, tuple 327] - +- [327, 'tuple 327'] box.space.memtx:insert{328, "tuple 328"} - -- [328, tuple 328] - +- [328, 'tuple 328'] box.space.memtx:insert{329, "tuple 329"} - -- [329, tuple 329] - +- [329, 'tuple 329'] box.space.vinyl:insert{325, "tuple 325"} - -- [325, tuple 325] - +- [325, 'tuple 325'] box.space.vinyl:insert{326, "tuple 326"} - -- [326, tuple 326] - +- [326, 'tuple 326'] box.space.vinyl:insert{327, "tuple 327"} - -- [327, tuple 327] - +- [327, 'tuple 327'] box.space.vinyl:insert{328, "tuple 328"} - -- [328, tuple 328] - +- [328, 'tuple 328'] box.space.vinyl:insert{329, "tuple 329"} - -- [329, tuple 329] - +- [329, 'tuple 329'] box.space.memtx:select{325} - -- [325, tuple 325] - +- [325, 'tuple 325'] box.space.memtx:select{326} - -- [326, tuple 326] - +- [326, 'tuple 326'] box.space.memtx:select{327} - -- [327, tuple 327] - +- [327, 'tuple 327'] box.space.memtx:select{328} - -- [328, tuple 328] - +- [328, 'tuple 328'] box.space.memtx:select{329} - -- [329, tuple 329] - +- [329, 'tuple 329'] box.space.vinyl:select{325} - -- [325, tuple 325] - +- [325, 'tuple 325'] box.space.vinyl:select{326} - -- [326, tuple 326] - +- [326, 'tuple 326'] box.space.vinyl:select{327} - -- [327, tuple 327] - +- [327, 'tuple 327'] box.space.vinyl:select{328} - -- [328, tuple 328] - +- [328, 'tuple 328'] box.space.vinyl:select{329} - -- [329, tuple 329] - +- [329, 'tuple 329'] swap servers switch replica to master box.cfg{replication=''} @@ -5519,164 +4199,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{330, "tuple 330"} - -- [330, tuple 330] - +- [330, 'tuple 330'] box.space.memtx:insert{331, "tuple 331"} - -- [331, tuple 331] - +- [331, 'tuple 331'] box.space.memtx:insert{332, "tuple 332"} - -- [332, tuple 332] - +- [332, 'tuple 332'] box.space.memtx:insert{333, "tuple 333"} - -- [333, tuple 333] - +- [333, 'tuple 333'] box.space.memtx:insert{334, "tuple 334"} - -- [334, tuple 334] - +- [334, 'tuple 334'] box.space.vinyl:insert{330, "tuple 330"} - -- [330, tuple 330] - +- [330, 'tuple 330'] box.space.vinyl:insert{331, "tuple 331"} - -- [331, tuple 331] - +- [331, 'tuple 331'] box.space.vinyl:insert{332, "tuple 332"} - -- [332, tuple 332] - +- [332, 'tuple 332'] box.space.vinyl:insert{333, "tuple 333"} - -- [333, tuple 333] - +- [333, 'tuple 333'] box.space.vinyl:insert{334, "tuple 334"} - -- [334, tuple 334] - +- [334, 'tuple 334'] box.space.memtx:select{330} - -- [330, tuple 330] - +- [330, 'tuple 330'] box.space.memtx:select{331} - -- [331, tuple 331] - +- [331, 'tuple 331'] box.space.memtx:select{332} - -- [332, tuple 332] - +- [332, 'tuple 332'] box.space.memtx:select{333} - -- [333, tuple 333] - +- [333, 'tuple 333'] box.space.memtx:select{334} - -- [334, tuple 334] - +- [334, 'tuple 334'] box.space.vinyl:select{330} - -- [330, tuple 330] - +- [330, 'tuple 330'] box.space.vinyl:select{331} - -- [331, tuple 331] - +- [331, 'tuple 331'] box.space.vinyl:select{332} - -- [332, tuple 332] - +- [332, 'tuple 332'] box.space.vinyl:select{333} - -- [333, tuple 333] - +- [333, 'tuple 333'] box.space.vinyl:select{334} - -- [334, tuple 334] - +- [334, 'tuple 334'] box.space.memtx:insert{335, "tuple 335"} - -- [335, tuple 335] - +- [335, 'tuple 335'] box.space.memtx:insert{336, "tuple 336"} - -- [336, tuple 336] - +- [336, 'tuple 336'] box.space.memtx:insert{337, "tuple 337"} - -- [337, tuple 337] - +- [337, 'tuple 337'] box.space.memtx:insert{338, "tuple 338"} - -- [338, tuple 338] - +- [338, 'tuple 338'] box.space.memtx:insert{339, "tuple 339"} - -- [339, tuple 339] - +- [339, 'tuple 339'] box.space.vinyl:insert{335, "tuple 335"} - -- [335, tuple 335] - +- [335, 'tuple 335'] box.space.vinyl:insert{336, "tuple 336"} - -- [336, tuple 336] - +- [336, 'tuple 336'] box.space.vinyl:insert{337, "tuple 337"} - -- [337, tuple 337] - +- [337, 'tuple 337'] box.space.vinyl:insert{338, "tuple 338"} - -- [338, tuple 338] - +- [338, 'tuple 338'] box.space.vinyl:insert{339, "tuple 339"} - -- [339, tuple 339] - +- [339, 'tuple 339'] box.space.memtx:select{335} - -- [335, tuple 335] - +- [335, 'tuple 335'] box.space.memtx:select{336} - -- [336, tuple 336] - +- [336, 'tuple 336'] box.space.memtx:select{337} - -- [337, tuple 337] - +- [337, 'tuple 337'] box.space.memtx:select{338} - -- [338, tuple 338] - +- [338, 'tuple 338'] box.space.memtx:select{339} - -- [339, tuple 339] - +- [339, 'tuple 339'] box.space.vinyl:select{335} - -- [335, tuple 335] - +- [335, 'tuple 335'] box.space.vinyl:select{336} - -- [336, tuple 336] - +- [336, 'tuple 336'] box.space.vinyl:select{337} - -- [337, tuple 337] - +- [337, 'tuple 337'] box.space.vinyl:select{338} - -- [338, tuple 338] - +- [338, 'tuple 338'] box.space.vinyl:select{339} - -- [339, tuple 339] - +- [339, 'tuple 339'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -5686,164 +4326,124 @@ switch replica to replica test 17 iteration box.space.memtx:insert{340, "tuple 340"} - -- [340, tuple 340] - +- [340, 'tuple 340'] box.space.memtx:insert{341, "tuple 341"} - -- [341, tuple 341] - +- [341, 'tuple 341'] box.space.memtx:insert{342, "tuple 342"} - -- [342, tuple 342] - +- [342, 'tuple 342'] box.space.memtx:insert{343, "tuple 343"} - -- [343, tuple 343] - +- [343, 'tuple 343'] box.space.memtx:insert{344, "tuple 344"} - -- [344, tuple 344] - +- [344, 'tuple 344'] box.space.vinyl:insert{340, "tuple 340"} - -- [340, tuple 340] - +- [340, 'tuple 340'] box.space.vinyl:insert{341, "tuple 341"} - -- [341, tuple 341] - +- [341, 'tuple 341'] box.space.vinyl:insert{342, "tuple 342"} - -- [342, tuple 342] - +- [342, 'tuple 342'] box.space.vinyl:insert{343, "tuple 343"} - -- [343, tuple 343] - +- [343, 'tuple 343'] box.space.vinyl:insert{344, "tuple 344"} - -- [344, tuple 344] - +- [344, 'tuple 344'] box.space.memtx:select{340} - -- [340, tuple 340] - +- [340, 'tuple 340'] box.space.memtx:select{341} - -- [341, tuple 341] - +- [341, 'tuple 341'] box.space.memtx:select{342} - -- [342, tuple 342] - +- [342, 'tuple 342'] box.space.memtx:select{343} - -- [343, tuple 343] - +- [343, 'tuple 343'] box.space.memtx:select{344} - -- [344, tuple 344] - +- [344, 'tuple 344'] box.space.vinyl:select{340} - -- [340, tuple 340] - +- [340, 'tuple 340'] box.space.vinyl:select{341} - -- [341, tuple 341] - +- [341, 'tuple 341'] box.space.vinyl:select{342} - -- [342, tuple 342] - +- [342, 'tuple 342'] box.space.vinyl:select{343} - -- [343, tuple 343] - +- [343, 'tuple 343'] box.space.vinyl:select{344} - -- [344, tuple 344] - +- [344, 'tuple 344'] box.space.memtx:insert{345, "tuple 345"} - -- [345, tuple 345] - +- [345, 'tuple 345'] box.space.memtx:insert{346, "tuple 346"} - -- [346, tuple 346] - +- [346, 'tuple 346'] box.space.memtx:insert{347, "tuple 347"} - -- [347, tuple 347] - +- [347, 'tuple 347'] box.space.memtx:insert{348, "tuple 348"} - -- [348, tuple 348] - +- [348, 'tuple 348'] box.space.memtx:insert{349, "tuple 349"} - -- [349, tuple 349] - +- [349, 'tuple 349'] box.space.vinyl:insert{345, "tuple 345"} - -- [345, tuple 345] - +- [345, 'tuple 345'] box.space.vinyl:insert{346, "tuple 346"} - -- [346, tuple 346] - +- [346, 'tuple 346'] box.space.vinyl:insert{347, "tuple 347"} - -- [347, tuple 347] - +- [347, 'tuple 347'] box.space.vinyl:insert{348, "tuple 348"} - -- [348, tuple 348] - +- [348, 'tuple 348'] box.space.vinyl:insert{349, "tuple 349"} - -- [349, tuple 349] - +- [349, 'tuple 349'] box.space.memtx:select{345} - -- [345, tuple 345] - +- [345, 'tuple 345'] box.space.memtx:select{346} - -- [346, tuple 346] - +- [346, 'tuple 346'] box.space.memtx:select{347} - -- [347, tuple 347] - +- [347, 'tuple 347'] box.space.memtx:select{348} - -- [348, tuple 348] - +- [348, 'tuple 348'] box.space.memtx:select{349} - -- [349, tuple 349] - +- [349, 'tuple 349'] box.space.vinyl:select{345} - -- [345, tuple 345] - +- [345, 'tuple 345'] box.space.vinyl:select{346} - -- [346, tuple 346] - +- [346, 'tuple 346'] box.space.vinyl:select{347} - -- [347, tuple 347] - +- [347, 'tuple 347'] box.space.vinyl:select{348} - -- [348, tuple 348] - +- [348, 'tuple 348'] box.space.vinyl:select{349} - -- [349, tuple 349] - +- [349, 'tuple 349'] swap servers switch replica to master box.cfg{replication=''} @@ -5852,164 +4452,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{350, "tuple 350"} - -- [350, tuple 350] - +- [350, 'tuple 350'] box.space.memtx:insert{351, "tuple 351"} - -- [351, tuple 351] - +- [351, 'tuple 351'] box.space.memtx:insert{352, "tuple 352"} - -- [352, tuple 352] - +- [352, 'tuple 352'] box.space.memtx:insert{353, "tuple 353"} - -- [353, tuple 353] - +- [353, 'tuple 353'] box.space.memtx:insert{354, "tuple 354"} - -- [354, tuple 354] - +- [354, 'tuple 354'] box.space.vinyl:insert{350, "tuple 350"} - -- [350, tuple 350] - +- [350, 'tuple 350'] box.space.vinyl:insert{351, "tuple 351"} - -- [351, tuple 351] - +- [351, 'tuple 351'] box.space.vinyl:insert{352, "tuple 352"} - -- [352, tuple 352] - +- [352, 'tuple 352'] box.space.vinyl:insert{353, "tuple 353"} - -- [353, tuple 353] - +- [353, 'tuple 353'] box.space.vinyl:insert{354, "tuple 354"} - -- [354, tuple 354] - +- [354, 'tuple 354'] box.space.memtx:select{350} - -- [350, tuple 350] - +- [350, 'tuple 350'] box.space.memtx:select{351} - -- [351, tuple 351] - +- [351, 'tuple 351'] box.space.memtx:select{352} - -- [352, tuple 352] - +- [352, 'tuple 352'] box.space.memtx:select{353} - -- [353, tuple 353] - +- [353, 'tuple 353'] box.space.memtx:select{354} - -- [354, tuple 354] - +- [354, 'tuple 354'] box.space.vinyl:select{350} - -- [350, tuple 350] - +- [350, 'tuple 350'] box.space.vinyl:select{351} - -- [351, tuple 351] - +- [351, 'tuple 351'] box.space.vinyl:select{352} - -- [352, tuple 352] - +- [352, 'tuple 352'] box.space.vinyl:select{353} - -- [353, tuple 353] - +- [353, 'tuple 353'] box.space.vinyl:select{354} - -- [354, tuple 354] - +- [354, 'tuple 354'] box.space.memtx:insert{355, "tuple 355"} - -- [355, tuple 355] - +- [355, 'tuple 355'] box.space.memtx:insert{356, "tuple 356"} - -- [356, tuple 356] - +- [356, 'tuple 356'] box.space.memtx:insert{357, "tuple 357"} - -- [357, tuple 357] - +- [357, 'tuple 357'] box.space.memtx:insert{358, "tuple 358"} - -- [358, tuple 358] - +- [358, 'tuple 358'] box.space.memtx:insert{359, "tuple 359"} - -- [359, tuple 359] - +- [359, 'tuple 359'] box.space.vinyl:insert{355, "tuple 355"} - -- [355, tuple 355] - +- [355, 'tuple 355'] box.space.vinyl:insert{356, "tuple 356"} - -- [356, tuple 356] - +- [356, 'tuple 356'] box.space.vinyl:insert{357, "tuple 357"} - -- [357, tuple 357] - +- [357, 'tuple 357'] box.space.vinyl:insert{358, "tuple 358"} - -- [358, tuple 358] - +- [358, 'tuple 358'] box.space.vinyl:insert{359, "tuple 359"} - -- [359, tuple 359] - +- [359, 'tuple 359'] box.space.memtx:select{355} - -- [355, tuple 355] - +- [355, 'tuple 355'] box.space.memtx:select{356} - -- [356, tuple 356] - +- [356, 'tuple 356'] box.space.memtx:select{357} - -- [357, tuple 357] - +- [357, 'tuple 357'] box.space.memtx:select{358} - -- [358, tuple 358] - +- [358, 'tuple 358'] box.space.memtx:select{359} - -- [359, tuple 359] - +- [359, 'tuple 359'] box.space.vinyl:select{355} - -- [355, tuple 355] - +- [355, 'tuple 355'] box.space.vinyl:select{356} - -- [356, tuple 356] - +- [356, 'tuple 356'] box.space.vinyl:select{357} - -- [357, tuple 357] - +- [357, 'tuple 357'] box.space.vinyl:select{358} - -- [358, tuple 358] - +- [358, 'tuple 358'] box.space.vinyl:select{359} - -- [359, tuple 359] - +- [359, 'tuple 359'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -6019,164 +4579,124 @@ switch replica to replica test 18 iteration box.space.memtx:insert{360, "tuple 360"} - -- [360, tuple 360] - +- [360, 'tuple 360'] box.space.memtx:insert{361, "tuple 361"} - -- [361, tuple 361] - +- [361, 'tuple 361'] box.space.memtx:insert{362, "tuple 362"} - -- [362, tuple 362] - +- [362, 'tuple 362'] box.space.memtx:insert{363, "tuple 363"} - -- [363, tuple 363] - +- [363, 'tuple 363'] box.space.memtx:insert{364, "tuple 364"} - -- [364, tuple 364] - +- [364, 'tuple 364'] box.space.vinyl:insert{360, "tuple 360"} - -- [360, tuple 360] - +- [360, 'tuple 360'] box.space.vinyl:insert{361, "tuple 361"} - -- [361, tuple 361] - +- [361, 'tuple 361'] box.space.vinyl:insert{362, "tuple 362"} - -- [362, tuple 362] - +- [362, 'tuple 362'] box.space.vinyl:insert{363, "tuple 363"} - -- [363, tuple 363] - +- [363, 'tuple 363'] box.space.vinyl:insert{364, "tuple 364"} - -- [364, tuple 364] - +- [364, 'tuple 364'] box.space.memtx:select{360} - -- [360, tuple 360] - +- [360, 'tuple 360'] box.space.memtx:select{361} - -- [361, tuple 361] - +- [361, 'tuple 361'] box.space.memtx:select{362} - -- [362, tuple 362] - +- [362, 'tuple 362'] box.space.memtx:select{363} - -- [363, tuple 363] - +- [363, 'tuple 363'] box.space.memtx:select{364} - -- [364, tuple 364] - +- [364, 'tuple 364'] box.space.vinyl:select{360} - -- [360, tuple 360] - +- [360, 'tuple 360'] box.space.vinyl:select{361} - -- [361, tuple 361] - +- [361, 'tuple 361'] box.space.vinyl:select{362} - -- [362, tuple 362] - +- [362, 'tuple 362'] box.space.vinyl:select{363} - -- [363, tuple 363] - +- [363, 'tuple 363'] box.space.vinyl:select{364} - -- [364, tuple 364] - +- [364, 'tuple 364'] box.space.memtx:insert{365, "tuple 365"} - -- [365, tuple 365] - +- [365, 'tuple 365'] box.space.memtx:insert{366, "tuple 366"} - -- [366, tuple 366] - +- [366, 'tuple 366'] box.space.memtx:insert{367, "tuple 367"} - -- [367, tuple 367] - +- [367, 'tuple 367'] box.space.memtx:insert{368, "tuple 368"} - -- [368, tuple 368] - +- [368, 'tuple 368'] box.space.memtx:insert{369, "tuple 369"} - -- [369, tuple 369] - +- [369, 'tuple 369'] box.space.vinyl:insert{365, "tuple 365"} - -- [365, tuple 365] - +- [365, 'tuple 365'] box.space.vinyl:insert{366, "tuple 366"} - -- [366, tuple 366] - +- [366, 'tuple 366'] box.space.vinyl:insert{367, "tuple 367"} - -- [367, tuple 367] - +- [367, 'tuple 367'] box.space.vinyl:insert{368, "tuple 368"} - -- [368, tuple 368] - +- [368, 'tuple 368'] box.space.vinyl:insert{369, "tuple 369"} - -- [369, tuple 369] - +- [369, 'tuple 369'] box.space.memtx:select{365} - -- [365, tuple 365] - +- [365, 'tuple 365'] box.space.memtx:select{366} - -- [366, tuple 366] - +- [366, 'tuple 366'] box.space.memtx:select{367} - -- [367, tuple 367] - +- [367, 'tuple 367'] box.space.memtx:select{368} - -- [368, tuple 368] - +- [368, 'tuple 368'] box.space.memtx:select{369} - -- [369, tuple 369] - +- [369, 'tuple 369'] box.space.vinyl:select{365} - -- [365, tuple 365] - +- [365, 'tuple 365'] box.space.vinyl:select{366} - -- [366, tuple 366] - +- [366, 'tuple 366'] box.space.vinyl:select{367} - -- [367, tuple 367] - +- [367, 'tuple 367'] box.space.vinyl:select{368} - -- [368, tuple 368] - +- [368, 'tuple 368'] box.space.vinyl:select{369} - -- [369, tuple 369] - +- [369, 'tuple 369'] swap servers switch replica to master box.cfg{replication=''} @@ -6185,164 +4705,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{370, "tuple 370"} - -- [370, tuple 370] - +- [370, 'tuple 370'] box.space.memtx:insert{371, "tuple 371"} - -- [371, tuple 371] - +- [371, 'tuple 371'] box.space.memtx:insert{372, "tuple 372"} - -- [372, tuple 372] - +- [372, 'tuple 372'] box.space.memtx:insert{373, "tuple 373"} - -- [373, tuple 373] - +- [373, 'tuple 373'] box.space.memtx:insert{374, "tuple 374"} - -- [374, tuple 374] - +- [374, 'tuple 374'] box.space.vinyl:insert{370, "tuple 370"} - -- [370, tuple 370] - +- [370, 'tuple 370'] box.space.vinyl:insert{371, "tuple 371"} - -- [371, tuple 371] - +- [371, 'tuple 371'] box.space.vinyl:insert{372, "tuple 372"} - -- [372, tuple 372] - +- [372, 'tuple 372'] box.space.vinyl:insert{373, "tuple 373"} - -- [373, tuple 373] - +- [373, 'tuple 373'] box.space.vinyl:insert{374, "tuple 374"} - -- [374, tuple 374] - +- [374, 'tuple 374'] box.space.memtx:select{370} - -- [370, tuple 370] - +- [370, 'tuple 370'] box.space.memtx:select{371} - -- [371, tuple 371] - +- [371, 'tuple 371'] box.space.memtx:select{372} - -- [372, tuple 372] - +- [372, 'tuple 372'] box.space.memtx:select{373} - -- [373, tuple 373] - +- [373, 'tuple 373'] box.space.memtx:select{374} - -- [374, tuple 374] - +- [374, 'tuple 374'] box.space.vinyl:select{370} - -- [370, tuple 370] - +- [370, 'tuple 370'] box.space.vinyl:select{371} - -- [371, tuple 371] - +- [371, 'tuple 371'] box.space.vinyl:select{372} - -- [372, tuple 372] - +- [372, 'tuple 372'] box.space.vinyl:select{373} - -- [373, tuple 373] - +- [373, 'tuple 373'] box.space.vinyl:select{374} - -- [374, tuple 374] - +- [374, 'tuple 374'] box.space.memtx:insert{375, "tuple 375"} - -- [375, tuple 375] - +- [375, 'tuple 375'] box.space.memtx:insert{376, "tuple 376"} - -- [376, tuple 376] - +- [376, 'tuple 376'] box.space.memtx:insert{377, "tuple 377"} - -- [377, tuple 377] - +- [377, 'tuple 377'] box.space.memtx:insert{378, "tuple 378"} - -- [378, tuple 378] - +- [378, 'tuple 378'] box.space.memtx:insert{379, "tuple 379"} - -- [379, tuple 379] - +- [379, 'tuple 379'] box.space.vinyl:insert{375, "tuple 375"} - -- [375, tuple 375] - +- [375, 'tuple 375'] box.space.vinyl:insert{376, "tuple 376"} - -- [376, tuple 376] - +- [376, 'tuple 376'] box.space.vinyl:insert{377, "tuple 377"} - -- [377, tuple 377] - +- [377, 'tuple 377'] box.space.vinyl:insert{378, "tuple 378"} - -- [378, tuple 378] - +- [378, 'tuple 378'] box.space.vinyl:insert{379, "tuple 379"} - -- [379, tuple 379] - +- [379, 'tuple 379'] box.space.memtx:select{375} - -- [375, tuple 375] - +- [375, 'tuple 375'] box.space.memtx:select{376} - -- [376, tuple 376] - +- [376, 'tuple 376'] box.space.memtx:select{377} - -- [377, tuple 377] - +- [377, 'tuple 377'] box.space.memtx:select{378} - -- [378, tuple 378] - +- [378, 'tuple 378'] box.space.memtx:select{379} - -- [379, tuple 379] - +- [379, 'tuple 379'] box.space.vinyl:select{375} - -- [375, tuple 375] - +- [375, 'tuple 375'] box.space.vinyl:select{376} - -- [376, tuple 376] - +- [376, 'tuple 376'] box.space.vinyl:select{377} - -- [377, tuple 377] - +- [377, 'tuple 377'] box.space.vinyl:select{378} - -- [378, tuple 378] - +- [378, 'tuple 378'] box.space.vinyl:select{379} - -- [379, tuple 379] - +- [379, 'tuple 379'] rollback servers configuration switch master to master box.cfg{replication=''} @@ -6352,164 +4832,124 @@ switch replica to replica test 19 iteration box.space.memtx:insert{380, "tuple 380"} - -- [380, tuple 380] - +- [380, 'tuple 380'] box.space.memtx:insert{381, "tuple 381"} - -- [381, tuple 381] - +- [381, 'tuple 381'] box.space.memtx:insert{382, "tuple 382"} - -- [382, tuple 382] - +- [382, 'tuple 382'] box.space.memtx:insert{383, "tuple 383"} - -- [383, tuple 383] - +- [383, 'tuple 383'] box.space.memtx:insert{384, "tuple 384"} - -- [384, tuple 384] - +- [384, 'tuple 384'] box.space.vinyl:insert{380, "tuple 380"} - -- [380, tuple 380] - +- [380, 'tuple 380'] box.space.vinyl:insert{381, "tuple 381"} - -- [381, tuple 381] - +- [381, 'tuple 381'] box.space.vinyl:insert{382, "tuple 382"} - -- [382, tuple 382] - +- [382, 'tuple 382'] box.space.vinyl:insert{383, "tuple 383"} - -- [383, tuple 383] - +- [383, 'tuple 383'] box.space.vinyl:insert{384, "tuple 384"} - -- [384, tuple 384] - +- [384, 'tuple 384'] box.space.memtx:select{380} - -- [380, tuple 380] - +- [380, 'tuple 380'] box.space.memtx:select{381} - -- [381, tuple 381] - +- [381, 'tuple 381'] box.space.memtx:select{382} - -- [382, tuple 382] - +- [382, 'tuple 382'] box.space.memtx:select{383} - -- [383, tuple 383] - +- [383, 'tuple 383'] box.space.memtx:select{384} - -- [384, tuple 384] - +- [384, 'tuple 384'] box.space.vinyl:select{380} - -- [380, tuple 380] - +- [380, 'tuple 380'] box.space.vinyl:select{381} - -- [381, tuple 381] - +- [381, 'tuple 381'] box.space.vinyl:select{382} - -- [382, tuple 382] - +- [382, 'tuple 382'] box.space.vinyl:select{383} - -- [383, tuple 383] - +- [383, 'tuple 383'] box.space.vinyl:select{384} - -- [384, tuple 384] - +- [384, 'tuple 384'] box.space.memtx:insert{385, "tuple 385"} - -- [385, tuple 385] - +- [385, 'tuple 385'] box.space.memtx:insert{386, "tuple 386"} - -- [386, tuple 386] - +- [386, 'tuple 386'] box.space.memtx:insert{387, "tuple 387"} - -- [387, tuple 387] - +- [387, 'tuple 387'] box.space.memtx:insert{388, "tuple 388"} - -- [388, tuple 388] - +- [388, 'tuple 388'] box.space.memtx:insert{389, "tuple 389"} - -- [389, tuple 389] - +- [389, 'tuple 389'] box.space.vinyl:insert{385, "tuple 385"} - -- [385, tuple 385] - +- [385, 'tuple 385'] box.space.vinyl:insert{386, "tuple 386"} - -- [386, tuple 386] - +- [386, 'tuple 386'] box.space.vinyl:insert{387, "tuple 387"} - -- [387, tuple 387] - +- [387, 'tuple 387'] box.space.vinyl:insert{388, "tuple 388"} - -- [388, tuple 388] - +- [388, 'tuple 388'] box.space.vinyl:insert{389, "tuple 389"} - -- [389, tuple 389] - +- [389, 'tuple 389'] box.space.memtx:select{385} - -- [385, tuple 385] - +- [385, 'tuple 385'] box.space.memtx:select{386} - -- [386, tuple 386] - +- [386, 'tuple 386'] box.space.memtx:select{387} - -- [387, tuple 387] - +- [387, 'tuple 387'] box.space.memtx:select{388} - -- [388, tuple 388] - +- [388, 'tuple 388'] box.space.memtx:select{389} - -- [389, tuple 389] - +- [389, 'tuple 389'] box.space.vinyl:select{385} - -- [385, tuple 385] - +- [385, 'tuple 385'] box.space.vinyl:select{386} - -- [386, tuple 386] - +- [386, 'tuple 386'] box.space.vinyl:select{387} - -- [387, tuple 387] - +- [387, 'tuple 387'] box.space.vinyl:select{388} - -- [388, tuple 388] - +- [388, 'tuple 388'] box.space.vinyl:select{389} - -- [389, tuple 389] - +- [389, 'tuple 389'] swap servers switch replica to master box.cfg{replication=''} @@ -6518,164 +4958,124 @@ box.cfg{replication=''} switch master to replica box.space.memtx:insert{390, "tuple 390"} - -- [390, tuple 390] - +- [390, 'tuple 390'] box.space.memtx:insert{391, "tuple 391"} - -- [391, tuple 391] - +- [391, 'tuple 391'] box.space.memtx:insert{392, "tuple 392"} - -- [392, tuple 392] - +- [392, 'tuple 392'] box.space.memtx:insert{393, "tuple 393"} - -- [393, tuple 393] - +- [393, 'tuple 393'] box.space.memtx:insert{394, "tuple 394"} - -- [394, tuple 394] - +- [394, 'tuple 394'] box.space.vinyl:insert{390, "tuple 390"} - -- [390, tuple 390] - +- [390, 'tuple 390'] box.space.vinyl:insert{391, "tuple 391"} - -- [391, tuple 391] - +- [391, 'tuple 391'] box.space.vinyl:insert{392, "tuple 392"} - -- [392, tuple 392] - +- [392, 'tuple 392'] box.space.vinyl:insert{393, "tuple 393"} - -- [393, tuple 393] - +- [393, 'tuple 393'] box.space.vinyl:insert{394, "tuple 394"} - -- [394, tuple 394] - +- [394, 'tuple 394'] box.space.memtx:select{390} - -- [390, tuple 390] - +- [390, 'tuple 390'] box.space.memtx:select{391} - -- [391, tuple 391] - +- [391, 'tuple 391'] box.space.memtx:select{392} - -- [392, tuple 392] - +- [392, 'tuple 392'] box.space.memtx:select{393} - -- [393, tuple 393] - +- [393, 'tuple 393'] box.space.memtx:select{394} - -- [394, tuple 394] - +- [394, 'tuple 394'] box.space.vinyl:select{390} - -- [390, tuple 390] - +- [390, 'tuple 390'] box.space.vinyl:select{391} - -- [391, tuple 391] - +- [391, 'tuple 391'] box.space.vinyl:select{392} - -- [392, tuple 392] - +- [392, 'tuple 392'] box.space.vinyl:select{393} - -- [393, tuple 393] - +- [393, 'tuple 393'] box.space.vinyl:select{394} - -- [394, tuple 394] - +- [394, 'tuple 394'] box.space.memtx:insert{395, "tuple 395"} - -- [395, tuple 395] - +- [395, 'tuple 395'] box.space.memtx:insert{396, "tuple 396"} - -- [396, tuple 396] - +- [396, 'tuple 396'] box.space.memtx:insert{397, "tuple 397"} - -- [397, tuple 397] - +- [397, 'tuple 397'] box.space.memtx:insert{398, "tuple 398"} - -- [398, tuple 398] - +- [398, 'tuple 398'] box.space.memtx:insert{399, "tuple 399"} - -- [399, tuple 399] - +- [399, 'tuple 399'] box.space.vinyl:insert{395, "tuple 395"} - -- [395, tuple 395] - +- [395, 'tuple 395'] box.space.vinyl:insert{396, "tuple 396"} - -- [396, tuple 396] - +- [396, 'tuple 396'] box.space.vinyl:insert{397, "tuple 397"} - -- [397, tuple 397] - +- [397, 'tuple 397'] box.space.vinyl:insert{398, "tuple 398"} - -- [398, tuple 398] - +- [398, 'tuple 398'] box.space.vinyl:insert{399, "tuple 399"} - -- [399, tuple 399] - +- [399, 'tuple 399'] box.space.memtx:select{395} - -- [395, tuple 395] - +- [395, 'tuple 395'] box.space.memtx:select{396} - -- [396, tuple 396] - +- [396, 'tuple 396'] box.space.memtx:select{397} - -- [397, tuple 397] - +- [397, 'tuple 397'] box.space.memtx:select{398} - -- [398, tuple 398] - +- [398, 'tuple 398'] box.space.memtx:select{399} - -- [399, tuple 399] - +- [399, 'tuple 399'] box.space.vinyl:select{395} - -- [395, tuple 395] - +- [395, 'tuple 395'] box.space.vinyl:select{396} - -- [396, tuple 396] - +- [396, 'tuple 396'] box.space.vinyl:select{397} - -- [397, tuple 397] - +- [397, 'tuple 397'] box.space.vinyl:select{398} - -- [398, tuple 398] - +- [398, 'tuple 398'] box.space.vinyl:select{399} - -- [399, tuple 399] - +- [399, 'tuple 399'] rollback servers configuration switch master to master box.cfg{replication=''} diff --git a/test/replication/gc_no_space.result b/test/replication/gc_no_space.result new file mode 100644 index 0000000000000000000000000000000000000000..8e663cdf065c2f5a123fac9fe72c2813389018a9 --- /dev/null +++ b/test/replication/gc_no_space.result @@ -0,0 +1,234 @@ +-- +-- This test checks that when the WAL thread runs out of disk +-- space it automatically deletes old WAL files and notifies +-- the TX thread so that the latter can shoot off WAL consumers +-- that need them. See gh-3397. +-- +test_run = require('test_run').new() +--- +... +engine = test_run:get_cfg('engine') +--- +... +fio = require('fio') +--- +... +errinj = box.error.injection +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function check_file_count(dir, glob, count) + local files = fio.glob(fio.pathjoin(dir, glob)) + if #files == count then + return true + end + return false, files +end; +--- +... +function check_wal_count(count) + return check_file_count(box.cfg.wal_dir, '*.xlog', count) +end; +--- +... +function check_snap_count(count) + return check_file_count(box.cfg.memtx_dir, '*.snap', count) +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +default_checkpoint_count = box.cfg.checkpoint_count +--- +... +box.cfg{checkpoint_count = 2} +--- +... +test_run:cleanup_cluster() +--- +... +box.schema.user.grant('guest', 'replication') +--- +... +s = box.schema.space.create('test', {engine = engine}) +--- +... +_ = s:create_index('pk') +--- +... +box.snapshot() +--- +- ok +... +-- +-- Create a few dead replicas to pin WAL files. +-- +test_run:cmd("create server replica with rpl_master=default, script='replication/replica.lua'") +--- +- true +... +test_run:cmd("start server replica") +--- +- true +... +test_run:cmd("stop server replica") +--- +- true +... +test_run:cmd("cleanup server replica") +--- +- true +... +s:auto_increment{} +--- +- [1] +... +box.snapshot() +--- +- ok +... +test_run:cmd("start server replica") +--- +- true +... +test_run:cmd("stop server replica") +--- +- true +... +test_run:cmd("cleanup server replica") +--- +- true +... +s:auto_increment{} +--- +- [2] +... +box.snapshot() +--- +- ok +... +test_run:cmd("start server replica") +--- +- true +... +test_run:cmd("stop server replica") +--- +- true +... +test_run:cmd("cleanup server replica") +--- +- true +... +test_run:cmd("delete server replica") +--- +- true +... +-- +-- Make a few checkpoints and check that old WAL files are not +-- deleted. +-- +s:auto_increment{} +--- +- [3] +... +box.snapshot() +--- +- ok +... +s:auto_increment{} +--- +- [4] +... +box.snapshot() +--- +- ok +... +s:auto_increment{} +--- +- [5] +... +check_wal_count(7) +--- +- true +... +check_snap_count(2) +--- +- true +... +#box.info.gc().consumers -- 3 +--- +- 3 +... +-- +-- Inject a ENOSPC error and check that the WAL thread deletes +-- old WAL files to prevent the user from seeing the error. +-- +errinj.set('ERRINJ_WAL_FALLOCATE', 3) +--- +- ok +... +s:auto_increment{} -- success +--- +- [6] +... +errinj.info()['ERRINJ_WAL_FALLOCATE'].state -- 0 +--- +- 0 +... +check_wal_count(3) +--- +- true +... +check_snap_count(2) +--- +- true +... +#box.info.gc().consumers -- 1 +--- +- 1 +... +-- +-- Check that the WAL thread never deletes WAL files that are +-- needed for recovery from a checkpoint. +-- +errinj.set('ERRINJ_WAL_FALLOCATE', 2) +--- +- ok +... +s:auto_increment{} -- failure +--- +- error: Failed to write to disk +... +errinj.info()['ERRINJ_WAL_FALLOCATE'].state -- 0 +--- +- 0 +... +check_wal_count(2) +--- +- true +... +check_snap_count(2) +--- +- true +... +#box.info.gc().consumers -- 0 +--- +- 0 +... +s:drop() +--- +... +box.schema.user.revoke('guest', 'replication') +--- +... +test_run:cleanup_cluster() +--- +... +box.cfg{checkpoint_count = default_checkpoint_count} +--- +... diff --git a/test/replication/gc_no_space.test.lua b/test/replication/gc_no_space.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..4bab2b0e9f5d922ff350fc70102430d30ee0990b --- /dev/null +++ b/test/replication/gc_no_space.test.lua @@ -0,0 +1,103 @@ +-- +-- This test checks that when the WAL thread runs out of disk +-- space it automatically deletes old WAL files and notifies +-- the TX thread so that the latter can shoot off WAL consumers +-- that need them. See gh-3397. +-- +test_run = require('test_run').new() +engine = test_run:get_cfg('engine') + +fio = require('fio') +errinj = box.error.injection + +test_run:cmd("setopt delimiter ';'") +function check_file_count(dir, glob, count) + local files = fio.glob(fio.pathjoin(dir, glob)) + if #files == count then + return true + end + return false, files +end; +function check_wal_count(count) + return check_file_count(box.cfg.wal_dir, '*.xlog', count) +end; +function check_snap_count(count) + return check_file_count(box.cfg.memtx_dir, '*.snap', count) +end; +test_run:cmd("setopt delimiter ''"); + +default_checkpoint_count = box.cfg.checkpoint_count +box.cfg{checkpoint_count = 2} + +test_run:cleanup_cluster() +box.schema.user.grant('guest', 'replication') +s = box.schema.space.create('test', {engine = engine}) +_ = s:create_index('pk') +box.snapshot() + +-- +-- Create a few dead replicas to pin WAL files. +-- +test_run:cmd("create server replica with rpl_master=default, script='replication/replica.lua'") +test_run:cmd("start server replica") +test_run:cmd("stop server replica") +test_run:cmd("cleanup server replica") + +s:auto_increment{} +box.snapshot() + +test_run:cmd("start server replica") +test_run:cmd("stop server replica") +test_run:cmd("cleanup server replica") + +s:auto_increment{} +box.snapshot() + +test_run:cmd("start server replica") +test_run:cmd("stop server replica") +test_run:cmd("cleanup server replica") +test_run:cmd("delete server replica") + +-- +-- Make a few checkpoints and check that old WAL files are not +-- deleted. +-- +s:auto_increment{} +box.snapshot() +s:auto_increment{} +box.snapshot() +s:auto_increment{} + +check_wal_count(7) +check_snap_count(2) +#box.info.gc().consumers -- 3 + +-- +-- Inject a ENOSPC error and check that the WAL thread deletes +-- old WAL files to prevent the user from seeing the error. +-- +errinj.set('ERRINJ_WAL_FALLOCATE', 3) +s:auto_increment{} -- success +errinj.info()['ERRINJ_WAL_FALLOCATE'].state -- 0 + +check_wal_count(3) +check_snap_count(2) +#box.info.gc().consumers -- 1 + +-- +-- Check that the WAL thread never deletes WAL files that are +-- needed for recovery from a checkpoint. +-- +errinj.set('ERRINJ_WAL_FALLOCATE', 2) +s:auto_increment{} -- failure +errinj.info()['ERRINJ_WAL_FALLOCATE'].state -- 0 + +check_wal_count(2) +check_snap_count(2) +#box.info.gc().consumers -- 0 + +s:drop() +box.schema.user.revoke('guest', 'replication') +test_run:cleanup_cluster() + +box.cfg{checkpoint_count = default_checkpoint_count} diff --git a/test/replication/suite.ini b/test/replication/suite.ini index f4abc7af1c243b9ca5b8c23a28b0031ba043b7a9..569c90480f9f466b729c2bcacdaba861a23e4f0a 100644 --- a/test/replication/suite.ini +++ b/test/replication/suite.ini @@ -3,7 +3,7 @@ core = tarantool script = master.lua description = tarantool/box, replication disabled = consistent.test.lua -release_disabled = catch.test.lua errinj.test.lua gc.test.lua before_replace.test.lua quorum.test.lua recover_missing_xlog.test.lua sync.test.lua +release_disabled = catch.test.lua errinj.test.lua gc.test.lua gc_no_space.test.lua before_replace.test.lua quorum.test.lua recover_missing_xlog.test.lua sync.test.lua config = suite.cfg lua_libs = lua/fast_replica.lua lua/rlimit.lua long_run = prune.test.lua diff --git a/test/unit/bloom.cc b/test/unit/bloom.cc index b8a2ef1356d641b4693438a7fec699cb54010b50..2e5b994126010617f6e563a094703078625042ce 100644 --- a/test/unit/bloom.cc +++ b/test/unit/bloom.cc @@ -14,8 +14,6 @@ void simple_test() { cout << "*** " << __func__ << " ***" << endl; - struct quota q; - quota_init(&q, 100500); srand(time(0)); uint32_t error_count = 0; uint32_t fp_rate_too_big = 0; @@ -24,7 +22,7 @@ simple_test() uint64_t false_positive = 0; for (uint32_t count = 1000; count <= 10000; count *= 2) { struct bloom bloom; - bloom_create(&bloom, count, p, &q); + bloom_create(&bloom, count, p); unordered_set<uint32_t> check; for (uint32_t i = 0; i < count; i++) { uint32_t val = rand() % (count * 10); @@ -41,7 +39,7 @@ simple_test() if (!has && bloom_possible) false_positive++; } - bloom_destroy(&bloom, &q); + bloom_destroy(&bloom); } double fp_rate = (double)false_positive / tests; if (fp_rate > p + 0.001) @@ -49,15 +47,12 @@ simple_test() } cout << "error_count = " << error_count << endl; cout << "fp_rate_too_big = " << fp_rate_too_big << endl; - cout << "memory after destruction = " << quota_used(&q) << endl << endl; } void store_load_test() { cout << "*** " << __func__ << " ***" << endl; - struct quota q; - quota_init(&q, 100500); srand(time(0)); uint32_t error_count = 0; uint32_t fp_rate_too_big = 0; @@ -66,7 +61,7 @@ store_load_test() uint64_t false_positive = 0; for (uint32_t count = 300; count <= 3000; count *= 10) { struct bloom bloom; - bloom_create(&bloom, count, p, &q); + bloom_create(&bloom, count, p); unordered_set<uint32_t> check; for (uint32_t i = 0; i < count; i++) { uint32_t val = rand() % (count * 10); @@ -76,9 +71,9 @@ store_load_test() struct bloom test = bloom; char *buf = (char *)malloc(bloom_store_size(&bloom)); bloom_store(&bloom, buf); - bloom_destroy(&bloom, &q); + bloom_destroy(&bloom); memset(&bloom, '#', sizeof(bloom)); - bloom_load_table(&test, buf, &q); + bloom_load_table(&test, buf); free(buf); for (uint32_t i = 0; i < count * 10; i++) { bool has = check.find(i) != check.end(); @@ -90,7 +85,7 @@ store_load_test() if (!has && bloom_possible) false_positive++; } - bloom_destroy(&test, &q); + bloom_destroy(&test); } double fp_rate = (double)false_positive / tests; double excess = fp_rate / p; @@ -99,7 +94,6 @@ store_load_test() } cout << "error_count = " << error_count << endl; cout << "fp_rate_too_big = " << fp_rate_too_big << endl; - cout << "memory after destruction = " << quota_used(&q) << endl << endl; } int diff --git a/test/unit/bloom.result b/test/unit/bloom.result index 1b1b1f94dee20036147db6e0ee31daa73e47f200..91193a618eb37f79b6a7146cd5bf10e5d697e939 100644 --- a/test/unit/bloom.result +++ b/test/unit/bloom.result @@ -1,10 +1,6 @@ *** simple_test *** error_count = 0 fp_rate_too_big = 0 -memory after destruction = 0 - *** store_load_test *** error_count = 0 fp_rate_too_big = 0 -memory after destruction = 0 - diff --git a/test/unit/vy_cache.c b/test/unit/vy_cache.c index 5d296aa6d36dd919ecc5308ab8da6aca41e77a14..d46d6c3f1f06c7b4283ebaca9026cb637418811f 100644 --- a/test/unit/vy_cache.c +++ b/test/unit/vy_cache.c @@ -18,8 +18,7 @@ test_basic() struct tuple_format *format; create_test_cache(fields, types, lengthof(fields), &cache, &key_def, &format); - struct tuple *select_all = vy_new_simple_stmt(format, NULL, - &key_template); + struct tuple *select_all = vy_new_simple_stmt(format, &key_template); struct mempool history_node_pool; mempool_create(&history_node_pool, cord_slab_cache(), @@ -96,7 +95,7 @@ test_basic() for (int i = 0; i < 4; ++i) vy_cache_iterator_next(&itr, &history, &unused); ret = vy_history_last_stmt(&history); - ok(vy_stmt_are_same(ret, &chain1[3], format, NULL), + ok(vy_stmt_are_same(ret, &chain1[3], format), "next_key * 4"); /* @@ -115,11 +114,11 @@ test_basic() * the last_stmt. So restore on chain1[0], but the result * must be chain1[1]. */ - struct tuple *last_stmt = vy_new_simple_stmt(format, NULL, &chain1[0]); + struct tuple *last_stmt = vy_new_simple_stmt(format, &chain1[0]); ok(vy_cache_iterator_restore(&itr, last_stmt, &history, &unused) >= 0, "restore"); ret = vy_history_last_stmt(&history); - ok(vy_stmt_are_same(ret, &chain1[1], format, NULL), + ok(vy_stmt_are_same(ret, &chain1[1], format), "restore on position after last"); tuple_unref(last_stmt); diff --git a/test/unit/vy_iterators_helper.c b/test/unit/vy_iterators_helper.c index 40d8d6a10b35e6e114e395bf36a5948efc0ec9e5..7fad5600c1fae0727120bab829928de6db6848c6 100644 --- a/test/unit/vy_iterators_helper.c +++ b/test/unit/vy_iterators_helper.c @@ -21,7 +21,7 @@ vy_iterator_C_test_init(size_t cache_size) tuple_init(NULL); vy_cache_env_create(&cache_env, cord_slab_cache()); vy_cache_env_set_quota(&cache_env, cache_size); - vy_key_format = tuple_format_new(&vy_tuple_format_vtab, NULL, 0, 0, + vy_key_format = tuple_format_new(&vy_tuple_format_vtab, NULL, 0, NULL, 0, NULL); tuple_format_ref(vy_key_format); @@ -42,7 +42,6 @@ vy_iterator_C_test_finish() struct tuple * vy_new_simple_stmt(struct tuple_format *format, - struct tuple_format *format_with_colmask, const struct vy_stmt_template *templ) { if (templ == NULL) @@ -59,9 +58,6 @@ vy_new_simple_stmt(struct tuple_format *format, ++i; } size += mp_sizeof_array(i); - fail_if(templ->optimize_update && templ->type == IPROTO_UPSERT); - if (templ->optimize_update) - format = format_with_colmask; /* Encode the statement. */ char *buf = (char *) malloc(size); @@ -119,7 +115,6 @@ vy_new_simple_stmt(struct tuple_format *format, ops = mp_encode_int(ops, templ->upsert_value); operations[0].iov_base = tmp; operations[0].iov_len = ops - tmp; - fail_if(templ->optimize_update); ret = vy_stmt_new_upsert(format, buf, pos, operations, 1); fail_if(ret == NULL); break; @@ -137,16 +132,13 @@ vy_new_simple_stmt(struct tuple_format *format, free(buf); vy_stmt_set_lsn(ret, templ->lsn); vy_stmt_set_flags(ret, templ->flags); - if (templ->optimize_update) - vy_stmt_set_column_mask(ret, 0); return ret; } const struct tuple * vy_mem_insert_template(struct vy_mem *mem, const struct vy_stmt_template *templ) { - struct tuple *stmt = vy_new_simple_stmt(mem->format, - mem->format_with_colmask, templ); + struct tuple *stmt = vy_new_simple_stmt(mem->format, templ); struct tuple *region_stmt = vy_stmt_dup_lsregion(stmt, &mem->env->allocator, mem->generation); assert(region_stmt != NULL); @@ -166,12 +158,12 @@ vy_cache_insert_templates_chain(struct vy_cache *cache, const struct vy_stmt_template *key_templ, enum iterator_type order) { - struct tuple *key = vy_new_simple_stmt(format, NULL, key_templ); + struct tuple *key = vy_new_simple_stmt(format, key_templ); struct tuple *prev_stmt = NULL; struct tuple *stmt = NULL; for (uint i = 0; i < length; ++i) { - stmt = vy_new_simple_stmt(format, NULL, &chain[i]); + stmt = vy_new_simple_stmt(format, &chain[i]); vy_cache_add(cache, stmt, prev_stmt, key, order); if (i != 0) tuple_unref(prev_stmt); @@ -187,7 +179,7 @@ void vy_cache_on_write_template(struct vy_cache *cache, struct tuple_format *format, const struct vy_stmt_template *templ) { - struct tuple *written = vy_new_simple_stmt(format, NULL, templ); + struct tuple *written = vy_new_simple_stmt(format, templ); vy_cache_on_write(cache, written, NULL); tuple_unref(written); } @@ -210,17 +202,11 @@ create_test_mem(struct key_def *def) struct key_def * const defs[] = { def }; struct tuple_format *format = tuple_format_new(&vy_tuple_format_vtab, defs, def->part_count, - 0, NULL, 0, NULL); + NULL, 0, NULL); fail_if(format == NULL); - /* Create format with column mask */ - struct tuple_format *format_with_colmask = - vy_tuple_format_new_with_colmask(format); - assert(format_with_colmask != NULL); - /* Create mem */ - struct vy_mem *mem = vy_mem_new(&mem_env, 1, def, format, - format_with_colmask, 0); + struct vy_mem *mem = vy_mem_new(&mem_env, def, format, 1, 0); fail_if(mem == NULL); return mem; } @@ -233,7 +219,7 @@ create_test_cache(uint32_t *fields, uint32_t *types, *def = box_key_def_new(fields, types, key_cnt); assert(*def != NULL); vy_cache_create(cache, &cache_env, *def, true); - *format = tuple_format_new(&vy_tuple_format_vtab, def, 1, 0, NULL, 0, + *format = tuple_format_new(&vy_tuple_format_vtab, def, 1, NULL, 0, NULL); tuple_format_ref(*format); } @@ -250,13 +236,11 @@ destroy_test_cache(struct vy_cache *cache, struct key_def *def, bool vy_stmt_are_same(const struct tuple *actual, const struct vy_stmt_template *expected, - struct tuple_format *format, - struct tuple_format *format_with_colmask) + struct tuple_format *format) { if (vy_stmt_type(actual) != expected->type) return false; - struct tuple *tmp = vy_new_simple_stmt(format, format_with_colmask, - expected); + struct tuple *tmp = vy_new_simple_stmt(format, expected); fail_if(tmp == NULL); uint32_t a_len, b_len; const char *a, *b; diff --git a/test/unit/vy_iterators_helper.h b/test/unit/vy_iterators_helper.h index 24641df3a81fabbb7fcf323e8a9cb75badbd5227..9690f6849c6454be6444665cdcb2166c2176f40d 100644 --- a/test/unit/vy_iterators_helper.h +++ b/test/unit/vy_iterators_helper.h @@ -43,13 +43,10 @@ #define vyend 99999999 #define MAX_FIELDS_COUNT 100 #define STMT_TEMPLATE(lsn, type, ...) \ -{ { __VA_ARGS__, vyend }, IPROTO_##type, lsn, false, 0, 0, 0 } - -#define STMT_TEMPLATE_OPTIMIZED(lsn, type, ...) \ -{ { __VA_ARGS__, vyend }, IPROTO_##type, lsn, true, 0, 0, 0 } +{ { __VA_ARGS__, vyend }, IPROTO_##type, lsn, 0, 0, 0 } #define STMT_TEMPLATE_FLAGS(lsn, type, flags, ...) \ -{ { __VA_ARGS__, vyend }, IPROTO_##type, lsn, false, flags, 0, 0 } +{ { __VA_ARGS__, vyend }, IPROTO_##type, lsn, flags, 0, 0 } #define STMT_TEMPLATE_DEFERRED_DELETE(lsn, type, ...) \ STMT_TEMPLATE_FLAGS(lsn, type, VY_STMT_DEFERRED_DELETE, __VA_ARGS__) @@ -83,11 +80,6 @@ struct vy_stmt_template { enum iproto_type type; /** Statement lsn. */ int64_t lsn; - /* - * True, if statement must have column mask, that allows - * to skip it in the write_iterator. - */ - bool optimize_update; /** Statement flags. */ uint8_t flags; /* @@ -103,15 +95,12 @@ struct vy_stmt_template { * Create a new vinyl statement using the specified template. * * @param format - * @param format_with_colmask Format for statements with a - * colmask. * @param templ Statement template. * * @return Created statement. */ struct tuple * vy_new_simple_stmt(struct tuple_format *format, - struct tuple_format *format_with_colmask, const struct vy_stmt_template *templ); /** @@ -210,15 +199,13 @@ destroy_test_cache(struct vy_cache *cache, struct key_def *def, * @param stmt Actual value. * @param templ Expected value. * @param format Template statement format. - * @param format_with_colmask Template statement format with colmask. * * @retval stmt === template. */ bool vy_stmt_are_same(const struct tuple *actual, const struct vy_stmt_template *expected, - struct tuple_format *format, - struct tuple_format *format_with_colmask); + struct tuple_format *format); #if defined(__cplusplus) } diff --git a/test/unit/vy_mem.c b/test/unit/vy_mem.c index 967aabe8b1366d8ed114e78433612f5e333e70be..ebf3fbc77ecb26282f81f86772931ca70c6e8e9e 100644 --- a/test/unit/vy_mem.c +++ b/test/unit/vy_mem.c @@ -77,7 +77,7 @@ test_iterator_restore_after_insertion() /* Create format */ struct tuple_format *format = tuple_format_new(&vy_tuple_format_vtab, - &key_def, 1, 0, NULL, 0, + &key_def, 1, NULL, 0, NULL); assert(format != NULL); tuple_format_ref(format); diff --git a/test/unit/vy_point_lookup.c b/test/unit/vy_point_lookup.c index dd33bbec55f65d392e399d0622d00f518bcec056..65dafcb233aec804982e8f87ddf3baaf871f3fa6 100644 --- a/test/unit/vy_point_lookup.c +++ b/test/unit/vy_point_lookup.c @@ -84,7 +84,7 @@ test_basic() vy_cache_create(&cache, &cache_env, key_def, true); struct tuple_format *format = tuple_format_new(&vy_tuple_format_vtab, - &key_def, 1, 0, NULL, 0, + &key_def, 1, NULL, 0, NULL); isnt(format, NULL, "tuple_format_new is not NULL"); tuple_format_ref(format); @@ -179,9 +179,8 @@ test_basic() /* create second run */ struct vy_mem *run_mem = - vy_mem_new(pk->mem->env, *pk->env->p_generation, - pk->cmp_def, pk->mem_format, - pk->mem_format_with_colmask, 0); + vy_mem_new(pk->mem->env, pk->cmp_def, pk->mem_format, + *pk->env->p_generation, 0); for (size_t i = 0; i < num_of_keys; i++) { if (!in_run2[i]) @@ -211,10 +210,8 @@ test_basic() vy_run_unref(run); /* create first run */ - run_mem = - vy_mem_new(pk->mem->env, *pk->env->p_generation, - pk->cmp_def, pk->mem_format, - pk->mem_format_with_colmask, 0); + run_mem = vy_mem_new(pk->mem->env, pk->cmp_def, pk->mem_format, + *pk->env->p_generation, 0); for (size_t i = 0; i < num_of_keys; i++) { if (!in_run1[i]) @@ -274,7 +271,7 @@ test_basic() struct vy_stmt_template tmpl_key = STMT_TEMPLATE(0, SELECT, i); struct tuple *key = vy_new_simple_stmt(format, - pk->mem_format_with_colmask, &tmpl_key); + &tmpl_key); struct tuple *res; rc = vy_point_lookup(pk, NULL, &prv, key, &res); tuple_unref(key); diff --git a/test/unit/vy_write_iterator.c b/test/unit/vy_write_iterator.c index 337e27ac300367e3a5885dcad86cd9c98e4aa3c2..bb0eb8d3951e7a2f8db20acdb0922da62ea455c0 100644 --- a/test/unit/vy_write_iterator.c +++ b/test/unit/vy_write_iterator.c @@ -119,8 +119,7 @@ compare_write_iterator_results(const struct vy_stmt_template *content, if (ret == NULL) break; fail_if(i >= expected_count); - ok(vy_stmt_are_same(ret, &expected[i], mem->format, - mem->format_with_colmask), + ok(vy_stmt_are_same(ret, &expected[i], mem->format), "stmt %d is correct", i); ++i; } while (ret != NULL); @@ -129,7 +128,7 @@ compare_write_iterator_results(const struct vy_stmt_template *content, for (i = 0; i < handler.count; i++) { fail_if(i >= deferred_count); ok(vy_stmt_are_same(handler.stmt[i], &deferred[i], - handler.format, NULL), + handler.format), "deferred stmt %d is correct", i); } if (deferred != NULL) { @@ -149,7 +148,7 @@ void test_basic(void) { header(); - plan(66); + plan(58); { /* * STATEMENT: REPL REPL REPL DEL REPL REPL REPL REPL REPL REPL @@ -311,54 +310,6 @@ test_basic(void) vlsns, vlsns_count, true, false); } { -/* - * STATEMENT: REPL DEL REPL REPL - * LSN: 5 6 6 7 - * READ VIEW: * - * \_______________/\_______/ - * \_____/\______/ - * merge skip as - * optimized - * update - * DEL and REPL with lsn 6 can be skipped for read view 6 for - * secondary index, because they do not change secondary key. - */ - const struct vy_stmt_template content[] = { - STMT_TEMPLATE(5, REPLACE, 1, 1), - STMT_TEMPLATE_OPTIMIZED(6, DELETE, 1), - STMT_TEMPLATE_OPTIMIZED(6, REPLACE, 1, 2), - STMT_TEMPLATE(7, REPLACE, 1, 3) - }; - const struct vy_stmt_template expected[] = { content[3], content[0] }; - const int vlsns[] = {6}; - int content_count = sizeof(content) / sizeof(content[0]); - int expected_count = sizeof(expected) / sizeof(expected[0]); - int vlsns_count = sizeof(vlsns) / sizeof(vlsns[0]); - compare_write_iterator_results(content, content_count, - expected, expected_count, NULL, 0, - vlsns, vlsns_count, false, true); -} -{ -/* - * STATEMENT: DEL REPL - * LSN: 6 6 - * \______/ - * skip both as optimized update - */ - const struct vy_stmt_template content[] = { - STMT_TEMPLATE_OPTIMIZED(6, DELETE, 1), - STMT_TEMPLATE_OPTIMIZED(6, REPLACE, 1, 2), - }; - const struct vy_stmt_template expected[] = {}; - const int vlsns[] = {}; - int content_count = sizeof(content) / sizeof(content[0]); - int expected_count = sizeof(expected) / sizeof(expected[0]); - int vlsns_count = sizeof(vlsns) / sizeof(vlsns[0]); - compare_write_iterator_results(content, content_count, - expected, expected_count, NULL, 0, - vlsns, vlsns_count, false, false); -} -{ /* * STATEMENT: UPS UPS UPS REPL * LSN: 6 7 8 9 @@ -414,56 +365,6 @@ test_basic(void) vlsns, vlsns_count, true, true); } { -/* - * STATEMENT: REPL DEL REPL - * LSN: 6 7 7 - * \___/\__________/ - * merge skip as optimized update - * - * last_level = false. - * Check if the key is not fully skipped in a case of optimized - * update as the newest version. - */ - const struct vy_stmt_template content[] = { - STMT_TEMPLATE(6, REPLACE, 1, 1), - STMT_TEMPLATE_OPTIMIZED(7, DELETE, 1), - STMT_TEMPLATE_OPTIMIZED(7, REPLACE, 1, 2), - }; - const struct vy_stmt_template expected[] = { content[0] }; - const int vlsns[] = {}; - int content_count = sizeof(content) / sizeof(content[0]); - int expected_count = sizeof(expected) / sizeof(expected[0]); - int vlsns_count = sizeof(vlsns) / sizeof(vlsns[0]); - compare_write_iterator_results(content, content_count, - expected, expected_count, NULL, 0, - vlsns, vlsns_count, false, false); -} -{ -/* - * STATEMENT: REPL DEL REPL - * LSN: 6 7 7 - * \_________/|\___/ - * skip last level | skip as optimized - * delete. | update. - * - * last_level = true. First apply 'last level DELETE' optimization - * and only then the 'optimized UPDATE'. - */ - const struct vy_stmt_template content[] = { - STMT_TEMPLATE(6, REPLACE, 1, 1), - STMT_TEMPLATE_OPTIMIZED(7, DELETE, 1), - STMT_TEMPLATE_OPTIMIZED(7, REPLACE, 1, 2), - }; - const struct vy_stmt_template expected[] = { content[2] }; - const int vlsns[] = {}; - int content_count = sizeof(content) / sizeof(content[0]); - int expected_count = sizeof(expected) / sizeof(expected[0]); - int vlsns_count = sizeof(vlsns) / sizeof(vlsns[0]); - compare_write_iterator_results(content, content_count, - expected, expected_count, NULL, 0, - vlsns, vlsns_count, true, false); -} -{ /* * STATEMENT: REPL DEL REPL DEL REPL DEL * LSN: 4 5 6 7 8 9 diff --git a/test/unit/vy_write_iterator.result b/test/unit/vy_write_iterator.result index 4f95aeb926876bbf1182c74ab021a38b7a6e8019..a80116852630c65adf4ed39af83faea1d8aec698 100644 --- a/test/unit/vy_write_iterator.result +++ b/test/unit/vy_write_iterator.result @@ -1,5 +1,5 @@ *** test_basic *** -1..66 +1..58 ok 1 - stmt 0 is correct ok 2 - stmt 1 is correct ok 3 - stmt 2 is correct @@ -24,46 +24,38 @@ ok 21 - correct results count ok 22 - stmt 0 is correct ok 23 - stmt 1 is correct ok 24 - correct results count -ok 25 - correct results count -ok 26 - stmt 0 is correct -ok 27 - stmt 1 is correct +ok 25 - stmt 0 is correct +ok 26 - stmt 1 is correct +ok 27 - stmt 2 is correct ok 28 - correct results count ok 29 - stmt 0 is correct -ok 30 - stmt 1 is correct -ok 31 - stmt 2 is correct -ok 32 - correct results count -ok 33 - stmt 0 is correct +ok 30 - correct results count +ok 31 - stmt 0 is correct +ok 32 - stmt 1 is correct +ok 33 - stmt 2 is correct ok 34 - correct results count ok 35 - stmt 0 is correct -ok 36 - correct results count -ok 37 - stmt 0 is correct +ok 36 - stmt 1 is correct +ok 37 - stmt 2 is correct ok 38 - correct results count ok 39 - stmt 0 is correct ok 40 - stmt 1 is correct ok 41 - stmt 2 is correct ok 42 - correct results count -ok 43 - stmt 0 is correct -ok 44 - stmt 1 is correct -ok 45 - stmt 2 is correct -ok 46 - correct results count -ok 47 - stmt 0 is correct -ok 48 - stmt 1 is correct -ok 49 - stmt 2 is correct +ok 43 - deferred stmt 0 is correct +ok 44 - deferred stmt 1 is correct +ok 45 - deferred stmt 2 is correct +ok 46 - deferred stmt 3 is correct +ok 47 - correct deferred stmt count +ok 48 - stmt 0 is correct +ok 49 - stmt 1 is correct ok 50 - correct results count -ok 51 - deferred stmt 0 is correct -ok 52 - deferred stmt 1 is correct -ok 53 - deferred stmt 2 is correct -ok 54 - deferred stmt 3 is correct +ok 51 - correct deferred stmt count +ok 52 - stmt 0 is correct +ok 53 - stmt 1 is correct +ok 54 - correct results count ok 55 - correct deferred stmt count ok 56 - stmt 0 is correct -ok 57 - stmt 1 is correct -ok 58 - correct results count -ok 59 - correct deferred stmt count -ok 60 - stmt 0 is correct -ok 61 - stmt 1 is correct -ok 62 - correct results count -ok 63 - correct deferred stmt count -ok 64 - stmt 0 is correct -ok 65 - correct results count -ok 66 - correct deferred stmt count +ok 57 - correct results count +ok 58 - correct deferred stmt count *** test_basic: done *** diff --git a/test/vinyl/info.result b/test/vinyl/info.result index a47c9a1b37369faed0d940cfa87779e7c41d594d..49c2037a6111b5b1786af0ef45e730a4af033f52 100644 --- a/test/vinyl/info.result +++ b/test/vinyl/info.result @@ -151,7 +151,11 @@ istat() disk: index_size: 0 rows: 0 - bytes: 0 + statement: + inserts: 0 + replaces: 0 + upserts: 0 + deletes: 0 dump: in: rows: 0 @@ -192,9 +196,10 @@ istat() get: rows: 0 bytes: 0 + bloom_size: 0 pages: 0 bytes_compressed: 0 - bloom_size: 0 + bytes: 0 txw: bytes: 0 rows: 0 @@ -286,10 +291,12 @@ stat_diff(istat(), st) rows: 25 index_size: 294 rows: 25 - bloom_size: 70 - pages: 7 bytes: 26049 bytes_compressed: <bytes_compressed> + bloom_size: 70 + statement: + replaces: 25 + pages: 7 bytes: 26049 put: rows: 25 @@ -324,9 +331,11 @@ stat_diff(istat(), st) rows: 50 index_size: 252 rows: 25 + bytes: 26042 bytes_compressed: <bytes_compressed> pages: 6 - bytes: 26042 + statement: + replaces: 25 compact: in: bytes: 78140 @@ -992,7 +1001,11 @@ istat() disk: index_size: 1050 rows: 100 - bytes: 104300 + statement: + inserts: 0 + replaces: 100 + upserts: 0 + deletes: 0 dump: in: rows: 0 @@ -1033,9 +1046,10 @@ istat() get: rows: 0 bytes: 0 + bloom_size: 140 pages: 25 bytes_compressed: <bytes_compressed> - bloom_size: 140 + bytes: 104300 txw: bytes: 0 rows: 0 @@ -1392,6 +1406,91 @@ gst.disk.index == 0 --- - true ... +-- +-- Statement statistics. +-- +s = box.schema.space.create('test', {engine = 'vinyl'}) +--- +... +i = s:create_index('primary', {run_count_per_level = 10}) +--- +... +i:stat().disk.statement +--- +- inserts: 0 + replaces: 0 + upserts: 0 + deletes: 0 +... +s:insert{1, 1} +--- +- [1, 1] +... +s:replace{2, 2} +--- +- [2, 2] +... +box.snapshot() +--- +- ok +... +i:stat().disk.statement +--- +- inserts: 1 + replaces: 1 + upserts: 0 + deletes: 0 +... +s:upsert({1, 1}, {{'+', 2, 1}}) +--- +... +s:delete{2} +--- +... +box.snapshot() +--- +- ok +... +i:stat().disk.statement +--- +- inserts: 1 + replaces: 1 + upserts: 1 + deletes: 1 +... +test_run:cmd('restart server test') +fiber = require('fiber') +--- +... +s = box.space.test +--- +... +i = s.index.primary +--- +... +i:stat().disk.statement +--- +- inserts: 1 + replaces: 1 + upserts: 1 + deletes: 1 +... +i:compact() +--- +... +while i:stat().disk.compact.count == 0 do fiber.sleep(0.01) end +--- +... +i:stat().disk.statement +--- +- inserts: 1 + replaces: 0 + upserts: 0 + deletes: 0 +... +s:drop() +--- +... test_run:cmd('switch default') --- - true diff --git a/test/vinyl/info.test.lua b/test/vinyl/info.test.lua index e5794a231c8a762cb2c82436b1de151c5bb1f44b..b11fc044179f63fe70717de499a1f29ba043ee38 100644 --- a/test/vinyl/info.test.lua +++ b/test/vinyl/info.test.lua @@ -411,6 +411,42 @@ gst.memory.bloom_filter == 0 gst.disk.data == 0 gst.disk.index == 0 +-- +-- Statement statistics. +-- +s = box.schema.space.create('test', {engine = 'vinyl'}) +i = s:create_index('primary', {run_count_per_level = 10}) + +i:stat().disk.statement + +s:insert{1, 1} +s:replace{2, 2} +box.snapshot() + +i:stat().disk.statement + +s:upsert({1, 1}, {{'+', 2, 1}}) +s:delete{2} +box.snapshot() + +i:stat().disk.statement + +test_run:cmd('restart server test') + +fiber = require('fiber') + +s = box.space.test +i = s.index.primary + +i:stat().disk.statement + +i:compact() +while i:stat().disk.compact.count == 0 do fiber.sleep(0.01) end + +i:stat().disk.statement + +s:drop() + test_run:cmd('switch default') test_run:cmd('stop server test') test_run:cmd('cleanup server test') diff --git a/test/vinyl/layout.result b/test/vinyl/layout.result index ee14cd512151ff0f9f5e21f914a8134447d96fb3..989ddf64e9e0c439c1e14fbb5dc451cffa1a786b 100644 --- a/test/vinyl/layout.result +++ b/test/vinyl/layout.result @@ -236,9 +236,10 @@ result type: RUNINFO BODY: min_lsn: 8 + bloom_filter: <bloom_filter> max_key: ['ÐÐÐ'] page_count: 1 - bloom_filter: <bloom_filter> + stmt_stat: {9: 0, 2: 0, 5: 0, 3: 3} max_lsn: 10 min_key: ['Ñ‘Ñ‘Ñ‘'] - HEADER: @@ -275,9 +276,10 @@ result type: RUNINFO BODY: min_lsn: 11 + bloom_filter: <bloom_filter> max_key: ['ЮЮЮ'] page_count: 1 - bloom_filter: <bloom_filter> + stmt_stat: {9: 0, 2: 0, 5: 0, 3: 3} max_lsn: 13 min_key: ['Ñ‘Ñ‘Ñ‘'] - HEADER: @@ -317,9 +319,10 @@ result type: RUNINFO BODY: min_lsn: 8 + bloom_filter: <bloom_filter> max_key: [null, 'ÐÐÐ'] page_count: 1 - bloom_filter: <bloom_filter> + stmt_stat: {9: 0, 2: 0, 5: 0, 3: 3} max_lsn: 10 min_key: [null, 'Ñ‘Ñ‘Ñ‘'] - HEADER: @@ -356,9 +359,10 @@ result type: RUNINFO BODY: min_lsn: 11 + bloom_filter: <bloom_filter> max_key: [789, 'ÑŽÑŽÑŽ'] page_count: 1 - bloom_filter: <bloom_filter> + stmt_stat: {9: 0, 2: 0, 5: 0, 3: 3} max_lsn: 13 min_key: [123, 'Ñ‘Ñ‘Ñ‘'] - HEADER: diff --git a/test/xlog/checkpoint_daemon.result b/test/xlog/checkpoint_daemon.result index d5ed666f201ade497cf2a9d87985425a9af766a8..3a75137d2f26c3049f12038f37841e21ae91e8a3 100644 --- a/test/xlog/checkpoint_daemon.result +++ b/test/xlog/checkpoint_daemon.result @@ -19,10 +19,10 @@ test_run:cleanup_cluster() box.cfg{checkpoint_interval = 0} --- ... -PERIOD = 0.03 +PERIOD = jit.os == 'Linux' and 0.03 or 1.5 --- ... -if jit.os ~= 'Linux' then PERIOD = 1.5 end +WAIT_COND_TIMEOUT = 10 --- ... space = box.schema.space.create('checkpoint_daemon') @@ -31,6 +31,50 @@ space = box.schema.space.create('checkpoint_daemon') index = space:create_index('pk', { type = 'tree', parts = { 1, 'unsigned' }}) --- ... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +-- wait_snapshot* functions update these variables. +snaps = {}; +--- +... +xlogs = {}; +--- +... +-- Wait until tarantool creates a snapshot containing current +-- data slice. +function wait_snapshot(timeout) + snaps = {} + xlogs = {} + local signature_str = tostring(box.info.signature) + signature_str = string.rjust(signature_str, 20, '0') + local exp_snap_filename = string.format('%s.snap', signature_str) + return test_run:wait_cond(function() + snaps = fio.glob(fio.pathjoin(box.cfg.memtx_dir, '*.snap')) + xlogs = fio.glob(fio.pathjoin(box.cfg.wal_dir, '*.xlog')) + return fio.basename(snaps[#snaps]) == exp_snap_filename + end, timeout) +end; +--- +... +-- Wait until snapshots count will be equal to the +-- checkpoint_count option. +function wait_snapshot_gc(timeout) + snaps = {} + xlogs = {} + return test_run:wait_cond(function() + snaps = fio.glob(fio.pathjoin(box.cfg.memtx_dir, '*.snap')) + xlogs = fio.glob(fio.pathjoin(box.cfg.wal_dir, '*.xlog')) + return #snaps == box.cfg.checkpoint_count + end, timeout) +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... box.cfg{checkpoint_interval = PERIOD, checkpoint_count = 2 } --- ... @@ -45,9 +89,9 @@ for i = 1, box.cfg.rows_per_wal + 10 do space:insert { no } no = no + 1 end for i = 1, box.cfg.rows_per_wal + 10 do space:insert { no } no = no + 1 end --- ... --- wait for last snapshot -fiber.sleep(1.5 * PERIOD) +wait_snapshot(WAIT_COND_TIMEOUT) --- +- true ... -- third xlog for i = 1, box.cfg.rows_per_wal + 10 do space:insert { no } no = no + 1 end @@ -57,23 +101,11 @@ for i = 1, box.cfg.rows_per_wal + 10 do space:insert { no } no = no + 1 end for i = 1, box.cfg.rows_per_wal + 10 do space:insert { no } no = no + 1 end --- ... --- wait for last snapshot -test_run:cmd("setopt delimiter ';'") +wait_snapshot(WAIT_COND_TIMEOUT) --- - true ... -for i = 1, 100 do - fiber.sleep(PERIOD) - snaps = fio.glob(fio.pathjoin(box.cfg.memtx_dir, '*.snap')) - xlogs = fio.glob(fio.pathjoin(box.cfg.wal_dir, '*.xlog')) - - if #snaps == 2 then - break - end -end; ---- -... -test_run:cmd("setopt delimiter ''"); +wait_snapshot_gc(WAIT_COND_TIMEOUT) --- - true ... @@ -85,20 +117,30 @@ test_run:cmd("setopt delimiter ''"); --- - true ... -fio.basename(snaps[1], '.snap') >= fio.basename(xlogs[1], '.xlog') +-- gh-2780: check that a last snapshot mtime will be changed at +-- least two times. +test_run:cmd("setopt delimiter ';'") --- - true ... --- gh-2780 check that scheduled snapshots are performed -fiber.sleep(3 * PERIOD) +last_mtime = fio.stat(snaps[#snaps]).mtime; --- ... --- check that it's not first snapshot -test_run:grep_log("default", "saving snapshot", 400) == nil +mtime_changes_cnt = 0; +--- +... +test_run:wait_cond(function() + local mtime = fio.stat(snaps[#snaps]).mtime + if mtime ~= last_mtime then + mtime_changes_cnt = mtime_changes_cnt + 1 + last_mtime = mtime + end + return mtime_changes_cnt == 2 +end, WAIT_COND_TIMEOUT); --- - true ... -test_run:grep_log("default", "making snapshot", 400) ~= nil +test_run:cmd("setopt delimiter ''"); --- - true ... diff --git a/test/xlog/checkpoint_daemon.test.lua b/test/xlog/checkpoint_daemon.test.lua index 4a0aafa84a33be2f100171e148e47c40ed274062..f34906217c7b3d9a3034da9581240fbd002b4a67 100644 --- a/test/xlog/checkpoint_daemon.test.lua +++ b/test/xlog/checkpoint_daemon.test.lua @@ -8,13 +8,46 @@ test_run:cleanup_cluster() box.cfg{checkpoint_interval = 0} -PERIOD = 0.03 -if jit.os ~= 'Linux' then PERIOD = 1.5 end - +PERIOD = jit.os == 'Linux' and 0.03 or 1.5 +WAIT_COND_TIMEOUT = 10 space = box.schema.space.create('checkpoint_daemon') index = space:create_index('pk', { type = 'tree', parts = { 1, 'unsigned' }}) +test_run:cmd("setopt delimiter ';'") + +-- wait_snapshot* functions update these variables. +snaps = {}; +xlogs = {}; + +-- Wait until tarantool creates a snapshot containing current +-- data slice. +function wait_snapshot(timeout) + snaps = {} + xlogs = {} + local signature_str = tostring(box.info.signature) + signature_str = string.rjust(signature_str, 20, '0') + local exp_snap_filename = string.format('%s.snap', signature_str) + return test_run:wait_cond(function() + snaps = fio.glob(fio.pathjoin(box.cfg.memtx_dir, '*.snap')) + xlogs = fio.glob(fio.pathjoin(box.cfg.wal_dir, '*.xlog')) + return fio.basename(snaps[#snaps]) == exp_snap_filename + end, timeout) +end; + +-- Wait until snapshots count will be equal to the +-- checkpoint_count option. +function wait_snapshot_gc(timeout) + snaps = {} + xlogs = {} + return test_run:wait_cond(function() + snaps = fio.glob(fio.pathjoin(box.cfg.memtx_dir, '*.snap')) + xlogs = fio.glob(fio.pathjoin(box.cfg.wal_dir, '*.xlog')) + return #snaps == box.cfg.checkpoint_count + end, timeout) +end; + +test_run:cmd("setopt delimiter ''"); box.cfg{checkpoint_interval = PERIOD, checkpoint_count = 2 } @@ -23,41 +56,34 @@ no = 1 for i = 1, box.cfg.rows_per_wal + 10 do space:insert { no } no = no + 1 end -- second xlog for i = 1, box.cfg.rows_per_wal + 10 do space:insert { no } no = no + 1 end --- wait for last snapshot -fiber.sleep(1.5 * PERIOD) + +wait_snapshot(WAIT_COND_TIMEOUT) + -- third xlog for i = 1, box.cfg.rows_per_wal + 10 do space:insert { no } no = no + 1 end -- fourth xlog for i = 1, box.cfg.rows_per_wal + 10 do space:insert { no } no = no + 1 end --- wait for last snapshot - -test_run:cmd("setopt delimiter ';'") - -for i = 1, 100 do - fiber.sleep(PERIOD) - snaps = fio.glob(fio.pathjoin(box.cfg.memtx_dir, '*.snap')) - xlogs = fio.glob(fio.pathjoin(box.cfg.wal_dir, '*.xlog')) - - if #snaps == 2 then - break - end -end; - -test_run:cmd("setopt delimiter ''"); - - +wait_snapshot(WAIT_COND_TIMEOUT) +wait_snapshot_gc(WAIT_COND_TIMEOUT) #snaps == 2 or snaps #xlogs > 0 -fio.basename(snaps[1], '.snap') >= fio.basename(xlogs[1], '.xlog') - --- gh-2780 check that scheduled snapshots are performed -fiber.sleep(3 * PERIOD) --- check that it's not first snapshot -test_run:grep_log("default", "saving snapshot", 400) == nil -test_run:grep_log("default", "making snapshot", 400) ~= nil +-- gh-2780: check that a last snapshot mtime will be changed at +-- least two times. +test_run:cmd("setopt delimiter ';'") +last_mtime = fio.stat(snaps[#snaps]).mtime; +mtime_changes_cnt = 0; +test_run:wait_cond(function() + local mtime = fio.stat(snaps[#snaps]).mtime + if mtime ~= last_mtime then + mtime_changes_cnt = mtime_changes_cnt + 1 + last_mtime = mtime + end + return mtime_changes_cnt == 2 +end, WAIT_COND_TIMEOUT); +test_run:cmd("setopt delimiter ''"); -- restore default options box.cfg{checkpoint_interval = 3600 * 4, checkpoint_count = 4 }