diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c index 85152a202e0390fd6f14ed60beef5a8f73a8e6bc..be672282a92bb13f132117b2f184b9b5a6f93069 100644 --- a/src/box/memtx_space.c +++ b/src/box/memtx_space.c @@ -263,17 +263,22 @@ memtx_space_replace_all_keys(struct space *space, struct tuple *old_tuple, return -1; assert(pk->def->opts.is_unique); - if (memtx_tx_manager_use_mvcc_engine) { - struct txn *txn = in_txn(); - struct txn_stmt *stmt = - txn == NULL ? NULL : txn_current_stmt(txn); - if (stmt != NULL) { - return memtx_tx_history_add_stmt(stmt, old_tuple, new_tuple, - mode, result); - } else { - /** Ephemeral space */ - assert(space->def->id == 0); - } + /* Replace must be done in transaction, except ephemeral spaces. */ + assert(space->def->opts.is_ephemeral || + (in_txn() != NULL && txn_current_stmt(in_txn()) != NULL)); + /* + * Don't use MVCC engine for ephemeral in any case. + * MVCC engine requires txn to be present as a storage for + * reads/writes/conflicts. + * Also now there's not way to MVCC engine off: once MVCC engine + * starts to manage a space - direct access to it must be prohibited. + * Since modification of ephemeral spaces are allowed without txn, + * we must not use MVCC for those spaces even if txn is present now. + */ + if (memtx_tx_manager_use_mvcc_engine && !space->def->opts.is_ephemeral) { + struct txn_stmt *stmt = txn_current_stmt(in_txn()); + return memtx_tx_history_add_stmt(stmt, old_tuple, new_tuple, + mode, result); } /* diff --git a/src/box/memtx_tx.c b/src/box/memtx_tx.c index 4b59789e40ee35017a0c5a456d23260136bee237..f871698de9d513c3f2220a3fb9ac6143f26097ca 100644 --- a/src/box/memtx_tx.c +++ b/src/box/memtx_tx.c @@ -636,6 +636,7 @@ memtx_tx_history_add_stmt(struct txn_stmt *stmt, struct tuple *old_tuple, struct tuple *new_tuple, enum dup_replace_mode mode, struct tuple **result) { + assert(stmt != NULL); assert(new_tuple != NULL || old_tuple != NULL); struct space *space = stmt->space; assert(space != NULL); @@ -1137,6 +1138,8 @@ memtx_tx_track_read(struct txn *txn, struct space *space, struct tuple *tuple) return 0; if (space == NULL) return 0; + if (space->def->opts.is_ephemeral) + return 0; struct memtx_story *story; struct tx_read_tracker *tracker = NULL;