summaryrefslogtreecommitdiff
path: root/storage/tokudb/hatoku_hton.cc
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2015-06-24 07:16:08 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2015-06-24 07:16:08 +0300
commit2e4984c185ddcd2da789017cd147338846ff409a (patch)
tree0293831900c860600efbaa747ea886d9d1cbf5bd /storage/tokudb/hatoku_hton.cc
parent792b53e80806df893ee62c9a1c1bd117114c8c6d (diff)
parenta6087e7dc1ef3561d8189c8db15e9591d0f9b520 (diff)
downloadmariadb-git-2e4984c185ddcd2da789017cd147338846ff409a.tar.gz
Merge tag 'mariadb-10.0.20' into 10.0-FusionIO10.0-FusionIO
Conflicts: storage/innobase/os/os0file.cc storage/xtradb/os/os0file.cc storage/xtradb/srv/srv0start.cc
Diffstat (limited to 'storage/tokudb/hatoku_hton.cc')
-rw-r--r--storage/tokudb/hatoku_hton.cc126
1 files changed, 99 insertions, 27 deletions
diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc
index 99f9cc56037..a804fc80489 100644
--- a/storage/tokudb/hatoku_hton.cc
+++ b/storage/tokudb/hatoku_hton.cc
@@ -780,7 +780,7 @@ extern "C" enum durability_properties thd_get_durability_property(const MYSQL_TH
#endif
// Determine if an fsync is used when a transaction is committed.
-static bool tokudb_fsync_on_commit(THD *thd, tokudb_trx_data *trx, DB_TXN *txn) {
+static bool tokudb_sync_on_commit(THD *thd, tokudb_trx_data *trx, DB_TXN *txn) {
#if MYSQL_VERSION_ID >= 50600
// Check the client durability property which is set during 2PC
if (thd_get_durability_property(thd) == HA_IGNORE_DURABILITY)
@@ -791,17 +791,19 @@ static bool tokudb_fsync_on_commit(THD *thd, tokudb_trx_data *trx, DB_TXN *txn)
if (txn->is_prepared(txn) && mysql_bin_log.is_open())
return false;
#endif
+ if (tokudb_fsync_log_period > 0)
+ return false;
return THDVAR(thd, commit_sync) != 0;
}
static int tokudb_commit(handlerton * hton, THD * thd, bool all) {
- TOKUDB_DBUG_ENTER("");
+ TOKUDB_DBUG_ENTER("%u", all);
DBUG_PRINT("trans", ("ending transaction %s", all ? "all" : "stmt"));
tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
DB_TXN **txn = all ? &trx->all : &trx->stmt;
DB_TXN *this_txn = *txn;
if (this_txn) {
- uint32_t syncflag = tokudb_fsync_on_commit(thd, trx, this_txn) ? 0 : DB_TXN_NOSYNC;
+ uint32_t syncflag = tokudb_sync_on_commit(thd, trx, this_txn) ? 0 : DB_TXN_NOSYNC;
if (tokudb_debug & TOKUDB_DEBUG_TXN) {
TOKUDB_TRACE("commit trx %u txn %p syncflag %u", all, this_txn, syncflag);
}
@@ -811,11 +813,11 @@ static int tokudb_commit(handlerton * hton, THD * thd, bool all) {
commit_txn_with_progress(this_txn, syncflag, thd);
// test hook to induce a crash on a debug build
DBUG_EXECUTE_IF("tokudb_crash_commit_after", DBUG_SUICIDE(););
- if (this_txn == trx->sp_level) {
- trx->sp_level = 0;
- }
- *txn = 0;
+ *txn = NULL;
trx->sub_sp_level = NULL;
+ if (this_txn == trx->sp_level || trx->all == NULL) {
+ trx->sp_level = NULL;
+ }
}
else if (tokudb_debug & TOKUDB_DEBUG_TXN) {
TOKUDB_TRACE("nothing to commit %d", all);
@@ -825,7 +827,7 @@ static int tokudb_commit(handlerton * hton, THD * thd, bool all) {
}
static int tokudb_rollback(handlerton * hton, THD * thd, bool all) {
- TOKUDB_DBUG_ENTER("");
+ TOKUDB_DBUG_ENTER("%u", all);
DBUG_PRINT("trans", ("aborting transaction %s", all ? "all" : "stmt"));
tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
DB_TXN **txn = all ? &trx->all : &trx->stmt;
@@ -836,11 +838,11 @@ static int tokudb_rollback(handlerton * hton, THD * thd, bool all) {
}
tokudb_cleanup_handlers(trx, this_txn);
abort_txn_with_progress(this_txn, thd);
- if (this_txn == trx->sp_level) {
- trx->sp_level = 0;
- }
- *txn = 0;
+ *txn = NULL;
trx->sub_sp_level = NULL;
+ if (this_txn == trx->sp_level || trx->all == NULL) {
+ trx->sp_level = NULL;
+ }
}
else {
if (tokudb_debug & TOKUDB_DEBUG_TXN) {
@@ -852,6 +854,13 @@ static int tokudb_rollback(handlerton * hton, THD * thd, bool all) {
}
#if TOKU_INCLUDE_XA
+static bool tokudb_sync_on_prepare(void) {
+ // skip sync of log if fsync log period > 0
+ if (tokudb_fsync_log_period > 0)
+ return false;
+ else
+ return true;
+}
static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) {
TOKUDB_DBUG_ENTER("");
@@ -866,6 +875,7 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) {
tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
DB_TXN* txn = all ? trx->all : trx->stmt;
if (txn) {
+ uint32_t syncflag = tokudb_sync_on_prepare() ? 0 : DB_TXN_NOSYNC;
if (tokudb_debug & TOKUDB_DEBUG_TXN) {
TOKUDB_TRACE("doing txn prepare:%d:%p", all, txn);
}
@@ -874,7 +884,7 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) {
thd_get_xid(thd, (MYSQL_XID*) &thd_xid);
// test hook to induce a crash on a debug build
DBUG_EXECUTE_IF("tokudb_crash_prepare_before", DBUG_SUICIDE(););
- r = txn->xa_prepare(txn, &thd_xid);
+ r = txn->xa_prepare(txn, &thd_xid, syncflag);
// test hook to induce a crash on a debug build
DBUG_EXECUTE_IF("tokudb_crash_prepare_after", DBUG_SUICIDE(););
}
@@ -939,7 +949,7 @@ cleanup:
#endif
static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint) {
- TOKUDB_DBUG_ENTER("");
+ TOKUDB_DBUG_ENTER("%p", savepoint);
int error;
SP_INFO save_info = (SP_INFO)savepoint;
tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
@@ -960,6 +970,9 @@ static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint) {
trx->sp_level = save_info->txn;
save_info->in_sub_stmt = false;
}
+ if (tokudb_debug & TOKUDB_DEBUG_TXN) {
+ TOKUDB_TRACE("begin txn %p", save_info->txn);
+ }
save_info->trx = trx;
error = 0;
cleanup:
@@ -967,7 +980,7 @@ cleanup:
}
static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *savepoint) {
- TOKUDB_DBUG_ENTER("");
+ TOKUDB_DBUG_ENTER("%p", savepoint);
int error;
SP_INFO save_info = (SP_INFO)savepoint;
DB_TXN* parent = NULL;
@@ -975,6 +988,9 @@ static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *save
tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
parent = txn_to_rollback->parent;
+ if (tokudb_debug & TOKUDB_DEBUG_TXN) {
+ TOKUDB_TRACE("rollback txn %p", txn_to_rollback);
+ }
if (!(error = txn_to_rollback->abort(txn_to_rollback))) {
if (save_info->in_sub_stmt) {
trx->sub_sp_level = parent;
@@ -988,24 +1004,27 @@ static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *save
}
static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoint) {
- TOKUDB_DBUG_ENTER("");
- int error;
-
+ TOKUDB_DBUG_ENTER("%p", savepoint);
+ int error = 0;
SP_INFO save_info = (SP_INFO)savepoint;
DB_TXN* parent = NULL;
DB_TXN* txn_to_commit = save_info->txn;
tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
parent = txn_to_commit->parent;
- if (!(error = txn_to_commit->commit(txn_to_commit, 0))) {
+ if (tokudb_debug & TOKUDB_DEBUG_TXN) {
+ TOKUDB_TRACE("commit txn %p", txn_to_commit);
+ }
+ DB_TXN *child = txn_to_commit->get_child(txn_to_commit);
+ if (child == NULL && !(error = txn_to_commit->commit(txn_to_commit, 0))) {
if (save_info->in_sub_stmt) {
trx->sub_sp_level = parent;
}
else {
trx->sp_level = parent;
}
- save_info->txn = NULL;
}
+ save_info->txn = NULL;
TOKUDB_DBUG_RETURN(error);
}
@@ -1393,8 +1412,6 @@ static MYSQL_SYSVAR_STR(data_dir, tokudb_data_dir, PLUGIN_VAR_READONLY, "TokuDB
static MYSQL_SYSVAR_STR(version, tokudb_version, PLUGIN_VAR_READONLY, "TokuDB Version", NULL, NULL, NULL);
-static MYSQL_SYSVAR_UINT(init_flags, tokudb_init_flags, PLUGIN_VAR_READONLY, "Sets TokuDB DB_ENV->open flags", NULL, NULL, tokudb_init_flags, 0, ~0U, 0);
-
static MYSQL_SYSVAR_UINT(write_status_frequency, tokudb_write_status_frequency, 0, "TokuDB frequency that show processlist updates status of writes", NULL, NULL, 1000, 0, ~0U, 0);
static MYSQL_SYSVAR_UINT(read_status_frequency, tokudb_read_status_frequency, 0, "TokuDB frequency that show processlist updates status of reads", NULL, NULL, 10000, 0, ~0U, 0);
static MYSQL_SYSVAR_INT(fs_reserve_percent, tokudb_fs_reserve_percent, PLUGIN_VAR_READONLY, "TokuDB file system space reserve (percent free required)", NULL, NULL, 5, 0, 100, 0);
@@ -1431,7 +1448,6 @@ static struct st_mysql_sys_var *tokudb_system_variables[] = {
MYSQL_SYSVAR(create_index_online),
MYSQL_SYSVAR(disable_prefetching),
MYSQL_SYSVAR(version),
- MYSQL_SYSVAR(init_flags),
MYSQL_SYSVAR(checkpointing_period),
MYSQL_SYSVAR(prelock_empty),
MYSQL_SYSVAR(checkpoint_lock),
@@ -1450,6 +1466,7 @@ static struct st_mysql_sys_var *tokudb_system_variables[] = {
MYSQL_SYSVAR(disable_slow_upsert),
#endif
MYSQL_SYSVAR(analyze_time),
+ MYSQL_SYSVAR(analyze_delete_fraction),
MYSQL_SYSVAR(fsync_log_period),
#if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL
MYSQL_SYSVAR(gdb_path),
@@ -1472,6 +1489,10 @@ static struct st_mysql_sys_var *tokudb_system_variables[] = {
MYSQL_SYSVAR(rpl_unique_checks_delay),
MYSQL_SYSVAR(rpl_lookup_rows),
MYSQL_SYSVAR(rpl_lookup_rows_delay),
+ MYSQL_SYSVAR(rpl_check_readonly),
+ MYSQL_SYSVAR(optimize_index_name),
+ MYSQL_SYSVAR(optimize_index_fraction),
+ MYSQL_SYSVAR(optimize_throttle),
NULL
};
@@ -1693,6 +1714,8 @@ static int tokudb_fractal_tree_info(TABLE *table, THD *thd) {
error = tmp_cursor->c_get(tmp_cursor, &curr_key, &curr_val, DB_NEXT);
if (!error) {
error = tokudb_report_fractal_tree_info_for_db(&curr_key, &curr_val, table, thd);
+ if (error)
+ error = 0; // ignore read uncommitted errors
}
if (!error && thd_killed(thd))
error = ER_QUERY_INTERRUPTED;
@@ -1964,6 +1987,35 @@ static int tokudb_fractal_tree_block_map_done(void *p) {
return 0;
}
+#if TOKU_INCLUDE_LOCK_TIMEOUT_QUERY_STRING
+struct tokudb_search_txn_extra {
+ bool match_found;
+ uint64_t match_txn_id;
+ uint64_t match_client_id;
+};
+
+static int tokudb_search_txn_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 = txn->get_client_id(txn);
+ struct tokudb_search_txn_extra *e = reinterpret_cast<struct tokudb_search_txn_extra *>(extra);
+ if (e->match_txn_id == txn_id) {
+ e->match_found = true;
+ e->match_client_id = client_id;
+ return 1;
+ }
+ return 0;
+}
+
+static bool tokudb_txn_id_to_client_id(THD *thd, uint64_t blocking_txnid, uint64_t *blocking_client_id) {
+ struct tokudb_search_txn_extra e = { false, blocking_txnid, 0};
+ (void) db_env->iterate_live_transactions(db_env, tokudb_search_txn_callback, &e);
+ if (e.match_found) {
+ *blocking_client_id = e.match_client_id;
+ }
+ return e.match_found;
+}
+#endif
+
static void tokudb_pretty_key(const DB *db, const DBT *key, const char *default_key, String *out) {
if (key->data == NULL) {
out->append(default_key);
@@ -2013,8 +2065,9 @@ static void tokudb_lock_timeout_callback(DB *db, uint64_t requesting_txnid, cons
// generate a JSON document with the lock timeout info
String log_str;
log_str.append("{");
+ uint64_t mysql_thread_id = thd->thread_id;
log_str.append("\"mysql_thread_id\":");
- log_str.append_ulonglong(thd->thread_id);
+ log_str.append_ulonglong(mysql_thread_id);
log_str.append(", \"dbname\":");
log_str.append("\""); log_str.append(tokudb_get_index_name(db)); log_str.append("\"");
log_str.append(", \"requesting_txnid\":");
@@ -2054,7 +2107,18 @@ static void tokudb_lock_timeout_callback(DB *db, uint64_t requesting_txnid, cons
}
// dump to stderr
if (lock_timeout_debug & 2) {
- sql_print_error("%s: %s", tokudb_hton_name, log_str.c_ptr());
+ sql_print_error("%s: lock timeout %s", tokudb_hton_name, log_str.c_ptr());
+ LEX_STRING *qs = thd_query_string(thd);
+ sql_print_error("%s: requesting_thread_id:%" PRIu64 " q:%.*s", tokudb_hton_name, mysql_thread_id, (int) qs->length, qs->str);
+#if TOKU_INCLUDE_LOCK_TIMEOUT_QUERY_STRING
+ uint64_t blocking_thread_id = 0;
+ if (tokudb_txn_id_to_client_id(thd, blocking_txnid, &blocking_thread_id)) {
+ String blocking_qs;
+ if (get_thread_query_string(blocking_thread_id, blocking_qs) == 0) {
+ sql_print_error("%s: blocking_thread_id:%" PRIu64 " q:%.*s", tokudb_hton_name, blocking_thread_id, blocking_qs.length(), blocking_qs.c_ptr());
+ }
+ }
+#endif
}
}
}
@@ -2064,6 +2128,7 @@ static struct st_mysql_information_schema tokudb_trx_information_schema = { MYSQ
static ST_FIELD_INFO tokudb_trx_field_info[] = {
{"trx_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE },
{"trx_mysql_thread_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE },
+ {"trx_time", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE },
{NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE}
};
@@ -2072,12 +2137,17 @@ struct tokudb_trx_extra {
TABLE *table;
};
-static int tokudb_trx_callback(uint64_t txn_id, uint64_t client_id, iterate_row_locks_callback iterate_locks, void *locks_extra, void *extra) {
+static int tokudb_trx_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 = txn->get_client_id(txn);
+ uint64_t start_time = txn->get_start_time(txn);
struct tokudb_trx_extra *e = reinterpret_cast<struct tokudb_trx_extra *>(extra);
THD *thd = e->thd;
TABLE *table = e->table;
table->field[0]->store(txn_id, false);
table->field[1]->store(client_id, false);
+ uint64_t tnow = (uint64_t) time(NULL);
+ table->field[2]->store(tnow >= start_time ? tnow - start_time : 0, false);
int error = schema_table_store_record(thd, table);
if (!error && thd_killed(thd))
error = ER_QUERY_INTERRUPTED;
@@ -2225,7 +2295,9 @@ struct tokudb_locks_extra {
TABLE *table;
};
-static int tokudb_locks_callback(uint64_t txn_id, uint64_t client_id, iterate_row_locks_callback iterate_locks, void *locks_extra, void *extra) {
+static int tokudb_locks_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 = txn->get_client_id(txn);
struct tokudb_locks_extra *e = reinterpret_cast<struct tokudb_locks_extra *>(extra);
THD *thd = e->thd;
TABLE *table = e->table;