summaryrefslogtreecommitdiff
path: root/storage/tokudb/hatoku_hton.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-12-29 13:23:18 +0100
committerSergei Golubchik <serg@mariadb.org>2016-12-29 13:23:18 +0100
commit4a5d25c338a5d1d2cc16343380193d6bf25ae6ae (patch)
tree73b84a9c8f3d5e3e3383fa79465b11f9ded512d3 /storage/tokudb/hatoku_hton.cc
parent48dc7cc66ef5b69fcf28ec0b2ecf0338c188cf4e (diff)
parentc13b5011629b5ff7b969d648265002e4d1ba94c2 (diff)
downloadmariadb-git-4a5d25c338a5d1d2cc16343380193d6bf25ae6ae.tar.gz
Merge branch '10.1' into 10.2
Diffstat (limited to 'storage/tokudb/hatoku_hton.cc')
-rw-r--r--storage/tokudb/hatoku_hton.cc88
1 files changed, 81 insertions, 7 deletions
diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc
index 6a32f35479e..c3fb6afed73 100644
--- a/storage/tokudb/hatoku_hton.cc
+++ b/storage/tokudb/hatoku_hton.cc
@@ -55,6 +55,7 @@ static bool tokudb_show_status(
static void tokudb_handle_fatal_signal(handlerton* hton, THD* thd, int sig);
#endif
static int tokudb_close_connection(handlerton* hton, THD* thd);
+static void tokudb_kill_query(handlerton *hton, THD *thd, enum thd_kill_levels level);
static int tokudb_commit(handlerton* hton, THD* thd, bool all);
static int tokudb_rollback(handlerton* hton, THD* thd, bool all);
#if TOKU_INCLUDE_XA
@@ -147,6 +148,11 @@ static void tokudb_lock_timeout_callback(
const DBT* right_key,
uint64_t blocking_txnid);
+static void tokudb_lock_wait_needed_callback(
+ void* arg,
+ uint64_t requesting_txnid,
+ uint64_t blocking_txnid);
+
#define ASSERT_MSGLEN 1024
void toku_hton_assert_fail(
@@ -331,6 +337,7 @@ static int tokudb_init_func(void *p) {
tokudb_hton->create = tokudb_create_handler;
tokudb_hton->close_connection = tokudb_close_connection;
+ tokudb_hton->kill_query = tokudb_kill_query;
tokudb_hton->savepoint_offset = sizeof(SP_INFO_T);
tokudb_hton->savepoint_set = tokudb_savepoint;
@@ -531,6 +538,8 @@ static int tokudb_init_func(void *p) {
db_env->change_fsync_log_period(db_env, tokudb::sysvars::fsync_log_period);
db_env->set_lock_timeout_callback(db_env, tokudb_lock_timeout_callback);
+ db_env->set_dir_per_db(db_env, tokudb::sysvars::dir_per_db);
+ db_env->set_lock_wait_callback(db_env, tokudb_lock_wait_needed_callback);
db_env->set_loader_memory_size(
db_env,
@@ -753,6 +762,12 @@ static int tokudb_close_connection(handlerton* hton, THD* thd) {
return error;
}
+void tokudb_kill_query(handlerton *hton, THD *thd, enum thd_kill_levels level) {
+ TOKUDB_DBUG_ENTER("");
+ db_env->kill_waiter(db_env, thd);
+ DBUG_VOID_RETURN;
+}
+
bool tokudb_flush_logs(handlerton * hton) {
TOKUDB_DBUG_ENTER("");
int error;
@@ -872,9 +887,9 @@ static int tokudb_commit(handlerton * hton, THD * thd, bool all) {
tokudb_sync_on_commit(thd, trx, this_txn) ? 0 : DB_TXN_NOSYNC;
TOKUDB_TRACE_FOR_FLAGS(
TOKUDB_DEBUG_TXN,
- "commit trx %u txn %p syncflag %u",
+ "commit trx %u txn %p %" PRIu64 " syncflag %u",
all,
- this_txn,
+ this_txn, this_txn->id64(this_txn),
syncflag);
// test hook to induce a crash on a debug build
DBUG_EXECUTE_IF("tokudb_crash_commit_before", DBUG_SUICIDE(););
@@ -903,9 +918,9 @@ static int tokudb_rollback(handlerton * hton, THD * thd, bool all) {
if (this_txn) {
TOKUDB_TRACE_FOR_FLAGS(
TOKUDB_DEBUG_TXN,
- "rollback %u txn %p",
+ "rollback %u txn %p %" PRIu64,
all,
- this_txn);
+ this_txn, this_txn->id64(this_txn));
tokudb_cleanup_handlers(trx, this_txn);
abort_txn_with_progress(this_txn, thd);
*txn = NULL;
@@ -951,9 +966,9 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) {
uint32_t syncflag = tokudb_sync_on_prepare() ? 0 : DB_TXN_NOSYNC;
TOKUDB_TRACE_FOR_FLAGS(
TOKUDB_DEBUG_XA,
- "doing txn prepare:%d:%p",
+ "doing txn prepare:%d:%p %" PRIu64,
all,
- txn);
+ txn, txn->id64(txn));
// a TOKU_XA_XID is identical to a MYSQL_XID
TOKU_XA_XID thd_xid;
thd_get_xid(thd, (MYSQL_XID*) &thd_xid);
@@ -1569,7 +1584,9 @@ static int tokudb_search_txn_callback(
void* extra) {
uint64_t txn_id = txn->id64(txn);
- uint64_t client_id = txn->get_client_id(txn);
+ uint64_t client_id;
+ void *client_extra;
+ txn->get_client_id(txn, &client_id, &client_extra);
struct tokudb_search_txn_extra* e =
reinterpret_cast<struct tokudb_search_txn_extra*>(extra);
if (e->match_txn_id == txn_id) {
@@ -1747,6 +1764,63 @@ static void tokudb_lock_timeout_callback(
}
}
+extern "C" int thd_rpl_deadlock_check(MYSQL_THD thd, MYSQL_THD other_thd);
+
+struct tokudb_search_txn_thd {
+ bool match_found;
+ uint64_t match_txn_id;
+ THD *match_client_thd;
+};
+
+static int tokudb_search_txn_thd_callback(
+ DB_TXN* txn,
+ iterate_row_locks_callback iterate_locks,
+ void* locks_extra,
+ void* extra) {
+
+ uint64_t txn_id = txn->id64(txn);
+ uint64_t client_id;
+ void *client_extra;
+ txn->get_client_id(txn, &client_id, &client_extra);
+ struct tokudb_search_txn_thd* e =
+ reinterpret_cast<struct tokudb_search_txn_thd*>(extra);
+ if (e->match_txn_id == txn_id) {
+ e->match_found = true;
+ e->match_client_thd = reinterpret_cast<THD *>(client_extra);
+ return 1;
+ }
+ return 0;
+}
+
+static bool tokudb_txn_id_to_thd(
+ uint64_t txnid,
+ THD **out_thd) {
+
+ struct tokudb_search_txn_thd e = {
+ false,
+ txnid,
+ 0
+ };
+ db_env->iterate_live_transactions(db_env, tokudb_search_txn_thd_callback, &e);
+ if (e.match_found) {
+ *out_thd = e.match_client_thd;
+ }
+ return e.match_found;
+}
+
+static void tokudb_lock_wait_needed_callback(
+ void *arg,
+ uint64_t requesting_txnid,
+ uint64_t blocking_txnid) {
+
+ THD *requesting_thd;
+ THD *blocking_thd;
+ if (tokudb_txn_id_to_thd(requesting_txnid, &requesting_thd) &&
+ tokudb_txn_id_to_thd(blocking_txnid, &blocking_thd)) {
+ thd_rpl_deadlock_check (requesting_thd, blocking_thd);
+ }
+}
+
// Retrieves variables for information_schema.global_status.
// Names (columnname) are automatically converted to upper case,
// and prefixed with "TOKUDB_"