diff options
-rw-r--r-- | .bzrignore | 91 | ||||
-rw-r--r-- | Docs/manual.texi | 4 | ||||
-rw-r--r-- | client/mysqltest.c | 27 | ||||
-rw-r--r-- | myisam/ft_search.c | 2 | ||||
-rwxr-xr-x | mysql-test/create-test-result | 8 | ||||
-rw-r--r-- | mysql-test/r/3.23/rpl000012.result | 7 | ||||
-rw-r--r-- | mysql-test/r/3.23/rpl000012.status.result | 2 | ||||
-rw-r--r-- | mysql-test/t/3.23/rpl000012.test | 19 | ||||
-rw-r--r-- | mysql-test/t/include/master-slave.inc | 2 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 12 | ||||
-rw-r--r-- | sql/ha_myisam.h | 1 | ||||
-rw-r--r-- | sql/item_func.cc | 9 | ||||
-rw-r--r-- | sql/log_event.h | 4 | ||||
-rw-r--r-- | sql/mysql_priv.h | 5 | ||||
-rw-r--r-- | sql/mysqlbinlog.cc | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 3 | ||||
-rw-r--r-- | sql/opt_range.cc | 7 | ||||
-rw-r--r-- | sql/opt_range.h | 2 | ||||
-rw-r--r-- | sql/share/romanian/errmsg.sys | bin | 11929 -> 12003 bytes | |||
-rw-r--r-- | sql/share/russian/errmsg.txt | 44 | ||||
-rw-r--r-- | sql/slave.cc | 22 | ||||
-rw-r--r-- | sql/sql_base.cc | 67 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 5 | ||||
-rw-r--r-- | sql/unireg.h | 3 |
27 files changed, 292 insertions, 64 deletions
diff --git a/.bzrignore b/.bzrignore index f3dace8599d..6aff656c225 100644 --- a/.bzrignore +++ b/.bzrignore @@ -280,3 +280,94 @@ mysql-test/rpl000011.test mysql-test/var/lib/mysql-bin.007 sql/share/norwegian/errmsg.sys sql/share/norwegian-ny/errmsg.sys +mysql-test/r/3.23/rpl000001.b.result.reject +mysql-test/r/3.23/rpl000012.result.reject +libmysql_r/acconfig.h +libmysql_r/array.c +libmysql_r/bchange.c +libmysql_r/bmove.c +libmysql_r/bmove_upp.c +libmysql_r/charset.c +libmysql_r/conf_to_src.c +libmysql_r/ctype_autoconf.c +libmysql_r/ctype-big5.c +libmysql_r/ctype.c +libmysql_r/ctype-czech.c +libmysql_r/ctype-euc_kr.c +libmysql_r/ctype-gb2312.c +libmysql_r/ctype-gbk.c +libmysql_r/ctype-sjis.c +libmysql_r/ctype-tis620.c +libmysql_r/ctype-ujis.c +libmysql_r/dbug.c +libmysql_r/default.c +libmysql_r/dll.c +libmysql_r/errmsg.c +libmysql_r/errors.c +libmysql_r/getopt1.c +libmysql_r/getopt.c +libmysql_r/get_password.c +libmysql_r/getvar.c +libmysql_r/int2str.c +libmysql_r/is_prefix.c +libmysql_r/libmysql.c +libmysql_r/list.c +libmysql_r/llstr.c +libmysql_r/longlong2str.c +libmysql_r/mf_casecnv.c +libmysql_r/mf_dirname.c +libmysql_r/mf_fn_ext.c +libmysql_r/mf_format.c +libmysql_r/mf_loadpath.c +libmysql_r/mf_pack.c +libmysql_r/mf_path.c +libmysql_r/mf_tempfile.c +libmysql_r/mf_unixpath.c +libmysql_r/mf_wcomp.c +libmysql_r/mulalloc.c +libmysql_r/my_alloc.c +libmysql_r/my_compress.c +libmysql_r/my_create.c +libmysql_r/my_delete.c +libmysql_r/my_div.c +libmysql_r/my_error.c +libmysql_r/my_fopen.c +libmysql_r/my_fstream.c +libmysql_r/my_getwd.c +libmysql_r/my_init.c +libmysql_r/my_lib.c +libmysql_r/my_malloc.c +libmysql_r/my_messnc.c +libmysql_r/my_net.c +libmysql_r/my_once.c +libmysql_r/my_open.c +libmysql_r/my_pthread.c +libmysql_r/my_read.c +libmysql_r/my_realloc.c +libmysql_r/my_static.c +libmysql_r/my_static.h +libmysql_r/mysys_priv.h +libmysql_r/my_thr_init.c +libmysql_r/my_write.c +libmysql_r/net.c +libmysql_r/password.c +libmysql_r/safemalloc.c +libmysql_r/str2int.c +libmysql_r/strcend.c +libmysql_r/strcont.c +libmysql_r/strend.c +libmysql_r/strfill.c +libmysql_r/string.c +libmysql_r/strinstr.c +libmysql_r/strmake.c +libmysql_r/strmov.c +libmysql_r/strnlen.c +libmysql_r/strnmov.c +libmysql_r/strto.c +libmysql_r/strtoll.c +libmysql_r/strtoull.c +libmysql_r/strxmov.c +libmysql_r/thr_mutex.c +libmysql_r/typelib.c +libmysql_r/violite.c +linked_libmysql_r_sources diff --git a/Docs/manual.texi b/Docs/manual.texi index a1cfd47c486..8ad5a5dec39 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -27560,7 +27560,7 @@ To make a complex application portable you need to choose a number of SQL servers that it should work with. You can use the @strong{MySQL} crash-me program/web-page -@uref{http://www.mysql.com/information/crashme/choose.php} to find functions, +@uref{http://www.mysql.com/information/crash-me.php} to find functions, types, and limits you can use with a selection of database servers. Crash-me now tests far from everything possible, but it is still comprehensive with about 450 things tested. @@ -27689,7 +27689,7 @@ This should contain a technical description of the @strong{MySQL} benchmark suite (and @code{crash-me}), but that description is not written yet. Currently, you should look at the code and results in the @file{sql-bench} directory in the distribution (and of course on the Web page -at @uref{http://www.mysql.com/crashme/choose.php} and (normally found in +at @uref{http://www.mysql.com/information/crash-me.php} and (normally found in the @file{sql-bench} directory in the @strong{MySQL} distribution)). It is meant to be a benchmark that will tell any user what things a diff --git a/client/mysqltest.c b/client/mysqltest.c index 3d8b72c5ae4..dd024bb339b 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -78,6 +78,7 @@ struct query }; static void die(const char* fmt, ...); +int close_connection(struct query* q); int hex_val(int c) @@ -155,6 +156,30 @@ int select_connection(struct query* q) return 1; } +int close_connection(struct query* q) +{ + char* p, *name; + struct connection *con; + p = (char*)q->q + q->first_word_len; + while(*p && isspace(*p)) p++; + if(!*p) + die("Missing connection name in connect\n"); + name = p; + while(*p && !isspace(*p)) + p++; + *p = 0; + + for(con = cons; con < next_con; con++) + if(!strcmp(con->name, name)) + { + mysql_close(&con->mysql); + return 0; + } + + die("connection '%s' not found in connection pool", name); + return 1; +} + /* this one now is a hack - we may want to improve in in the future to handle quotes. For now we assume that anything that is not @@ -851,6 +876,8 @@ int main(int argc, char** argv) do_connect(&q); else if(check_first_word(&q, "connection", 10)) select_connection(&q); + else if(check_first_word(&q, "disconnect", 10)) + close_connection(&q); else if(check_first_word(&q, "source", 6)) do_source(&q); else if(check_first_word(&q, "sleep", 5)) diff --git a/myisam/ft_search.c b/myisam/ft_search.c index 9baab10df1e..4ca1551e809 100644 --- a/myisam/ft_search.c +++ b/myisam/ft_search.c @@ -158,6 +158,7 @@ FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key, ALL_IN_ONE aio; FT_DOCLIST *dlist; FT_DOC *dptr; + my_off_t saved_lastpos=((MI_INFO *)info)->lastpos; /* black magic ON */ if ((int) (keynr = _mi_check_index((MI_INFO *)info,keynr)) < 0) @@ -204,6 +205,7 @@ err: delete_tree(&aio.dtree); delete_tree(wtree); my_free((char*) wtree,MYF(0)); + ((MI_INFO *)info)->lastpos=saved_lastpos; return dlist; } diff --git a/mysql-test/create-test-result b/mysql-test/create-test-result index 08ca7a71921..24c3d175303 100755 --- a/mysql-test/create-test-result +++ b/mysql-test/create-test-result @@ -6,7 +6,7 @@ # to start mysqld yourself and run mysqltest -r RESULT_DIR=r/3.23 -if [ -z $EDITOR] then; +if [ -z $EDITOR] ; then EDITOR=vi fi @@ -26,7 +26,7 @@ test_name=$1 [ -z $test_name ] && usage -result_file=$result_dir/$test_name.result +result_file=$RESULT_DIR/$test_name.result [ -f $result_file ] && die "result file $result_file has already been created" @@ -39,11 +39,11 @@ reject_file=$result_file.reject if [ -f $reject_file ] ; then echo "Below are the contents of the reject file:" echo "-----start---------------------" - cat $result_file. + cat $reject_file echo "-----end-----------------------" echo "Is this the output you expected from your test case?(y/n)[n]" read yes_no - if [ x$yes_no = xy ] then; + if [ x$yes_no = xy ] ; then echo "Press any key to edit it in $EDITOR, or Ctrl-C to abort" read junk $EDITOR $reject_file diff --git a/mysql-test/r/3.23/rpl000012.result b/mysql-test/r/3.23/rpl000012.result new file mode 100644 index 00000000000..22fd6be3003 --- /dev/null +++ b/mysql-test/r/3.23/rpl000012.result @@ -0,0 +1,7 @@ +n +1 +2 +3 +4 +5 +6 diff --git a/mysql-test/r/3.23/rpl000012.status.result b/mysql-test/r/3.23/rpl000012.status.result new file mode 100644 index 00000000000..fbbae06c3f9 --- /dev/null +++ b/mysql-test/r/3.23/rpl000012.status.result @@ -0,0 +1,2 @@ +Variable_name Value +Slave_open_temp_tables 0 diff --git a/mysql-test/t/3.23/rpl000012.test b/mysql-test/t/3.23/rpl000012.test new file mode 100644 index 00000000000..205c78d604c --- /dev/null +++ b/mysql-test/t/3.23/rpl000012.test @@ -0,0 +1,19 @@ +source t/include/master-slave.inc; +connection master; +drop table if exists x; +create table x(n int); +create temporary table t(n int); +insert into t values(1),(2),(3); +insert into x select * from t; +connection master1; +create temporary table t (n int); +insert into t values (4),(5); +insert into x select * from t; +disconnect master; +connection master1; +insert into x values(6); +disconnect master1; +connection slave; +sleep 1; +@r/3.23/rpl000012.result select * from x; +@r/3.23/rpl000012.status.result show status like 'Slave_open_temp_tables'; diff --git a/mysql-test/t/include/master-slave.inc b/mysql-test/t/include/master-slave.inc index 590332bfa85..137749912a7 100644 --- a/mysql-test/t/include/master-slave.inc +++ b/mysql-test/t/include/master-slave.inc @@ -1,5 +1,7 @@ connect (master,localhost,root,,test,0,var/tmp/mysql.sock); +connect (master1,localhost,root,,test,0,var/tmp/mysql.sock); connect (slave,localhost,root,,test,0,var/tmp/mysql-slave.sock); +connect (slave1,localhost,root,,test,0,var/tmp/mysql-slave.sock); connection slave; !slave stop; connection master; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 229c24df107..21cfab6b701 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1094,7 +1094,17 @@ int ha_myisam::ft_read(byte * buf) if (error=ft_read_next((FT_DOCLIST *) ft_handler,(char*) buf)) ft_handler=NULL; // Magic here ! See Item_func_match::val() - + // and ha_myisam::index_init() table->status=error ? STATUS_NOT_FOUND: 0; return error; } + +int ha_myisam::index_init(uint idx) +{ + if (idx != active_index) + ft_handler=NULL; // Magic here ! + + active_index=idx; + return 0; +} + diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index d9f322fe9ca..c72b29ed3c7 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -71,6 +71,7 @@ class ha_myisam: public handler int index_first(byte * buf); int index_last(byte * buf); int index_next_same(byte *buf, const byte *key, uint keylen); + int index_init(uint idx); int ft_init() { if(!ft_handler) return 1; ft_reinit_search(ft_handler); return 0; } void *ft_init_ext(uint inx,const byte *key, uint keylen, bool presort) diff --git a/sql/item_func.cc b/sql/item_func.cc index 3d002e5c9d9..ac1e3298d02 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1840,9 +1840,12 @@ err: double Item_func_match::val() { - // Don't know how to return an error from val(), so NULL will be returned - if ((null_value=(ft_handler==NULL))) - return 0.0; + /* If called uninitialized we should return neither NULL nor 0 (important + for const_tables) so, let's return -1, which is obviously incorrect + for normal operation, and could be easily spotted */ + + if (ft_handler==NULL) + return -1.0; if (join_key) { diff --git a/sql/log_event.h b/sql/log_event.h index c956cfde396..b31d444ad21 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -115,7 +115,7 @@ public: // otherwise, set it to 0, in which case, we compute it with strlen() uint32 db_len; uint16 error_code; - int thread_id; + ulong thread_id; #if !defined(MYSQL_CLIENT) THD* thd; Query_log_event(THD* thd_arg, const char* query_arg): @@ -186,7 +186,7 @@ protected: void copy_log_event(const char *buf, ulong data_len); public: - int thread_id; + ulong thread_id; uint32 table_name_len; uint32 db_len; uint32 fname_len; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d37e04db8b3..ef6f1e7a81e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -403,7 +403,7 @@ void close_temporary_tables(THD *thd); TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name); bool close_temporary_table(THD *thd, const char *db, const char *table_name); void close_temporary(TABLE *table, bool delete_table=1); -bool rename_temporary_table(TABLE *table, const char *new_db, +bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db, const char *table_name); void remove_db_from_cache(const my_string db); void flush_tables(); @@ -469,7 +469,8 @@ extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables, extern ulong filesort_rows, filesort_range_count, filesort_scan_count; extern ulong filesort_merge_passes; extern ulong select_range_check_count, select_range_count, select_scan_count; -extern ulong select_full_range_join_count,select_full_join_count; +extern ulong select_full_range_join_count,select_full_join_count, + slave_open_temp_tables; extern uint test_flags,select_errors,mysql_port,ha_open_options; extern ulong thd_startup_options, slow_launch_threads, slow_launch_time; extern time_t start_time; diff --git a/sql/mysqlbinlog.cc b/sql/mysqlbinlog.cc index 21a740ca1f4..0fe9ab21987 100644 --- a/sql/mysqlbinlog.cc +++ b/sql/mysqlbinlog.cc @@ -361,8 +361,7 @@ static void dump_local_log_entries(const char* logname) die("Could not read entry at offset %ld : Error in log format or \ read error", my_b_tell(file)); - else - die("Could not construct event object"); + // file->error == 0 means EOF, that's OK, we break in this case break; } if (rec_count >= offset) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4bb079cf5dc..88b60ef92ad 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -199,7 +199,7 @@ ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size, thread_stack_min,net_wait_timeout,what_to_log= ~ (1L << (uint) COM_TIME), query_buff_size, lower_case_table_names, mysqld_net_retry_count, net_interactive_timeout, slow_launch_time = 2L, - net_read_timeout,net_write_timeout; + net_read_timeout,net_write_timeout,slave_open_temp_tables=0; ulong thread_cache_size=0; volatile ulong cached_thread_count=0; @@ -2540,6 +2540,7 @@ struct show_var_st status_vars[]= { {"Select_range_check", (char*) &select_range_check_count, SHOW_LONG}, {"Select_scan", (char*) &select_scan_count, SHOW_LONG}, {"Slave_running", (char*) &slave_running, SHOW_BOOL}, + {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG}, {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG}, {"Slow_queries", (char*) &long_query_count, SHOW_LONG}, {"Sort_merge_passes", (char*) &filesort_merge_passes, SHOW_LONG}, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 442597bbfad..d0310bf58e5 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -393,7 +393,7 @@ QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc) else bzero((char*) &alloc,sizeof(alloc)); file=head->file; - error=file->index_init(index); + // error=file->index_init(index); record=head->record[0]; } @@ -403,13 +403,16 @@ QUICK_SELECT::~QUICK_SELECT() free_root(&alloc,MYF(0)); } +int QUICK_SELECT::init() +{ + return error=file->index_init(index); +} QUICK_RANGE::QUICK_RANGE() :min_key(0),max_key(0),min_length(0),max_length(0), flag(NO_MIN_RANGE | NO_MAX_RANGE) {} - SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc() { type=arg.type; diff --git a/sql/opt_range.h b/sql/opt_range.h index 586c35f397f..2005773eca7 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -73,7 +73,7 @@ public: QUICK_SELECT(TABLE *table,uint index_arg,bool no_alloc=0); virtual ~QUICK_SELECT(); void reset(void) { next=0; it.rewind(); } - virtual int init() { return 0; } + virtual int init(); virtual int get_next(); int cmp_next(QUICK_RANGE *range); bool unique_key_range(); diff --git a/sql/share/romanian/errmsg.sys b/sql/share/romanian/errmsg.sys Binary files differindex 1638246579c..a8336a034a8 100644 --- a/sql/share/romanian/errmsg.sys +++ b/sql/share/romanian/errmsg.sys diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 9f9d34b9d05..a759a495c37 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -163,7 +163,7 @@ "Получен пакет в неправильном порядке", "Не могу распаковать пакет", "Ошибка при чтении пакетов" -"Timeout при чтении пакетов", +"Таймаут при чтении пакетов", "Ошибка при отправке пакетов", "Ошибка при отправке пакетов", "Результирующая строка больше чем max_allowed_packet", @@ -171,25 +171,25 @@ "Используемая таблица не поддерживает поля AUTO_INCREMENT", "INSERT DELAYED не может использоваться с таблицей '%-.64s', она занята использованием LOCK TABLES", "Неверное имя поля '%-.100s'", -"Используемый table handler не может индексировать поле '%-.64s'", -"All tables in the MERGE table are not defined identically", -"Can't write, because of unique constraint, to table '%-.64s'", -"BLOB column '%-.64s' used in key specification without a key length", -"All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead", -"Result consisted of more than one row", -"This table type requires a primary key", -"This version of MySQL is not compiled with RAID support", +"Таблица используемого типа не может индексировать поле '%-.64s'", +"Не все таблицы в MERGE определены одинаково", +"Не могу писать в таблицу '%-.64s' из-за UNIQUE условий", +"Поле типа BLOB '%-.64s' в определении индекса без указания длины", +"Все части PRIMARY KEY должны быть NOT NULL; если NULL в индексе необходим, используйте UNIQUE", +"Результат содержит больше одной строки", +"Таблица этого типа обязана иметь PRIMARY KEY", +"Эта копия MySQL скомпилирована без поддержки RAID", "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column", -"Key '%-.64s' doesn't exist in table '%-.64s'", -"Can't open table", -"The handler for the table doesn't support check/repair", -"You are not allowed to execute this command in a transaction", -"Got error %d during COMMIT", -"Got error %d during ROLLBACK", -"Got error %d during FLUSH_LOGS", -"Got error %d during CHECKPOINT", -"Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: `%-.64s' (%-.64s)", -"The handler for the table does not support binary table dump", +"Индекс '%-.64s' не найден в таблице '%-.64s'", +"Не могу открыть таблицу", +"Данный тип таблиц не поддерживает check/repair", +"Эта команда внутри транзакции запрещена", +"Ошибка %d во время COMMIT", +"Ошибка %d во время ROLLBACK", +"Ошибка %d во время FLUSH_LOGS", +"Ошибка %d во время CHECKPOINT", +"Прерванное соединение %ld к базе данных: '%-.64s' пользователь: '%-.32s' хост: `%-.64s' (%-.64s)", +"Этот тип таблиц не поддерживает binary table dump", "Binlog closed while trying to FLUSH MASTER", "Failed rebuilding the index of dumped table '%-.64s'", "Error from master: '%-.64s'", @@ -197,7 +197,7 @@ "Net error writing to master", "FULLTEXT индекс, соответствующий заданному списку столбцов, не найден", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", -"Table '%-.64s' is marked as crashed and should be repaired", -"Table '%-.64s' is marked as crashed and last (automatic?) repair failed", +"Неизвестная системная переменная '%-.64'", +"Таблица '%-.64s' помечена как испорченная и должна быть исправлена", +"Таблица '%-.64s' помечена как испорченная и последняя попытка исправления (автоматическая?) не удалась", "Warning: Some non-transactional changed tables couldn't be rolled back", diff --git a/sql/slave.cc b/sql/slave.cc index f2636ab5380..830ea070293 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -761,6 +761,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) thd->query_error = 0; // clear error thd->net.last_errno = 0; thd->net.last_error[0] = 0; + thd->slave_proxy_id = qev->thread_id; // for temp tables mysql_parse(thd, thd->query, q_len); int expected_error,actual_error; if((expected_error = qev->error_code) != @@ -781,24 +782,17 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) thd->convert_set = 0; // assume no convert for next query // unless set explictly close_thread_tables(thd); - free_root(&thd->mem_root,0); - if (thd->query_error) + if (thd->query_error || thd->fatal_error) { sql_print_error("Slave: error running query '%s' ", qev->query); + free_root(&thd->mem_root,0); delete ev; return 1; } - + free_root(&thd->mem_root,0); delete ev; - - if(thd->fatal_error) - { - sql_print_error("Slave: Fatal error running query '%s' ", - thd->query); - return 1; - } mi->inc_pos(event_len); flush_master_info(mi); @@ -874,6 +868,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) List<Item> fields; lev->set_fields(fields); + thd->slave_proxy_id = thd->thread_id; thd->net.vio = net->vio; // mysql_load will use thd->net to read the file thd->net.pkt_nr = net->pkt_nr; @@ -919,11 +914,13 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) } case START_EVENT: + close_temporary_tables(thd); mi->inc_pos(event_len); flush_master_info(mi); break; case STOP_EVENT: + close_temporary_tables(thd); mi->inc_pos(event_len); flush_master_info(mi); break; @@ -1164,9 +1161,8 @@ static void safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, mi->port, 0, 0)) { - sql_print_error( - "Slave thread: error connecting to master:%s, retry in %d sec", - mc_mysql_error(mysql), mi->connect_retry); + sql_print_error("Slave thread: error connecting to master:%s(%d),\ + retry in %d sec", mc_mysql_error(mysql), errno, mi->connect_retry); safe_sleep(thd, mi->connect_retry); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 66c4a22ad67..f582b4a85af 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -422,11 +422,47 @@ void close_temporary(TABLE *table,bool delete_table) void close_temporary_tables(THD *thd) { TABLE *table,*next; + uint init_query_buf_size = 11, query_buf_size; // "drop table " + char* query, *p; + LINT_INIT(p); + query_buf_size = init_query_buf_size; + + for (table=thd->temporary_tables ; table ; table=table->next) + { + query_buf_size += table->key_length; + + } + + if(query_buf_size == init_query_buf_size) + return; // no tables to close + + if((query = alloc_root(&thd->mem_root, query_buf_size))) + { + memcpy(query, "drop table ", init_query_buf_size); + p = query + init_query_buf_size; + } + for (table=thd->temporary_tables ; table ; table=next) { + if(query) // we might be out of memory, but this is not fatal + { + p = strxmov(p,table->table_cache_key,".", + table->table_name,",", NullS); + // here we assume table_cache_key always starts + // with \0 terminated db name + } next=table->next; close_temporary(table); } + if(query && mysql_bin_log.is_open()) + { + uint save_query_len = thd->query_length; + *--p = 0; + thd->query_length = (uint)(p-query); + Query_log_event qinfo(thd, query); + mysql_bin_log.write(&qinfo); + thd->query_length = save_query_len; + } thd->temporary_tables=0; } @@ -437,6 +473,9 @@ TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name) uint key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1; TABLE *table,**prev; + int4store(key+key_length,thd->slave_proxy_id); + key_length += 4; + prev= &thd->temporary_tables; for (table=thd->temporary_tables ; table ; table=table->next) { @@ -457,21 +496,25 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name) table= *prev; *prev= table->next; close_temporary(table); + if(thd->slave_thread) + --slave_open_temp_tables; return 0; } -bool rename_temporary_table(TABLE *table, const char *db, +bool rename_temporary_table(THD* thd, TABLE *table, const char *db, const char *table_name) { char *key; if (!(key=(char*) alloc_root(&table->mem_root, (uint) strlen(db)+ - (uint) strlen(table_name)+2))) + (uint) strlen(table_name)+6))) return 1; /* purecov: inspected */ table->key_length=(uint) (strmov((table->real_name=strmov(table->table_cache_key=key, db)+1), table_name) - table->table_cache_key)+1; + int4store(key+table->key_length,thd->slave_proxy_id); + table->key_length += 4; return 0; } @@ -624,8 +667,10 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, *refresh=0; if (thd->killed) DBUG_RETURN(0); - key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; - + key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1; + int4store(key + key_length, thd->slave_proxy_id); + key_length += 4; + for (table=thd->temporary_tables; table ; table=table->next) { if (table->key_length == key_length && @@ -1339,8 +1384,14 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db, { TABLE *tmp_table; DBUG_ENTER("open_temporary_table"); + + // the extra size in my_malloc() is for table_cache_key + // 4 bytes for master thread id if we are in the slave + // 1 byte to terminate db + // 1 byte to terminate table_name + // total of 6 extra bytes in my_malloc in addition to table/db stuff if (!(tmp_table=(TABLE*) my_malloc(sizeof(*tmp_table)+(uint) strlen(db)+ - (uint) strlen(table_name)+2, + (uint) strlen(table_name)+6, MYF(MY_WME)))) DBUG_RETURN(0); /* purecov: inspected */ @@ -1361,10 +1412,16 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db, tmp_table->key_length= (uint) (strmov(strmov(tmp_table->table_cache_key,db) +1, table_name) - tmp_table->table_cache_key)+1; + int4store(tmp_table->table_cache_key + tmp_table->key_length, + thd->slave_proxy_id); + tmp_table->key_length += 4; + if (link_in_list) { tmp_table->next=thd->temporary_tables; thd->temporary_tables=tmp_table; + if(thd->slave_thread) + ++slave_open_temp_tables; } DBUG_RETURN(tmp_table); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 5be229a2695..c484573c560 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -98,6 +98,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), start_time=(time_t) 0; current_linfo = 0; slave_thread = 0; + slave_proxy_id = 0; last_nx_table = last_nx_db = 0; inactive_timeout=net_wait_timeout; open_options=ha_open_options; diff --git a/sql/sql_class.h b/sql/sql_class.h index 83c70f29d19..7e3864fad01 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -274,6 +274,10 @@ public: // if we do a purge of binary logs, log index info of the threads // that are currently reading it needs to be adjusted. To do that // each thread that is using LOG_INFO needs to adjust the pointer to it + + ulong slave_proxy_id; // in slave thread we need to know in behalf of which + // thread the query is being run to replicate temp tables properly + THD(); ~THD(); bool store_globals(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5eba2ab880b..c54bf0dc9c1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -875,7 +875,7 @@ mysql_execute_command(void) TABLE_LIST *tables=(TABLE_LIST*) lex->table_list.first; DBUG_ENTER("mysql_execute_command"); - if(thd->slave_thread && table_rules_on && tables && !tables_ok(thd,tables)) + if(table_rules_on && thd->slave_thread && tables && !tables_ok(thd,tables)) DBUG_VOID_RETURN; // skip if we are in the slave thread, some table // rules have been given and the table list says the query should not be // replicated diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f51e1d1abe8..fe0c7f7e60e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1437,7 +1437,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } /* Remove link to old table and rename the new one */ close_temporary_table(thd,table->table_cache_key,table_name); - if (rename_temporary_table(new_table, new_db, new_name)) + if (rename_temporary_table(thd, new_table, new_db, new_name)) { // Fatal error close_temporary_table(thd,new_db,tmp_name); my_free((gptr) new_table,MYF(0)); @@ -1615,6 +1615,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, (copy_end++)->set(*ptr,def->field,0); } + found_count=delete_count=0; + if(order) { from->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); @@ -1632,7 +1634,6 @@ copy_data_between_tables(TABLE *from,TABLE *to, init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1); - found_count=delete_count=0; next_field=to->next_number_field; while (!(error=info.read_record(&info))) { diff --git a/sql/unireg.h b/sql/unireg.h index c293433dd42..9f078ef3766 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -41,7 +41,8 @@ #define ERRMAPP 1 /* Errormap f|r my_error */ #define LIBLEN FN_REFLEN-FN_LEN /* Max l{ngd p} dev */ -#define MAX_DBKEY_LENGTH (FN_LEN*2+2) +#define MAX_DBKEY_LENGTH (FN_LEN*2+6) /* extra 4 bytes for slave tmp + * tables */ #define MAX_FIELD_NAME 34 /* Max colum name length +2 */ #define MAX_KEY 32 /* Max used keys */ #define MAX_REF_PARTS 16 /* Max parts used as ref */ |