mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
client/mysqltest.c
fixed bug that created empty result files in no-record mode mysql-test/t/rpl000007.test testing non-replication of load data infile when the table is excluded from replication mysql-test/t/rpl000016.test test purge master logs sql/slave.cc fix memory leaks found by purge master logs test sql/sql_repl.cc fixed race condition and delete before close bug in reset_slave() Overall comments - coverage testing is a very good thing!
This commit is contained in:
@ -1306,9 +1306,9 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
close_cons();
|
close_cons();
|
||||||
|
|
||||||
if(result_file)
|
if(result_file && ds_res.len)
|
||||||
{
|
{
|
||||||
if(!record && ds_res.len)
|
if(!record)
|
||||||
error |= check_result(&ds_res, result_file);
|
error |= check_result(&ds_res, result_file);
|
||||||
else
|
else
|
||||||
str_to_file(result_file, ds_res.str, ds_res.len);
|
str_to_file(result_file, ds_res.str, ds_res.len);
|
||||||
|
@ -9,8 +9,9 @@ insert into foo values(4);
|
|||||||
connection master;
|
connection master;
|
||||||
use test;
|
use test;
|
||||||
drop table if exists foo;
|
drop table if exists foo;
|
||||||
create table foo (n int);
|
create table foo (s char(20));
|
||||||
insert into foo values(5);
|
load data infile '../../std_data/words.dat' into table foo;
|
||||||
|
insert into foo values('five');
|
||||||
drop table if exists bar;
|
drop table if exists bar;
|
||||||
create table bar (m int);
|
create table bar (m int);
|
||||||
insert into bar values(15);
|
insert into bar values(15);
|
||||||
|
@ -17,3 +17,17 @@ insert into foo values('Could not break slave'),('Tried hard');
|
|||||||
connection slave;
|
connection slave;
|
||||||
sleep 0.3;
|
sleep 0.3;
|
||||||
select * from foo;
|
select * from foo;
|
||||||
|
connection master;
|
||||||
|
flush logs;
|
||||||
|
drop table if exists bar;
|
||||||
|
create table bar(m int);
|
||||||
|
insert into bar values (34),(67),(123);
|
||||||
|
flush logs;
|
||||||
|
sleep 0.3;
|
||||||
|
show master logs;
|
||||||
|
purge master logs to 'master-bin.003';
|
||||||
|
show master logs;
|
||||||
|
insert into bar values (65);
|
||||||
|
connection slave;
|
||||||
|
sleep 0.3;
|
||||||
|
select * from bar;
|
||||||
|
163
sql/slave.cc
163
sql/slave.cc
@ -259,7 +259,7 @@ int db_ok(const char* db, I_List<i_string> &do_list,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void 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)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -272,12 +272,18 @@ static void init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
|
|||||||
while( ((c=my_b_get(f)) != '\n' && c != my_b_EOF));
|
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;
|
||||||
}
|
}
|
||||||
else if(default_val)
|
else if(default_val)
|
||||||
strmake(var, default_val, max_size);
|
{
|
||||||
|
strmake(var, default_val, max_size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void 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];
|
||||||
@ -285,9 +291,14 @@ static void init_intvar_from_file(int* var, IO_CACHE* f,
|
|||||||
if(my_b_gets(f, buf, sizeof(buf)))
|
if(my_b_gets(f, buf, sizeof(buf)))
|
||||||
{
|
{
|
||||||
*var = atoi(buf);
|
*var = atoi(buf);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else if(default_val)
|
else if(default_val)
|
||||||
*var = default_val;
|
{
|
||||||
|
*var = default_val;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -462,6 +473,8 @@ int init_master_info(MASTER_INFO* mi)
|
|||||||
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
|
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
|
||||||
MYF(MY_WME)))
|
MYF(MY_WME)))
|
||||||
{
|
{
|
||||||
|
if(fd >= 0)
|
||||||
|
my_close(fd, MYF(0));
|
||||||
pthread_mutex_unlock(&mi->lock);
|
pthread_mutex_unlock(&mi->lock);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -487,6 +500,8 @@ int init_master_info(MASTER_INFO* mi)
|
|||||||
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
|
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
|
||||||
0, MYF(MY_WME)))
|
0, MYF(MY_WME)))
|
||||||
{
|
{
|
||||||
|
if(fd >= 0)
|
||||||
|
my_close(fd, MYF(0));
|
||||||
pthread_mutex_unlock(&mi->lock);
|
pthread_mutex_unlock(&mi->lock);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -494,6 +509,8 @@ int init_master_info(MASTER_INFO* mi)
|
|||||||
if(!my_b_gets(&mi->file, mi->log_file_name, sizeof(mi->log_file_name)))
|
if(!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 ");
|
sql_print_error("Error reading log file name from master info file ");
|
||||||
|
end_io_cache(&mi->file);
|
||||||
|
my_close(fd, MYF(0));
|
||||||
pthread_mutex_unlock(&mi->lock);
|
pthread_mutex_unlock(&mi->lock);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -503,23 +520,30 @@ int init_master_info(MASTER_INFO* mi)
|
|||||||
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");
|
sql_print_error("Error reading log file position from master info file");
|
||||||
|
end_io_cache(&mi->file);
|
||||||
|
my_close(fd, MYF(0));
|
||||||
pthread_mutex_unlock(&mi->lock);
|
pthread_mutex_unlock(&mi->lock);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mi->pos = atoi(buf);
|
mi->pos = atoi(buf);
|
||||||
mi->fd = fd;
|
mi->fd = fd;
|
||||||
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");
|
||||||
|
end_io_cache(&mi->file);
|
||||||
|
my_close(fd, MYF(0));
|
||||||
|
pthread_mutex_unlock(&mi->lock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mi->inited = 1;
|
mi->inited = 1;
|
||||||
@ -858,65 +882,72 @@ 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));
|
||||||
|
|
||||||
enum enum_duplicates handle_dup = DUP_IGNORE;
|
|
||||||
if(lev->sql_ex.opt_flags && REPLACE_FLAG)
|
|
||||||
handle_dup = DUP_REPLACE;
|
|
||||||
sql_exchange ex((char*)lev->fname, lev->sql_ex.opt_flags &&
|
|
||||||
DUMPFILE_FLAG );
|
|
||||||
String field_term(&lev->sql_ex.field_term, 1),
|
|
||||||
enclosed(&lev->sql_ex.enclosed, 1),
|
|
||||||
line_term(&lev->sql_ex.line_term,1),
|
|
||||||
escaped(&lev->sql_ex.escaped, 1),
|
|
||||||
line_start(&lev->sql_ex.line_start, 1);
|
|
||||||
|
|
||||||
ex.field_term = &field_term;
|
|
||||||
if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
|
|
||||||
ex.field_term->length(0);
|
|
||||||
|
|
||||||
ex.enclosed = &enclosed;
|
|
||||||
if(lev->sql_ex.empty_flags & ENCLOSED_EMPTY)
|
|
||||||
ex.enclosed->length(0);
|
|
||||||
|
|
||||||
ex.line_term = &line_term;
|
|
||||||
if(lev->sql_ex.empty_flags & LINE_TERM_EMPTY)
|
|
||||||
ex.line_term->length(0);
|
|
||||||
|
|
||||||
ex.line_start = &line_start;
|
|
||||||
if(lev->sql_ex.empty_flags & LINE_START_EMPTY)
|
|
||||||
ex.line_start->length(0);
|
|
||||||
|
|
||||||
ex.escaped = &escaped;
|
|
||||||
if(lev->sql_ex.empty_flags & ESCAPED_EMPTY)
|
|
||||||
ex.escaped->length(0);
|
|
||||||
|
|
||||||
ex.opt_enclosed = (lev->sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
|
|
||||||
if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
|
|
||||||
ex.field_term->length(0);
|
|
||||||
|
|
||||||
ex.skip_lines = lev->skip_lines;
|
|
||||||
|
|
||||||
TABLE_LIST tables;
|
TABLE_LIST tables;
|
||||||
bzero((char*) &tables,sizeof(tables));
|
bzero((char*) &tables,sizeof(tables));
|
||||||
tables.db = thd->db;
|
tables.db = thd->db;
|
||||||
tables.name = tables.real_name = (char*)lev->table_name;
|
tables.name = tables.real_name = (char*)lev->table_name;
|
||||||
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))
|
||||||
|
{
|
||||||
|
skip_load_data_infile(net);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enum enum_duplicates handle_dup = DUP_IGNORE;
|
||||||
|
if(lev->sql_ex.opt_flags && REPLACE_FLAG)
|
||||||
|
handle_dup = DUP_REPLACE;
|
||||||
|
sql_exchange ex((char*)lev->fname, lev->sql_ex.opt_flags &&
|
||||||
|
DUMPFILE_FLAG );
|
||||||
|
String field_term(&lev->sql_ex.field_term, 1),
|
||||||
|
enclosed(&lev->sql_ex.enclosed, 1),
|
||||||
|
line_term(&lev->sql_ex.line_term,1),
|
||||||
|
escaped(&lev->sql_ex.escaped, 1),
|
||||||
|
line_start(&lev->sql_ex.line_start, 1);
|
||||||
|
|
||||||
List<Item> fields;
|
ex.field_term = &field_term;
|
||||||
lev->set_fields(fields);
|
if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
|
||||||
thd->slave_proxy_id = thd->thread_id;
|
ex.field_term->length(0);
|
||||||
thd->net.vio = net->vio;
|
|
||||||
// mysql_load will use thd->net to read the file
|
ex.enclosed = &enclosed;
|
||||||
thd->net.pkt_nr = net->pkt_nr;
|
if(lev->sql_ex.empty_flags & ENCLOSED_EMPTY)
|
||||||
// make sure the client does get confused
|
ex.enclosed->length(0);
|
||||||
// about the packet sequence
|
|
||||||
if(mysql_load(thd, &ex, &tables, fields, handle_dup, 1,
|
ex.line_term = &line_term;
|
||||||
TL_WRITE))
|
if(lev->sql_ex.empty_flags & LINE_TERM_EMPTY)
|
||||||
thd->query_error = 1;
|
ex.line_term->length(0);
|
||||||
if(thd->cuted_fields)
|
|
||||||
sql_print_error("Slave: load data infile at position %d in log \
|
ex.line_start = &line_start;
|
||||||
|
if(lev->sql_ex.empty_flags & LINE_START_EMPTY)
|
||||||
|
ex.line_start->length(0);
|
||||||
|
|
||||||
|
ex.escaped = &escaped;
|
||||||
|
if(lev->sql_ex.empty_flags & ESCAPED_EMPTY)
|
||||||
|
ex.escaped->length(0);
|
||||||
|
|
||||||
|
ex.opt_enclosed = (lev->sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
|
||||||
|
if(lev->sql_ex.empty_flags & FIELD_TERM_EMPTY)
|
||||||
|
ex.field_term->length(0);
|
||||||
|
|
||||||
|
ex.skip_lines = lev->skip_lines;
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
// make sure the client does get confused
|
||||||
|
// about the packet sequence
|
||||||
|
if(mysql_load(thd, &ex, &tables, fields, handle_dup, 1,
|
||||||
|
TL_WRITE))
|
||||||
|
thd->query_error = 1;
|
||||||
|
if(thd->cuted_fields)
|
||||||
|
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 // we will just ask the master to send us /dev/null if we do not want to
|
||||||
// load the data :-)
|
// load the data :-)
|
||||||
|
@ -577,16 +577,22 @@ void reset_slave()
|
|||||||
{
|
{
|
||||||
MY_STAT stat_area;
|
MY_STAT stat_area;
|
||||||
char fname[FN_REFLEN];
|
char fname[FN_REFLEN];
|
||||||
bool slave_was_running = slave_running;
|
bool slave_was_running ;
|
||||||
|
|
||||||
if(slave_running)
|
pthread_mutex_lock(&LOCK_slave);
|
||||||
stop_slave(0,0);
|
if((slave_was_running = slave_running))
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&LOCK_slave);
|
||||||
|
stop_slave(0,0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pthread_mutex_unlock(&LOCK_slave);
|
||||||
|
|
||||||
|
end_master_info(&glob_mi);
|
||||||
fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
|
fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
|
||||||
if(my_stat(fname, &stat_area, MYF(0)))
|
if(my_stat(fname, &stat_area, MYF(0)))
|
||||||
if(my_delete(fname, MYF(MY_WME)))
|
if(my_delete(fname, MYF(MY_WME)))
|
||||||
return;
|
return;
|
||||||
end_master_info(&glob_mi);
|
|
||||||
if(slave_was_running)
|
if(slave_was_running)
|
||||||
start_slave(0,0);
|
start_slave(0,0);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user