diff --git a/sql/slave.cc b/sql/slave.cc index b8689a28a54..30c345f8030 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -867,6 +867,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, const char* table_name) { ulong packet_len = my_net_read(net); // read create table statement + char *query; Vio* save_vio; HA_CHECK_OPT check_opt; TABLE_LIST tables; @@ -886,15 +887,23 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, return 1; } thd->command = COM_TABLE_DUMP; - thd->query = sql_alloc(packet_len + 1); - if (!thd->query) + /* Note that we should not set thd->query until the area is initalized */ + if (!(query = sql_alloc(packet_len + 1))) { sql_print_error("create_table_from_dump: out of memory"); net_printf(&thd->net, ER_GET_ERRNO, "Out of memory"); return 1; } - memcpy(thd->query, net->read_pos, packet_len); - thd->query[packet_len] = 0; + memcpy(query, net->read_pos, packet_len); + query[packet_len]= 0; + thd->query_length= packet_len; + /* + We make the following lock in an attempt to ensure that the compiler will + not rearrange the code so that thd->query is set too soon + */ + VOID(pthread_mutex_lock(&LOCK_thread_count)); + thd->query= query; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->current_tablenr = 0; thd->query_error = 0; thd->net.no_send_ok = 1; @@ -2049,7 +2058,9 @@ err: // print the current replication position sql_print_error("Slave I/O thread exiting, read up to log '%s', position %s", IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff)); + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (mysql) { mc_mysql_close(mysql); @@ -2183,7 +2194,9 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff)); err: + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&rli->run_lock); DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun diff --git a/sql/sql_db.cc b/sql/sql_db.cc index e805cf74f19..ffb02cd36c1 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -78,9 +78,9 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) if (!thd->query) { /* The client used the old obsolete mysql_create_db() call */ - thd->query = path; thd->query_length = (uint) (strxmov(path,"create database `", db, "`", NullS) - path); + thd->query = path; } { mysql_update_log.write(thd,thd->query, thd->query_length); @@ -92,8 +92,9 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) } if (thd->query == path) { + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = 0; // just in case - thd->query_length = 0; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); } send_ok(&thd->net, result); } @@ -167,9 +168,10 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { if (!thd->query) { - thd->query = path; - thd->query_length = (uint) (strxmov(path,"drop database ", db, NullS)- - path); + thd->query_length= (uint) (strxmov(path,"drop database `", db, "`", + NullS)- + path); + thd->query= path; } mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) @@ -179,8 +181,9 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) } if (thd->query == path) { + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = 0; // just in case - thd->query_length = 0; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); } send_ok(&thd->net,(ulong) deleted); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5bf3a1c0bcd..0b6170f1e37 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -852,7 +852,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) goto err; } net_flush(&thd->net); - if ((error = table->file->dump(thd,fd))) + if ((error= table->file->dump(thd,fd))) my_error(ER_GET_ERRNO, MYF(0)); err: @@ -958,7 +958,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, tbl_name[tbl_len] = 0; if (mysql_table_dump(thd, db, tbl_name, -1)) send_error(&thd->net); // dump to NET - break; } case COM_CHANGE_USER: