summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore91
-rw-r--r--Docs/manual.texi4
-rw-r--r--client/mysqltest.c27
-rw-r--r--myisam/ft_search.c2
-rwxr-xr-xmysql-test/create-test-result8
-rw-r--r--mysql-test/r/3.23/rpl000012.result7
-rw-r--r--mysql-test/r/3.23/rpl000012.status.result2
-rw-r--r--mysql-test/t/3.23/rpl000012.test19
-rw-r--r--mysql-test/t/include/master-slave.inc2
-rw-r--r--sql/ha_myisam.cc12
-rw-r--r--sql/ha_myisam.h1
-rw-r--r--sql/item_func.cc9
-rw-r--r--sql/log_event.h4
-rw-r--r--sql/mysql_priv.h5
-rw-r--r--sql/mysqlbinlog.cc3
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/opt_range.cc7
-rw-r--r--sql/opt_range.h2
-rw-r--r--sql/share/romanian/errmsg.sysbin11929 -> 12003 bytes
-rw-r--r--sql/share/russian/errmsg.txt44
-rw-r--r--sql/slave.cc22
-rw-r--r--sql/sql_base.cc67
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h4
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_table.cc5
-rw-r--r--sql/unireg.h3
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
index 1638246579c..a8336a034a8 100644
--- a/sql/share/romanian/errmsg.sys
+++ b/sql/share/romanian/errmsg.sys
Binary files differ
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 */