summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sasha@mysql.sashanet.com>2001-04-10 21:17:21 -0600
committerunknown <sasha@mysql.sashanet.com>2001-04-10 21:17:21 -0600
commit2adf9320a45a28415d08658015b66d31a590e0e9 (patch)
tree5838b91568f8c08dfafa5e892ec51ce052383a58
parenta5052f001bd138a02e1075d5f7ba87742fbbe275 (diff)
parent0969368d13772f8a61ddefb53efd64d4cf42d9d3 (diff)
downloadmariadb-git-2adf9320a45a28415d08658015b66d31a590e0e9.tar.gz
Merge work:/home/bk/mysql
into mysql.sashanet.com:/home/sasha/src/bk/mysql BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
-rw-r--r--.bzrignore8
-rw-r--r--BitKeeper/etc/logging_ok1
-rw-r--r--mysql-test/r/rpl000001.result8
-rw-r--r--mysql-test/r/rpl000012.result2
-rw-r--r--mysql-test/t/rpl000001.test42
-rw-r--r--mysql-test/t/rpl000012.test9
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/slave.cc67
-rw-r--r--sql/sql_base.cc16
9 files changed, 134 insertions, 21 deletions
diff --git a/.bzrignore b/.bzrignore
index 16606fdbf1a..719b30a518e 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -236,3 +236,11 @@ support-files/mysql.server
support-files/mysql.spec
tags
tmp/*
+bdb/btree/btree_auto.c
+bdb/build_vxworks/db_int.h
+bdb/build_win32/db_int.h
+bdb/build_win32/include.tcl
+bdb/build_win32/libdb.rc
+bdb/db/crdel_auto.c
+bdb/db/db_auto.c
+bdb/dist/config.hin
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 966f7a398de..3f079a376a3 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -1 +1,2 @@
jani@hynda.mysql.fi
+sasha@mysql.sashanet.com
diff --git a/mysql-test/r/rpl000001.result b/mysql-test/r/rpl000001.result
index a15ce85526c..57621d1ec0b 100644
--- a/mysql-test/r/rpl000001.result
+++ b/mysql-test/r/rpl000001.result
@@ -3,3 +3,11 @@ n
2
sum(length(word))
71
+(@id := id) - id
+0
+Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter
+127.0.0.1 root 9306 1 master-bin.001 1729584 No 1053 Slave: query ' update t1 set n = n + 1' partially completed on the master and was aborted. There is a chance that your master is inconsistent at this point. If you are sure that your master is ok, run this query manually on the slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START; 0
+count(*)
+30000
+n
+3456
diff --git a/mysql-test/r/rpl000012.result b/mysql-test/r/rpl000012.result
index ec2bd0684f1..9ce7037101e 100644
--- a/mysql-test/r/rpl000012.result
+++ b/mysql-test/r/rpl000012.result
@@ -2,6 +2,8 @@ n
1
2
3
+100
+101
4
5
6
diff --git a/mysql-test/t/rpl000001.test b/mysql-test/t/rpl000001.test
index c7b1f817e81..c2a6b2aaec9 100644
--- a/mysql-test/t/rpl000001.test
+++ b/mysql-test/t/rpl000001.test
@@ -20,4 +20,46 @@ drop table t1;
save_master_pos;
connection slave;
sync_with_master;
+#test handling of aborted connection in the middle of update
+connection master;
+drop table if exists t1,t2;
+create table t1(n int);
+let $1=30000;
+while ($1)
+{
+ eval insert into t1 values($1);
+ dec $1;
+}
+create table t2(id int);
+insert into t2 values(connection_id());
+save_master_pos;
+send update t1 set n = n + 1;
+connection master1;
+select (@id := id) - id from t2;
+sleep 0.1;
+kill @id;
+drop table t2;
+connection master;
+--error 1053;
+reap;
+connection slave;
+sync_with_master ;
+show slave status;
+set sql_slave_skip_counter=1;
+slave start;
+select count(*) from t1;
+connection master1;
+drop table t1;
+create table t1 (n int);
+insert into t1 values(3456);
+save_master_pos;
+connection slave;
+sync_with_master;
+select n from t1;
+connection master1;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+
diff --git a/mysql-test/t/rpl000012.test b/mysql-test/t/rpl000012.test
index ec93234094e..01ff9ec8a37 100644
--- a/mysql-test/t/rpl000012.test
+++ b/mysql-test/t/rpl000012.test
@@ -1,11 +1,18 @@
source include/master-slave.inc;
connection master;
-drop table if exists t1,t2;
+drop table if exists t1,t2,t3;
create table t2 (n int);
create temporary table t1 (n int);
insert into t1 values(1),(2),(3);
insert into t2 select * from t1;
+drop table if exists test.t3;
+create temporary table test.t3 (n int not null);
+alter table test.t3 add primary key(n);
+insert into t3 values (100);
+insert into t2 select * from t3;
+drop table if exists test.t3;
+insert into t2 values (101);
connection master1;
create temporary table t1 (n int);
insert into t1 values (4),(5);
diff --git a/sql/log_event.h b/sql/log_event.h
index 79186e329da..0f4945bae3c 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -136,7 +136,7 @@ public:
Query_log_event(THD* thd_arg, const char* query_arg, bool using_trans=0):
Log_event(thd_arg->start_time,0,1,thd_arg->server_id), data_buf(0),
query(query_arg), db(thd_arg->db), q_len(thd_arg->query_length),
- error_code(thd_arg->net.last_errno),
+ error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
thread_id(thd_arg->thread_id), thd(thd_arg),
cache_stmt(using_trans &&
(thd_arg->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
diff --git a/sql/slave.cc b/sql/slave.cc
index be1d919c4cd..5e6b616c720 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -59,6 +59,8 @@ static int request_table_dump(MYSQL* mysql, char* db, char* table);
static int create_table_from_dump(THD* thd, NET* net, const char* db,
const char* table_name);
inline char* rewrite_db(char* db);
+static int check_expected_error(THD* thd, int expected_error);
+
static void free_table_ent(TABLE_RULE_ENT* e)
{
my_free((gptr) e, MYF(0));
@@ -834,6 +836,27 @@ server_errno=%d)",
return len - 1;
}
+static int check_expected_error(THD* thd, int expected_error)
+{
+ switch(expected_error)
+ {
+ case ER_NET_READ_ERROR:
+ case ER_NET_ERROR_ON_WRITE:
+ case ER_SERVER_SHUTDOWN:
+ case ER_NEW_ABORTING_CONNECTION:
+ my_snprintf(last_slave_error, sizeof(last_slave_error),
+ "Slave: query '%s' partially completed on the master \
+and was aborted. There is a chance that your master is inconsistent at this \
+point. If you are sure that your master is ok, run this query manually on the\
+ slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\
+ SLAVE START;", thd->query);
+ last_slave_errno = expected_error;
+ sql_print_error(last_slave_error);
+ return 1;
+ default:
+ return 0;
+ }
+}
static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
{
@@ -883,22 +906,38 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
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);
- if ((expected_error = qev->error_code) !=
- (actual_error = thd->net.last_errno) && expected_error)
- {
- const char* errmsg = "Slave: did not get the expected error\
+
+ // sanity check to make sure the master did not get a really bad
+ // error on the query
+ if(!check_expected_error(thd, (expected_error = qev->error_code)))
+ {
+ mysql_parse(thd, thd->query, q_len);
+ if (expected_error !=
+ (actual_error = thd->net.last_errno) && expected_error)
+ {
+ const char* errmsg = "Slave: did not get the expected error\
running query from master - expected: '%s', got '%s'";
- sql_print_error(errmsg, ER(expected_error),
- actual_error ? thd->net.last_error:"no error"
- );
- thd->query_error = 1;
- }
- else if (expected_error == actual_error)
+ sql_print_error(errmsg, ER(expected_error),
+ actual_error ? thd->net.last_error:"no error"
+ );
+ thd->query_error = 1;
+ }
+ else if (expected_error == actual_error)
+ {
+ thd->query_error = 0;
+ *last_slave_error = 0;
+ last_slave_errno = 0;
+ }
+ }
+ else // master could be inconsistent, abort and tell DBA to
+ // check/fix it
{
- thd->query_error = 0;
- *last_slave_error = 0;
- last_slave_errno = 0;
+ thd->db = thd->query = 0;
+ thd->convert_set = 0;
+ close_thread_tables(thd);
+ free_root(&thd->mem_root,0);
+ delete ev;
+ return 1;
}
}
thd->db = 0; // prevent db from being freed
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 38dfcbdaa7a..49c858b7a16 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -497,13 +497,14 @@ void close_temporary_tables(THD *thd)
TABLE *table,*next;
uint init_query_buf_size = 11, query_buf_size; // "drop table "
char* query, *p;
+ bool found_user_tables = 0;
+
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)
@@ -519,15 +520,20 @@ void close_temporary_tables(THD *thd)
{
if(query) // we might be out of memory, but this is not fatal
{
- p = strxmov(p,table->table_cache_key,".",
+ // skip temporary tables not created directly by the user
+ if(table->table_name[0] != '#')
+ {
+ p = strxmov(p,table->table_cache_key,".",
table->table_name,",", NullS);
- // here we assume table_cache_key always starts
- // with \0 terminated db name
+ // here we assume table_cache_key always starts
+ // with \0 terminated db name
+ found_user_tables = 1;
+ }
}
next=table->next;
close_temporary(table);
}
- if (query && mysql_bin_log.is_open())
+ if (query && found_user_tables && mysql_bin_log.is_open())
{
uint save_query_len = thd->query_length;
*--p = 0;