Commit b80ead72 authored by unknown's avatar unknown

keep bk happy


Docs/manual.texi:
  Changelog
mysql-test/mysql-test-run.sh:
  Added missing --user
sql/ha_berkeley.cc:
  Fixed bug in SHOW LOGS
sql/item_func.cc:
  Cleanup; Fixed possible problem with NULL
sql/mini_client.cc:
  cleanup
sql/slave.cc:
  Cleanup
sql/sql_repl.cc:
  Fixed timing problem where we could miss a broadcast
sql/sql_show.cc:
  Fixed bug in SHOW LOGS when there wasn't any log files
parent 6c367019
...@@ -40712,6 +40712,11 @@ not yet 100 % confident in this code. ...@@ -40712,6 +40712,11 @@ not yet 100 % confident in this code.
@appendixsubsec Changes in release 3.23.32 @appendixsubsec Changes in release 3.23.32
@itemize @bullet @itemize @bullet
@item @item
Fixed bug in @code{SHOW LOGS} when there wheren't any BDB logs.
@item
Fixed a timing problem in replication that could delay sending an update
to the client until a new update was done.
@item
Don't convert field names when using @code{mysql_list_fields()}. This is Don't convert field names when using @code{mysql_list_fields()}. This is
to keep this code compatible with @code{SHOW FIELDS}. to keep this code compatible with @code{SHOW FIELDS}.
@item @item
...@@ -239,7 +239,7 @@ SLAVE_MYSQLD=$MYSQLD #this can be changed later if we are doing gcov ...@@ -239,7 +239,7 @@ SLAVE_MYSQLD=$MYSQLD #this can be changed later if we are doing gcov
#-- #--
wait_for_server_start () wait_for_server_start ()
{ {
$MYSQL -e "select 1" --silent -w1 --host=127.0.0.1 --port=$1 \ $MYSQL --no-defaults -u $DBUSER -e "select 1" --silent -w1 --host=127.0.0.1 --port=$1 \
>/dev/null >/dev/null
} }
...@@ -492,7 +492,7 @@ mysql_restart () { ...@@ -492,7 +492,7 @@ mysql_restart () {
mysql_loadstd () { mysql_loadstd () {
cp $STD_DATA/*.frm $STD_DATA/*.MRG $MASTER_MYDDIR/test # cp $STD_DATA/*.frm $STD_DATA/*.MRG $MASTER_MYDDIR/test
return 1 return 1
} }
......
...@@ -253,27 +253,33 @@ int berkeley_show_logs(THD *thd) ...@@ -253,27 +253,33 @@ int berkeley_show_logs(THD *thd)
{ {
DBUG_PRINT("error", ("log_archive failed (error %d)", error)); DBUG_PRINT("error", ("log_archive failed (error %d)", error));
db_env->err(db_env, error, "log_archive: DB_ARCH_ABS"); db_env->err(db_env, error, "log_archive: DB_ARCH_ABS");
if (error== DB_NOTFOUND)
error=0; // No log files
goto err; goto err;
} }
/* Error is 0 here */
for (a = all_logs, f = free_logs; *a; ++a) if (all_logs)
{ {
packet->length(0); for (a = all_logs, f = free_logs; *a; ++a)
net_store_data(packet,*a);
net_store_data(packet,"BDB");
if (*f && strcmp(*a, *f) == 0)
{ {
++f; packet->length(0);
net_store_data(packet, SHOW_LOG_STATUS_FREE); net_store_data(packet,*a);
} net_store_data(packet,"BDB");
else if (f && *f && strcmp(*a, *f) == 0)
net_store_data(packet, SHOW_LOG_STATUS_INUSE); {
++f;
net_store_data(packet, SHOW_LOG_STATUS_FREE);
}
else
net_store_data(packet, SHOW_LOG_STATUS_INUSE);
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
goto err; {
error=1;
goto err;
}
}
} }
error=0;
err: err:
free_root(&show_logs_root,MYF(0)); free_root(&show_logs_root,MYF(0));
my_pthread_setspecific_ptr(THR_MALLOC,old_root); my_pthread_setspecific_ptr(THR_MALLOC,old_root);
...@@ -317,12 +323,12 @@ void berkeley_cleanup_log_files(void) ...@@ -317,12 +323,12 @@ void berkeley_cleanup_log_files(void)
} }
if (names) if (names)
{ /* purecov: tested */ { /* purecov: tested */
char **np; /* purecov: tested */ char **np; /* purecov: tested */
for (np = names; *np; ++np) /* purecov: tested */ for (np = names; *np; ++np) /* purecov: tested */
my_delete(*np, MYF(MY_WME)); /* purecov: tested */ my_delete(*np, MYF(MY_WME)); /* purecov: tested */
free(names); /* purecov: tested */ free(names); /* purecov: tested */
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -526,9 +532,9 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked) ...@@ -526,9 +532,9 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
{ {
if ((error=db_create(ptr, db_env, 0))) if ((error=db_create(ptr, db_env, 0)))
{ {
close(); /* purecov: inspected */ close(); /* purecov: inspected */
my_errno=error; /* purecov: inspected */ my_errno=error; /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */
} }
sprintf(part,"key%02d",++used_keys); sprintf(part,"key%02d",++used_keys);
key_type[i]=table->key_info[i].flags & HA_NOSAME ? DB_NOOVERWRITE : 0; key_type[i]=table->key_info[i].flags & HA_NOSAME ? DB_NOOVERWRITE : 0;
...@@ -539,9 +545,9 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked) ...@@ -539,9 +545,9 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
if ((error=((*ptr)->open(*ptr, name_buff, part, DB_BTREE, if ((error=((*ptr)->open(*ptr, name_buff, part, DB_BTREE,
open_mode, 0)))) open_mode, 0))))
{ {
close(); /* purecov: inspected */ close(); /* purecov: inspected */
my_errno=error; /* purecov: inspected */ my_errno=error; /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */
} }
} }
} }
...@@ -1042,6 +1048,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) ...@@ -1042,6 +1048,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
ulong thd_options = table->in_use ? table->in_use->options : 0; ulong thd_options = table->in_use ? table->in_use->options : 0;
bool primary_key_changed; bool primary_key_changed;
DBUG_ENTER("update_row"); DBUG_ENTER("update_row");
LINT_INIT(error);
statistic_increment(ha_update_count,&LOCK_status); statistic_increment(ha_update_count,&LOCK_status);
if (table->time_stamp) if (table->time_stamp)
...@@ -1066,7 +1073,6 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) ...@@ -1066,7 +1073,6 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
} }
sub_trans = transaction; sub_trans = transaction;
LINT_INIT(error);
for (uint retry=0 ; retry < berkeley_trans_retry ; retry++) for (uint retry=0 ; retry < berkeley_trans_retry ; retry++)
{ {
key_map changed_keys = 0; key_map changed_keys = 0;
......
...@@ -1399,14 +1399,18 @@ longlong Item_master_pos_wait::val_int() ...@@ -1399,14 +1399,18 @@ longlong Item_master_pos_wait::val_int()
String *log_name = args[0]->val_str(&value); String *log_name = args[0]->val_str(&value);
int event_count; int event_count;
if(thd->slave_thread || !log_name || !log_name->length()) null_value=0;
{ if (thd->slave_thread || !log_name || !log_name->length())
null_value = 1; {
return 0; null_value = 1;
} return 0;
}
ulong pos = (ulong)args[1]->val_int(); ulong pos = (ulong)args[1]->val_int();
if((event_count = glob_mi.wait_for_pos(thd, log_name, pos)) == -1) if ((event_count = glob_mi.wait_for_pos(thd, log_name, pos)) == -1)
null_value = 1;; {
null_value = 1;
event_count=0;
}
return event_count; return event_count;
} }
......
...@@ -298,9 +298,9 @@ static int mc_sock_connect(my_socket s, const struct sockaddr *name, ...@@ -298,9 +298,9 @@ static int mc_sock_connect(my_socket s, const struct sockaddr *name,
return(-1); return(-1);
if (s_err) if (s_err)
{ /* getsockopt() could suceed */ { // getsockopt() could succeed
errno = s_err; errno = s_err;
return(-1); /* but return an error... */ return(-1); // but return an error...
} }
return(0); /* It's all good! */ return(0); /* It's all good! */
#endif #endif
...@@ -403,8 +403,8 @@ my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql) ...@@ -403,8 +403,8 @@ my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
int STDCALL int STDCALL
mc_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg, mc_simple_command(MYSQL *mysql,enum enum_server_command command,
uint length, my_bool skipp_check) const char *arg, uint length, my_bool skipp_check)
{ {
NET *net= &mysql->net; NET *net= &mysql->net;
int result= -1; int result= -1;
......
...@@ -102,35 +102,37 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len) ...@@ -102,35 +102,37 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len)
int tables_ok(THD* thd, TABLE_LIST* tables) int tables_ok(THD* thd, TABLE_LIST* tables)
{ {
for(; tables; tables = tables->next) for (; tables; tables = tables->next)
{
if (!tables->updating)
continue;
char hash_key[2*NAME_LEN+2];
char* p;
p = strmov(hash_key, tables->db ? tables->db : thd->db);
*p++ = '.';
uint len = strmov(p, tables->real_name) - hash_key ;
if (do_table_inited) // if there are any do's
{ {
if(!tables->updating) if (hash_search(&replicate_do_table, (byte*) hash_key, len))
continue; return 1;
char hash_key[2*NAME_LEN+2]; }
char* p; if (ignore_table_inited) // if there are any do's
p = strmov(hash_key, tables->db ? tables->db : thd->db); {
*p++ = '.'; if (hash_search(&replicate_ignore_table, (byte*) hash_key, len))
uint len = strmov(p, tables->real_name) - hash_key ; return 0;
if(do_table_inited) // if there are any do's
{
if(hash_search(&replicate_do_table, (byte*) hash_key, len))
return 1;
}
if(ignore_table_inited) // if there are any do's
{
if(hash_search(&replicate_ignore_table, (byte*) hash_key, len))
return 0;
}
if(wild_do_table_inited && find_wild(&replicate_wild_do_table,
hash_key, len)) return 1;
if(wild_ignore_table_inited && find_wild(&replicate_wild_ignore_table,
hash_key, len)) return 0;
} }
if (wild_do_table_inited && find_wild(&replicate_wild_do_table,
hash_key, len))
return 1;
if (wild_ignore_table_inited && find_wild(&replicate_wild_ignore_table,
hash_key, len))
return 0;
}
return !do_table_inited && !wild_do_table_inited;
// if no explicit rule found // if no explicit rule found
// and there was a do list, do not replicate. If there was // and there was a do list, do not replicate. If there was
// no do list, go ahead // no do list, go ahead
return !do_table_inited && !wild_do_table_inited;
} }
...@@ -138,8 +140,8 @@ int add_table_rule(HASH* h, const char* table_spec) ...@@ -138,8 +140,8 @@ int add_table_rule(HASH* h, const char* table_spec)
{ {
const char* dot = strchr(table_spec, '.'); const char* dot = strchr(table_spec, '.');
if(!dot) return 1; if(!dot) return 1;
// len is always > 0 because we know the there exists a '.'
uint len = (uint)strlen(table_spec); uint len = (uint)strlen(table_spec);
if(!len) return 1;
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT) TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
+ len, MYF(MY_WME)); + len, MYF(MY_WME));
if(!e) return 1; if(!e) return 1;
...@@ -156,7 +158,6 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec) ...@@ -156,7 +158,6 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
const 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;
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT) TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
+ len, MYF(MY_WME)); + len, MYF(MY_WME));
if(!e) return 1; if(!e) return 1;
...@@ -174,7 +175,7 @@ static void free_string_array(DYNAMIC_ARRAY *a) ...@@ -174,7 +175,7 @@ static void free_string_array(DYNAMIC_ARRAY *a)
for(i = 0; i < a->elements; i++) for(i = 0; i < a->elements; i++)
{ {
char* p; char* p;
get_dynamic(a, (gptr)&p, i); get_dynamic(a, (gptr) &p, i);
my_free(p, MYF(MY_WME)); my_free(p, MYF(MY_WME));
} }
delete_dynamic(a); delete_dynamic(a);
...@@ -227,9 +228,10 @@ int db_ok(const char* db, I_List<i_string> &do_list, ...@@ -227,9 +228,10 @@ int db_ok(const char* db, I_List<i_string> &do_list,
if(do_list.is_empty() && ignore_list.is_empty()) if(do_list.is_empty() && ignore_list.is_empty())
return 1; // ok to replicate if the user puts no constraints return 1; // ok to replicate if the user puts no constraints
if(!db) // if the user has specified restrictions on which databases to replicate
return 0; // if the user has specified restrictions on which databases to replicate
// and db was not selected, do not replicate // and db was not selected, do not replicate
if(!db)
return 0;
if(!do_list.is_empty()) // if the do's are not empty if(!do_list.is_empty()) // if the do's are not empty
{ {
...@@ -255,49 +257,49 @@ int db_ok(const char* db, I_List<i_string> &do_list, ...@@ -255,49 +257,49 @@ int db_ok(const char* db, I_List<i_string> &do_list,
} }
return 1; return 1;
} }
} }
static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f, static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
char* default_val) char* default_val)
{ {
uint length;
if(my_b_gets(f,var, max_size)) if ((length=my_b_gets(f,var, max_size)))
{
char* last_p = var + length -1;
if (*last_p == '\n')
*last_p = 0; // if we stopped on newline, kill it
else
{ {
char* last_p = strend(var) - 1;
int c;
if(*last_p == '\n') *last_p = 0; // if we stopped on newline, kill it
else
while( ((c=my_b_get(f)) != '\n' && c != my_b_EOF));
// if we truncated a line or stopped on last char, remove all chars // if we truncated a line or stopped on last char, remove all chars
// up to and including newline // up to and including newline
return 0; int c;
} while( ((c=my_b_get(f)) != '\n' && c != my_b_EOF));
else if(default_val)
{
strmake(var, default_val, max_size);
return 0;
} }
return 0;
}
else if (default_val)
{
strmake(var, default_val, max_size);
return 0;
}
return 1; return 1;
} }
static int init_intvar_from_file(int* var, IO_CACHE* f, static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
int default_val)
{ {
char buf[32]; char buf[32];
if(my_b_gets(f, buf, sizeof(buf))) if (my_b_gets(f, buf, sizeof(buf)))
{ {
*var = atoi(buf); *var = atoi(buf);
return 0; return 0;
} }
else if(default_val) else if(default_val)
{ {
*var = default_val; *var = default_val;
return 0; return 0;
} }
return 1; return 1;
} }
...@@ -334,41 +336,41 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, ...@@ -334,41 +336,41 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
thd->query_error = 0; thd->query_error = 0;
thd->net.no_send_ok = 1; thd->net.no_send_ok = 1;
thd->proc_info = "Creating table from master dump"; thd->proc_info = "Creating table from master dump";
// save old db in case we are creating in a different database
char* save_db = thd->db; char* save_db = thd->db;
thd->db = thd->last_nx_db; // in case we are creating in a different thd->db = thd->last_nx_db;
// database
mysql_parse(thd, thd->query, packet_len); // run create table mysql_parse(thd, thd->query, packet_len); // run create table
thd->db = save_db; // leave things the way the were before thd->db = save_db; // leave things the way the were before
if(thd->query_error) if(thd->query_error)
{ {
close_thread_tables(thd); // mysql_parse takes care of the error send close_thread_tables(thd); // mysql_parse takes care of the error send
return 1; return 1;
} }
bzero((char*) &tables,sizeof(tables)); bzero((char*) &tables,sizeof(tables));
tables.db = (char*)db; tables.db = (char*)db;
tables.name = tables.real_name = (char*)table_name; tables.name = tables.real_name = (char*)table_name;
tables.lock_type = TL_WRITE; tables.lock_type = TL_WRITE;
thd->proc_info = "Opening master dump table"; thd->proc_info = "Opening master dump table";
if(!open_ltable(thd, &tables, TL_WRITE)) if (!open_ltable(thd, &tables, TL_WRITE))
{ {
// open tables will send the error // open tables will send the error
sql_print_error("create_table_from_dump: could not open created table"); sql_print_error("create_table_from_dump: could not open created table");
close_thread_tables(thd); close_thread_tables(thd);
return 1; return 1;
} }
handler *file = tables.table->file; handler *file = tables.table->file;
thd->proc_info = "Reading master dump table data"; thd->proc_info = "Reading master dump table data";
if(file->net_read_dump(net)) if (file->net_read_dump(net))
{ {
net_printf(&thd->net, ER_MASTER_NET_READ); net_printf(&thd->net, ER_MASTER_NET_READ);
sql_print_error("create_table_from_dump::failed in\ sql_print_error("create_table_from_dump::failed in\
handler::net_read_dump()"); handler::net_read_dump()");
close_thread_tables(thd); close_thread_tables(thd);
return 1; return 1;
} }
HA_CHECK_OPT check_opt; HA_CHECK_OPT check_opt;
check_opt.init(); check_opt.init();
...@@ -376,14 +378,15 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, ...@@ -376,14 +378,15 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
check_opt.quick = 1; check_opt.quick = 1;
thd->proc_info = "rebuilding the index on master dump table"; thd->proc_info = "rebuilding the index on master dump table";
Vio* save_vio = thd->net.vio; Vio* save_vio = thd->net.vio;
thd->net.vio = 0; // we do not want repair() to spam us with messages // we do not want repair() to spam us with messages
// just send them to the error log, and report the failure in case of // just send them to the error log, and report the failure in case of
// problems // problems
if(file->repair(thd,&check_opt )) thd->net.vio = 0;
{ if (file->repair(thd,&check_opt ))
{
net_printf(&thd->net, ER_INDEX_REBUILD,tables.table->real_name ); net_printf(&thd->net, ER_INDEX_REBUILD,tables.table->real_name );
error = 1; error = 1;
} }
thd->net.vio = save_vio; thd->net.vio = save_vio;
close_thread_tables(thd); close_thread_tables(thd);
...@@ -423,15 +426,12 @@ int fetch_nx_table(THD* thd, MASTER_INFO* mi) ...@@ -423,15 +426,12 @@ int fetch_nx_table(THD* thd, MASTER_INFO* mi)
} }
error = 0; error = 0;
err: err:
if(mysql) if (mysql)
{ mc_mysql_close(mysql);
mc_mysql_close(mysql); if (nx_errno && thd->net.vio)
mysql = 0;
}
if(nx_errno && thd->net.vio)
send_error(&thd->net, nx_errno, "Error in fetch_nx_table"); send_error(&thd->net, nx_errno, "Error in fetch_nx_table");
return error; return error;
} }
...@@ -448,13 +448,13 @@ void end_master_info(MASTER_INFO* mi) ...@@ -448,13 +448,13 @@ void end_master_info(MASTER_INFO* mi)
int init_master_info(MASTER_INFO* mi) int init_master_info(MASTER_INFO* mi)
{ {
if(mi->inited) if (mi->inited)
return 0; return 0;
int fd; int fd,length,error;
MY_STAT stat_area; MY_STAT stat_area;
char fname[FN_REFLEN+128]; char fname[FN_REFLEN+128];
const char *msg;
fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32); fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
// we need a mutex while we are changing master info parameters to // we need a mutex while we are changing master info parameters to
// keep other threads from reading bogus info // keep other threads from reading bogus info
...@@ -463,101 +463,95 @@ int init_master_info(MASTER_INFO* mi) ...@@ -463,101 +463,95 @@ int init_master_info(MASTER_INFO* mi)
mi->pending = 0; mi->pending = 0;
fd = mi->fd; fd = mi->fd;
if(!my_stat(fname, &stat_area, MYF(0))) // we do not want any messages // we do not want any messages if the file does not exist
// if the file does not exist if (!my_stat(fname, &stat_area, MYF(0)))
{
// if someone removed the file from underneath our feet, just close
// the old descriptor and re-create the old file
if (fd >= 0)
my_close(fd, MYF(MY_WME));
if ((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
MYF(MY_WME)))
{ {
// if someone removed the file from underneath our feet, just close if(fd >= 0)
// the old descriptor and re-create the old file my_close(fd, MYF(0));
if(fd >= 0) my_close(fd, MYF(MY_WME)); pthread_mutex_unlock(&mi->lock);
if((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 return 1;
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
MYF(MY_WME)))
{
if(fd >= 0)
my_close(fd, MYF(0));
pthread_mutex_unlock(&mi->lock);
return 1;
}
mi->log_file_name[0] = 0;
mi->pos = 4; // skip magic number
mi->fd = fd;
if(master_host)
strmake(mi->host, master_host, sizeof(mi->host) - 1);
if(master_user)
strmake(mi->user, master_user, sizeof(mi->user) - 1);
if(master_password)
strmake(mi->password, master_password, sizeof(mi->password) - 1);
mi->port = master_port;
mi->connect_retry = master_connect_retry;
} }
mi->log_file_name[0] = 0;
mi->pos = 4; // skip magic number
mi->fd = fd;
if (master_host)
strmake(mi->host, master_host, sizeof(mi->host) - 1);
if (master_user)
strmake(mi->user, master_user, sizeof(mi->user) - 1);
if (master_password)
strmake(mi->password, master_password, sizeof(mi->password) - 1);
mi->port = master_port;
mi->connect_retry = master_connect_retry;
}
else // file exists else // file exists
{
if(fd >= 0)
reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
else if((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
0, MYF(MY_WME)))
{ {
if(fd >= 0) if(fd >= 0)
reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0); my_close(fd, MYF(0));
else if((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 pthread_mutex_unlock(&mi->lock);
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L, return 1;
0, MYF(MY_WME))) }
{
if(fd >= 0)
my_close(fd, MYF(0));
pthread_mutex_unlock(&mi->lock);
return 1;
}
if(!my_b_gets(&mi->file, mi->log_file_name, sizeof(mi->log_file_name))) if (!(length=my_b_gets(&mi->file, mi->log_file_name,
{ sizeof(mi->log_file_name))))
sql_print_error("Error reading log file name from master info file "); {
end_io_cache(&mi->file); msg="Error reading log file name from master info file ";
my_close(fd, MYF(0)); goto error;
pthread_mutex_unlock(&mi->lock); }
return 1;
}
*(strend(mi->log_file_name) - 1) = 0; // kill \n mi->log_file_name[length]= 0; // kill \n
char buf[FN_REFLEN]; char buf[FN_REFLEN];
if(!my_b_gets(&mi->file, buf, sizeof(buf))) if(!my_b_gets(&mi->file, buf, sizeof(buf)))
{ {
sql_print_error("Error reading log file position from master info file"); msg="Error reading log file position from master info file";
end_io_cache(&mi->file); goto error;
my_close(fd, MYF(0)); }
pthread_mutex_unlock(&mi->lock);
return 1;
}
mi->pos = strtoull(buf,(char**) 0, 10); mi->pos = strtoull(buf,(char**) 0, 10);
mi->fd = fd; mi->fd = fd;
if(init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file, if(init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
master_host) || master_host) ||
init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file, init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
master_user) || master_user) ||
init_strvar_from_file(mi->password, sizeof(mi->password), &mi->file, init_strvar_from_file(mi->password, sizeof(mi->password), &mi->file,
master_password) || master_password) ||
init_intvar_from_file((int*)&mi->port, &mi->file, master_port) || init_intvar_from_file((int*)&mi->port, &mi->file, master_port) ||
init_intvar_from_file((int*)&mi->connect_retry, &mi->file, init_intvar_from_file((int*)&mi->connect_retry, &mi->file,
master_connect_retry)) master_connect_retry))
{ {
sql_print_error("Error reading master configuration"); msg="Error reading master configuration";
end_io_cache(&mi->file); goto error;
my_close(fd, MYF(0));
pthread_mutex_unlock(&mi->lock);
return 1;
}
} }
}
mi->inited = 1; mi->inited = 1;
// now change the cache from READ to WRITE - must do this // now change the cache from READ to WRITE - must do this
// before flush_master_info // before flush_master_info
reinit_io_cache(&mi->file, WRITE_CACHE, 0L,0,1); reinit_io_cache(&mi->file, WRITE_CACHE, 0L,0,1);
if(flush_master_info(mi)) error=test(flush_master_info(mi));
{
pthread_mutex_unlock(&mi->lock);
return 1;
}
pthread_mutex_unlock(&mi->lock); pthread_mutex_unlock(&mi->lock);
return error;
return 0;
error:
sql_print_error(msg);
end_io_cache(&mi->file);
my_close(fd, MYF(0));
pthread_mutex_unlock(&mi->lock);
return 1;
} }
int show_master_info(THD* thd) int show_master_info(THD* thd)
...@@ -588,7 +582,7 @@ int show_master_info(THD* thd) ...@@ -588,7 +582,7 @@ int show_master_info(THD* thd)
net_store_data(packet, (uint32) glob_mi.port); net_store_data(packet, (uint32) glob_mi.port);
net_store_data(packet, (uint32) glob_mi.connect_retry); net_store_data(packet, (uint32) glob_mi.connect_retry);
net_store_data(packet, glob_mi.log_file_name); net_store_data(packet, glob_mi.log_file_name);
net_store_data(packet, (longlong)glob_mi.pos); net_store_data(packet, (longlong) glob_mi.pos);
pthread_mutex_unlock(&glob_mi.lock); pthread_mutex_unlock(&glob_mi.lock);
pthread_mutex_lock(&LOCK_slave); pthread_mutex_lock(&LOCK_slave);
net_store_data(packet, slave_running ? "Yes":"No"); net_store_data(packet, slave_running ? "Yes":"No");
...@@ -596,7 +590,7 @@ int show_master_info(THD* thd) ...@@ -596,7 +590,7 @@ int show_master_info(THD* thd)
net_store_data(packet, &replicate_do_db); net_store_data(packet, &replicate_do_db);
net_store_data(packet, &replicate_ignore_db); net_store_data(packet, &replicate_ignore_db);
if(my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length())) if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
DBUG_RETURN(-1); DBUG_RETURN(-1);
send_eof(&thd->net); send_eof(&thd->net);
...@@ -610,50 +604,51 @@ int flush_master_info(MASTER_INFO* mi) ...@@ -610,50 +604,51 @@ int flush_master_info(MASTER_INFO* mi)
my_b_seek(file, 0L); my_b_seek(file, 0L);
my_b_printf(file, "%s\n%s\n%s\n%s\n%s\n%d\n%d\n", my_b_printf(file, "%s\n%s\n%s\n%s\n%s\n%d\n%d\n",
mi->log_file_name, llstr(mi->pos, lbuf), mi->host, mi->user, mi->password, mi->log_file_name, llstr(mi->pos, lbuf), mi->host, mi->user,
mi->port, mi->connect_retry); mi->password, mi->port, mi->connect_retry);
flush_io_cache(file); flush_io_cache(file);
return 0; return 0;
} }
int st_master_info::wait_for_pos(THD* thd, String* log_name, ulong log_pos) int st_master_info::wait_for_pos(THD* thd, String* log_name, ulong log_pos)
{ {
if(!inited) return -1; if (!inited) return -1;
bool pos_reached = 0; bool pos_reached;
int event_count = 0; int event_count = 0;
for(;!pos_reached && !thd->killed;) pthread_mutex_lock(&lock);
do
{
int cmp_result;
if (*log_file_name)
{ {
int cmp_result; /*
char* basename; We should use dirname_length() here when we have a version of
pthread_mutex_lock(&lock); this that doesn't modify the argument */
if(*log_file_name) char *basename = strrchr(log_file_name, FN_LIBCHAR);
{ if (basename)
basename = strrchr(log_file_name, FN_LIBCHAR); ++basename;
if(basename)
++basename;
else
basename = log_file_name;
cmp_result = strncmp(basename, log_name->ptr(),
log_name->length());
}
else else
cmp_result = 0; basename = log_file_name;
cmp_result = strncmp(basename, log_name->ptr(),
log_name->length());
}
else
cmp_result = 0;
pos_reached = ((!cmp_result && pos >= log_pos) || cmp_result > 0); pos_reached = ((!cmp_result && pos >= log_pos) || cmp_result > 0);
if(!pos_reached && !thd->killed) if (pos_reached || thd->killed)
{ break;
const char* msg = thd->enter_cond(&cond, &lock, {
"Waiting for master update"); const char* msg = thd->enter_cond(&cond, &lock,
pthread_cond_wait(&cond, &lock); "Waiting for master update");
thd->exit_cond(msg); pthread_cond_wait(&cond, &lock);
event_count++; thd->exit_cond(msg);
} event_count++;
pthread_mutex_unlock(&lock); pos_reached = (pos >= log_pos);
if(thd->killed)
return -1;
} }
} while (!pos_reached && !thd->killed);
return event_count; pthread_mutex_unlock(&lock);
return thd->killed ? -1 : event_count;
} }
...@@ -715,12 +710,17 @@ static int safe_sleep(THD* thd, int sec) ...@@ -715,12 +710,17 @@ static int safe_sleep(THD* thd, int sec)
while (start_time < end_time) while (start_time < end_time)
{ {
int nap_time = (int) (end_time - start_time); int nap_time = (int) (end_time - start_time);
thr_alarm(&alarmed, 2 * nap_time,&alarm_buff); // the only reason we are asking for alarm is so that /*
// we will be woken up in case of murder, so if we do not get killed, set the alarm the only reason we are asking for alarm is so that
// so it goes off after we wake up naturally we will be woken up in case of murder, so if we do not get killed,
set the alarm so it goes off after we wake up naturally
*/
thr_alarm(&alarmed, 2 * nap_time,&alarm_buff);
sleep(nap_time); sleep(nap_time);
if (thr_alarm_in_use(&alarmed)) // if we wake up before the alarm goes off, hit the button // if we wake up before the alarm goes off, hit the button
thr_end_alarm(&alarmed); // so it will not wake up the wife and kids :-) // so it will not wake up the wife and kids :-)
if (thr_alarm_in_use(&alarmed))
thr_end_alarm(&alarmed);
if (slave_killed(thd)) if (slave_killed(thd))
return 1; return 1;
...@@ -741,15 +741,15 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi) ...@@ -741,15 +741,15 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
int4store(buf + 6, server_id); int4store(buf + 6, server_id);
len = (uint) strlen(logname); len = (uint) strlen(logname);
memcpy(buf + 10, logname,len); memcpy(buf + 10, logname,len);
if(mc_simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1)) if (mc_simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
// something went wrong, so we will just reconnect and retry later {
// in the future, we should do a better error analysis, but for // something went wrong, so we will just reconnect and retry later
// now we just fill up the error log :-) // in the future, we should do a better error analysis, but for
{ // now we just fill up the error log :-)
sql_print_error("Error on COM_BINLOG_DUMP: %s, will retry in %d secs", sql_print_error("Error on COM_BINLOG_DUMP: %s, will retry in %d secs",
mc_mysql_error(mysql), master_connect_retry); mc_mysql_error(mysql), master_connect_retry);
return 1; return 1;
} }
return 0; return 0;
} }
...@@ -772,12 +772,12 @@ static int request_table_dump(MYSQL* mysql, char* db, char* table) ...@@ -772,12 +772,12 @@ static int request_table_dump(MYSQL* mysql, char* db, char* table)
*p++ = table_len; *p++ = table_len;
memcpy(p, table, table_len); memcpy(p, table, table_len);
if(mc_simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1)) if (mc_simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1))
{ {
sql_print_error("request_table_dump: Error sending the table dump \ sql_print_error("request_table_dump: Error sending the table dump \
command"); command");
return 1; return 1;
} }
return 0; return 0;
} }
...@@ -786,21 +786,24 @@ command"); ...@@ -786,21 +786,24 @@ command");
static uint read_event(MYSQL* mysql, MASTER_INFO *mi) static uint read_event(MYSQL* mysql, MASTER_INFO *mi)
{ {
uint len = packet_error; uint len = packet_error;
int read_errno = EINTR; // for convinience lets think we start by // for convinience lets think we start by
// being in the interrupted state :-) // being in the interrupted state :-)
int read_errno = EINTR;
// my_real_read() will time us out // my_real_read() will time us out
// we check if we were told to die, and if not, try reading again // we check if we were told to die, and if not, try reading again
#ifndef DBUG_OFF #ifndef DBUG_OFF
if(disconnect_slave_event_count && !(events_till_disconnect--)) if (disconnect_slave_event_count && !(events_till_disconnect--))
return packet_error; return packet_error;
#endif #endif
while (!abort_loop && !abort_slave && len == packet_error && read_errno == EINTR ) while (!abort_loop && !abort_slave && len == packet_error &&
read_errno == EINTR )
{ {
len = mc_net_safe_read(mysql); len = mc_net_safe_read(mysql);
read_errno = errno; read_errno = errno;
} }
if(abort_loop || abort_slave) if (abort_loop || abort_slave)
return packet_error; return packet_error;
if (len == packet_error || (int) len < 1) if (len == packet_error || (int) len < 1)
{ {
...@@ -810,17 +813,16 @@ server_errno=%d)", ...@@ -810,17 +813,16 @@ server_errno=%d)",
return packet_error; return packet_error;
} }
if(len == 1) if (len == 1)
{ {
sql_print_error("Slave: received 0 length packet from server, apparent\ sql_print_error("Slave: received 0 length packet from server, apparent\
master shutdown: %s (%d)", master shutdown: %s (%d)",
mc_mysql_error(mysql), read_errno); mc_mysql_error(mysql), read_errno);
return packet_error; return packet_error;
} }
DBUG_PRINT("info",( "len=%u, net->read_pos[4] = %d\n", DBUG_PRINT("info",( "len=%u, net->read_pos[4] = %d\n",
len, mysql->net.read_pos[4])); len, mysql->net.read_pos[4]));
return len - 1; return len - 1;
} }
...@@ -833,30 +835,29 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) ...@@ -833,30 +835,29 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
if (ev) if (ev)
{ {
int type_code = ev->get_type_code(); int type_code = ev->get_type_code();
if(ev->server_id == ::server_id) if (ev->server_id == ::server_id)
{ {
if(type_code == LOAD_EVENT) if(type_code == LOAD_EVENT)
skip_load_data_infile(net); skip_load_data_infile(net);
mi->inc_pos(event_len); mi->inc_pos(event_len);
flush_master_info(mi); flush_master_info(mi);
delete ev; delete ev;
return 0; // avoid infinite update loops return 0; // avoid infinite update loops
} }
thd->server_id = ev->server_id; // use the original server id for logging thd->server_id = ev->server_id; // use the original server id for logging
thd->set_time(); // time the query thd->set_time(); // time the query
ev->when = time(NULL); ev->when = time(NULL);
switch(type_code) switch(type_code) {
{
case QUERY_EVENT: case QUERY_EVENT:
{ {
Query_log_event* qev = (Query_log_event*)ev; Query_log_event* qev = (Query_log_event*)ev;
int q_len = qev->q_len; int q_len = qev->q_len;
init_sql_alloc(&thd->mem_root, 8192,0); init_sql_alloc(&thd->mem_root, 8192,0);
thd->db = rewrite_db((char*)qev->db); thd->db = rewrite_db((char*)qev->db);
if(db_ok(thd->db, replicate_do_db, replicate_ignore_db)) if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
{ {
thd->query = (char*)qev->query; thd->query = (char*)qev->query;
thd->set_time((time_t)qev->when); thd->set_time((time_t)qev->when);
...@@ -865,29 +866,29 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) ...@@ -865,29 +866,29 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
thd->query_id = query_id++; thd->query_id = query_id++;
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->last_nx_table = thd->last_nx_db = 0; thd->last_nx_table = thd->last_nx_db = 0;
thd->query_error = 0; // clear error thd->query_error = 0; // clear error
thd->net.last_errno = 0; thd->net.last_errno = 0;
thd->net.last_error[0] = 0; thd->net.last_error[0] = 0;
thd->slave_proxy_id = qev->thread_id; // for temp tables thd->slave_proxy_id = qev->thread_id; // for temp tables
mysql_parse(thd, thd->query, q_len); mysql_parse(thd, thd->query, q_len);
int expected_error,actual_error; int expected_error,actual_error;
if((expected_error = qev->error_code) != if ((expected_error = qev->error_code) !=
(actual_error = thd->net.last_errno) && expected_error) (actual_error = thd->net.last_errno) && expected_error)
{ {
sql_print_error("Slave: did not get the expected error\ sql_print_error("Slave: did not get the expected error\
running query from master - expected: '%s', got '%s'", running query from master - expected: '%s', got '%s'",
ER(expected_error), ER(expected_error),
actual_error ? ER(actual_error):"no error" actual_error ? ER(actual_error):"no error"
); );
thd->query_error = 1; thd->query_error = 1;
} }
else if(expected_error == actual_error) else if (expected_error == actual_error)
thd->query_error = 0; thd->query_error = 0;
} }
thd->db = 0;// prevent db from being freed thd->db = 0; // prevent db from being freed
thd->query = 0; // just to be sure thd->query = 0; // just to be sure
thd->convert_set = 0; // assume no convert for next query // assume no convert for next query unless set explictly
// unless set explictly thd->convert_set = 0;
close_thread_tables(thd); close_thread_tables(thd);
if (thd->query_error || thd->fatal_error) if (thd->query_error || thd->fatal_error)
...@@ -929,69 +930,70 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) ...@@ -929,69 +930,70 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
tables.lock_type = TL_WRITE; tables.lock_type = TL_WRITE;
// the table will be opened in mysql_load // the table will be opened in mysql_load
if(table_rules_on && !tables_ok(thd, &tables)) if(table_rules_on && !tables_ok(thd, &tables))
{ {
skip_load_data_infile(net); skip_load_data_infile(net);
} }
else else
{ {
enum enum_duplicates handle_dup = DUP_IGNORE; enum enum_duplicates handle_dup = DUP_IGNORE;
if(lev->sql_ex.opt_flags && REPLACE_FLAG) if(lev->sql_ex.opt_flags && REPLACE_FLAG)
handle_dup = DUP_REPLACE; handle_dup = DUP_REPLACE;
sql_exchange ex((char*)lev->fname, lev->sql_ex.opt_flags && sql_exchange ex((char*)lev->fname, lev->sql_ex.opt_flags &&
DUMPFILE_FLAG ); DUMPFILE_FLAG );
String field_term(&lev->sql_ex.field_term, 1), String field_term(&lev->sql_ex.field_term, 1),
enclosed(&lev->sql_ex.enclosed, 1), enclosed(&lev->sql_ex.enclosed, 1),
line_term(&lev->sql_ex.line_term,1), line_term(&lev->sql_ex.line_term,1),
escaped(&lev->sql_ex.escaped, 1), escaped(&lev->sql_ex.escaped, 1),
line_start(&lev->sql_ex.line_start, 1); line_start(&lev->sql_ex.line_start, 1);
ex.field_term = &field_term; ex.field_term = &field_term;
if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY) if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
ex.field_term->length(0); ex.field_term->length(0);
ex.enclosed = &enclosed; ex.enclosed = &enclosed;
if(lev->sql_ex.empty_flags & ENCLOSED_EMPTY) if(lev->sql_ex.empty_flags & ENCLOSED_EMPTY)
ex.enclosed->length(0); ex.enclosed->length(0);
ex.line_term = &line_term; ex.line_term = &line_term;
if(lev->sql_ex.empty_flags & LINE_TERM_EMPTY) if(lev->sql_ex.empty_flags & LINE_TERM_EMPTY)
ex.line_term->length(0); ex.line_term->length(0);
ex.line_start = &line_start; ex.line_start = &line_start;
if(lev->sql_ex.empty_flags & LINE_START_EMPTY) if(lev->sql_ex.empty_flags & LINE_START_EMPTY)
ex.line_start->length(0); ex.line_start->length(0);
ex.escaped = &escaped; ex.escaped = &escaped;
if(lev->sql_ex.empty_flags & ESCAPED_EMPTY) if(lev->sql_ex.empty_flags & ESCAPED_EMPTY)
ex.escaped->length(0); ex.escaped->length(0);
ex.opt_enclosed = (lev->sql_ex.opt_flags & OPT_ENCLOSED_FLAG); ex.opt_enclosed = (lev->sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY) if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
ex.field_term->length(0); ex.field_term->length(0);
ex.skip_lines = lev->skip_lines; ex.skip_lines = lev->skip_lines;
List<Item> fields; List<Item> fields;
lev->set_fields(fields); lev->set_fields(fields);
thd->slave_proxy_id = thd->thread_id; thd->slave_proxy_id = thd->thread_id;
thd->net.vio = net->vio; thd->net.vio = net->vio;
// mysql_load will use thd->net to read the file // mysql_load will use thd->net to read the file
thd->net.pkt_nr = net->pkt_nr; thd->net.pkt_nr = net->pkt_nr;
// make sure the client does get confused // make sure the client does get confused
// about the packet sequence // about the packet sequence
if(mysql_load(thd, &ex, &tables, fields, handle_dup, 1, if(mysql_load(thd, &ex, &tables, fields, handle_dup, 1,
TL_WRITE)) TL_WRITE))
thd->query_error = 1; thd->query_error = 1;
if(thd->cuted_fields) if(thd->cuted_fields)
sql_print_error("Slave: load data infile at position %d in log \ sql_print_error("Slave: load data infile at position %d in log \
'%s' produced %d warning(s)", glob_mi.pos, RPL_LOG_NAME, thd->cuted_fields ); '%s' produced %d warning(s)", glob_mi.pos, RPL_LOG_NAME, thd->cuted_fields );
net->pkt_nr = thd->net.pkt_nr; net->pkt_nr = thd->net.pkt_nr;
} }
} }
else // we will just ask the master to send us /dev/null if we do not want to else
// load the data :-)
{ {
// we will just ask the master to send us /dev/null if we do not
// want to load the data :-)
skip_load_data_infile(net); skip_load_data_infile(net);
} }
...@@ -1077,7 +1079,6 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) ...@@ -1077,7 +1079,6 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
break; break;
} }
} }
} }
else else
{ {
...@@ -1099,13 +1100,13 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) ...@@ -1099,13 +1100,13 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
MYSQL *mysql = NULL ; MYSQL *mysql = NULL ;
pthread_mutex_lock(&LOCK_slave); pthread_mutex_lock(&LOCK_slave);
if(!server_id) if (!server_id)
{ {
pthread_cond_broadcast(&COND_slave_start); pthread_cond_broadcast(&COND_slave_start);
pthread_mutex_unlock(&LOCK_slave); pthread_mutex_unlock(&LOCK_slave);
sql_print_error("Server id not set, will not start slave"); sql_print_error("Server id not set, will not start slave");
pthread_exit((void*)1); pthread_exit((void*)1);
} }
if(slave_running) if(slave_running)
{ {
...@@ -1125,14 +1126,14 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) ...@@ -1125,14 +1126,14 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
bool retried_once = 0; bool retried_once = 0;
ulonglong last_failed_pos = 0; ulonglong last_failed_pos = 0;
my_thread_init(); // needs to be up here, otherwise we get a coredump // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
// trying to use DBUG_ stuff my_thread_init();
thd = new THD; // note that contructor of THD uses DBUG_ ! thd = new THD; // note that contructor of THD uses DBUG_ !
thd->set_time(); thd->set_time();
DBUG_ENTER("handle_slave"); DBUG_ENTER("handle_slave");
pthread_detach_this_thread(); pthread_detach_this_thread();
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 thd->temporary_tables = save_temporary_tables; // restore temp tables
...@@ -1141,12 +1142,12 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) ...@@ -1141,12 +1142,12 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
DBUG_PRINT("info",("master info: log_file_name=%s, position=%d", DBUG_PRINT("info",("master info: log_file_name=%s, position=%d",
glob_mi.log_file_name, glob_mi.pos)); glob_mi.log_file_name, glob_mi.pos));
mysql = mc_mysql_init(NULL);
if(!mysql) if (!(mysql = mc_mysql_init(NULL)))
{ {
sql_print_error("Slave thread: error in mc_mysql_init()"); sql_print_error("Slave thread: error in mc_mysql_init()");
goto err; goto err;
} }
thd->proc_info = "connecting to master"; thd->proc_info = "connecting to master";
#ifndef DBUG_OFF #ifndef DBUG_OFF
...@@ -1162,8 +1163,8 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused))) ...@@ -1162,8 +1163,8 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
else else
goto err; goto err;
while(!slave_killed(thd)) while (!slave_killed(thd))
{ {
thd->proc_info = "requesting binlog dump"; thd->proc_info = "requesting binlog dump";
if(request_dump(mysql, &glob_mi)) if(request_dump(mysql, &glob_mi))
{ {
...@@ -1255,12 +1256,11 @@ reconnecting to retry, log '%s' position %ld", RPL_LOG_NAME, ...@@ -1255,12 +1256,11 @@ reconnecting to retry, log '%s' position %ld", RPL_LOG_NAME,
#ifndef DBUG_OFF #ifndef DBUG_OFF
else else
{ {
stuck_count++; // show a little mercy, allow slave to read one more event
// show a little mercy, allow slave to read one more event // before cutting him off - otherwise he gets stuck
// before cutting him off - otherwise he gets stuck // on Invar events, since they do not advance the offset
// on Invar events, since they do not advance the offset // immediately
// immediately if (++stuck_count > 2)
if(stuck_count > 2)
events_till_disconnect++; events_till_disconnect++;
} }
#endif #endif
...@@ -1276,10 +1276,7 @@ position %ld", ...@@ -1276,10 +1276,7 @@ position %ld",
RPL_LOG_NAME, glob_mi.pos); RPL_LOG_NAME, glob_mi.pos);
thd->query = thd->db = 0; // extra safety thd->query = thd->db = 0; // extra safety
if(mysql) if(mysql)
{
mc_mysql_close(mysql); mc_mysql_close(mysql);
mysql = 0;
}
thd->proc_info = "waiting for slave mutex on exit"; thd->proc_info = "waiting for slave mutex on exit";
pthread_mutex_lock(&LOCK_slave); pthread_mutex_lock(&LOCK_slave);
slave_running = 0; slave_running = 0;
...@@ -1299,8 +1296,10 @@ position %ld", ...@@ -1299,8 +1296,10 @@ position %ld",
DBUG_RETURN(0); // Can't return anything here DBUG_RETURN(0); // Can't return anything here
} }
/* try to connect until successful or slave killed */
static int 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 or slave killed
{ {
int slave_was_killed; int slave_was_killed;
#ifndef DBUG_OFF #ifndef DBUG_OFF
...@@ -1322,13 +1321,14 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) ...@@ -1322,13 +1321,14 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
return slave_was_killed; return slave_was_killed;
} }
// will try to connect until successful or slave killed /* try to connect until successful or slave killed */
static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
{ {
int slave_was_killed; int slave_was_killed;
mi->pending = 0; // if we lost connection after reading a state set event // 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
mi->pending = 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
events_till_disconnect = disconnect_slave_event_count; events_till_disconnect = disconnect_slave_event_count;
#endif #endif
...@@ -1346,7 +1346,7 @@ replication resumed in log '%s' at position %ld", glob_mi.user, ...@@ -1346,7 +1346,7 @@ replication resumed 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);
return slave_was_killed; return slave_was_killed;
} }
...@@ -1354,4 +1354,3 @@ replication resumed in log '%s' at position %ld", glob_mi.user, ...@@ -1354,4 +1354,3 @@ replication resumed in log '%s' at position %ld", glob_mi.user,
template class I_List_iterator<i_string>; template class I_List_iterator<i_string>;
template class I_List_iterator<i_string_pair>; template class I_List_iterator<i_string_pair>;
#endif #endif
...@@ -311,29 +311,30 @@ sweepstakes if you report the bug"; ...@@ -311,29 +311,30 @@ sweepstakes if you report the bug";
// we need to start a packet with something other than 255 // we need to start a packet with something other than 255
// to distiquish it from error // to distiquish it from error
if(pos == 4) // tell the client log name with a fake rotate_event // tell the client log name with a fake rotate_event
// if we are at the start of the log // if we are at the start of the log
{ if(pos == 4)
if(fake_rotate_event(net, packet, log_file_name, &errmsg)) {
goto err; if (fake_rotate_event(net, packet, log_file_name, &errmsg))
packet->length(0); goto err;
packet->append("\0", 1); packet->length(0);
} packet->append("\0", 1);
}
while(!net->error && net->vio != 0 && !thd->killed) while (!net->error && net->vio != 0 && !thd->killed)
{ {
pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock(); pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
while (!(error = Log_event::read_log_event(&log, packet, log_lock))) while (!(error = Log_event::read_log_event(&log, packet, log_lock)))
{ {
if(my_net_write(net, (char*)packet->ptr(), packet->length()) ) if (my_net_write(net, (char*)packet->ptr(), packet->length()) )
{ {
errmsg = "Failed on my_net_write()"; errmsg = "Failed on my_net_write()";
goto err; goto err;
} }
DBUG_PRINT("info", ("log event code %d", DBUG_PRINT("info", ("log event code %d",
(*packet)[LOG_EVENT_OFFSET+1] )); (*packet)[LOG_EVENT_OFFSET+1] ));
if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT) if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
{ {
if(send_file(thd)) if(send_file(thd))
{ {
...@@ -345,8 +346,7 @@ sweepstakes if you report the bug"; ...@@ -345,8 +346,7 @@ sweepstakes if you report the bug";
packet->append("\0",1); packet->append("\0",1);
} }
if (error != LOG_READ_EOF)
if(error != LOG_READ_EOF)
{ {
switch(error) switch(error)
{ {
...@@ -399,7 +399,8 @@ sweepstakes if you report the bug"; ...@@ -399,7 +399,8 @@ sweepstakes if you report the bug";
// no one will update the log while we are reading // no one will update the log while we are reading
// now, but we'll be quick and just read one record // now, but we'll be quick and just read one record
switch(Log_event::read_log_event(&log, packet, log_lock)) pthread_mutex_lock(log_lock);
switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*) 0))
{ {
case 0: case 0:
read_packet = 1; read_packet = 1;
...@@ -407,15 +408,14 @@ sweepstakes if you report the bug"; ...@@ -407,15 +408,14 @@ sweepstakes if you report the bug";
// slave // slave
break; break;
case LOG_READ_EOF: case LOG_READ_EOF:
pthread_mutex_lock(log_lock);
pthread_cond_wait(&COND_binlog_update, log_lock); pthread_cond_wait(&COND_binlog_update, log_lock);
pthread_mutex_unlock(log_lock);
break; break;
default: default:
fatal_error = 1; fatal_error = 1;
break; break;
} }
pthread_mutex_unlock(log_lock);
pthread_mutex_lock(&thd->mysys_var->mutex); pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0; thd->mysys_var->current_mutex= 0;
......
...@@ -592,7 +592,7 @@ mysqld_show_logs(THD *thd) ...@@ -592,7 +592,7 @@ mysqld_show_logs(THD *thd)
#ifdef HAVE_BERKELEY_DB #ifdef HAVE_BERKELEY_DB
if (berkeley_show_logs(thd)) if (berkeley_show_logs(thd))
DBUG_RETURN(1); DBUG_RETURN(-1);
#endif #endif
send_eof(&thd->net); send_eof(&thd->net);
......
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