diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 86d66e6b54059757fe68050becec1708b39d665d..4e5cee0d0ff57a36fe98a6dbd40b5869d6661b69 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -165,3 +165,43 @@ insert into t3 (ID, DateOfAction) values (87, '1999-07-19'), (89, '1999-07-19 select t3.DateOfAction, t1.TransactionID from t1 join t2 join t3 where t2.ID = t1.TransactionID and t3.ID = t2.GroupID order by t3.DateOfAction, t1.TransactionID; select t3.DateOfAction, t1.TransactionID from t1 join t2 join t3 where t2.ID = t1.TransactionID and t3.ID = t2.GroupID order by t1.TransactionID,t3.DateOfAction; drop table t1,t2,t3; + +#bug reported by Wouter de Jong + +drop table if exists members; +CREATE TABLE members ( + member_id int(11) NOT NULL auto_increment, + inschrijf_datum varchar(20) NOT NULL default '', + lastchange_datum varchar(20) NOT NULL default '', + nickname varchar(20) NOT NULL default '', + password varchar(8) NOT NULL default '', + voornaam varchar(30) NOT NULL default '', + tussenvoegsels varchar(10) NOT NULL default '', + achternaam varchar(50) NOT NULL default '', + straat varchar(100) NOT NULL default '', + postcode varchar(10) NOT NULL default '', + wijk varchar(40) NOT NULL default '', + plaats varchar(50) NOT NULL default '', + telefoon varchar(10) NOT NULL default '', + geboortedatum date NOT NULL default '0000-00-00', + geslacht varchar(5) NOT NULL default '', + email varchar(80) NOT NULL default '', + uin varchar(15) NOT NULL default '', + homepage varchar(100) NOT NULL default '', + internet varchar(15) NOT NULL default '', + scherk varchar(30) NOT NULL default '', + favo_boek varchar(50) NOT NULL default '', + favo_tijdschrift varchar(50) NOT NULL default '', + favo_tv varchar(50) NOT NULL default '', + favo_eten varchar(50) NOT NULL default '', + favo_muziek varchar(30) NOT NULL default '', + info text NOT NULL, + ipnr varchar(30) NOT NULL default '', + PRIMARY KEY (member_id) +) TYPE=MyISAM PACK_KEYS=1; + +insert into members (member_id) values (1),(2),(3); +select member_id, nickname, voornaam FROM members +ORDER by lastchange_datum DESC LIMIT 2; +drop table members; + diff --git a/sql/slave.cc b/sql/slave.cc index e0220a28454d9a55f1a1ab0c234cca99be03ee38..37e11d435735aaafde0d3123294d0fb2901b8560 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -36,6 +36,7 @@ bool wild_do_table_inited = 0, wild_ignore_table_inited = 0; bool table_rules_on = 0; uint32 slave_skip_counter = 0; static TABLE* save_temporary_tables = 0; +THD* slave_thd = 0; // when slave thread exits, we need to remember the temporary tables so we // can re-use them on slave start @@ -1157,7 +1158,7 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff my_thread_init(); - thd = new THD; // note that contructor of THD uses DBUG_ ! + slave_thd = thd = new THD; // note that contructor of THD uses DBUG_ ! thd->set_time(); DBUG_ENTER("handle_slave"); @@ -1347,6 +1348,7 @@ position %s", pthread_cond_broadcast(&COND_slave_stopped); // tell the world we are done pthread_mutex_unlock(&LOCK_slave); net_end(&thd->net); // destructor will not free it, because we are weird + slave_thd = 0; delete thd; my_thread_end(); #ifndef DBUG_OFF @@ -1376,8 +1378,13 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) } if(!slave_was_killed) - mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d", + { + mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d", mi->user, mi->host, mi->port); +#ifdef STOP_IO_WITH_FD_CLOSE + thd->set_active_fd(vio_fd(mysql->net.vio)); +#endif + } return slave_was_killed; } @@ -1404,11 +1411,16 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) } if(!slave_was_killed) - sql_print_error("Slave: reconnected to master '%s@%s:%d',\ + { + sql_print_error("Slave: reconnected to master '%s@%s:%d',\ replication resumed in log '%s' at position %s", glob_mi.user, glob_mi.host, glob_mi.port, RPL_LOG_NAME, llstr(glob_mi.pos,llbuff)); +#ifdef STOP_IO_WITH_FD_CLOSE + thd->set_active_fd(vio_fd(mysql->net.vio)); +#endif + } return slave_was_killed; } diff --git a/sql/slave.h b/sql/slave.h index e667cac52eb069e14e07201602f04861c5439bb5..048cb3f01000d14dd54657ee81b61767317fd153 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -99,6 +99,7 @@ extern uint32 slave_skip_counter; // have caused errors, and have been manually applied by DBA already extern pthread_t slave_real_id; +extern THD* slave_thd; extern MASTER_INFO glob_mi; extern HASH replicate_do_table, replicate_ignore_table; extern DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 30eeb2e5e2c731da912a57a6899af9a59f17c1be..1bced49be57ad038a7220e1f2d70dc6f09a5ab71 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -84,6 +84,10 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), query_start_used=0; query_length=col_access=0; query_error=0; +#ifdef STOP_IO_WITH_FD_CLOSE + active_fd = -1; + pthread_mutex_init(&active_fd_lock, NULL); +#endif server_id = ::server_id; server_status=SERVER_STATUS_AUTOCOMMIT; next_insert_id=last_insert_id=0; @@ -182,6 +186,9 @@ THD::~THD() safeFree(ip); free_root(&mem_root,MYF(0)); mysys_var=0; // Safety (shouldn't be needed) +#ifdef STOP_IO_WITH_FD_CLOSE + pthread_mutex_destroy(&active_fd_lock); +#endif DBUG_VOID_RETURN; } diff --git a/sql/sql_class.h b/sql/sql_class.h index f9720a3774a0e7dc2cc541ef042140706f7d8493..d1b870852ee7b18270a5a998bb119e69c4ebd8d1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -21,6 +21,8 @@ #pragma interface /* gcc class implementation */ #endif +#include <thr_alarm.h> + class Query_log_event; class Load_log_event; @@ -256,6 +258,10 @@ public: #ifndef __WIN__ sigset_t signals,block_signals; #endif +#ifdef STOP_IO_WITH_FD_CLOSE + int active_fd; + pthread_mutex_t active_fd_lock; +#endif ulonglong next_insert_id,last_insert_id,current_insert_id; ha_rows select_limit,offset_limit,default_select_limit,cuted_fields, max_join_size,sent_row_count; @@ -284,6 +290,51 @@ public: THD(); ~THD(); bool store_globals(); +#ifdef STOP_IO_WITH_FD_CLOSE + inline void set_active_fd(int fd) + { + pthread_mutex_lock(&active_fd_lock); + active_fd = fd; + pthread_mutex_unlock(&active_fd_lock); + } + inline void clear_active_fd() + { + pthread_mutex_lock(&active_fd_lock); + active_fd = -1; + pthread_mutex_unlock(&active_fd_lock); + } + inline void close_active_fd() + { + pthread_mutex_lock(&active_fd_lock); + if(active_fd >= 0) + { + my_close(active_fd, MYF(MY_WME)); + active_fd = -1; + } + pthread_mutex_unlock(&active_fd_lock); + } +#endif + inline void prepare_to_die() + { + thr_alarm_kill(real_id); + killed = 1; +#ifdef STOP_IO_WITH_FD_CLOSE + close_active_fd(); +#endif + if (mysys_var) + { + pthread_mutex_lock(&mysys_var->mutex); + if (!system_thread) // Don't abort locks + mysys_var->abort=1; + if (mysys_var->current_mutex) + { + pthread_mutex_lock(mysys_var->current_mutex); + pthread_cond_broadcast(mysys_var->current_cond); + pthread_mutex_unlock(mysys_var->current_mutex); + } + pthread_mutex_unlock(&mysys_var->mutex); + } + } inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, const char* msg) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 31f59c5b85020f1421b25480e3af03026e7d67cb..1884a8825baf98e188e5c76aeb0a5c362a2036d1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2778,22 +2778,8 @@ void kill_one_thread(THD *thd, ulong id) if ((thd->master_access & PROCESS_ACL) || !strcmp(thd->user,tmp->user)) { - thr_alarm_kill(tmp->real_id); - tmp->killed=1; + tmp->prepare_to_die(); error=0; - if (tmp->mysys_var) - { - pthread_mutex_lock(&tmp->mysys_var->mutex); - if (!tmp->system_thread) // Don't abort locks - tmp->mysys_var->abort=1; - if (tmp->mysys_var->current_mutex) - { - pthread_mutex_lock(tmp->mysys_var->current_mutex); - pthread_cond_broadcast(tmp->mysys_var->current_cond); - pthread_mutex_unlock(tmp->mysys_var->current_mutex); - } - pthread_mutex_unlock(&tmp->mysys_var->mutex); - } } else error=ER_KILL_DENIED_ERROR; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index e354bb65713be9109610769d10146cdc96fd221f..7922ad0eb6a9540160edb093e6ab5ed87da3acbc 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -572,6 +572,9 @@ int stop_slave(THD* thd, bool net_report ) { abort_slave = 1; thr_alarm_kill(slave_real_id); +#ifdef STOP_IO_WITH_FD_CLOSE + slave_thd->close_active_fd(); +#endif // do not abort the slave in the middle of a query, so we do not set // thd->killed for the slave thread thd->proc_info = "waiting for slave to die";