summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mysqld_error.h3
-rwxr-xr-xmysql-test/fix-result22
-rw-r--r--mysql-test/r/rpl_log.result10
-rw-r--r--mysql-test/t/rpl_log.test10
-rw-r--r--sql/lex.h3
-rw-r--r--sql/share/czech/errmsg.txt1
-rw-r--r--sql/share/danish/errmsg.txt1
-rw-r--r--sql/share/dutch/errmsg.txt1
-rw-r--r--sql/share/english/errmsg.txt1
-rw-r--r--sql/share/estonian/errmsg.txt1
-rw-r--r--sql/share/french/errmsg.txt1
-rw-r--r--sql/share/german/errmsg.txt1
-rw-r--r--sql/share/greek/errmsg.txt1
-rw-r--r--sql/share/hungarian/errmsg.txt1
-rw-r--r--sql/share/italian/errmsg.txt1
-rw-r--r--sql/share/japanese/errmsg.txt1
-rw-r--r--sql/share/korean/errmsg.txt1
-rw-r--r--sql/share/norwegian-ny/errmsg.txt1
-rw-r--r--sql/share/norwegian/errmsg.txt1
-rw-r--r--sql/share/polish/errmsg.txt1
-rw-r--r--sql/share/portuguese/errmsg.txt1
-rw-r--r--sql/share/romanian/errmsg.txt1
-rw-r--r--sql/share/russian/errmsg.txt1
-rw-r--r--sql/share/slovak/errmsg.txt1
-rw-r--r--sql/share/spanish/errmsg.txt1
-rw-r--r--sql/share/swedish/errmsg.txt1
-rw-r--r--sql/sql_lex.h4
-rw-r--r--sql/sql_parse.cc7
-rw-r--r--sql/sql_repl.cc272
-rw-r--r--sql/sql_repl.h4
-rw-r--r--sql/sql_yacc.yy14
31 files changed, 367 insertions, 3 deletions
diff --git a/include/mysqld_error.h b/include/mysqld_error.h
index 106c49dc110..5777c8c7bef 100644
--- a/include/mysqld_error.h
+++ b/include/mysqld_error.h
@@ -213,4 +213,5 @@
#define ER_CONNECT_TO_MASTER 1210
#define ER_QUERY_ON_MASTER 1211
#define ER_SHOW_BINLOG_EVENTS 1212
-#define ER_ERROR_MESSAGES 213
+#define ER_SHOW_NEW_MASTER 1213
+#define ER_ERROR_MESSAGES 214
diff --git a/mysql-test/fix-result b/mysql-test/fix-result
new file mode 100755
index 00000000000..7060db36e03
--- /dev/null
+++ b/mysql-test/fix-result
@@ -0,0 +1,22 @@
+#! /bin/sh
+
+# Sasha's hack to fix results generated with mysql-test-run --record
+# to be version and test port independent. In some cases, further minor
+# manual edititing may be required, but most of the time it should not
+# happen
+
+#It is assumed we are running the script in mysql-test directory
+
+VERSION=4.0.0-debug-log
+TEST_CASE=$1
+
+if [ -z "$TEST_CASE" ] ;
+then
+ echo "usage: $0 test_case_name"
+ exit 1
+fi
+
+../extra/replace $VERSION '$VERSION' 9306 '$MASTER_MYPORT' 9307 \
+'$SLAVE_MYPORT' \\ \\\\ -- r/$TEST_CASE.result
+
+
diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result
index 35a91d03489..0152c9652e9 100644
--- a/mysql-test/r/rpl_log.result
+++ b/mysql-test/r/rpl_log.result
@@ -55,3 +55,13 @@ slave-bin.002 190 Query 1 3 use test; insert into t1 values (1)
slave-bin.002 250 Query 1 4 use test; drop table t1
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 Last_log_seq
127.0.0.1 root $MASTER_MYPORT 1 master-bin.002 245 Yes 0 0 4
+Log_name Log_pos
+slave-bin.001 132
+Log_name Log_pos
+slave-bin.001 225
+Log_name Log_pos
+slave-bin.001 439
+Log_name Log_pos
+slave-bin.002 132
+Log_name Log_pos
+slave-bin.002 250
diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test
index 9ac6e7ab6b8..426553b4bdc 100644
--- a/mysql-test/t/rpl_log.test
+++ b/mysql-test/t/rpl_log.test
@@ -36,3 +36,13 @@ show master logs;
show binlog events in 'slave-bin.001' from 4;
show binlog events in 'slave-bin.002' from 4;
show slave status;
+show new master for slave with master_log_file='master-bin.001' and
+ master_log_pos=4 and master_log_seq=1 and master_server_id=1;
+show new master for slave with master_log_file='master-bin.001' and
+ master_log_pos=79 and master_log_seq=2 and master_server_id=1;
+show new master for slave with master_log_file='master-bin.001' and
+ master_log_pos=311 and master_log_seq=6 and master_server_id=1;
+show new master for slave with master_log_file='master-bin.002' and
+ master_log_pos=4 and master_log_seq=1 and master_server_id=1;
+show new master for slave with master_log_file='master-bin.002' and
+ master_log_pos=137 and master_log_seq=3 and master_server_id=1;
diff --git a/sql/lex.h b/sql/lex.h
index e9ab150f5b2..8e03570d93b 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -215,8 +215,10 @@ static SYMBOL symbols[] = {
{ "MASTER_HOST", SYM(MASTER_HOST_SYM),0,0},
{ "MASTER_LOG_FILE", SYM(MASTER_LOG_FILE_SYM),0,0},
{ "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM),0,0},
+ { "MASTER_LOG_SEQ", SYM(MASTER_LOG_SEQ_SYM),0,0},
{ "MASTER_PASSWORD", SYM(MASTER_PASSWORD_SYM),0,0},
{ "MASTER_PORT", SYM(MASTER_PORT_SYM),0,0},
+ { "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM),0,0},
{ "MASTER_USER", SYM(MASTER_USER_SYM),0,0},
{ "MAX_ROWS", SYM(MAX_ROWS),0,0},
{ "MATCH", SYM(MATCH),0,0},
@@ -237,6 +239,7 @@ static SYMBOL symbols[] = {
{ "NATURAL", SYM(NATURAL),0,0},
{ "NATIONAL", SYM(NATIONAL_SYM),0,0},
{ "NEXT", SYM(NEXT_SYM),0,0},
+ { "NEW", SYM(NEW_SYM),0,0},
{ "NCHAR", SYM(NCHAR_SYM),0,0},
{ "NO", SYM(NO_SYM),0,0},
{ "NOT", SYM(NOT),0,0},
diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt
index a8d7c187ad3..afd4c6363ac 100644
--- a/sql/share/czech/errmsg.txt
+++ b/sql/share/czech/errmsg.txt
@@ -223,3 +223,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt
index 57a6ad3d13f..c481113e378 100644
--- a/sql/share/danish/errmsg.txt
+++ b/sql/share/danish/errmsg.txt
@@ -217,3 +217,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt
index b886ba43f6f..c37554009ae 100644
--- a/sql/share/dutch/errmsg.txt
+++ b/sql/share/dutch/errmsg.txt
@@ -214,3 +214,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt
index f0887f5b376..eadca864949 100644
--- a/sql/share/english/errmsg.txt
+++ b/sql/share/english/errmsg.txt
@@ -214,3 +214,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt
index 77a7d2f7841..a27c7f4f9b7 100644
--- a/sql/share/estonian/errmsg.txt
+++ b/sql/share/estonian/errmsg.txt
@@ -218,3 +218,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt
index 2e375bd5e15..18186b61204 100644
--- a/sql/share/french/errmsg.txt
+++ b/sql/share/french/errmsg.txt
@@ -214,3 +214,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt
index 85289b46967..073e33bd443 100644
--- a/sql/share/german/errmsg.txt
+++ b/sql/share/german/errmsg.txt
@@ -217,3 +217,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt
index bdae260f2f8..1e5d10eac17 100644
--- a/sql/share/greek/errmsg.txt
+++ b/sql/share/greek/errmsg.txt
@@ -214,3 +214,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt
index f2d45b94b50..6510c856b2d 100644
--- a/sql/share/hungarian/errmsg.txt
+++ b/sql/share/hungarian/errmsg.txt
@@ -216,3 +216,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt
index a46e712a6e6..070bc7ca8d1 100644
--- a/sql/share/italian/errmsg.txt
+++ b/sql/share/italian/errmsg.txt
@@ -214,3 +214,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt
index 6d5ab99f86d..c52bd19d00c 100644
--- a/sql/share/japanese/errmsg.txt
+++ b/sql/share/japanese/errmsg.txt
@@ -216,3 +216,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt
index 5fa44f581bf..9f5db7b6f97 100644
--- a/sql/share/korean/errmsg.txt
+++ b/sql/share/korean/errmsg.txt
@@ -214,3 +214,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt
index f45daa00449..cac6a00fa92 100644
--- a/sql/share/norwegian-ny/errmsg.txt
+++ b/sql/share/norwegian-ny/errmsg.txt
@@ -216,3 +216,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt
index 951631cae75..059ccad2670 100644
--- a/sql/share/norwegian/errmsg.txt
+++ b/sql/share/norwegian/errmsg.txt
@@ -216,3 +216,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt
index 79b420022bf..efd36ac3049 100644
--- a/sql/share/polish/errmsg.txt
+++ b/sql/share/polish/errmsg.txt
@@ -218,3 +218,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt
index cd3e948546e..bf049ec6b43 100644
--- a/sql/share/portuguese/errmsg.txt
+++ b/sql/share/portuguese/errmsg.txt
@@ -214,3 +214,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt
index 05362606c44..9272418e533 100644
--- a/sql/share/romanian/errmsg.txt
+++ b/sql/share/romanian/errmsg.txt
@@ -218,3 +218,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt
index 64adb134c34..0c369b3099c 100644
--- a/sql/share/russian/errmsg.txt
+++ b/sql/share/russian/errmsg.txt
@@ -217,3 +217,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt
index f951e8f9435..189180845d3 100644
--- a/sql/share/slovak/errmsg.txt
+++ b/sql/share/slovak/errmsg.txt
@@ -222,3 +222,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt
index 3088c9b4ee1..e3ef7edd743 100644
--- a/sql/share/spanish/errmsg.txt
+++ b/sql/share/spanish/errmsg.txt
@@ -215,3 +215,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt
index b8ee9e62b03..10cc61579ff 100644
--- a/sql/share/swedish/errmsg.txt
+++ b/sql/share/swedish/errmsg.txt
@@ -214,3 +214,4 @@
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
"Error in SHOW BINLOG EVENTS: %-.128s",
+"Error in SHOW NEW MASTER: %-.128s",
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index e585ec65191..372e4814910 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -56,7 +56,7 @@ enum enum_sql_command {
SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_MULTI_DELETE, SQLCOM_UNION_SELECT,
- SQLCOM_SHOW_BINLOG_EVENTS
+ SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER
};
enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
@@ -93,7 +93,9 @@ typedef struct st_lex_master_info
{
char* host, *user, *password,*log_file_name;
uint port, connect_retry;
+ ulong last_log_seq;
ulonglong pos;
+ ulong server_id;
} LEX_MASTER_INFO;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 928a62a397e..62075c1be5b 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1173,6 +1173,13 @@ mysql_execute_command(void)
res = purge_master_logs(thd, lex->to_log);
break;
}
+ case SQLCOM_SHOW_NEW_MASTER:
+ {
+ if(check_access(thd, FILE_ACL, any_db))
+ goto error;
+ res = show_new_master(thd);
+ break;
+ }
case SQLCOM_SHOW_SLAVE_HOSTS:
{
if(check_access(thd, FILE_ACL, any_db))
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 6153c4bd0f9..2fd7f29c560 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -26,6 +26,7 @@
#include <my_dir.h>
#define SLAVE_LIST_CHUNK 128
+#define SLAVE_ERRMSG_SIZE (FN_REFLEN+64)
extern const char* any_db;
extern pthread_handler_decl(handle_slave,arg);
@@ -38,6 +39,10 @@ bool opt_sporadic_binlog_dump_fail = 0;
static int binlog_dump_count = 0;
#endif
+static Slave_log_event* find_slave_event(IO_CACHE* log,
+ const char* log_file_name,
+ char* errmsg);
+
static uint32* slave_list_key(SLAVE_INFO* si, uint* len,
my_bool not_used __attribute__((unused)))
{
@@ -863,6 +868,272 @@ void reset_master()
}
+int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
+ const char* log_file_name2, ulonglong log_pos2)
+{
+ int res;
+ if ((res = strcmp(log_file_name1, log_file_name2)))
+ return res;
+ if (log_pos1 > log_pos2)
+ return 1;
+ else if (log_pos1 == log_pos2)
+ return 0;
+ return -1;
+}
+
+static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi)
+{
+ return cmp_master_pos(sev->master_log, sev->master_pos, mi->log_file_name,
+ mi->pos);
+}
+
+static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg)
+{
+ uint32 log_seq = mi->last_log_seq;
+ uint32 target_server_id = mi->server_id;
+
+ for (;;)
+ {
+ Log_event* ev;
+ if (!(ev = Log_event::read_log_event(log, 0)))
+ {
+ if (log->error > 0)
+ strmov(errmsg, "Binary log truncated in the middle of event");
+ else if(log->error < 0)
+ strmov(errmsg, "I/O error reading binary log");
+ else
+ strmov(errmsg, "Could not find target event in the binary log");
+ return 1;
+ }
+
+ if (ev->log_seq == log_seq && ev->server_id == target_server_id)
+ {
+ delete ev;
+ mi->pos = my_b_tell(log);
+ return 0;
+ }
+
+ delete ev;
+ }
+}
+
+static void copy_base_name(char* dest, char* src)
+{
+ char* p;
+ p = strrchr(src, FN_LIBCHAR);
+ if (p)
+ p++;
+ else
+ p = src;
+ strmov(dest, p);
+}
+
+int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg)
+{
+ LOG_INFO linfo;
+ char search_file_name[FN_REFLEN],last_log_name[FN_REFLEN];
+ IO_CACHE log, last_log;
+ File file = -1, last_file = -1;
+ pthread_mutex_t *log_lock;
+ const char* errmsg_p;
+ Slave_log_event* sev = 0;
+ my_off_t last_pos = 0;
+ int error = 1;
+ int cmp_res;
+ LINT_INIT(cmp_res);
+
+ if (!mysql_bin_log.is_open())
+ {
+ strmov(errmsg,"Binary log is not open");
+ return 1;
+ }
+
+ if (!server_id_supplied)
+ {
+ strmov(errmsg, "Misconfigured master - server id was not set");
+ return 1;
+ }
+
+ linfo.index_file_offset = 0;
+ thd->current_linfo = &linfo;
+ search_file_name[0] = 0;
+
+ if (mysql_bin_log.find_first_log(&linfo, search_file_name))
+ {
+ strmov(errmsg,"Could not find first log");
+ return 1;
+ }
+
+ bzero((char*) &log,sizeof(log));
+ log_lock = mysql_bin_log.get_log_lock();
+ pthread_mutex_lock(log_lock);
+
+ for (;;)
+ {
+
+ if ((file=open_binlog(&log, linfo.log_file_name, &errmsg_p)) < 0)
+ {
+ pthread_mutex_unlock(log_lock);
+ strmov(errmsg, errmsg_p);
+ goto err;
+ }
+
+ if (!(sev = find_slave_event(&log, linfo.log_file_name, errmsg)))
+ {
+ pthread_mutex_unlock(log_lock);
+ goto err;
+ }
+
+ cmp_res = cmp_master_pos(sev, mi);
+ delete sev;
+
+ if(!cmp_res)
+ {
+ pthread_mutex_unlock(log_lock);
+ copy_base_name(mi->log_file_name, linfo.log_file_name);
+ mi->pos = my_b_tell(&log);
+ goto mi_inited;
+ }
+
+ if (!last_pos && cmp_res > 0)
+ {
+ pthread_mutex_unlock(log_lock);
+ strmov(errmsg, "Slave event in first log points past the \
+target position");
+ goto err;
+ }
+
+ if (last_pos && cmp_res > 0)
+ {
+ end_io_cache(&log);
+ (void) my_close(file, MYF(MY_WME));
+ if (init_io_cache(&log, (file = last_file), IO_SIZE, READ_CACHE, 0, 0,
+ MYF(MY_WME)))
+ {
+ errmsg[0] = 0;
+ goto err;
+ }
+
+ goto found_log;
+ }
+
+ strmov(last_log_name, linfo.log_file_name);
+ last_pos = my_b_tell(&log);
+
+ switch (mysql_bin_log.find_next_log(&linfo))
+ {
+ case LOG_INFO_EOF:
+ if (last_file >= 0)
+ (void)my_close(last_file, MYF(MY_WME));
+ last_file = -1;
+ goto found_log;
+ case 0:
+ break;
+ default:
+ pthread_mutex_unlock(log_lock);
+ strmov(errmsg, "Error reading log index");
+ goto err;
+ }
+
+ end_io_cache(&log);
+ if (last_file >= 0)
+ (void) my_close(last_file, MYF(MY_WME));
+ last_file = file;
+ }
+
+found_log:
+ my_b_seek(&log, last_pos);
+ if (find_target_pos(mi,&log,errmsg))
+ {
+ pthread_mutex_unlock(log_lock);
+ goto err;
+ }
+ pthread_mutex_unlock(log_lock);
+ copy_base_name(mi->log_file_name, last_log_name);
+mi_inited:
+ error = 0;
+err:
+ end_io_cache(&log);
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->current_linfo = 0;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ if (file >= 0)
+ (void) my_close(file, MYF(MY_WME));
+ if (last_file >= 0 && last_file != file)
+ (void) my_close(last_file, MYF(MY_WME));
+
+ return error;
+}
+
+// caller must delete result when done
+static Slave_log_event* find_slave_event(IO_CACHE* log,
+ const char* log_file_name,
+ char* errmsg)
+{
+ Log_event* ev;
+ if (!(ev = Log_event::read_log_event(log, 0)))
+ {
+ my_vsnprintf(errmsg, SLAVE_ERRMSG_SIZE,
+ "Error reading start event in log '%s'",
+ (char*)log_file_name);
+ return 0;
+ }
+
+ delete ev;
+
+ if (!(ev = Log_event::read_log_event(log, 0)))
+ {
+ my_vsnprintf(errmsg, SLAVE_ERRMSG_SIZE,
+ "Error reading slave event in log '%s'",
+ (char*)log_file_name);
+ return 0;
+ }
+
+ if (ev->get_type_code() != SLAVE_EVENT)
+ {
+ my_vsnprintf(errmsg, SLAVE_ERRMSG_SIZE,
+ "Second event in log '%s' is not slave event",
+ (char*)log_file_name);
+ delete ev;
+ return 0;
+ }
+
+ return (Slave_log_event*)ev;
+}
+
+int show_new_master(THD* thd)
+{
+ DBUG_ENTER("show_new_master");
+ List<Item> field_list;
+ char errmsg[SLAVE_ERRMSG_SIZE];
+ LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
+
+ if (translate_master(thd, lex_mi, errmsg))
+ {
+ if (errmsg[0])
+ net_printf(&thd->net, ER_SHOW_NEW_MASTER, errmsg);
+ else
+ send_error(&thd->net, 0);
+
+ DBUG_RETURN(1);
+ }
+ else
+ {
+ String* packet = &thd->packet;
+ field_list.push_back(new Item_empty_string("Log_name", 20));
+ field_list.push_back(new Item_empty_string("Log_pos", 20));
+ if (send_fields(thd, field_list, 1))
+ DBUG_RETURN(-1);
+ packet->length(0);
+ net_store_data(packet, lex_mi->log_file_name);
+ net_store_data(packet, (longlong)lex_mi->pos);
+ if (my_net_write(&thd->net, packet->ptr(), packet->length()))
+ DBUG_RETURN(-1);
+ send_eof(&thd->net);
+ DBUG_RETURN(0);
+ }
+
+}
int show_binlog_events(THD* thd)
{
@@ -913,7 +1184,6 @@ int show_binlog_events(THD* thd)
}
pthread_mutex_lock(mysql_bin_log.get_log_lock());
-
my_b_seek(&log, pos);
for (event_count = 0;
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index a988658ed68..7d40f22d8fb 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -33,8 +33,12 @@ int stop_slave(THD* thd = 0, bool net_report = 1);
int load_master_data(THD* thd);
int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi);
int change_master(THD* thd);
+int show_new_master(THD* thd);
int show_slave_hosts(THD* thd);
int show_binlog_events(THD* thd);
+int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg);
+int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
+ const char* log_file_name2, ulonglong log_pos2);
void reset_slave();
void reset_master();
void init_slave_list();
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index c013ebe1c8c..a978e9ae857 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -223,9 +223,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MASTER_USER_SYM
%token MASTER_LOG_FILE_SYM
%token MASTER_LOG_POS_SYM
+%token MASTER_LOG_SEQ_SYM
%token MASTER_PASSWORD_SYM
%token MASTER_PORT_SYM
%token MASTER_CONNECT_RETRY_SYM
+%token MASTER_SERVER_ID_SYM
%token MATCH
%token MAX_ROWS
%token MEDIUM_SYM
@@ -234,6 +236,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MYISAM_SYM
%token NATIONAL_SYM
%token NATURAL
+%token NEW_SYM
%token NCHAR_SYM
%token NOT
%token NO_SYM
@@ -2402,6 +2405,17 @@ show_param:
if (!add_table_to_list($4,NULL,0))
YYABORT;
}
+ | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
+ TEXT_STRING AND MASTER_LOG_POS_SYM EQ ULONGLONG_NUM AND
+ MASTER_LOG_SEQ_SYM EQ ULONG_NUM AND MASTER_SERVER_ID_SYM EQ
+ ULONG_NUM
+ {
+ Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
+ Lex->mi.log_file_name = $8.str;
+ Lex->mi.pos = $12;
+ Lex->mi.last_log_seq = $16;
+ Lex->mi.server_id = $20;
+ }
| MASTER_SYM LOGS_SYM
{
Lex->sql_command = SQLCOM_SHOW_BINLOGS;