diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc index 8c27328020cdb89423aa144ec6bee1be5a757473..cc92cf7b75fbfe8de9d24636bd4a1fdb4ef12c24 100644 --- a/src/box/lua/call.cc +++ b/src/box/lua/call.cc @@ -360,10 +360,15 @@ lbox_commit(lua_State * /* L */) * Do nothing if transaction is not started, * it's the same as BEGIN + COMMIT. */ - if (txn) { + if (! txn) + return 0; + try { txn_commit(txn); - txn_finish(txn); + } catch (...) { + txn_rollback(); + throw; } + txn_finish(txn); return 0; } @@ -615,6 +620,13 @@ execute_call(lua_State *L, struct request *request, struct obuf *out) void box_lua_call(struct request *request, struct obuf *out) { + auto txn_guard = make_scoped_guard([=] { + struct txn *txn = in_txn(); + if (txn) { + say_warn("transaction is active at CALL return"); + txn_rollback(); + } + }); lua_State *L = NULL; try { L = lua_newthread(tarantool_L); diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua index be134f513847b37597850c49776af67349e09f96..55ee8e14fdada0b749ba62297ed5873f90e3231a 100644 --- a/src/box/lua/load_cfg.lua +++ b/src/box/lua/load_cfg.lua @@ -21,7 +21,8 @@ local default_sophia_cfg = { memory_limit = 0, threads = 5, node_size = 134217728, - page_size = 131072 + page_size = 131072, + compression = "none" } -- all available options @@ -65,7 +66,8 @@ local sophia_template_cfg = { memory_limit = 'number', threads = 'number', node_size = 'number', - page_size = 'number' + page_size = 'number', + compression = 'string' } -- types of available options diff --git a/src/box/sophia_engine.cc b/src/box/sophia_engine.cc index 2d56e7c152246b2cf4ede600aae9388678f9e961..8f294a7687bd69836ac3a1f0bc630cdb8dd89b87 100644 --- a/src/box/sophia_engine.cc +++ b/src/box/sophia_engine.cc @@ -76,6 +76,15 @@ void sophia_info(void (*callback)(const char*, const char*, void*), void *arg) sp_destroy(cur); } +static struct tuple * +sophia_replace(struct space *space, struct tuple *old_tuple, + struct tuple *new_tuple, + enum dup_replace_mode mode) +{ + Index *index = index_find(space, 0); + return index->replace(old_tuple, new_tuple, mode); +} + struct SophiaSpace: public Handler { SophiaSpace(Engine*); }; @@ -88,8 +97,7 @@ static void sophia_recovery_end(struct space *space) { engine_recovery *r = &space->handler->recovery; - r->state = READY_ALL_KEYS; - r->replace = sophia_replace; + r->state = READY_ALL_KEYS; r->recover = space_noop; } @@ -97,7 +105,7 @@ static void sophia_recovery_end_snapshot(struct space *space) { engine_recovery *r = &space->handler->recovery; - r->state = READY_PRIMARY_KEY; + r->state = READY_PRIMARY_KEY; r->recover = sophia_recovery_end; } @@ -118,7 +126,7 @@ SophiaEngine::SophiaEngine() env = NULL; recovery.state = READY_NO_KEYS; recovery.recover = sophia_recovery_begin_snapshot; - recovery.replace = sophia_replace_recover; + recovery.replace = sophia_replace; } void @@ -148,10 +156,20 @@ SophiaEngine::open() return new SophiaSpace(this); } +static inline void +sophia_snapshot_recover(void *env, int64_t lsn); + void SophiaEngine::end_recover_snapshot() { - recovery.replace = sophia_replace_recover; + /* create snapshot reference after tarantool + * recovery, to ensure correct ref counting + * with spaces involved in snapshot. */ + if (m_checkpoint_lsn >= 0) { + sophia_snapshot_recover(env, m_checkpoint_lsn); + m_prev_checkpoint_lsn = m_checkpoint_lsn; + m_checkpoint_lsn = -1; + } recovery.recover = sophia_recovery_end_snapshot; } @@ -237,29 +255,17 @@ SophiaEngine::join(Relay *relay) sp_destroy(db_cursor); } -static inline void -sophia_snapshot_recover(void *env, int64_t lsn); - void SophiaEngine::end_recovery() { if (recovery_complete) return; - /* create snapshot reference after tarantool - * recovery, to ensure correct ref - * counting */ - if (m_checkpoint_lsn >= 0) { - sophia_snapshot_recover(env, m_checkpoint_lsn); - m_prev_checkpoint_lsn = m_checkpoint_lsn; - m_checkpoint_lsn = -1; - } /* complete two-phase recovery */ int rc = sp_open(env); if (rc == -1) sophia_raise(env); - recovery.state = READY_NO_KEYS; - recovery.replace = sophia_replace; - recovery.recover = space_noop; + recovery.state = READY_NO_KEYS; + recovery.recover = space_noop; recovery_complete = 1; } @@ -377,8 +383,9 @@ SophiaEngine::commit(struct txn *txn) if (rc == -1) sophia_raise(env); rc = sp_commit(txn->engine_tx); - if (rc == -1) + if (rc == -1) { sophia_raise(env); + } assert(rc == 0); } diff --git a/src/box/sophia_index.cc b/src/box/sophia_index.cc index d81d2b6ca21575136899f70749e3f34db79535a7..e7b47577c10c105d0e5f24447167cdd7996f5ca3 100644 --- a/src/box/sophia_index.cc +++ b/src/box/sophia_index.cc @@ -78,38 +78,6 @@ sophia_index_get(void *env, void *db, void *tx, const char *key, size_t keysize, return tuple_new(format, (char*)value, (char*)value + valuesize); } -struct tuple* -sophia_replace_recover(struct space *space, - struct tuple *old_tuple, struct tuple *new_tuple, - enum dup_replace_mode) -{ - SophiaIndex *index = (SophiaIndex*)index_find(space, 0); - struct txn *txn = in_txn(); - assert(txn != NULL && txn->engine_tx != NULL); - int rc; - if (old_tuple) { - rc = sophia_index_stmt(txn->engine_tx, index->db, 1, - index->key_def, - old_tuple); - } else { - rc = sophia_index_stmt(txn->engine_tx, index->db, 0, - index->key_def, - new_tuple); - } - if (rc == -1) - sophia_raise(index->env); - return NULL; -} - -struct tuple * -sophia_replace(struct space *space, - struct tuple *old_tuple, struct tuple *new_tuple, - enum dup_replace_mode mode) -{ - Index *index = index_find(space, 0); - return index->replace(old_tuple, new_tuple, mode); -} - static inline int sophia_index_compare(char *a, size_t asz __attribute__((unused)), char *b, size_t bsz __attribute__((unused)), @@ -139,6 +107,8 @@ sophia_configure(struct space *space, struct key_def *key_def) snprintf(pointer, sizeof(pointer), "pointer: %p", (void*)sophia_index_compare); snprintf(pointer_arg, sizeof(pointer_arg), "pointer: %p", (void*)key_def); sp_set(c, name, pointer, pointer_arg); + snprintf(name, sizeof(name), "db.%" PRIu32 ".compression", key_def->space_id); + sp_set(c, name, cfg_gets("sophia.compression")); snprintf(name, sizeof(name), "db.%" PRIu32, key_def->space_id); void *db = sp_get(c, name); if (db == NULL) @@ -166,16 +136,6 @@ SophiaIndex::SophiaIndex(struct key_def *key_def_arg __attribute__((unused))) tuple_format_ref(space->format, 1); } -void -sophia_complete_recovery(struct space *space) -{ - SophiaIndex *index = (SophiaIndex*)index_find(space, 0); - assert(space->handler->recovery.recover == space_noop); - int rc = sp_open(index->db); - if (rc == -1) - sophia_raise(index->env); -} - SophiaIndex::~SophiaIndex() { if (m_position != NULL) { diff --git a/src/box/sophia_index.h b/src/box/sophia_index.h index f1d2752c6372d25ffcc831bd8f721a219f404573..8a9bacc0c08bc09bc958a47302e05bf003a1c5bd 100644 --- a/src/box/sophia_index.h +++ b/src/box/sophia_index.h @@ -52,17 +52,4 @@ class SophiaIndex: public Index { void *db; }; -struct tuple * -sophia_replace_recover(struct space*, - struct tuple*, struct tuple*, - enum dup_replace_mode); - -struct tuple * -sophia_replace(struct space*, - struct tuple*, struct tuple*, - enum dup_replace_mode); - -void -sophia_complete_recovery(struct space*); - #endif /* TARANTOOL_BOX_SOPHIA_INDEX_H_INCLUDED */ diff --git a/src/box/txn.cc b/src/box/txn.cc index 30c04c3aa0d5ed065fe4fcb57212dca9a77f7114..3d4ae07f2d6d4cf15cf84c081c172e5f9ebb9cb7 100644 --- a/src/box/txn.cc +++ b/src/box/txn.cc @@ -208,6 +208,14 @@ txn_commit(struct txn *txn) struct txn_stmt *stmt; /* if (!txn->autocommit && txn->n_stmts && engine_no_yield(txn->engine)) */ + /* xxx: temporary workaround to handle transaction + * conflicts with sophia. + */ + if (txn->engine) { + txn->engine->commit(txn); + txn->engine_tx = NULL; + } + trigger_clear(&txn->fiber_on_yield); trigger_clear(&txn->fiber_on_stop); @@ -229,8 +237,10 @@ txn_commit(struct txn *txn) tnt_raise(LoggedError, ER_WAL_IO); txn->signature = res; } + /* if (txn->engine) txn->engine->commit(txn); + */ trigger_run(&txn->on_commit, txn); /* must not throw. */ } diff --git a/test/box/admin.result b/test/box/admin.result index 807cff8b1fdc2191de54ab3bfe0745a8b11243df..973347aa1bf609cbebd3b827727fad26fa23c4a6 100644 --- a/test/box/admin.result +++ b/test/box/admin.result @@ -26,9 +26,10 @@ box.cfg slab_alloc_arena: 0.1 sophia: page_size: 131072 + memory_limit: 0 threads: 5 node_size: 134217728 - memory_limit: 0 + compression: none listen: <uri> logger_nonblock: true snap_dir: . diff --git a/test/box/cfg.result b/test/box/cfg.result index 61e12fb73d441be2a8f7e3918be35412a7201ef0..fc615be3ed65375fb4c314c964cfb8460d8efa40 100644 --- a/test/box/cfg.result +++ b/test/box/cfg.result @@ -2,7 +2,7 @@ --# push filter 'admin: .*' to 'admin: <uri>' box.cfg.nosuchoption = 1 --- -- error: '[string "-- load_cfg.lua - internal file..."]:260: Attempt to modify a read-only +- error: '[string "-- load_cfg.lua - internal file..."]:262: Attempt to modify a read-only table' ... t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end @@ -36,7 +36,7 @@ t -- must be read-only box.cfg() --- -- error: '[string "-- load_cfg.lua - internal file..."]:206: bad argument #1 to ''pairs'' +- error: '[string "-- load_cfg.lua - internal file..."]:208: bad argument #1 to ''pairs'' (table expected, got nil)' ... t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end @@ -70,23 +70,23 @@ t -- check that cfg with unexpected parameter fails. box.cfg{sherlock = 'holmes'} --- -- error: '[string "-- load_cfg.lua - internal file..."]:162: Error: cfg parameter +- error: '[string "-- load_cfg.lua - internal file..."]:164: Error: cfg parameter ''sherlock'' is unexpected' ... -- check that cfg with unexpected type of parameter failes box.cfg{listen = {}} --- -- error: '[string "-- load_cfg.lua - internal file..."]:182: Error: cfg parameter +- error: '[string "-- load_cfg.lua - internal file..."]:184: Error: cfg parameter ''listen'' should be one of types: string, number' ... box.cfg{wal_dir = 0} --- -- error: '[string "-- load_cfg.lua - internal file..."]:176: Error: cfg parameter +- error: '[string "-- load_cfg.lua - internal file..."]:178: Error: cfg parameter ''wal_dir'' should be of type string' ... box.cfg{coredump = 'true'} --- -- error: '[string "-- load_cfg.lua - internal file..."]:176: Error: cfg parameter +- error: '[string "-- load_cfg.lua - internal file..."]:178: Error: cfg parameter ''coredump'' should be of type boolean' ... -------------------------------------------------------------------------------- @@ -94,17 +94,17 @@ box.cfg{coredump = 'true'} -------------------------------------------------------------------------------- box.cfg{slab_alloc_arena = "100500"} --- -- error: '[string "-- load_cfg.lua - internal file..."]:176: Error: cfg parameter +- error: '[string "-- load_cfg.lua - internal file..."]:178: Error: cfg parameter ''slab_alloc_arena'' should be of type number' ... box.cfg{sophia = "sophia"} --- -- error: '[string "-- load_cfg.lua - internal file..."]:170: Error: cfg parameter +- error: '[string "-- load_cfg.lua - internal file..."]:172: Error: cfg parameter ''sophia'' should be a table' ... box.cfg{sophia = {threads = "threads"}} --- -- error: '[string "-- load_cfg.lua - internal file..."]:176: Error: cfg parameter +- error: '[string "-- load_cfg.lua - internal file..."]:178: Error: cfg parameter ''sophia.threads'' should be of type number' ... -------------------------------------------------------------------------------- diff --git a/test/sophia/options.result b/test/sophia/options.result index 75c23ee4a8d5f129793fca2178484888994edce6..4249fd3862eb027730828d2108c946b35d499774 100644 --- a/test/sophia/options.result +++ b/test/sophia/options.result @@ -1,9 +1,10 @@ box.cfg.sophia --- - page_size: 131072 + memory_limit: 0 threads: 0 node_size: 134217728 - memory_limit: 0 + compression: none ... box.cfg.sophia.threads = 3 --- diff --git a/third_party/sophia b/third_party/sophia index d7010473cfe8ceb7b1254183a77d286aa0cd3b11..68ce375fb75f9194edf967d96d0ff5dc04f3724f 160000 --- a/third_party/sophia +++ b/third_party/sophia @@ -1 +1 @@ -Subproject commit d7010473cfe8ceb7b1254183a77d286aa0cd3b11 +Subproject commit 68ce375fb75f9194edf967d96d0ff5dc04f3724f