diff options
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index dadb03abfff..45815fe7a02 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2446,7 +2446,7 @@ static bool do_execute_sp(THD *thd, sp_head *sp) int mysql_execute_command(THD *thd) { - int res= FALSE; + int res= 0; int up_result= 0; LEX *lex= thd->lex; /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ @@ -3119,10 +3119,17 @@ mysql_execute_command(THD *thd) if (check_global_access(thd, SUPER_ACL)) goto error; + /* + In this code it's ok to use LOCK_active_mi as we are adding new things + into master_info_index + */ mysql_mutex_lock(&LOCK_active_mi); - if (!master_info_index) + { + mysql_mutex_unlock(&LOCK_active_mi); + my_error(ER_SERVER_SHUTDOWN, MYF(0)); goto error; + } mi= master_info_index->get_master_info(&lex_mi->connection_name, Sql_condition::WARN_LEVEL_NOTE); @@ -3151,7 +3158,7 @@ mysql_execute_command(THD *thd) If new master was not added, we still need to free mi. */ if (master_info_added) - master_info_index->remove_master_info(&lex_mi->connection_name); + master_info_index->remove_master_info(mi); else delete mi; } @@ -3169,22 +3176,24 @@ mysql_execute_command(THD *thd) /* Accept one of two privileges */ if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL)) goto error; - mysql_mutex_lock(&LOCK_active_mi); if (lex->verbose) + { + mysql_mutex_lock(&LOCK_active_mi); res= show_all_master_info(thd); + mysql_mutex_unlock(&LOCK_active_mi); + } else { LEX_MASTER_INFO *lex_mi= &thd->lex->mi; Master_info *mi; - mi= master_info_index->get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR); - if (mi != NULL) + if ((mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR))) { res= show_master_info(thd, mi, 0); + mi->release(); } } - mysql_mutex_unlock(&LOCK_active_mi); break; } case SQLCOM_SHOW_MASTER_STAT: @@ -3528,22 +3537,23 @@ end_with_restore_list: load_error= rpl_load_gtid_slave_state(thd); - mysql_mutex_lock(&LOCK_active_mi); - - if ((mi= (master_info_index-> - get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR)))) + /* + We don't need to ensure that only one user is using master_info + as start_slave is protected against simultaneous usage + */ + if ((mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR))) { if (load_error) { /* - We cannot start a slave using GTID if we cannot load the GTID position - from the mysql.gtid_slave_pos table. But we can allow non-GTID - replication (useful eg. during upgrade). + We cannot start a slave using GTID if we cannot load the + GTID position from the mysql.gtid_slave_pos table. But we + can allow non-GTID replication (useful eg. during upgrade). */ if (mi->using_gtid != Master_info::USE_GTID_NO) { - mysql_mutex_unlock(&LOCK_active_mi); + mi->release(); break; } else @@ -3551,8 +3561,8 @@ end_with_restore_list: } if (!start_slave(thd, mi, 1 /* net report*/)) my_ok(thd); + mi->release(); } - mysql_mutex_unlock(&LOCK_active_mi); break; } case SQLCOM_SLAVE_STOP: @@ -3582,13 +3592,17 @@ end_with_restore_list: } lex_mi= &thd->lex->mi; - mysql_mutex_lock(&LOCK_active_mi); - if ((mi= (master_info_index-> - get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR)))) - if (!stop_slave(thd, mi, 1/* net report*/)) + if ((mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR))) + { + if (stop_slave(thd, mi, 1/* net report*/)) + res= 1; + mi->release(); + if (rpl_parallel_resize_pool_if_no_slaves()) + res= 1; + if (!res) my_ok(thd); - mysql_mutex_unlock(&LOCK_active_mi); + } break; } case SQLCOM_SLAVE_ALL_START: @@ -4900,11 +4914,13 @@ end_with_restore_list: reload_acl_and_cache binlog interactions failed */ res= 1; - } + } if (!res) my_ok(thd); } + else + res= 1; // reload_acl_and_cache failed #ifdef HAVE_REPLICATION if (lex->type & REFRESH_READ_LOCK) rpl_unpause_after_ftwrl(thd); |