diff options
Diffstat (limited to 'sql/sql_reload.cc')
-rw-r--r-- | sql/sql_reload.cc | 136 |
1 files changed, 101 insertions, 35 deletions
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 8cc9dbd45fb..bcf2585ca2a 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <my_global.h> #include "sql_reload.h" #include "sql_priv.h" #include "mysqld.h" // select_errors @@ -54,7 +55,7 @@ static void disable_checkpoints(THD *thd); @retval !=0 Error; thd->killed is set or thd->is_error() is true */ -bool reload_acl_and_cache(THD *thd, unsigned long options, +bool reload_acl_and_cache(THD *thd, unsigned long long options, TABLE_LIST *tables, int *write_to_binlog) { bool result=0; @@ -93,12 +94,11 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, my_error(ER_UNKNOWN_ERROR, MYF(0)); } } + opt_noacl= 0; if (tmp_thd) { delete tmp_thd; - /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); thd= 0; } reset_mqh((LEX_USER *)NULL, TRUE); @@ -159,10 +159,39 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, if (options & REFRESH_RELAY_LOG) { #ifdef HAVE_REPLICATION - mysql_mutex_lock(&active_mi->data_lock); - if (rotate_relay_log(active_mi)) - *write_to_binlog= -1; - mysql_mutex_unlock(&active_mi->data_lock); + LEX_STRING connection_name; + Master_info *mi; + if (thd) + connection_name= thd->lex->relay_log_connection_name; + else + { + connection_name.str= (char*) ""; + connection_name.length= 0; + } + + /* + Writing this command to the binlog may cause problems as the + slave is not likely to have the same connection names. + */ + tmp_write_to_binlog= 0; + mysql_mutex_lock(&LOCK_active_mi); + if (master_info_index) + { + if (!(mi= (master_info_index-> + get_master_info(&connection_name, + Sql_condition::WARN_LEVEL_ERROR)))) + { + result= 1; + } + else + { + mysql_mutex_lock(&mi->data_lock); + if (rotate_relay_log(mi)) + *write_to_binlog= -1; + mysql_mutex_unlock(&mi->data_lock); + } + } + mysql_mutex_unlock(&LOCK_active_mi); #endif } #ifdef HAVE_QUERY_CACHE @@ -180,6 +209,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, DBUG_ASSERT(!thd || thd->locked_tables_mode || !thd->mdl_context.has_locks() || thd->handler_tables_hash.records || + thd->ull_hash.records || thd->global_read_lock.is_acquired()); /* @@ -296,7 +326,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, { DBUG_ASSERT(thd); tmp_write_to_binlog= 0; - if (reset_master(thd)) + if (reset_master(thd, NULL, 0)) { /* NOTE: my_error() has been already called by reset_master(). */ result= 1; @@ -316,12 +346,28 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, #ifdef HAVE_REPLICATION if (options & REFRESH_SLAVE) { + LEX_MASTER_INFO* lex_mi= &thd->lex->mi; + Master_info *mi; tmp_write_to_binlog= 0; mysql_mutex_lock(&LOCK_active_mi); - if (reset_slave(thd, active_mi)) + if (master_info_index) { - /* NOTE: my_error() has been already called by reset_slave(). */ - result= 1; + if (!(mi= (master_info_index-> + get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR)))) + { + result= 1; + } + else if (reset_slave(thd, mi)) + { + /* NOTE: my_error() has been already called by reset_slave(). */ + result= 1; + } + else if (mi->connection_name.length && thd->lex->reset_slave_info.all) + { + /* If not default connection and 'all' is used */ + master_info_index->remove_master_info(&mi->connection_name); + } } mysql_mutex_unlock(&LOCK_active_mi); } @@ -367,7 +413,8 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, /** - Implementation of FLUSH TABLES <table_list> WITH READ LOCK. + Implementation of FLUSH TABLES <table_list> WITH READ LOCK + and FLUSH TABLES <table_list> FOR EXPORT In brief: take exclusive locks, expel tables from the table cache, reopen the tables, enter the 'LOCKED TABLES' mode, @@ -456,33 +503,36 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables) goto error; } - /* - Acquire SNW locks on tables to be flushed. Don't acquire global - IX and database-scope IX locks on the tables as this will make - this statement incompatible with FLUSH TABLES WITH READ LOCK. - */ - if (lock_table_names(thd, all_tables, NULL, - thd->variables.lock_wait_timeout, - MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK)) - goto error; + if (thd->lex->type & REFRESH_READ_LOCK) + { + /* + Acquire SNW locks on tables to be flushed. Don't acquire global + IX and database-scope IX locks on the tables as this will make + this statement incompatible with FLUSH TABLES WITH READ LOCK. + */ + if (lock_table_names(thd, all_tables, NULL, + thd->variables.lock_wait_timeout, + MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK)) + goto error; - DEBUG_SYNC(thd,"flush_tables_with_read_lock_after_acquire_locks"); + DEBUG_SYNC(thd,"flush_tables_with_read_lock_after_acquire_locks"); - for (table_list= all_tables; table_list; - table_list= table_list->next_global) - { - /* Request removal of table from cache. */ - tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, - table_list->db, - table_list->table_name, FALSE); - /* Reset ticket to satisfy asserts in open_tables(). */ - table_list->mdl_request.ticket= NULL; + for (table_list= all_tables; table_list; + table_list= table_list->next_global) + { + /* Request removal of table from cache. */ + tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, + table_list->db, + table_list->table_name, FALSE); + /* Reset ticket to satisfy asserts in open_tables(). */ + table_list->mdl_request.ticket= NULL; + } } /* Before opening and locking tables the below call also waits for old shares to go away, so the fact that we don't pass - MYSQL_LOCK_IGNORE_FLUSH flag to it is important. + MYSQL_OPEN_IGNORE_FLUSH flag to it is important. Also we don't pass MYSQL_OPEN_HAS_MDL_LOCK flag as we want to open underlying tables if merge table is flushed. For underlying tables of the merge the below call has to @@ -491,11 +541,27 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables) */ if (open_and_lock_tables(thd, all_tables, FALSE, MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK, - &lock_tables_prelocking_strategy) || - thd->locked_tables_list.init_locked_tables(thd)) - { + &lock_tables_prelocking_strategy)) goto error; + + if (thd->lex->type & REFRESH_FOR_EXPORT) + { + // Check if all storage engines support FOR EXPORT. + for (TABLE_LIST *table_list= all_tables; table_list; + table_list= table_list->next_global) + { + if (!(table_list->table->file->ha_table_flags() & HA_CAN_EXPORT)) + { + my_error(ER_ILLEGAL_HA, MYF(0),table_list->table->file->table_type(), + table_list->db, table_list->table_name); + return true; + } + } } + + if (thd->locked_tables_list.init_locked_tables(thd)) + goto error; + thd->variables.option_bits|= OPTION_TABLE_LOCK; /* |