diff options
42 files changed, 606 insertions, 88 deletions
diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 17ededfbb52..2f74e8c3dc6 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -288,4 +288,7 @@ #define ER_CANT_AGGREGATE_NCOLLATIONS 1269 #define ER_VARIABLE_IS_NOT_STRUCT 1270 #define ER_UNKNOWN_COLLATION 1271 -#define ER_ERROR_MESSAGES 272 +#define ER_BAD_SLAVE_UNTIL_COND 1272 +#define ER_MISSING_SKIP_SLAVE 1273 +#define ER_UNTIL_COND_IGNORED 1274 +#define ER_ERROR_MESSAGES 275 diff --git a/mysql-test/r/rpl000015.result b/mysql-test/r/rpl000015.result index 047f1ac5044..86a3520473b 100644 --- a/mysql-test/r/rpl000015.result +++ b/mysql-test/r/rpl000015.result @@ -4,20 +4,20 @@ File Position Binlog_do_db Binlog_ignore_db master-bin.000001 79 reset slave; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos change master to master_host='127.0.0.1'; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 test MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 test MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=MASTER_PORT; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 start slave; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 7 master-bin.000001 79 slave-relay-bin.000001 123 master-bin.000001 Yes Yes 0 0 79 123 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 7 master-bin.000001 79 slave-relay-bin.000001 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 drop table if exists t1; create table t1 (n int); insert into t1 values (10),(45),(90); diff --git a/mysql-test/r/rpl_empty_master_crash.result b/mysql-test/r/rpl_empty_master_crash.result index 6aac1cbfc91..5a0ea8f195d 100644 --- a/mysql-test/r/rpl_empty_master_crash.result +++ b/mysql-test/r/rpl_empty_master_crash.result @@ -5,7 +5,7 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos load table t1 from master; ERROR 08S01: Error connecting to master: Master is not configured load table t1 from master; diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flush_log_loop.result index 954ab107123..6819bad96b8 100644 --- a/mysql-test/r/rpl_flush_log_loop.result +++ b/mysql-test/r/rpl_flush_log_loop.result @@ -13,5 +13,5 @@ master_password='',master_port=SLAVE_PORT; start slave; flush logs; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root SLAVE_PORT 60 slave-bin.000001 79 relay-log.000001 122 slave-bin.000001 Yes Yes 0 0 79 122 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root SLAVE_PORT 60 slave-bin.000001 79 relay-log.000001 122 slave-bin.000001 Yes Yes 0 0 79 122 None 0 diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 050e9274a99..463352bf2ab 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -92,7 +92,7 @@ slave-bin.000002 4 Query 1 110 use `test`; create table t1 (n int) slave-bin.000002 62 Query 1 168 use `test`; insert into t1 values (1) slave-bin.000002 122 Query 1 228 use `test`; drop table t1 show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.000002 276 slave-relay-bin.000002 1531 master-bin.000002 Yes Yes 0 0 276 1535 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 1 master-bin.000002 276 slave-relay-bin.000002 1531 master-bin.000002 Yes Yes 0 0 276 1535 None 0 show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result index b42e7ff5dc4..17072d6e472 100644 --- a/mysql-test/r/rpl_log_pos.result +++ b/mysql-test/r/rpl_log_pos.result @@ -8,26 +8,26 @@ show master status; File Position Binlog_do_db Binlog_ignore_db master-bin.000001 79 show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 127 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 127 None 0 stop slave; change master to master_log_pos=73; start slave; stop slave; change master to master_log_pos=73; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 73 4 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 73 4 None 0 start slave; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 4 master-bin.000001 No Yes 0 0 73 4 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 4 master-bin.000001 No Yes 0 0 73 4 None 0 stop slave; change master to master_log_pos=173; start slave; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.000001 173 slave-relay-bin.000001 4 master-bin.000001 No Yes 0 0 173 4 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 1 master-bin.000001 173 slave-relay-bin.000001 4 master-bin.000001 No Yes 0 0 173 4 None 0 show master status; File Position Binlog_do_db Binlog_ignore_db master-bin.000001 79 diff --git a/mysql-test/r/rpl_redirect.result b/mysql-test/r/rpl_redirect.result index 79ff6685706..4460f3acdc2 100644 --- a/mysql-test/r/rpl_redirect.result +++ b/mysql-test/r/rpl_redirect.result @@ -5,7 +5,7 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; SHOW SLAVE STATUS; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos SHOW SLAVE HOSTS; Server_id Host Port Rpl_recovery_rank Master_id 2 127.0.0.1 SLAVE_PORT 2 1 diff --git a/mysql-test/r/rpl_replicate_do.result b/mysql-test/r/rpl_replicate_do.result index 4d740cafbd0..7c4a603bea8 100644 --- a/mysql-test/r/rpl_replicate_do.result +++ b/mysql-test/r/rpl_replicate_do.result @@ -27,5 +27,5 @@ select * from t11; ERROR 42S02: Table 'test.t11' doesn't exist drop table if exists t1,t2,t11; show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.000001 1281 slave-relay-bin.000002 1325 master-bin.000001 Yes Yes test.t1 0 0 1281 1329 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 1 master-bin.000001 1281 slave-relay-bin.000002 1325 master-bin.000001 Yes Yes test.t1 0 0 1281 1329 None 0 diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index 753edebea60..e0919568103 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -15,8 +15,8 @@ insert into temp_table values ("testing temporary tables"); create table t1 (s text); insert into t1 values('Could not break slave'),('Tried hard'); show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 60 master-bin.000001 417 slave-relay-bin.000001 461 master-bin.000001 Yes Yes 0 0 417 461 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 60 master-bin.000001 417 slave-relay-bin.000001 461 master-bin.000001 Yes Yes 0 0 417 461 None 0 select * from t1; s Could not break slave @@ -56,8 +56,8 @@ Log_name master-bin.000003 insert into t2 values (65); show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 60 master-bin.000003 290 slave-relay-bin.000001 1088 master-bin.000003 Yes Yes 0 0 290 1088 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 60 master-bin.000003 290 slave-relay-bin.000001 1088 master-bin.000003 Yes Yes 0 0 290 1088 None 0 select * from t2; m 34 @@ -82,8 +82,8 @@ select * from t4; a testing temporary tables part 2 show slave status; -Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 60 master-bin.000006 838 slave-relay-bin.000001 8067 master-bin.000006 Yes Yes 0 0 838 8067 +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_PORT 60 master-bin.000006 838 slave-relay-bin.000001 8067 master-bin.000006 Yes Yes 0 0 838 8067 None 0 lock tables t3 read; select count(*) from t3 where n >= 4; count(*) diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result new file mode 100644 index 00000000000..629c7c26bd5 --- /dev/null +++ b/mysql-test/r/rpl_until.result @@ -0,0 +1,72 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +stop slave; +create table t1(n int not null auto_increment primary key); +insert into t1 values (1),(2),(3),(4); +drop table t1; +create table t2(n int not null auto_increment primary key); +insert into t2 values (1),(2); +insert into t2 values (3),(4); +drop table t2; +show binlog events; +Log_name Pos Event_type Server_id Orig_log_pos Info +master-bin.000001 4 Start 1 4 Server ver: 4.1.1-alpha-debug-log, Binlog ver: 3 +master-bin.000001 79 Query 1 79 use `test`; create table t1(n int not null auto_increment primary key) +master-bin.000001 172 Query 1 172 use `test`; insert into t1 values (1),(2),(3),(4) +master-bin.000001 244 Query 1 244 use `test`; drop table t1 +master-bin.000001 292 Query 1 292 use `test`; create table t2(n int not null auto_increment primary key) +master-bin.000001 385 Query 1 385 use `test`; insert into t2 values (1),(2) +master-bin.000001 449 Query 1 449 use `test`; insert into t2 values (3),(4) +master-bin.000001 513 Query 1 513 use `test`; drop table t2 +start slave until master_log_file='master-bin.000001', master_log_pos=244; +select * from t1; +n +1 +2 +3 +4 +show slave status; +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 288 master-bin.000001 Yes No 0 0 244 609 Master master-bin.000001 244 +start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; +select * from t1; +n +1 +2 +3 +4 +show slave status; +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 288 master-bin.000001 Yes No 0 0 244 609 Master master-no-such-bin.000001 291 +start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=493; +select * from t2; +n +1 +2 +show slave status; +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 493 master-bin.000001 Yes No 0 0 449 609 Relay slave-relay-bin.000002 493 +start slave; +stop slave; +start slave until master_log_file='master-bin.000001', master_log_pos=561; +show slave status; +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos +127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 605 master-bin.000001 Yes No 0 0 561 609 Master master-bin.000001 561 +start slave until master_log_file='master-bin', master_log_pos=561; +ERROR HY000: Wrong parameter or combination of parameters for START SLAVE UNTIL +start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; +ERROR HY000: Wrong parameter or combination of parameters for START SLAVE UNTIL +start slave until master_log_file='master-bin.000001'; +ERROR HY000: Wrong parameter or combination of parameters for START SLAVE UNTIL +start slave until relay_log_file='slave-relay-bin.000002'; +ERROR HY000: Wrong parameter or combination of parameters for START SLAVE UNTIL +start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561; +ERROR HY000: Wrong parameter or combination of parameters for START SLAVE UNTIL +start slave sql_thread; +start slave until master_log_file='master-bin.000001', master_log_pos=561; +Warnings: +Note 1252 The slave was already running diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test new file mode 100644 index 00000000000..77e29057357 --- /dev/null +++ b/mysql-test/t/rpl_until.test @@ -0,0 +1,70 @@ +source include/master-slave.inc; + +# stop slave before he will start replication +connection slave; +stop slave; + +connection master; +# create some events on master +create table t1(n int not null auto_increment primary key); +insert into t1 values (1),(2),(3),(4); +drop table t1; +create table t2(n int not null auto_increment primary key); +insert into t2 values (1),(2); +insert into t2 values (3),(4); +drop table t2; +show binlog events; + +# try to replicate all queries until drop of t1 +connection slave; +start slave until master_log_file='master-bin.000001', master_log_pos=244; +sleep 2; +# here table should be still not deleted +select * from t1; +--replace_result $MASTER_MYPORT MASTER_MYPORT +show slave status; + +# this should fail right after start +start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; +# again this table should be still not deleted +select * from t1; +sleep 2; +--replace_result $MASTER_MYPORT MASTER_MYPORT +show slave status; + +# try replicate all until second insert to t2; +start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=493; +sleep 2; +select * from t2; +--replace_result $MASTER_MYPORT MASTER_MYPORT +show slave status; + +# clean up +start slave; +connection master; +save_master_pos; +connection slave; +sync_with_master; +stop slave; + +# this should stop immideately +start slave until master_log_file='master-bin.000001', master_log_pos=561; +sleep 2; +# here the sql slave thread should be stopped +--replace_result $MASTER_MYPORT MASTER_MYPORT +show slave status; + +#testing various error conditions +--error 1272 +start slave until master_log_file='master-bin', master_log_pos=561; +--error 1272 +start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; +--error 1272 +start slave until master_log_file='master-bin.000001'; +--error 1272 +start slave until relay_log_file='slave-relay-bin.000002'; +--error 1272 +start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561; + +start slave sql_thread; +start slave until master_log_file='master-bin.000001', master_log_pos=561; diff --git a/sql/lex.h b/sql/lex.h index c2860f4551a..9216307cdce 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -403,6 +403,7 @@ static SYMBOL symbols[] = { { "USE", SYM(USE_SYM),0,0}, { "USE_FRM", SYM(USE_FRM),0,0}, { "USER", SYM(USER),0,0}, + { "UNTIL", SYM(UNTIL_SYM),0,0}, { "USING", SYM(USING),0,0}, { "UPDATE", SYM(UPDATE_SYM),0,0}, { "USAGE", SYM(USAGE),0,0}, diff --git a/sql/log.cc b/sql/log.cc index dd544dcac93..d7f8c1f6651 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -692,6 +692,7 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli, bool included) rli->group_relay_log_pos = BIN_LOG_HEADER_SIZE; strmake(rli->group_relay_log_name,rli->linfo.log_file_name, sizeof(rli->group_relay_log_name)-1); + rli->notify_group_relay_log_name_update(); } /* Store where we are in the new file for the execution thread */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 749732384c7..4247c915a88 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1820,6 +1820,7 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli) pthread_mutex_lock(&rli->data_lock); memcpy(log_name, new_log_ident, ident_len+1); + rli->notify_group_master_log_name_update(); rli->group_master_log_pos = pos; rli->event_relay_log_pos += get_event_len(); rli->group_relay_log_pos = rli->event_relay_log_pos; diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 60af9a92c76..9df3f29f724 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -902,6 +902,12 @@ int load_master_data(THD* thd) strmake(active_mi->rli.group_master_log_name,active_mi->master_log_name, sizeof(active_mi->rli.group_master_log_name)-1); /* + Cancel the previous START SLAVE UNTIL, as the fact to download + a new copy logically makes UNTIL irrelevant. + */ + clear_until_condition(&active_mi->rli); + + /* No need to update rli.event* coordinates, they will be when the slave threads start ; only rli.group* coordinates are necessary here. */ diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index b43c4b43b50..6fefae628f8 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -277,3 +277,6 @@ v/* "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 2eb9e6d2219..4e4a50d50cd 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -271,3 +271,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 2a663a176f8..8ae681c422e 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -279,3 +279,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index f4019d63055..165b437892f 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -273,3 +273,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index d3a38ede5bc..a1dbf186e2b 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -273,3 +273,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index ccff24c5759..2c2a658f3b5 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -268,3 +268,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 52f3eb78c11..1b40bc1c2b4 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -277,3 +277,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 1ce052bdf22..68b7294e82d 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -268,3 +268,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 6143ea2a1c4..44b026071aa 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -270,3 +270,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 8164757d823..9fc411f6f08 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -268,3 +268,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 747d3611cc9..ed3ac780011 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -270,3 +270,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 93d86d32937..1a21c0eb318 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -268,3 +268,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index e9319246fc6..f6ce58f79a6 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -270,3 +270,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index edb5854db7e..f49bbb01924 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -270,3 +270,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 27b4d0d661f..67c889363ad 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -272,3 +272,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 60ace09ab33..5cf165eee1b 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -268,3 +268,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 8824d64876a..3977becbeac 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -272,3 +272,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index ddfc0a8f7de..af15a5a0b5a 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -270,3 +270,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 9e2a37e4053..3ecd6faf0f0 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -264,3 +264,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index ed1d8cadb80..86e19c92977 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -276,3 +276,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 5f3a2f38109..e4d4414cf83 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -269,3 +269,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index d108618834e..1969c87819c 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -268,3 +268,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 96b9f40feac..e7e30c6d8ed 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -273,3 +273,6 @@ "Illegal mix of collations for operation '%s'", "Variable '%-.64s' is not a variable component (Can't be used as XXXX.variable_name)", "Unknown collation: '%-.64s'", +"Wrong parameter or combination of parameters for START SLAVE UNTIL" +"It is recommended to run with --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL, otherwise you are not safe in case of unexpected slave's mysqld restart" +"SQL thread is not to be started so UNTIL options are ignored" diff --git a/sql/slave.cc b/sql/slave.cc index 37979576b73..2747ce548e1 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -232,10 +232,12 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log, *errmsg=0; pthread_mutex_t *log_lock=rli->relay_log.get_log_lock(); - pthread_mutex_lock(log_lock); + if (need_data_lock) pthread_mutex_lock(&rli->data_lock); + pthread_mutex_lock(log_lock); + /* Close log file and free buffers if it's already open */ if (rli->cur_log_fd >= 0) { @@ -298,9 +300,11 @@ err: if (!relay_log_purge) rli->log_space_limit= 0; pthread_cond_broadcast(&rli->data_cond); + + pthread_mutex_unlock(log_lock); + if (need_data_lock) pthread_mutex_unlock(&rli->data_lock); - pthread_mutex_unlock(log_lock); DBUG_RETURN ((*errmsg) ? 1 : 0); } @@ -1410,6 +1414,20 @@ static int count_relay_log_space(RELAY_LOG_INFO* rli) } +/* + Reset UNTIL condition for RELAY_LOG_INFO + SYNOPSYS + clear_until_condition() + rli - RELAY_LOG_INFO structure where UNTIL condition should be reset + */ +void clear_until_condition(RELAY_LOG_INFO* rli) +{ + rli->until_condition= RELAY_LOG_INFO::UNTIL_NONE; + rli->until_log_name[0]= 0; + rli->until_log_pos= 0; +} + + int init_master_info(MASTER_INFO* mi, const char* master_info_fname, const char* slave_info_fname, bool abort_if_no_master_info_file) @@ -1648,6 +1666,10 @@ int show_master_info(THD* thd, MASTER_INFO* mi) MYSQL_TYPE_LONGLONG)); field_list.push_back(new Item_return_int("Relay_log_space", 10, MYSQL_TYPE_LONGLONG)); + field_list.push_back(new Item_empty_string("Until_condition", 6)); + field_list.push_back(new Item_empty_string("Until_Log_File", FN_REFLEN)); + field_list.push_back(new Item_return_int("Until_Log_pos", 10, + MYSQL_TYPE_LONGLONG)); if (protocol->send_fields(&field_list, 1)) DBUG_RETURN(-1); @@ -1694,6 +1716,14 @@ int show_master_info(THD* thd, MASTER_INFO* mi) protocol->store((uint32) mi->rli.slave_skip_counter); protocol->store((ulonglong) mi->rli.group_master_log_pos); protocol->store((ulonglong) mi->rli.log_space_total); + + protocol->store( + mi->rli.until_condition==RELAY_LOG_INFO::UNTIL_NONE ? "None": + ( mi->rli.until_condition==RELAY_LOG_INFO::UNTIL_MASTER_POS? "Master": + "Relay"), &my_charset_bin); + protocol->store(mi->rli.until_log_name, &my_charset_bin); + protocol->store((ulonglong) mi->rli.until_log_pos); + pthread_mutex_unlock(&mi->rli.data_lock); pthread_mutex_unlock(&mi->data_lock); @@ -1727,11 +1757,11 @@ st_relay_log_info::st_relay_log_info() cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0), slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_thd(0), last_slave_errno(0), inited(0), abort_slave(0), - slave_running(0) + slave_running(0), until_condition(UNTIL_NONE), until_log_pos(0) { group_relay_log_name[0]= event_relay_log_name[0]= group_master_log_name[0]= 0; - last_slave_error[0]=0; - + last_slave_error[0]=0; until_log_name[0]= 0; + bzero(&info_file,sizeof(info_file)); bzero(&cache_buf, sizeof(cache_buf)); pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST); @@ -2151,14 +2181,127 @@ point. If you are sure that your master is ok, run this query manually on the\ } } +/* + Check if condition stated in UNTIL clause of START SLAVE is reached. + SYNOPSYS + st_relay_log_info::is_until_satisfied() + DESCRIPTION + Checks if UNTIL condition is reached. Uses caching result of last + comparison of current log file name and target log file name. So cached + value should be invalidated if current log file name changes + (see st_relay_log_info::notify_... functions). + + This caching is needed to avoid of expensive string comparisons and + strtol() conversions needed for log names comparison. We don't need to + compare them each time this function is called, we only need to do this + when current log name changes. If we have UNTIL_MASTER_POS condition we + need to do this only after Rotate_log_event::exec_event() (which is + rare, so caching gives real benifit), and if we have UNTIL_RELAY_POS + condition then we should invalidate cached comarison value after + inc_group_relay_log_pos() which called for each group of events (so we + have some benefit if we have something like queries that use + autoincrement or if we have transactions). + + Should be called ONLY if until_condition != UNTIL_NONE ! + RETURN VALUE + true - condition met or error happened (condition seems to have + bad log file name) + false - condition not met +*/ + +bool st_relay_log_info::is_until_satisfied() +{ + const char *log_name; + ulonglong log_pos; + + DBUG_ASSERT(until_condition != UNTIL_NONE); + + if (until_condition == UNTIL_MASTER_POS) + { + log_name= group_master_log_name; + log_pos= group_master_log_pos; + } + else + { /* until_condition == UNTIL_RELAY_POS */ + log_name= group_relay_log_name; + log_pos= group_relay_log_pos; + } + + if (until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_UNKNOWN) + { + /* + We have no cached comaprison results so we should compare log names + and cache result + */ + + DBUG_ASSERT(*log_name || log_pos == 0); + + if (*log_name) + { + const char *basename= log_name + dirname_length(log_name); + + const char *q= (const char*)(fn_ext(basename)+1); + if (strncmp(basename, until_log_name, (int)(q-basename)) == 0) + { + /* Now compare extensions. */ + char *q_end; + ulong log_name_extension= strtoul(q, &q_end, 10); + if (log_name_extension < until_log_name_extension) + until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_LESS; + else + until_log_names_cmp_result= + (log_name_extension > until_log_name_extension) ? + UNTIL_LOG_NAMES_CMP_GREATER : UNTIL_LOG_NAMES_CMP_EQUAL ; + } + else + { + /* Probably error so we aborting */ + sql_print_error("Slave SQL thread is stopped because UNTIL " + "condition is bad."); + return true; + } + } + else + return until_log_pos == 0; + } + + return ((until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_EQUAL && + log_pos >= until_log_pos) || + until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_GREATER); +} + static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) { + /* + We acquire this mutex since we need it for all operations except + event execution. But we will release it in places where we will + wait for something for example inside of next_event(). + */ + pthread_mutex_lock(&rli->data_lock); + + if (rli->until_condition!=RELAY_LOG_INFO::UNTIL_NONE && + rli->is_until_satisfied()) + { + sql_print_error("Slave SQL thread stopped because it reached its" + " UNTIL position"); + /* + Setting abort_slave flag because we do not want additional message about + error in query execution to be printed. + */ + rli->abort_slave= 1; + pthread_mutex_unlock(&rli->data_lock); + return 1; + } + Log_event * ev = next_event(rli); + DBUG_ASSERT(rli->sql_thd==thd); + if (sql_slave_killed(thd,rli)) { /* do not forget to free ev ! */ + pthread_mutex_unlock(&rli->data_lock); if (ev) delete ev; return 1; } @@ -2166,7 +2309,6 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) { int type_code = ev->get_type_code(); int exec_res; - pthread_mutex_lock(&rli->data_lock); /* Skip queries originating from this server or number of @@ -2195,7 +2337,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) pthread_mutex_unlock(&rli->data_lock); delete ev; return 0; // avoid infinite update loops - } + } pthread_mutex_unlock(&rli->data_lock); thd->server_id = ev->server_id; // use the original server id for logging @@ -2211,6 +2353,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) } else { + pthread_mutex_unlock(&rli->data_lock); sql_print_error("\ Could not parse relay log event entry. The possible reasons are: the master's \ binary log is corrupted (you can check this by running 'mysqlbinlog' on the \ @@ -3228,17 +3371,18 @@ Log_event* next_event(RELAY_LOG_INFO* rli) pthread_mutex_t *log_lock = rli->relay_log.get_log_lock(); const char* errmsg=0; THD* thd = rli->sql_thd; + DBUG_ENTER("next_event"); DBUG_ASSERT(thd != 0); /* For most operations we need to protect rli members with data_lock, - so we will hold it for the most of the loop below - However, we will release it whenever it is worth the hassle, - and in the cases when we go into a pthread_cond_wait() with the - non-data_lock mutex + so we assume calling function acquired this mutex for us and we will + hold it for the most of the loop below However, we will release it + whenever it is worth the hassle, and in the cases when we go into a + pthread_cond_wait() with the non-data_lock mutex */ - pthread_mutex_lock(&rli->data_lock); + safe_mutex_assert_owner(&rli->data_lock); while (!sql_slave_killed(thd,rli)) { @@ -3284,7 +3428,6 @@ Log_event* next_event(RELAY_LOG_INFO* rli) DBUG_ASSERT(thd==rli->sql_thd); if (hot_log) pthread_mutex_unlock(log_lock); - pthread_mutex_unlock(&rli->data_lock); DBUG_RETURN(ev); } DBUG_ASSERT(thd==rli->sql_thd); @@ -3460,7 +3603,6 @@ event(errno: %d cur_log->error: %d)", errmsg = "slave SQL thread was killed"; err: - pthread_mutex_unlock(&rli->data_lock); if (errmsg) sql_print_error("Error reading relay log event: %s", errmsg); DBUG_RETURN(0); diff --git a/sql/slave.h b/sql/slave.h index 668fff52d08..7320d8fc1fe 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -208,9 +208,55 @@ typedef struct st_relay_log_info bool inited; volatile bool abort_slave, slave_running; + /* + Condition and its parameters from START SLAVE UNTIL clause. + + UNTIL condition is tested with is_until_satisfied() method that is + called by exec_relay_log_event(). is_until_satisfied() caches the result + of the comparison of log names because log names don't change very often; + this cache is invalidated by parts of code which change log names with + notify_*_log_name_updated() methods. (They need to be called only if SQL + thread is running). + */ + + enum {UNTIL_NONE= 0, UNTIL_MASTER_POS, UNTIL_RELAY_POS} until_condition; + char until_log_name[FN_REFLEN]; + ulonglong until_log_pos; + /* extension extracted from log_name and converted to int */ + ulong until_log_name_extension; + /* + Cached result of comparison of until_log_name and current log name + -2 means unitialised, -1,0,1 are comarison results + */ + enum + { + UNTIL_LOG_NAMES_CMP_UNKNOWN= -2, UNTIL_LOG_NAMES_CMP_LESS= -1, + UNTIL_LOG_NAMES_CMP_EQUAL= 0, UNTIL_LOG_NAMES_CMP_GREATER= 1 + } until_log_names_cmp_result; + st_relay_log_info(); ~st_relay_log_info(); + /* + Invalidate cached until_log_name and group_relay_log_name comparison + result. Should be called after any update of group_realy_log_name if + there chances that sql_thread is running. + */ + inline void notify_group_relay_log_name_update() + { + if (until_condition==UNTIL_RELAY_POS) + until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN; + } + + /* + The same as previous but for group_master_log_name. + */ + inline void notify_group_master_log_name_update() + { + if (until_condition==UNTIL_MASTER_POS) + until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN; + } + inline void inc_event_relay_log_pos(ulonglong val) { event_relay_log_pos+= val; @@ -224,6 +270,9 @@ typedef struct st_relay_log_info group_relay_log_pos= event_relay_log_pos; strmake(group_relay_log_name,event_relay_log_name, sizeof(group_relay_log_name)-1); + + notify_group_relay_log_name_update(); + /* If the slave does not support transactions and replicates a transaction, users should not trust group_master_log_pos (which they can display with @@ -243,6 +292,10 @@ typedef struct st_relay_log_info int wait_for_pos(THD* thd, String* log_name, longlong log_pos, longlong timeout); + + /* Check if UNTIL condition is satisfied. See slave.cc for more. */ + bool is_until_satisfied(); + } RELAY_LOG_INFO; @@ -424,6 +477,7 @@ void skip_load_data_infile(NET* net); void slave_print_error(RELAY_LOG_INFO* rli,int err_code, const char* msg, ...); void end_slave(); /* clean up */ +void clear_until_condition(RELAY_LOG_INFO* rli); int init_master_info(MASTER_INFO* mi, const char* master_info_fname, const char* slave_info_fname, bool abort_if_no_master_info_file); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 121411379f8..2abfda5e4c3 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -632,7 +632,7 @@ Increase max_allowed_packet on master"; int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) { - int slave_errno; + int slave_errno= 0; if (!thd) thd = current_thd; int thread_mask; @@ -656,21 +656,88 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) if (init_master_info(mi,master_info_file,relay_log_info_file, 0)) slave_errno=ER_MASTER_INFO; else if (server_id_supplied && *mi->host) - slave_errno = start_slave_threads(0 /*no mutex */, + { + /* + If we will start SQL thread we will care about UNTIL options + If not and they are specified we will ignore them and warn user + about this fact. + */ + if (thread_mask & SLAVE_SQL) + { + pthread_mutex_lock(&mi->rli.data_lock); + + if (thd->lex.mi.pos) + { + mi->rli.until_condition= RELAY_LOG_INFO::UNTIL_MASTER_POS; + mi->rli.until_log_pos= thd->lex.mi.pos; + /* + We don't check thd->lex.mi.log_file_name for NULL here + since it is checked in sql_yacc.yy + */ + strmake(mi->rli.until_log_name, thd->lex.mi.log_file_name, + sizeof(mi->rli.until_log_name)-1); + } + else if (thd->lex.mi.relay_log_pos) + { + mi->rli.until_condition= RELAY_LOG_INFO::UNTIL_RELAY_POS; + mi->rli.until_log_pos= thd->lex.mi.relay_log_pos; + strmake(mi->rli.until_log_name, thd->lex.mi.relay_log_name, + sizeof(mi->rli.until_log_name)-1); + } + else + clear_until_condition(&mi->rli); + + if (mi->rli.until_condition != RELAY_LOG_INFO::UNTIL_NONE) + { + /* Preparing members for effective until condition checking */ + const char *p= fn_ext(mi->rli.until_log_name); + char *p_end; + if (*p) + { + //p points to '.' + mi->rli.until_log_name_extension= strtoul(++p,&p_end, 10); + /* + p_end points to the first invalid character. If it equals + to p, no digits were found, error. If it contains '\0' it + means conversion went ok. + */ + if(p_end==p || *p_end) + slave_errno=ER_BAD_SLAVE_UNTIL_COND; + } + else + slave_errno=ER_BAD_SLAVE_UNTIL_COND; + + /* mark the cached result of the UNTIL comparison as "undefined" */ + mi->rli.until_log_names_cmp_result= + RELAY_LOG_INFO::UNTIL_LOG_NAMES_CMP_UNKNOWN; + + /* Issuing warning then started without --skip-slave-start */ + if (!opt_skip_slave_start) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_MISSING_SKIP_SLAVE, + ER(ER_MISSING_SKIP_SLAVE)); + } + + pthread_mutex_unlock(&mi->rli.data_lock); + } + else if (thd->lex.mi.pos || thd->lex.mi.relay_log_pos) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_UNTIL_COND_IGNORED, + ER(ER_UNTIL_COND_IGNORED)); + + + if(!slave_errno) + slave_errno = start_slave_threads(0 /*no mutex */, 1 /* wait for start */, mi, master_info_file,relay_log_info_file, thread_mask); + } else slave_errno = ER_BAD_SLAVE; } else - { //no error if all threads are already started, only a warning - slave_errno= 0; push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SLAVE_WAS_RUNNING, ER(ER_SLAVE_WAS_RUNNING)); - } unlock_slave_threads(mi); @@ -777,6 +844,7 @@ int reset_slave(THD *thd, MASTER_INFO* mi) // Clear master's log coordinates (only for good display of SHOW SLAVE STATUS) mi->master_log_name[0]= 0; mi->master_log_pos= BIN_LOG_HEADER_SIZE; + clear_until_condition(&mi->rli); // close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0 end_master_info(mi); // and delete these two files @@ -943,6 +1011,7 @@ int change_master(THD* thd, MASTER_INFO* mi) pthread_mutex_lock(&mi->rli.data_lock); mi->rli.abort_pos_wait++; + clear_until_condition(&mi->rli); pthread_cond_broadcast(&mi->data_cond); pthread_mutex_unlock(&mi->rli.data_lock); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index aef58e6cb94..823ce6a2672 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -167,6 +167,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SUPER_SYM %token TRUNCATE_SYM %token UNLOCK_SYM +%token UNTIL_SYM %token UPDATE_SYM %token ACTION @@ -665,7 +666,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); query verb_clause create change select do drop insert replace insert2 insert_values update delete truncate rename show describe load alter optimize preload flush - reset purge begin commit rollback slave master_def master_defs + reset purge begin commit rollback slave master_def + master_defs master_file_def repair restore backup analyze check start field_list field_list_item field_spec kill column_def key_def preload_list preload_keys @@ -801,52 +803,52 @@ master_def: Lex->mi.password = $3.str; } | - MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys - { - Lex->mi.log_file_name = $3.str; - } - | MASTER_PORT_SYM EQ ULONG_NUM { Lex->mi.port = $3; } | - 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 { Lex->mi.connect_retry = $3; } | - RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys - { - Lex->mi.relay_log_name = $3.str; - } - | - RELAY_LOG_POS_SYM EQ ULONG_NUM + master_file_def + ; + +master_file_def: + MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys { - 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); + Lex->mi.log_file_name = $3.str; } + | 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); + } + | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys + { + Lex->mi.relay_log_name = $3.str; + } + | 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); + } ; - /* create a table */ create: @@ -1694,12 +1696,16 @@ opt_to: */ slave: - START_SYM SLAVE slave_thread_opts - { - LEX *lex=Lex; - lex->sql_command = SQLCOM_SLAVE_START; - lex->type = 0; - } + START_SYM SLAVE slave_thread_opts + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_START; + lex->type = 0; + /* We'll use mi structure for UNTIL options */ + bzero((char*) &lex->mi, sizeof(lex->mi)); + } + slave_until + {} | STOP_SYM SLAVE slave_thread_opts { LEX *lex=Lex; @@ -1716,6 +1722,7 @@ start: slave_thread_opts: { Lex->slave_thd_opt= 0; } slave_thread_opt_list + {} ; slave_thread_opt_list: @@ -1729,6 +1736,28 @@ slave_thread_opt: | RELAY_THREAD { Lex->slave_thd_opt|=SLAVE_IO; } ; +slave_until: + /*empty*/ {} + | UNTIL_SYM slave_until_opts + { + LEX *lex=Lex; + if ((lex->mi.log_file_name || lex->mi.pos) && + (lex->mi.relay_log_name || lex->mi.relay_log_pos) || + !((lex->mi.log_file_name && lex->mi.pos) || + (lex->mi.relay_log_name && lex->mi.relay_log_pos))) + { + send_error(lex->thd, ER_BAD_SLAVE_UNTIL_COND); + YYABORT; + } + + } + ; + +slave_until_opts: + master_file_def + | slave_until_opts ',' master_file_def ; + + restore: RESTORE_SYM table_or_tables { @@ -4520,6 +4549,7 @@ keyword: | UDF_SYM {} | UNCOMMITTED_SYM {} | UNICODE_SYM {} + | UNTIL_SYM {} | USER {} | USE_FRM {} | VARIABLES {} |