Commit e0100606 authored by sasha@mysql.sashanet.com's avatar sasha@mysql.sashanet.com

Merge work.mysql.com:/home/bk/mysql

into mysql.sashanet.com:/home/sasha/src/bk/mysql
parents 4dfa7cad de445fe9
...@@ -371,3 +371,5 @@ libmysql_r/thr_mutex.c ...@@ -371,3 +371,5 @@ libmysql_r/thr_mutex.c
libmysql_r/typelib.c libmysql_r/typelib.c
libmysql_r/violite.c libmysql_r/violite.c
linked_libmysql_r_sources linked_libmysql_r_sources
client/thimble
support-files/mysql-3.23.29-gamma.spec
This diff is collapsed.
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include "my_global.h"
static void spawn_stern_thread(pthread_t *t); static void spawn_stern_thread(pthread_t *t);
static int act_goofy(void); static int act_goofy(void);
...@@ -13,6 +14,7 @@ static struct { ...@@ -13,6 +14,7 @@ static struct {
int msg; int msg;
} comm = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0 }; } comm = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0 };
int int
main(void) main(void)
{ {
...@@ -65,7 +67,7 @@ static int act_goofy(void) ...@@ -65,7 +67,7 @@ static int act_goofy(void)
return ret; return ret;
} }
static void *be_stern(void *v __attribute((unused))) static void *be_stern(void *v __attribute__((unused)))
{ {
int msg; int msg;
for (;;) { for (;;) {
...@@ -87,3 +89,5 @@ static void *be_stern(void *v __attribute((unused))) ...@@ -87,3 +89,5 @@ static void *be_stern(void *v __attribute((unused)))
fputs("You are NOTHING!\n", stderr); fputs("You are NOTHING!\n", stderr);
return NULL; return NULL;
} }
Variable_name Value
Slave_open_temp_tables 0
...@@ -8,7 +8,7 @@ drop table if exists foo; ...@@ -8,7 +8,7 @@ drop table if exists foo;
create table foo(n int); create table foo(n int);
insert into foo values(1),(2); insert into foo values(1),(2);
connection slave; connection slave;
sleep 3; sleep 2;
use test; use test;
@r/3.23/rpl000001.a.result select * from foo; @r/3.23/rpl000001.a.result select * from foo;
@r/3.23/rpl000001.b.result select sum(length(word)) from words; @r/3.23/rpl000001.b.result select sum(length(word)) from words;
......
...@@ -7,5 +7,5 @@ set insert_id = 2000; ...@@ -7,5 +7,5 @@ set insert_id = 2000;
insert into x values (NULL),(NULL),(NULL); insert into x values (NULL),(NULL),(NULL);
connection slave; connection slave;
use test; use test;
sleep 1; sleep 0.5;
@r/3.23/rpl000002.result select * from x; @r/3.23/rpl000002.result select * from x;
...@@ -5,5 +5,5 @@ create table x(n int primary key); ...@@ -5,5 +5,5 @@ create table x(n int primary key);
!insert into x values (1),(2),(2); !insert into x values (1),(2),(2);
insert into x values (3); insert into x values (3);
connection slave; connection slave;
sleep 1; sleep 0.5;
@r/3.23/rpl000003.result select * from x; @r/3.23/rpl000003.result select * from x;
...@@ -8,5 +8,5 @@ INSERT into test SET name='Caleb', age=1; ...@@ -8,5 +8,5 @@ INSERT into test SET name='Caleb', age=1;
ALTER TABLE test ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY; ALTER TABLE test ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
@r/3.23/rpl000005.result select * from test; @r/3.23/rpl000005.result select * from test;
connection slave; connection slave;
sleep 1; sleep 0.5;
@r/3.23/rpl000005.result select * from test; @r/3.23/rpl000005.result select * from test;
--abort-slave-event-count=1
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;
let $1=12;
while ($1)
{
!slave start;
sleep 0.2;
dec $1;
}
@r/3.23/rpl000013.result select * from x;
@r/3.23/rpl000013.status.result show status like 'Slave_open_temp_tables';
...@@ -2217,7 +2217,7 @@ enum options { ...@@ -2217,7 +2217,7 @@ enum options {
OPT_SKIP_INNOBASE,OPT_SAFEMALLOC_MEM_LIMIT, OPT_SKIP_INNOBASE,OPT_SAFEMALLOC_MEM_LIMIT,
OPT_REPLICATE_DO_TABLE, OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_DO_TABLE, OPT_REPLICATE_IGNORE_TABLE,
OPT_REPLICATE_WILD_DO_TABLE, OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE, OPT_REPLICATE_WILD_IGNORE_TABLE,
OPT_DISCONNECT_SLAVE_EVENT_COUNT OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_ABORT_SLAVE_EVENT_COUNT
}; };
static struct option long_options[] = { static struct option long_options[] = {
...@@ -2277,6 +2277,8 @@ static struct option long_options[] = { ...@@ -2277,6 +2277,8 @@ static struct option long_options[] = {
// is a no-op // is a no-op
{"disconnect-slave-event-count", required_argument, 0, {"disconnect-slave-event-count", required_argument, 0,
(int) OPT_DISCONNECT_SLAVE_EVENT_COUNT}, (int) OPT_DISCONNECT_SLAVE_EVENT_COUNT},
{"abort-slave-event-count", required_argument, 0,
(int) OPT_ABORT_SLAVE_EVENT_COUNT},
#if !defined(DBUG_OFF) && defined(SAFEMALLOC) #if !defined(DBUG_OFF) && defined(SAFEMALLOC)
{"safemalloc-mem-limit", required_argument, 0, (int) {"safemalloc-mem-limit", required_argument, 0, (int)
OPT_SAFEMALLOC_MEM_LIMIT}, OPT_SAFEMALLOC_MEM_LIMIT},
...@@ -2883,6 +2885,11 @@ static void get_options(int argc,char **argv) ...@@ -2883,6 +2885,11 @@ static void get_options(int argc,char **argv)
case (int)OPT_DISCONNECT_SLAVE_EVENT_COUNT: case (int)OPT_DISCONNECT_SLAVE_EVENT_COUNT:
#ifndef DBUG_OFF #ifndef DBUG_OFF
disconnect_slave_event_count = atoi(optarg); disconnect_slave_event_count = atoi(optarg);
#endif
break;
case (int)OPT_ABORT_SLAVE_EVENT_COUNT:
#ifndef DBUG_OFF
abort_slave_event_count = atoi(optarg);
#endif #endif
break; break;
case (int) OPT_LOG_SLAVE_UPDATES: case (int) OPT_LOG_SLAVE_UPDATES:
......
...@@ -33,9 +33,13 @@ DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table; ...@@ -33,9 +33,13 @@ DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
bool do_table_inited = 0, ignore_table_inited = 0; bool do_table_inited = 0, ignore_table_inited = 0;
bool wild_do_table_inited = 0, wild_ignore_table_inited = 0; bool wild_do_table_inited = 0, wild_ignore_table_inited = 0;
bool table_rules_on = 0; bool table_rules_on = 0;
// when slave thread exits, we need to remember the temporary tables so we
// can re-use them on slave start
static TABLE* save_temporary_tables = 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
int disconnect_slave_event_count = 0; int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
static int events_till_disconnect = -1; static int events_till_disconnect = -1, events_till_abort = -1;
static int stuck_count = 0; static int stuck_count = 0;
#endif #endif
...@@ -43,8 +47,8 @@ static int stuck_count = 0; ...@@ -43,8 +47,8 @@ static int stuck_count = 0;
static inline void skip_load_data_infile(NET* net); static inline void skip_load_data_infile(NET* net);
static inline bool slave_killed(THD* thd); static inline bool slave_killed(THD* thd);
static int init_slave_thread(THD* thd); static int init_slave_thread(THD* thd);
static void safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi); static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
static void safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi); static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
static int safe_sleep(THD* thd, int sec); static int safe_sleep(THD* thd, int sec);
static int request_table_dump(MYSQL* mysql, char* db, char* table); static int request_table_dump(MYSQL* mysql, char* db, char* table);
static int create_table_from_dump(THD* thd, NET* net, const char* db, static int create_table_from_dump(THD* thd, NET* net, const char* db,
...@@ -131,7 +135,7 @@ int tables_ok(THD* thd, TABLE_LIST* tables) ...@@ -131,7 +135,7 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
int add_table_rule(HASH* h, const char* table_spec) int add_table_rule(HASH* h, const char* table_spec)
{ {
char* dot = strchr(table_spec, '.'); const char* dot = strchr(table_spec, '.');
if(!dot) return 1; if(!dot) return 1;
uint len = (uint)strlen(table_spec); uint len = (uint)strlen(table_spec);
if(!len) return 1; if(!len) return 1;
...@@ -148,7 +152,7 @@ int add_table_rule(HASH* h, const char* table_spec) ...@@ -148,7 +152,7 @@ int add_table_rule(HASH* h, const char* table_spec)
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec) int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
{ {
char* dot = strchr(table_spec, '.'); const char* dot = strchr(table_spec, '.');
if(!dot) return 1; if(!dot) return 1;
uint len = (uint)strlen(table_spec); uint len = (uint)strlen(table_spec);
if(!len) return 1; if(!len) return 1;
...@@ -968,7 +972,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) ...@@ -968,7 +972,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
pthread_handler_decl(handle_slave,arg __attribute__((unused))) pthread_handler_decl(handle_slave,arg __attribute__((unused)))
{ {
THD *thd;; // needs to be first for thread_stack THD *thd; // needs to be first for thread_stack
MYSQL *mysql = NULL ; MYSQL *mysql = NULL ;
if(!server_id) if(!server_id)
...@@ -985,6 +989,9 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) ...@@ -985,6 +989,9 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
} }
slave_running = 1; slave_running = 1;
abort_slave = 0; abort_slave = 0;
#ifndef DBUG_OFF
events_till_abort = abort_slave_event_count;
#endif
pthread_mutex_unlock(&LOCK_slave); pthread_mutex_unlock(&LOCK_slave);
int error = 1; int error = 1;
...@@ -1001,7 +1008,7 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) ...@@ -1001,7 +1008,7 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
if(init_slave_thread(thd) || init_master_info(&glob_mi)) if(init_slave_thread(thd) || init_master_info(&glob_mi))
goto err; goto err;
thd->thread_stack = (char*)&thd; // remember where our stack is thd->thread_stack = (char*)&thd; // remember where our stack is
thd->temporary_tables = save_temporary_tables; // restore temp tables
threads.append(thd); threads.append(thd);
DBUG_PRINT("info",("master info: log_file_name=%s, position=%d", DBUG_PRINT("info",("master info: log_file_name=%s, position=%d",
...@@ -1017,14 +1024,16 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) ...@@ -1017,14 +1024,16 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
thd->proc_info = "connecting to master"; thd->proc_info = "connecting to master";
#ifndef DBUG_OFF #ifndef DBUG_OFF
sql_print_error("Slave thread initialized"); sql_print_error("Slave thread initialized");
#endif #endif
safe_connect(thd, mysql, &glob_mi); // we can get killed during safe_connect
// always report status on startup, even if we are not in debug if(!safe_connect(thd, mysql, &glob_mi))
sql_print_error("Slave: connected to master '%s@%s:%d',\ sql_print_error("Slave: connected to master '%s@%s:%d',\
replication started in log '%s' at position %ld", glob_mi.user, replication started in log '%s' at position %ld", glob_mi.user,
glob_mi.host, glob_mi.port, glob_mi.host, glob_mi.port,
RPL_LOG_NAME, RPL_LOG_NAME,
glob_mi.pos); glob_mi.pos);
else
goto err;
while(!slave_killed(thd)) while(!slave_killed(thd))
{ {
...@@ -1053,8 +1062,7 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) ...@@ -1053,8 +1062,7 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
sql_print_error("Slave: failed dump request, reconnecting to \ sql_print_error("Slave: failed dump request, reconnecting to \
try again, log '%s' at postion %ld", RPL_LOG_NAME, try again, log '%s' at postion %ld", RPL_LOG_NAME,
last_failed_pos = glob_mi.pos ); last_failed_pos = glob_mi.pos );
safe_reconnect(thd, mysql, &glob_mi); if(safe_reconnect(thd, mysql, &glob_mi) || slave_killed(thd))
if(slave_killed(thd))
goto err; goto err;
continue; continue;
...@@ -1084,8 +1092,7 @@ try again, log '%s' at postion %ld", RPL_LOG_NAME, ...@@ -1084,8 +1092,7 @@ try again, log '%s' at postion %ld", RPL_LOG_NAME,
sql_print_error("Slave: Failed reading log event, \ sql_print_error("Slave: Failed reading log event, \
reconnecting to retry, log '%s' position %ld", RPL_LOG_NAME, reconnecting to retry, log '%s' position %ld", RPL_LOG_NAME,
last_failed_pos = glob_mi.pos); last_failed_pos = glob_mi.pos);
safe_reconnect(thd, mysql, &glob_mi); if(safe_reconnect(thd, mysql, &glob_mi) || slave_killed(thd))
if(slave_killed(thd))
goto err; goto err;
break; break;
} }
...@@ -1101,6 +1108,13 @@ reconnecting to retry, log '%s' position %ld", RPL_LOG_NAME, ...@@ -1101,6 +1108,13 @@ reconnecting to retry, log '%s' position %ld", RPL_LOG_NAME,
// abort the slave thread, when the problem is fixed, the user // abort the slave thread, when the problem is fixed, the user
// should restart the slave with mysqladmin start-slave // should restart the slave with mysqladmin start-slave
} }
#ifndef DBUG_OFF
if(abort_slave_event_count && !--events_till_abort)
{
sql_print_error("Slave: debugging abort");
goto err;
}
#endif
// successful exec with offset advance, // successful exec with offset advance,
// the slave repents and his sins are forgiven! // the slave repents and his sins are forgiven!
...@@ -1143,6 +1157,8 @@ position %ld", ...@@ -1143,6 +1157,8 @@ position %ld",
pthread_mutex_lock(&LOCK_slave); pthread_mutex_lock(&LOCK_slave);
slave_running = 0; slave_running = 0;
abort_slave = 0; abort_slave = 0;
save_temporary_tables = thd->temporary_tables;
thd->temporary_tables = 0; // remove tempation from destructor to close them
pthread_cond_broadcast(&COND_slave_stopped); // tell the world we are done pthread_cond_broadcast(&COND_slave_stopped); // tell the world we are done
pthread_mutex_unlock(&LOCK_slave); pthread_mutex_unlock(&LOCK_slave);
delete thd; delete thd;
...@@ -1151,13 +1167,14 @@ position %ld", ...@@ -1151,13 +1167,14 @@ position %ld",
DBUG_RETURN(0); // Can't return anything here DBUG_RETURN(0); // Can't return anything here
} }
static void safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
// will try to connect until successful // will try to connect until successful or slave killed
{ {
int slave_was_killed;
#ifndef DBUG_OFF #ifndef DBUG_OFF
events_till_disconnect = disconnect_slave_event_count; events_till_disconnect = disconnect_slave_event_count;
#endif #endif
while(!slave_killed(thd) && while(!(slave_was_killed = slave_killed(thd)) &&
!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
mi->port, 0, 0)) mi->port, 0, 0))
{ {
...@@ -1166,28 +1183,39 @@ static void safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) ...@@ -1166,28 +1183,39 @@ static void safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
safe_sleep(thd, mi->connect_retry); safe_sleep(thd, mi->connect_retry);
} }
mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d", if(!slave_was_killed)
mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d",
mi->user, mi->host, mi->port); mi->user, mi->host, mi->port);
return slave_was_killed;
} }
// will try to connect until successful // will try to connect until successful or slave killed
static void safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
{ {
int slave_was_killed;
mi->pending = 0; // if we lost connection after reading a state set event mi->pending = 0; // if we lost connection after reading a state set event
// we will be re-reading it, so pending needs to be cleared // we will be re-reading it, so pending needs to be cleared
#ifndef DBUG_OFF #ifndef DBUG_OFF
events_till_disconnect = disconnect_slave_event_count; events_till_disconnect = disconnect_slave_event_count;
#endif #endif
while(!slave_killed(thd) && mc_mysql_reconnect(mysql)) while(!(slave_was_killed = slave_killed(thd)) && mc_mysql_reconnect(mysql))
{ {
sql_print_error("Slave thread: error connecting to master:\ sql_print_error("Slave thread: error re-connecting to master:\
%s, retry in %d sec", %s, last_errno=%d, retry in %d sec",
mc_mysql_error(mysql), mi->connect_retry); mc_mysql_error(mysql), errno, mi->connect_retry);
safe_sleep(thd, mi->connect_retry); safe_sleep(thd, mi->connect_retry);
} }
if(!slave_was_killed)
sql_print_error("Slave: reconnected to master '%s@%s:%d',\
replication resumed in log '%s' at position %ld", glob_mi.user,
glob_mi.host, glob_mi.port,
RPL_LOG_NAME,
glob_mi.pos);
return slave_was_killed;
} }
#ifdef __GNUC__ #ifdef __GNUC__
......
...@@ -95,7 +95,7 @@ extern bool do_table_inited, ignore_table_inited, ...@@ -95,7 +95,7 @@ extern bool do_table_inited, ignore_table_inited,
extern bool table_rules_on; extern bool table_rules_on;
#ifndef DBUG_OFF #ifndef DBUG_OFF
extern int disconnect_slave_event_count ; extern int disconnect_slave_event_count, abort_slave_event_count ;
#endif #endif
// the master variables are defaults read from my.cnf or command line // the master variables are defaults read from my.cnf or command line
......
...@@ -462,7 +462,7 @@ pthread_handler_decl(handle_bootstrap,arg) ...@@ -462,7 +462,7 @@ pthread_handler_decl(handle_bootstrap,arg)
thd->proc_info=0; thd->proc_info=0;
thd->version=refresh_version; thd->version=refresh_version;
thd->priv_user=thd->user="boot"; thd->priv_user=thd->user=(char*)"boot";
buff= (char*) thd->net.buff; buff= (char*) thd->net.buff;
init_sql_alloc(&thd->mem_root,8192,8192); init_sql_alloc(&thd->mem_root,8192,8192);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment