diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-03-16 14:35:42 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-03-16 15:49:53 +0200 |
commit | 84129fb1b52a0631f05ba193f464665c5b369e77 (patch) | |
tree | 98d4cec4446a5d2ce541438402f5dbf1931b5a63 | |
parent | 98eb9518db1da854048b09d94244a982a1d32f9a (diff) | |
download | mariadb-git-84129fb1b52a0631f05ba193f464665c5b369e77.tar.gz |
After-merge fix for commit 98eb9518db1da854048b09d94244a982a1d32f9a
The merge only covered 10.1 up to
commit 4d248974e00eb915a2fc433cc6b2fb5146281594.
Actually merge the changes up to
commit 0a534348c75cf435d2017959855de2efa798fd0b.
Also, remove the unused InnoDB field trx_t::abort_type.
36 files changed, 176 insertions, 398 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index 9e50bb86933..a13617cc9cb 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1176,11 +1176,7 @@ int main(int argc,char *argv[]) close(stdout_fileno_copy); /* Clean up dup(). */ } - if (load_defaults("my",load_default_groups,&argc,&argv)) - { - my_end(0); - exit(1); - } + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; if ((status.exit_status= get_options(argc, (char **) argv))) { diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 14a47bce352..0f153fde158 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1133,6 +1133,8 @@ int main(int argc, char **argv) char self_name[FN_REFLEN + 1]; MY_INIT(argv[0]); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); + defaults_argv= argv; /* Must be freed by 'free_defaults' */ #if __WIN__ if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0) @@ -1145,10 +1147,6 @@ int main(int argc, char **argv) init_dynamic_string(&conn_args, "", 512, 256)) die("Out of memory"); - if (load_defaults("my", load_default_groups, &argc, &argv)) - die(NULL); - defaults_argv= argv; /* Must be freed by 'free_defaults' */ - if (handle_options(&argc, &argv, my_long_options, get_one_option)) die(NULL); if (debug_info_flag) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index bd80dd01a1e..5e7fb80b2b5 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -320,8 +320,7 @@ int main(int argc,char *argv[]) MY_INIT(argv[0]); mysql_init(&mysql); sf_leaking_memory=1; /* don't report memory leaks on early exits */ - if ((error= load_defaults("my",load_default_groups,&argc,&argv))) - goto err1; + load_defaults_or_exit("my", load_default_groups, &argc, &argv); save_argv = argv; /* Save for free_defaults */ if ((error=handle_options(&argc, &argv, my_long_options, get_one_option))) @@ -501,10 +500,8 @@ err2: my_free(shared_memory_base_name); #endif free_defaults(save_argv); -err1: my_end(my_end_arg); - exit(error); - return 0; + return error; } diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 9d18c45d7a1..9a3a4aaa9eb 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -2948,9 +2948,7 @@ int main(int argc, char** argv) my_init_time(); // for time functions tzset(); // set tzname - if (load_defaults("my", load_groups, &argc, &argv)) - exit(1); - + load_defaults_or_exit("my", load_groups, &argc, &argv); defaults_argv= argv; if (!(binlog_filter= new Rpl_filter)) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index d3bb5c48837..45ad2612d44 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1166,9 +1166,7 @@ int main(int argc, char **argv) /* ** Check out the args */ - if (load_defaults("my", load_default_groups, &argc, &argv)) - goto end2; - + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv= argv; if (get_options(&argc, &argv)) goto end1; @@ -1244,7 +1242,6 @@ int main(int argc, char **argv) my_free(shared_memory_base_name); mysql_library_end(); free_defaults(defaults_argv); - end2: my_end(my_end_arg); return ret; } /* main */ diff --git a/client/mysqldump.c b/client/mysqldump.c index 57d087b331b..9a89c805955 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -980,8 +980,7 @@ static int get_options(int *argc, char ***argv) opt_net_buffer_length= *mysql_params->p_net_buffer_length; md_result_file= stdout; - if (load_defaults("my",load_default_groups,argc,argv)) - return 1; + load_defaults_or_exit("my", load_default_groups, argc, argv); defaults_argv= *argv; if (my_hash_init(&ignore_table, charset_info, 16, 0, 0, diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 6da14aa1520..02caf2df198 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -643,8 +643,7 @@ int main(int argc, char **argv) MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ - if (load_defaults("my",load_default_groups,&argc,&argv)) - return 1; + load_defaults_or_exit("my", load_default_groups, &argc, &argv); /* argv is changed in the program */ argv_to_free= argv; if (get_options(&argc, &argv)) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 0a761edff4c..65b915655a6 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -72,8 +72,7 @@ int main(int argc, char **argv) static char **defaults_argv; MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ - if (load_defaults("my",load_default_groups,&argc,&argv)) - exit(1); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; get_options(&argc,&argv); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index f0ad2f40abc..05bc9430541 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -325,11 +325,7 @@ int main(int argc, char **argv) MY_INIT(argv[0]); sf_leaking_memory=1; /* don't report memory leaks on early exits */ - if (load_defaults("my",load_default_groups,&argc,&argv)) - { - my_end(0); - exit(1); - } + load_defaults_or_exit("my", load_default_groups, &argc, &argv); defaults_argv=argv; if (get_options(&argc,&argv)) { diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 4003e57226d..6f041e92a32 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7298,9 +7298,7 @@ get_one_option(int optid, const struct my_option *opt, char *argument) int parse_args(int argc, char **argv) { - if (load_defaults("my",load_default_groups,&argc,&argv)) - exit(1); - + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; if ((handle_options(&argc, &argv, my_long_options, get_one_option))) diff --git a/extra/mariabackup/xbcloud.cc b/extra/mariabackup/xbcloud.cc index 56661b03dd0..878b4c81023 100644 --- a/extra/mariabackup/xbcloud.cc +++ b/extra/mariabackup/xbcloud.cc @@ -443,9 +443,7 @@ int parse_args(int argc, char **argv) exit(EXIT_FAILURE); } - if (load_defaults("my", load_default_groups, &argc, &argv)) { - exit(EXIT_FAILURE); - } + load_defaults_or_exit("my", load_default_groups, &argc, &argv); if (handle_options(&argc, &argv, my_long_options, get_one_option)) { exit(EXIT_FAILURE); diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 78003cd64af..e560ce1e042 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -5209,10 +5209,8 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) *argv_client = argv; *argv_server = argv; - if (load_defaults(conf_file, xb_server_default_groups, - &argc_server, argv_server)) { - exit(EXIT_FAILURE); - } + load_defaults_or_exit(conf_file, xb_server_default_groups, + &argc_server, argv_server); int n; for (n = 0; (*argv_server)[n]; n++) {}; @@ -5262,10 +5260,8 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) xb_server_options, xb_get_one_option))) exit(ho_error); - if (load_defaults(conf_file, xb_client_default_groups, - &argc_client, argv_client)) { - exit(EXIT_FAILURE); - } + load_defaults_or_exit(conf_file, xb_client_default_groups, + &argc_client, argv_client); for (n = 0; (*argv_client)[n]; n++) {}; argc_client = n; diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c index 78940e02ca4..07c95a79ddc 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -206,6 +206,9 @@ int main(int argc, char **argv) if ((error= load_defaults(config_file, (const char **) load_default_groups, &count, &arguments))) { + my_end(0); + if (error == 4) + return 0; if (verbose && opt_defaults_file_used) { if (error == 1) @@ -216,8 +219,7 @@ int main(int argc, char **argv) fprintf(stderr, "WARNING: Defaults file '%s' is not a regular file!\n", config_file); } - error= 2; - exit(error); + return 2; } for (argument= arguments+1 ; *argument ; argument++) diff --git a/include/my_default.h b/include/my_default.h index 0ed94b09492..bd3a21f03a8 100644 --- a/include/my_default.h +++ b/include/my_default.h @@ -45,6 +45,13 @@ extern void free_defaults(char **argv); extern void my_print_default_files(const char *conf_file); extern void print_defaults(const char *conf_file, const char **groups); + +/** Simplify load_defaults() common use */ +#define load_defaults_or_exit(A, B, C, D) switch (load_defaults(A, B, C, D)) { \ + case 0: break; \ + case 4: my_end(0); exit(0); \ + default: my_end(0); exit(1); } + C_MODE_END #endif /* MY_DEFAULT_INCLUDED */ diff --git a/mysys/my_default.c b/mysys/my_default.c index 544a6392e4d..9efbf054131 100644 --- a/mysys/my_default.c +++ b/mysys/my_default.c @@ -631,7 +631,7 @@ int my_load_defaults(const char *conf_file, const char **groups, if (!my_getopt_is_args_separator((*argv)[i])) /* skip arguments separator */ printf("%s ", (*argv)[i]); puts(""); - exit(0); + DBUG_RETURN(4); } if (default_directories) @@ -641,7 +641,7 @@ int my_load_defaults(const char *conf_file, const char **groups, err: fprintf(stderr,"Fatal error in defaults handling. Program aborted\n"); - return 2; + DBUG_RETURN(2); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6783231022c..01f5febd5a0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5659,8 +5659,7 @@ int mysqld_main(int argc, char **argv) orig_argc= argc; orig_argv= argv; my_getopt_use_args_separator= TRUE; - if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv)) - return 1; + load_defaults_or_exit(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv); my_getopt_use_args_separator= FALSE; defaults_argc= argc; defaults_argv= argv; diff --git a/sql/tztime.cc b/sql/tztime.cc index a9db91668bb..ccd5ed4a86b 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2687,9 +2687,7 @@ main(int argc, char **argv) char **default_argv; MY_INIT(argv[0]); - if (load_defaults("my",load_default_groups,&argc,&argv)) - exit(1); - + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; if ((handle_options(&argc, &argv, my_long_options, get_one_option))) diff --git a/storage/archive/archive_reader.c b/storage/archive/archive_reader.c index 1b15fa16ce4..e87bc70ade4 100644 --- a/storage/archive/archive_reader.c +++ b/storage/archive/archive_reader.c @@ -408,8 +408,7 @@ static void print_version(void) static void get_options(int *argc, char ***argv) { - if (load_defaults("my", load_default_groups, argc, argv)) - exit(1); + load_defaults_or_exit("my", load_default_groups, argc, argv); default_argv= *argv; handle_options(argc, argv, my_long_options, get_one_option); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 1b230c4b91d..2a860ff8e7c 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1254,7 +1254,9 @@ innobase_close_connection( THD* thd); /*!< in: MySQL thread handle for which to close the connection */ -static void innobase_kill_query(handlerton *hton, THD* thd, enum thd_kill_levels level); +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels); static void innobase_commit_ordered(handlerton *hton, THD* thd, bool all); /*****************************************************************//** @@ -5299,21 +5301,11 @@ innobase_close_connection( UNIV_INTERN void lock_cancel_waiting_and_release(lock_t* lock); -/*****************************************************************//** -Cancel any pending lock request associated with the current THD. */ -static -void -innobase_kill_query( -/*================*/ - handlerton* hton, /*!< in: innobase handlerton */ - THD* thd, /*!< in: MySQL thread being killed */ - enum thd_kill_levels level) /*!< in: kill level */ +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) { - trx_t* trx; - DBUG_ENTER("innobase_kill_query"); - DBUG_ASSERT(hton == innodb_hton_ptr); - #ifdef WITH_WSREP wsrep_thd_LOCK(thd); if (wsrep_thd_get_conflict_state(thd) != NO_CONFLICT) { @@ -5329,43 +5321,10 @@ innobase_kill_query( wsrep_thd_UNLOCK(thd); #endif /* WITH_WSREP */ - trx = thd_to_trx(thd); - - if (trx != NULL) { + if (trx_t* trx = thd_to_trx(thd)) { + ut_ad(trx->mysql_thd == thd); /* Cancel a pending lock request if there are any */ - bool lock_mutex_taken = false; - bool trx_mutex_taken = false; - - if (trx->lock.wait_lock) { - WSREP_DEBUG("Killing victim trx %p BF %d trx BF %d trx_id " IB_ID_FMT " ABORT %d thd %p" - " current_thd %p BF %d", - trx, wsrep_thd_is_BF(trx->mysql_thd, FALSE), - wsrep_thd_is_BF(thd, FALSE), - trx->id, trx->abort_type, - trx->mysql_thd, - current_thd, - wsrep_thd_is_BF(current_thd, FALSE)); - } - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && trx->abort_type != TRX_WSREP_ABORT) { - lock_mutex_enter(); - lock_mutex_taken = true; - } - - if (trx->abort_type != TRX_WSREP_ABORT) { - trx_mutex_enter(trx); - trx_mutex_taken = true; - } - - lock_trx_handle_wait(trx, true, true); - - if (lock_mutex_taken) { - lock_mutex_exit(); - } - - if (trx_mutex_taken) { - trx_mutex_exit(trx); - } + lock_trx_handle_wait(trx); } DBUG_VOID_RETURN; @@ -9392,8 +9351,8 @@ ha_innobase::unlock_row(void) transaction is in state TRX_STATE_NOT_STARTED. The check on m_prebuilt->select_lock_type above gets around this issue. */ - ut_ad(trx_state_eq(m_prebuilt->trx, TRX_STATE_ACTIVE) - || trx_state_eq(m_prebuilt->trx, TRX_STATE_FORCED_ROLLBACK)); + ut_ad(trx_state_eq(m_prebuilt->trx, TRX_STATE_ACTIVE, true) + || trx_state_eq(m_prebuilt->trx, TRX_STATE_FORCED_ROLLBACK, true)); switch (m_prebuilt->row_read_type) { case ROW_READ_WITH_LOCKS: @@ -20063,7 +20022,7 @@ wsrep_innobase_kill_one_trx( thd_get_thread_id(thd))); WSREP_DEBUG("kill query for: %ld", thd_get_thread_id(thd)); - /* Note that innobase_kill_connection will take lock_mutex + /* Note that innobase_kill_query will take lock_mutex and trx_mutex */ wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal); @@ -20140,12 +20099,10 @@ wsrep_abort_transaction( if (victim_trx) { lock_mutex_enter(); trx_mutex_enter(victim_trx); - victim_trx->abort_type = TRX_WSREP_ABORT; int rcode = wsrep_innobase_kill_one_trx(bf_thd, bf_trx, victim_trx, signal); - trx_mutex_exit(victim_trx); lock_mutex_exit(); - victim_trx->abort_type = TRX_SERVER_ABORT; + trx_mutex_exit(victim_trx); wsrep_srv_conc_cancel_wait(victim_trx); DBUG_RETURN(rcode); } else { diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index b1f27e7f456..026aac1b367 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -781,9 +781,7 @@ the wait lock. dberr_t lock_trx_handle_wait( /*=================*/ - trx_t* trx, /*!< in/out: trx lock state */ - bool lock_mutex_taken, - bool trx_mutex_taken); + trx_t* trx); /*!< in/out: trx lock state */ /*********************************************************************//** Get the number of locks on a table. @return number of locks */ diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 412a35a14f4..50e270fb3c5 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -827,12 +827,6 @@ lock_rec_convert_impl_to_expl()) will access transactions associated to other connections. The locks of transactions are protected by lock_sys->mutex and sometimes by trx->mutex. */ -typedef enum { - TRX_SERVER_ABORT = 0, - TRX_WSREP_ABORT = 1 -} trx_abort_t; - - /** Represents an instance of rollback segment along with its state variables.*/ struct trx_undo_ptr_t { trx_rseg_t* rseg; /*!< rollback segment assigned to the @@ -1088,7 +1082,6 @@ struct trx_t { /*------------------------------*/ THD* mysql_thd; /*!< MySQL thread handle corresponding to this trx, or NULL */ - trx_abort_t abort_type; /*!< Transaction abort type*/ const char* mysql_log_file_name; /*!< if MySQL binlog is used, this field diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 67a40e7639f..819e53e14cc 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1282,10 +1282,8 @@ wsrep_kill_victim( << wsrep_thd_query(lock->trx->mysql_thd); } - lock->trx->abort_type = TRX_WSREP_ABORT; wsrep_innobase_kill_one_trx(trx->mysql_thd, (const trx_t*) trx, lock->trx, TRUE); - lock->trx->abort_type = TRX_SERVER_ABORT; } } } @@ -2936,21 +2934,8 @@ lock_grant_and_move_on_page( && lock_get_wait(lock) && !lock_rec_has_to_wait_in_queue(lock)) { - bool exit_trx_mutex = false; - - if (lock->trx->abort_type != TRX_SERVER_ABORT) { - ut_ad(trx_mutex_own(lock->trx)); - trx_mutex_exit(lock->trx); - exit_trx_mutex = true; - } - lock_grant(lock, false); - if (exit_trx_mutex) { - ut_ad(!trx_mutex_own(lock->trx)); - trx_mutex_enter(lock->trx); - } - if (previous != NULL) { /* Move the lock to the head of the list. */ HASH_GET_NEXT(hash, previous) = HASH_GET_NEXT(hash, lock); @@ -3030,20 +3015,7 @@ lock_rec_dequeue_from_page( /* Grant the lock */ ut_ad(lock->trx != in_lock->trx); - bool exit_trx_mutex = false; - - if (lock->trx->abort_type != TRX_SERVER_ABORT) { - ut_ad(trx_mutex_own(lock->trx)); - trx_mutex_exit(lock->trx); - exit_trx_mutex = true; - } - lock_grant(lock, false); - - if (exit_trx_mutex) { - ut_ad(!trx_mutex_own(lock->trx)); - trx_mutex_enter(lock->trx); - } } } } else { @@ -4270,58 +4242,50 @@ lock_table_create( UT_LIST_ADD_LAST(trx->lock.trx_locks, lock); #ifdef WITH_WSREP - if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { - ut_list_insert(table->locks, c_lock, lock, TableLockGetNode()); - if (wsrep_debug) { - ib::info() << "table lock BF conflict for " << - ib::hex(c_lock->trx->id); - ib::info() << " SQL: " - << wsrep_thd_query(c_lock->trx->mysql_thd); - } - } else { - ut_list_append(table->locks, lock, TableLockGetNode()); - } if (c_lock) { - ut_ad(!trx_mutex_own(c_lock->trx)); - trx_mutex_enter(c_lock->trx); - } + if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + ut_list_insert(table->locks, c_lock, lock, + TableLockGetNode()); + if (wsrep_debug) { + ib::info() << "table lock BF conflict for " + << ib::hex(c_lock->trx->id) + << " SQL: " + << wsrep_thd_query( + c_lock->trx->mysql_thd); + } + } else { + ut_list_append(table->locks, lock, TableLockGetNode()); + } - if (c_lock && c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { - c_lock->trx->lock.was_chosen_as_deadlock_victim = TRUE; + trx_mutex_enter(c_lock->trx); - if (wsrep_debug) { - wsrep_print_wait_locks(c_lock); - } + if (c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { + c_lock->trx->lock.was_chosen_as_deadlock_victim = TRUE; - /* have to release trx mutex for the duration of - victim lock release. This will eventually call - lock_grant, which wants to grant trx mutex again - */ - /* caller has trx_mutex, have to release for lock cancel */ - trx_mutex_exit(trx); - lock_cancel_waiting_and_release(c_lock->trx->lock.wait_lock); - trx_mutex_enter(trx); + if (wsrep_debug) { + wsrep_print_wait_locks(c_lock); + } - /* trx might not wait for c_lock, but some other lock - does not matter if wait_lock was released above - */ - if (c_lock->trx->lock.wait_lock == c_lock) { - lock_reset_lock_and_trx_wait(lock); - } + /* The lock release will call lock_grant(), + which would acquire trx->mutex again. */ + trx_mutex_exit(trx); + lock_cancel_waiting_and_release( + c_lock->trx->lock.wait_lock); + trx_mutex_enter(trx); - if (wsrep_debug) { - ib::info() << "WSREP: c_lock canceled " << ib::hex(c_lock->trx->id); - ib::info() << " SQL: " - << wsrep_thd_query(c_lock->trx->mysql_thd); + if (wsrep_debug) { + ib::info() << "WSREP: c_lock canceled " + << ib::hex(c_lock->trx->id) + << " SQL: " + << wsrep_thd_query( + c_lock->trx->mysql_thd); + } } - } - if (c_lock) { trx_mutex_exit(c_lock->trx); - } -#else - ut_list_append(table->locks, lock, TableLockGetNode()); + } else #endif /* WITH_WSREP */ + ut_list_append(table->locks, lock, TableLockGetNode()); if (type_mode & LOCK_WAIT) { @@ -7586,6 +7550,23 @@ lock_trx_release_locks( mem_heap_empty(trx->lock.lock_heap); } +static inline dberr_t lock_trx_handle_wait_low(trx_t* trx) +{ + ut_ad(lock_mutex_own()); + ut_ad(trx_mutex_own(trx)); + + if (trx->lock.was_chosen_as_deadlock_victim) { + return DB_DEADLOCK; + } + if (!trx->lock.wait_lock) { + /* The lock was probably granted before we got here. */ + return DB_SUCCESS; + } + + lock_cancel_waiting_and_release(trx->lock.wait_lock); + return DB_LOCK_WAIT; +} + /*********************************************************************//** Check whether the transaction has already been rolled back because it was selected as a deadlock victim, or if it has to wait then cancel @@ -7594,71 +7575,14 @@ the wait lock. dberr_t lock_trx_handle_wait( /*=================*/ - trx_t* trx, /*!< in/out: trx lock state */ - bool lock_mutex_taken, - bool trx_mutex_taken) + trx_t* trx) /*!< in/out: trx lock state */ { - dberr_t err=DB_SUCCESS; - bool take_lock_mutex = false; - bool take_trx_mutex = false; - - if (!lock_mutex_taken) { - ut_ad(!lock_mutex_own()); - lock_mutex_enter(); - take_lock_mutex = true; - } - - if (!trx_mutex_taken) { - ut_ad(!trx_mutex_own(trx)); - trx_mutex_enter(trx); - take_trx_mutex = true; - } - - if (trx->lock.was_chosen_as_deadlock_victim) { - err = DB_DEADLOCK; - } else if (trx->lock.wait_lock != NULL) { - bool take_wait_trx_mutex = false; - trx_t* wait_trx = trx->lock.wait_lock->trx; - - /* We take trx mutex for waiting trx if we have not yet - already taken it or we know that waiting trx and parameter - trx are not same and we are not already holding trx mutex. */ - if ((wait_trx && wait_trx == trx && !take_trx_mutex && !trx_mutex_taken) || - (wait_trx && wait_trx != trx && wait_trx->abort_type == TRX_SERVER_ABORT)) { - ut_ad(!trx_mutex_own(wait_trx)); - trx_mutex_enter(wait_trx); - take_wait_trx_mutex = true; - } - - ut_ad(trx_mutex_own(wait_trx)); - - lock_cancel_waiting_and_release(trx->lock.wait_lock); - - if (wait_trx && take_wait_trx_mutex) { - ut_ad(trx_mutex_own(wait_trx)); - trx_mutex_exit(wait_trx); - } - - err = DB_LOCK_WAIT; - } else { - /* The lock was probably granted before we got here. */ - err = DB_SUCCESS; - } - - if (take_lock_mutex) { - ut_ad(lock_mutex_own()); - lock_mutex_exit(); - } - - if (take_trx_mutex) { - ut_ad(trx_mutex_own(trx)); - trx_mutex_exit(trx); - } - - ut_ad(err == DB_SUCCESS || err == DB_LOCK_WAIT - || err == DB_DEADLOCK); - - return(err); + lock_mutex_enter(); + trx_mutex_enter(trx); + dberr_t err = lock_trx_handle_wait_low(trx); + lock_mutex_exit(); + trx_mutex_exit(trx); + return err; } /*********************************************************************//** diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 46cd1e00021..623961945b2 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -5008,8 +5008,7 @@ no_gap_lock: a deadlock and the transaction had to wait then release the lock it is waiting on. */ - trx->abort_type = TRX_SERVER_ABORT; - err = lock_trx_handle_wait(trx, false, false); + err = lock_trx_handle_wait(trx); switch (err) { case DB_SUCCESS: diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index cb8b374691e..bff6a87dc61 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -895,7 +895,7 @@ static void get_options(register int *argc,register char ***argv) { int ho_error; - load_defaults("my", load_default_groups, argc, argv); + load_defaults_or_exit("my", load_default_groups, argc, argv); default_argv= *argv; check_param.testflag= T_UPDATE_STATE; if (isatty(fileno(stdout))) diff --git a/storage/maria/maria_dump_log.c b/storage/maria/maria_dump_log.c index 42c694bf1bf..3570dede80e 100644 --- a/storage/maria/maria_dump_log.c +++ b/storage/maria/maria_dump_log.c @@ -133,7 +133,7 @@ int main(int argc, char **argv) uchar buffer[TRANSLOG_PAGE_SIZE]; MY_INIT(argv[0]); - load_defaults("my", load_default_groups, &argc, &argv); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc, &argv); diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c index 814c50e1db8..28b4ff4cfc7 100644 --- a/storage/maria/maria_pack.c +++ b/storage/maria/maria_pack.c @@ -208,7 +208,7 @@ int main(int argc, char **argv) char **default_argv; MY_INIT(argv[0]); - load_defaults("my",load_default_groups,&argc,&argv); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc,&argv); maria_init(); diff --git a/storage/maria/maria_read_log.c b/storage/maria/maria_read_log.c index 2c24c125f36..551732d8ba3 100644 --- a/storage/maria/maria_read_log.c +++ b/storage/maria/maria_read_log.c @@ -47,7 +47,7 @@ int main(int argc, char **argv) maria_data_root= (char *)"."; sf_leaking_memory=1; /* don't report memory leaks on early exits */ - load_defaults("my", load_default_groups, &argc, &argv); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc, &argv); diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c index cffe188e855..cbf914f5d45 100644 --- a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c @@ -256,7 +256,7 @@ int main(int argc __attribute__((unused)), char *argv[]) #endif long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2); - load_defaults("my", load_default_groups, &argc, &argv); + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc, &argv); diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 2e36c364453..dcf1d5ccaaf 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -752,9 +752,7 @@ static void get_options(register int *argc,register char ***argv) { int ho_error; - if (load_defaults("my", load_default_groups, argc, argv)) - exit(1); - + load_defaults_or_exit("my", load_default_groups, argc, argv); default_argv= *argv; if (isatty(fileno(stdout))) check_param.testflag|=T_WRITE_LOOP; diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index 966edc877cd..bb9f59f86f7 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -209,9 +209,7 @@ int main(int argc, char **argv) char **default_argv; MY_INIT(argv[0]); - if (load_defaults("my",load_default_groups,&argc,&argv)) - exit(1); - + load_defaults_or_exit("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc,&argv); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 464f56721af..0f5ef12bfb3 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1428,20 +1428,13 @@ innobase_close_connection( THD* thd); /*!< in: MySQL thread handle for which to close the connection */ +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels); static void innobase_commit_ordered(handlerton *hton, THD* thd, bool all); static void innobase_checkpoint_request(handlerton *hton, void *cookie); /*****************************************************************//** -Cancel any pending lock request associated with the current THD. */ -static -void -innobase_kill_connection( -/*======================*/ - handlerton* hton, /*!< in: innobase handlerton */ - THD* thd, /*!< in: handle to the MySQL thread being killed */ - thd_kill_levels); - -/*****************************************************************//** Commits a transaction in an InnoDB database or marks an SQL statement ended. @return 0 */ @@ -3855,7 +3848,7 @@ innobase_init( innobase_hton->flags = HTON_SUPPORTS_EXTENDED_KEYS | HTON_SUPPORTS_FOREIGN_KEYS; - innobase_hton->kill_query = innobase_kill_connection; + innobase_hton->kill_query = innobase_kill_query; if (srv_file_per_table) innobase_hton->tablefile_extensions = ha_innobase_exts; @@ -5465,20 +5458,11 @@ ha_innobase::get_row_type() const return(ROW_TYPE_NOT_USED); } -/*****************************************************************//** -Cancel any pending lock request associated with the current THD. */ -static -void -innobase_kill_connection( -/*======================*/ - handlerton* hton, /*!< in: innobase handlerton */ - THD* thd, /*!< in: handle to the MySQL thread being killed */ - thd_kill_levels) +/** Cancel any pending lock request associated with the current THD. +@sa THD::awake() @sa ha_kill_query() */ +static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) { - trx_t* trx; - - DBUG_ENTER("innobase_kill_connection"); - DBUG_ASSERT(hton == innodb_hton_ptr); + DBUG_ENTER("innobase_kill_query"); #ifdef WITH_WSREP wsrep_thd_LOCK(thd); @@ -5494,50 +5478,37 @@ innobase_kill_connection( } wsrep_thd_UNLOCK(thd); #endif /* WITH_WSREP */ - trx = thd_to_trx(thd); + if (trx_t* trx = thd_to_trx(thd)) { + ut_ad(trx->mysql_thd == thd); - if (trx && trx->lock.wait_lock) { - /* In wsrep BF we have already took lock_sys and trx - mutex either on wsrep_abort_transaction() or - before wsrep_kill_victim(). In replication we - could own lock_sys mutex taken in - lock_deadlock_check_and_resolve().*/ - - WSREP_DEBUG("Killing victim trx %p BF %d trx BF %d trx_id " TRX_ID_FMT " ABORT %d thd %p" - " current_thd %p BF %d wait_lock_modes: %s\n", - trx, wsrep_thd_is_BF(trx->mysql_thd, FALSE), - wsrep_thd_is_BF(thd, FALSE), - trx->id, trx->abort_type, - trx->mysql_thd, - current_thd, - wsrep_thd_is_BF(current_thd, FALSE), - lock_get_info(trx->lock.wait_lock).c_str()); - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) - && trx->abort_type == TRX_SERVER_ABORT) { - ut_ad(!lock_mutex_own()); - lock_mutex_enter(); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { + switch (trx->abort_type) { +#ifdef WITH_WSREP + case TRX_WSREP_ABORT: + break; +#endif + case TRX_SERVER_ABORT: + if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + lock_mutex_enter(); + } + /* fall through */ + case TRX_REPLICATION_ABORT: trx_mutex_enter(trx); } - - ut_ad(lock_mutex_own()); - ut_ad(trx_mutex_own(trx)); - - if (trx->lock.wait_lock) { - lock_cancel_waiting_and_release(trx->lock.wait_lock); - } - - if (trx->abort_type != TRX_WSREP_ABORT) { + /* Cancel a pending lock request if there are any */ + lock_trx_handle_wait(trx); + switch (trx->abort_type) { +#ifdef WITH_WSREP + case TRX_WSREP_ABORT: + break; +#endif + case TRX_SERVER_ABORT: + if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + lock_mutex_exit(); + } + /* fall through */ + case TRX_REPLICATION_ABORT: trx_mutex_exit(trx); } - - if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - trx->abort_type == TRX_SERVER_ABORT) { - lock_mutex_exit(); - } } DBUG_VOID_RETURN; @@ -9635,7 +9606,7 @@ ha_innobase::unlock_row(void) But there are some calls to this function from the SQL layer when the transaction is in state TRX_STATE_NOT_STARTED. The check on prebuilt->select_lock_type above gets around this issue. */ - ut_ad(trx_state_eq(prebuilt->trx, TRX_STATE_ACTIVE)); + ut_ad(trx_state_eq(prebuilt->trx, TRX_STATE_ACTIVE, true)); switch (prebuilt->row_read_type) { case ROW_READ_WITH_LOCKS: @@ -19765,7 +19736,7 @@ wsrep_innobase_kill_one_trx( thd_get_thread_id(thd))); WSREP_DEBUG("kill query for: %ld", thd_get_thread_id(thd)); - /* Note that innobase_kill_connection will take lock_mutex + /* Note that innobase_kill_query will take lock_mutex and trx_mutex */ wsrep_thd_UNLOCK(thd); wsrep_thd_awake(thd, signal); diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index b50452c1d5d..b8446013bc7 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -910,7 +910,7 @@ UNIV_INLINE void lock_reset_lock_and_trx_wait( /*=========================*/ - lock_t* lock) /*!< in/out: record lock */ + lock_t* lock) /*!< in/out: record lock */ { ut_ad(lock_get_wait(lock)); ut_ad(lock_mutex_own()); @@ -2358,13 +2358,6 @@ lock_rec_create( trx_mutex_enter(trx); } - /* trx might not wait for c_lock, but some other lock - does not matter if wait_lock was released above - */ - if (c_lock->trx->lock.wait_lock == c_lock) { - lock_reset_lock_and_trx_wait(lock); - } - trx_mutex_exit(c_lock->trx); if (wsrep_debug) { @@ -5010,19 +5003,18 @@ lock_table_create( UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock); #ifdef WITH_WSREP - if (wsrep_thd_is_wsrep(trx->mysql_thd)) { - if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { + if (c_lock) { + if (wsrep_thd_is_wsrep(trx->mysql_thd) + && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { UT_LIST_INSERT_AFTER( un_member.tab_lock.locks, table->locks, c_lock, lock); } else { UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock); } - if (c_lock) { - trx_mutex_enter(c_lock->trx); - } + trx_mutex_enter(c_lock->trx); - if (c_lock && c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { + if (c_lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { c_lock->trx->lock.was_chosen_as_deadlock_victim = TRUE; @@ -5031,36 +5023,21 @@ lock_table_create( wsrep_print_wait_locks(c_lock->trx->lock.wait_lock); } - /* have to release trx mutex for the duration of - victim lock release. This will eventually call - lock_grant, which wants to grant trx mutex again - */ - /* caller has trx_mutex, have to release for lock cancel */ + /* The lock release will call lock_grant(), + which would acquire trx->mutex again. */ trx_mutex_exit(trx); lock_cancel_waiting_and_release(c_lock->trx->lock.wait_lock); trx_mutex_enter(trx); - /* trx might not wait for c_lock, but some other lock - does not matter if wait_lock was released above - */ - if (c_lock->trx->lock.wait_lock == c_lock) { - lock_reset_lock_and_trx_wait(lock); - } - if (wsrep_debug) { fprintf(stderr, "WSREP: c_lock canceled " TRX_ID_FMT "\n", c_lock->trx->id); } } - if (c_lock) { - trx_mutex_exit(c_lock->trx); - } - } else { + trx_mutex_exit(c_lock->trx); + } else #endif /* WITH_WSREP */ UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock); -#ifdef WITH_WSREP - } -#endif /* WITH_WSREP */ if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) { @@ -8110,26 +8087,19 @@ lock_trx_handle_wait( /*=================*/ trx_t* trx) /*!< in/out: trx lock state */ { - dberr_t err; - - lock_mutex_enter(); - - trx_mutex_enter(trx); + ut_ad(lock_mutex_own()); + ut_ad(trx_mutex_own(trx)); if (trx->lock.was_chosen_as_deadlock_victim) { - err = DB_DEADLOCK; - } else if (trx->lock.wait_lock != NULL) { - lock_cancel_waiting_and_release(trx->lock.wait_lock); - err = DB_LOCK_WAIT; - } else { + return DB_DEADLOCK; + } + if (!trx->lock.wait_lock) { /* The lock was probably granted before we got here. */ - err = DB_SUCCESS; + return DB_SUCCESS; } - lock_mutex_exit(); - trx_mutex_exit(trx); - - return(err); + lock_cancel_waiting_and_release(trx->lock.wait_lock); + return DB_LOCK_WAIT; } /*********************************************************************//** diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc index 03ae6822fb7..b81ea60a413 100644 --- a/storage/xtradb/row/row0sel.cc +++ b/storage/xtradb/row/row0sel.cc @@ -4627,7 +4627,11 @@ no_gap_lock: a deadlock and the transaction had to wait then release the lock it is waiting on. */ + lock_mutex_enter(); + trx_mutex_enter(trx); err = lock_trx_handle_wait(trx); + lock_mutex_exit(); + trx_mutex_exit(trx); switch (err) { case DB_SUCCESS: diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c index bf06e2b502b..f69eb28a287 100644 --- a/tests/mysql_client_fw.c +++ b/tests/mysql_client_fw.c @@ -1410,8 +1410,7 @@ int main(int argc, char **argv) for (i= 0; i < argc; i++) original_argv[i]= strdup(argv[i]); - if (load_defaults("my", client_test_load_default_groups, &argc, &argv)) - exit(1); + load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv); get_options(&argc, &argv); /* Set main opt_count. */ diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 741e1e53532..99cee8f7ed4 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -7109,11 +7109,7 @@ static void test_embedded_start_stop() MY_INIT(argv[0]); /* Load the client defaults from the .cnf file[s]. */ - if (load_defaults("my", client_test_load_default_groups, &argc, &argv)) - { - myerror("load_defaults failed"); - exit(1); - } + load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv); /* Parse the options (including the ones given from defaults files). */ get_options(&argc, &argv); @@ -7161,12 +7157,7 @@ static void test_embedded_start_stop() MY_INIT(argv[0]); - if (load_defaults("my", client_test_load_default_groups, &argc, &argv)) - { - myerror("load_defaults failed \n "); - exit(1); - } - + load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv); get_options(&argc, &argv); /* Must start the main embedded server again after the test. */ diff --git a/tests/thread_test.c b/tests/thread_test.c index bf0fb8ea2c0..38e453e9cb8 100644 --- a/tests/thread_test.c +++ b/tests/thread_test.c @@ -168,8 +168,8 @@ static void get_options(int argc, char **argv) { int ho_error; - if ((ho_error= load_defaults("my",load_default_groups,&argc,&argv)) || - (ho_error= handle_options(&argc, &argv, my_long_options, get_one_option))) + load_defaults_or_exit("my", load_default_groups, &argc, &argv); + if ((ho_error= handle_options(&argc, &argv, my_long_options, get_one_option))) exit(ho_error); free_defaults(argv); |