summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorguilhem@mysql.com <>2003-06-03 23:14:09 +0200
committerguilhem@mysql.com <>2003-06-03 23:14:09 +0200
commitc172cab87538674d84fda28de42d3334de982ef0 (patch)
treea22f48fd10bf00e97aae33278c36620d7507eb20
parent5a6d4e7e3b5c00cd92f8e97fe45316506a19236b (diff)
parent4a80a6c7b9a7f81e239a667145e71e6d4e40212a (diff)
downloadmariadb-git-c172cab87538674d84fda28de42d3334de982ef0.tar.gz
Merge gbichot@213.136.52.20:/home/bk/mysql-4.0
into mysql.com:/home/mysql_src/mysql-4.0
-rw-r--r--mysql-test/r/rpl_loaddata.result6
-rw-r--r--mysql-test/t/rpl_loaddata.test17
-rw-r--r--sql/log_event.cc37
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sql_repl.cc8
-rw-r--r--sql/sql_yacc.yy14
-rw-r--r--sql/unireg.h8
7 files changed, 76 insertions, 16 deletions
diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result
index 62071a07d0c..844a9d66cb3 100644
--- a/mysql-test/r/rpl_loaddata.result
+++ b/mysql-test/r/rpl_loaddata.result
@@ -22,3 +22,9 @@ day id category name
drop table t1;
drop table t2;
drop table t3;
+create table t1(a int, b int, unique(b));
+insert into t1 values(1,10);
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+show status like 'slave_running';
+Variable_name Value
+Slave_running OFF
diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test
index 1f34aa9d3f9..dc4eadda192 100644
--- a/mysql-test/t/rpl_loaddata.test
+++ b/mysql-test/t/rpl_loaddata.test
@@ -4,6 +4,9 @@
#
# check replication of load data for temporary tables with additional parameters
#
+# check if duplicate entries trigger an error (they should unless IGNORE or
+# REPLACE was used on the master) (bug 571).
+
source include/master-slave.inc;
create table t1(a int not null auto_increment, b int, primary key(a) );
@@ -27,7 +30,21 @@ connection master;
drop table t1;
drop table t2;
drop table t3;
+create table t1(a int, b int, unique(b));
save_master_pos;
connection slave;
sync_with_master;
+insert into t1 values(1,10);
+
+connection master;
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+
+save_master_pos;
+connection slave;
+# don't sync_with_master because the slave SQL thread should be stopped because
+# of the error so MASTER_POS_WAIT() will not return; just sleep and hope the
+# slave SQL thread will have had time to stop.
+
+sleep 1;
+show status like 'slave_running';
diff --git a/sql/log_event.cc b/sql/log_event.cc
index cda2e50c53d..369ef940af2 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1886,9 +1886,27 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
else
{
char llbuff[22];
- enum enum_duplicates handle_dup = DUP_IGNORE;
+ enum enum_duplicates handle_dup;
if (sql_ex.opt_flags & REPLACE_FLAG)
handle_dup= DUP_REPLACE;
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+ handle_dup= DUP_IGNORE;
+ else
+ /*
+ Note that when replication is running fine, if it was DUP_ERROR on the
+ master then we could choose DUP_IGNORE here, because if DUP_ERROR
+ suceeded on master, and data is identical on the master and slave,
+ then there should be no uniqueness errors on slave, so DUP_IGNORE is
+ the same as DUP_ERROR. But in the unlikely case of uniqueness errors
+ (because the data on the master and slave happen to be different (user
+ error or bug), we want LOAD DATA to print an error message on the
+ slave to discover the problem.
+
+ If reading from net (a 3.23 master), mysql_load() will change this
+ to DUP_IGNORE.
+ */
+ handle_dup= DUP_ERROR;
+
sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
String field_term(sql_ex.field_term,sql_ex.field_term_len);
String enclosed(sql_ex.enclosed,sql_ex.enclosed_len);
@@ -1949,12 +1967,19 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
close_thread_tables(thd);
if (thd->query_error)
{
- int sql_error= thd->net.last_errno;
- if (!sql_error)
- sql_error= ER_UNKNOWN_ERROR;
- slave_print_error(rli,sql_error,
+ /* this err/sql_errno code is copy-paste from send_error() */
+ const char *err;
+ int sql_errno;
+ if ((err=thd->net.last_error)[0])
+ sql_errno=thd->net.last_errno;
+ else
+ {
+ sql_errno=ER_UNKNOWN_ERROR;
+ err=ER(sql_errno);
+ }
+ slave_print_error(rli,sql_errno,
"Error '%s' running load data infile",
- ER_SAFE(sql_error));
+ err);
free_root(&thd->mem_root,0);
return 1;
}
diff --git a/sql/slave.cc b/sql/slave.cc
index ec1041894bd..c2762dbd6f4 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -269,7 +269,7 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
goto err;
rli->cur_log = &rli->cache_buf;
}
- if (pos > BIN_LOG_HEADER_SIZE)
+ if (pos >= BIN_LOG_HEADER_SIZE)
my_b_seek(rli->cur_log,(off_t)pos);
err:
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 283dd20a56c..ca993c053a1 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -961,7 +961,7 @@ int show_binlog_events(THD* thd)
{
LEX_MASTER_INFO *lex_mi = &thd->lex.mi;
ha_rows event_count, limit_start, limit_end;
- my_off_t pos = lex_mi->pos;
+ my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
char search_file_name[FN_REFLEN], *name;
const char *log_file_name = lex_mi->log_file_name;
pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
@@ -989,12 +989,6 @@ int show_binlog_events(THD* thd)
if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
goto err;
- if (pos < 4)
- {
- errmsg = "Invalid log position";
- goto err;
- }
-
pthread_mutex_lock(log_lock);
my_b_seek(&log, pos);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index c79750c8014..b0c81d6f6b0 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -706,6 +706,18 @@ master_def:
MASTER_LOG_POS_SYM EQ ulonglong_num
{
Lex->mi.pos = $3;
+ /*
+ If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it
+ instead of causing subsequent errors.
+ We need to do it in this file, because only there we know that
+ MASTER_LOG_POS has been explicitely specified. On the contrary
+ in change_master() (sql_repl.cc) we cannot distinguish between 0
+ (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified),
+ whereas we want to distinguish (specified 0 means "read the binlog
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+ Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
}
|
MASTER_CONNECT_RETRY_SYM EQ ULONG_NUM
@@ -721,6 +733,8 @@ master_def:
RELAY_LOG_POS_SYM EQ ULONG_NUM
{
Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+ Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
};
diff --git a/sql/unireg.h b/sql/unireg.h
index f69d67455dd..f2cace51fa7 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -130,9 +130,13 @@ bfill((A)->null_flags,(A)->null_bytes,255);\
*/
#define MIN_TURBOBM_PATTERN_LEN 3
-/* Defines for binary logging */
+/*
+ Defines for binary logging.
+ Do not decrease the value of BIN_LOG_HEADER_SIZE.
+ Do not even increase it before checking code.
+*/
-#define BIN_LOG_HEADER_SIZE 4
+#define BIN_LOG_HEADER_SIZE 4
/* Include prototypes for unireg */