summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysqlbinlog.cc41
-rw-r--r--mysql-test/include/check-testcase.test3
-rw-r--r--mysql-test/main/mysqlbinlog.result15
-rw-r--r--mysql-test/suite/multi_source/info_logs.result12
-rw-r--r--mysql-test/suite/multi_source/multi_source_slave_alias_replica.result2
-rw-r--r--mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.cnf19
-rw-r--r--mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.result67
-rw-r--r--mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.test96
-rw-r--r--mysql-test/suite/multi_source/reset_slave.result8
-rw-r--r--mysql-test/suite/multi_source/simple.result7
-rw-r--r--mysql-test/suite/multi_source/syntax.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_rewrite_db_sys_vars.result163
-rw-r--r--mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars-slave.opt2
-rw-r--r--mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test163
-rw-r--r--mysql-test/suite/sys_vars/r/replicate_rewrite_db.result99
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result10
-rw-r--r--mysql-test/suite/sys_vars/t/replicate_rewrite_db.opt3
-rw-r--r--mysql-test/suite/sys_vars/t/replicate_rewrite_db.test84
-rw-r--r--sql/mysqld.cc38
-rw-r--r--sql/privilege.h2
-rw-r--r--sql/protocol.cc38
-rw-r--r--sql/protocol.h1
-rw-r--r--sql/rpl_filter.cc152
-rw-r--r--sql/rpl_filter.h11
-rw-r--r--sql/rpl_mi.cc8
-rw-r--r--sql/slave.cc4
-rw-r--r--sql/sql_list.cc7
-rw-r--r--sql/sql_list.h1
-rw-r--r--sql/sys_vars.cc13
-rw-r--r--tests/mysql_client_test.c2
30 files changed, 936 insertions, 141 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index d885bc08af0..75fc7268b0d 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -2394,48 +2394,11 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi
case OPT_REWRITE_DB: // db_from->db_to
{
/* See also handling of OPT_REPLICATE_REWRITE_DB in sql/mysqld.cc */
- const char* ptr;
- const char* key= argument; // db-from
- const char* val; // db-to
-
- // Skipp pre-space in key
- while (*key && my_isspace(&my_charset_latin1, *key))
- key++;
-
- // Where val begins
- if (!(ptr= strstr(key, "->")))
- {
- sql_print_error("Bad syntax in rewrite-db: missing '->'\n");
- return 1;
- }
- val= ptr + 2;
-
- // Skip blanks at the end of key
- while (ptr > key && my_isspace(&my_charset_latin1, ptr[-1]))
- ptr--;
-
- if (ptr == key)
+ if (binlog_filter->add_rewrite_db(argument))
{
- sql_print_error("Bad syntax in rewrite-db: empty FROM db\n");
+ sql_print_error("Bad syntax in rewrite-db. Expected syntax is FROM->TO.");
return 1;
}
- key= strmake_root(&glob_root, key, (size_t) (ptr-key));
-
- /* Skipp pre space in value */
- while (*val && my_isspace(&my_charset_latin1, *val))
- val++;
-
- // Value ends with \0 or space
- for (ptr= val; *ptr && !my_isspace(&my_charset_latin1, *ptr) ; ptr++)
- {}
- if (ptr == val)
- {
- sql_print_error("Bad syntax in rewrite-db: empty TO db\n");
- return 1;
- }
- val= strmake_root(&glob_root, val, (size_t) (ptr-val));
-
- binlog_filter->add_db_rewrite(key, val);
break;
}
case OPT_PRINT_ROW_COUNT:
diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test
index 4a1af2a4553..078f6572bed 100644
--- a/mysql-test/include/check-testcase.test
+++ b/mysql-test/include/check-testcase.test
@@ -32,6 +32,7 @@ if ($tmp)
--echo Relay_Master_Log_File #
--echo Slave_IO_Running No
--echo Slave_SQL_Running No
+ --echo Replicate_Rewrite_DB #
--echo Replicate_Do_DB #
--echo Replicate_Ignore_DB #
--echo Replicate_Do_Table #
@@ -76,7 +77,7 @@ if ($tmp)
}
if (!$tmp) {
# Note: after WL#5177, fields 13-18 shall not be filtered-out.
- --replace_column 4 # 5 # 6 # 7 # 8 # 9 # 10 # 13 # 14 # 15 # 16 # 17 # 18 # 22 # 23 # 24 # 25 # 26 # 40 # 41 # 42 # 44 # 51 # 52 # 53 #
+ --replace_column 4 # 5 # 6 # 7 # 8 # 9 # 10 # 13 # 14 # 15 # 16 # 17 # 18 # 19 # 23 # 24 # 25 # 26 # 27 # 41 # 42 # 43 # 45 # 52 # 53 # 54 #
query_vertical
SHOW SLAVE STATUS;
}
diff --git a/mysql-test/main/mysqlbinlog.result b/mysql-test/main/mysqlbinlog.result
index a5732caf76e..034d48791aa 100644
--- a/mysql-test/main/mysqlbinlog.result
+++ b/mysql-test/main/mysqlbinlog.result
@@ -1276,13 +1276,8 @@ CREATE TABLE t1 (a int);
INSERT INTO t1 values(1);
DROP TABLE t1;
FLUSH LOGS;
-ERROR: Bad syntax in rewrite-db: missing '->'
-
-ERROR: Bad syntax in rewrite-db: empty TO db
-
-ERROR: Bad syntax in rewrite-db: empty TO db
-
-ERROR: Bad syntax in rewrite-db: empty FROM db
-
-ERROR: Bad syntax in rewrite-db: empty FROM db
-
+ERROR: Bad syntax in rewrite-db. Expected syntax is FROM->TO.
+ERROR: Bad syntax in rewrite-db. Expected syntax is FROM->TO.
+ERROR: Bad syntax in rewrite-db. Expected syntax is FROM->TO.
+ERROR: Bad syntax in rewrite-db. Expected syntax is FROM->TO.
+ERROR: Bad syntax in rewrite-db. Expected syntax is FROM->TO.
diff --git a/mysql-test/suite/multi_source/info_logs.result b/mysql-test/suite/multi_source/info_logs.result
index c19620b46cc..a35a20bdbf7 100644
--- a/mysql-test/suite/multi_source/info_logs.result
+++ b/mysql-test/suite/multi_source/info_logs.result
@@ -94,17 +94,17 @@ MASTER 2.2
# EOF
#
show all slaves status;
-Connection_name Slave_SQL_State Slave_IO_State 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
- Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> relay.000002 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space1> None 0 No 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000
-MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 <read_master_log_pos> relay-master@00202@002e2.000002 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space2> None 0 No 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000
+Connection_name Slave_SQL_State Slave_IO_State 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_Rewrite_DB 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
+ Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> relay.000002 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space1> None 0 No 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000
+MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 <read_master_log_pos> relay-master@00202@002e2.000002 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space2> None 0 No 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000
include/wait_for_slave_to_start.inc
set default_master_connection = 'MASTER 2.2';
include/wait_for_slave_to_start.inc
set default_master_connection = '';
show all slaves status;
-Connection_name Slave_SQL_State Slave_IO_State 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
- Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> relay.000004 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space1> None 0 No 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000
-MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 <read_master_log_pos> relay-master@00202@002e2.000004 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space2> None 0 No 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000
+Connection_name Slave_SQL_State Slave_IO_State 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_Rewrite_DB 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
+ Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> relay.000004 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space1> None 0 No 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000
+MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 <read_master_log_pos> relay-master@00202@002e2.000004 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space2> None 0 No 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000
#
# List of files matching '*info*' pattern
# after slave server restart
diff --git a/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result b/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result
index 25cd85d7018..355919def5a 100644
--- a/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result
+++ b/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result
@@ -34,6 +34,7 @@ Relay_Log_Pos <relay_log_pos>
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
+Replicate_Rewrite_DB
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
@@ -95,6 +96,7 @@ Relay_Log_Pos <relay_log_pos>
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
+Replicate_Rewrite_DB
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
diff --git a/mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.cnf b/mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.cnf
new file mode 100644
index 00000000000..a22ddacd30f
--- /dev/null
+++ b/mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.cnf
@@ -0,0 +1,19 @@
+!include my.cnf
+
+[mysqld.1]
+gtid-domain-id=1
+server-id=1
+log-bin
+log-slave-updates
+
+[mysqld.2]
+gtid-domain-id=2
+server-id=2
+log-bin
+log-slave-updates
+
+[mysqld.3]
+gtid-domain-id=3
+server-id=3
+log-bin
+log-slave-updates
diff --git a/mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.result b/mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.result
new file mode 100644
index 00000000000..3be8b364593
--- /dev/null
+++ b/mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.result
@@ -0,0 +1,67 @@
+connect server_1,127.0.0.1,root,,,$SERVER_MYPORT_1;
+connect server_2,127.0.0.1,root,,,$SERVER_MYPORT_2;
+connect server_3,127.0.0.1,root,,,$SERVER_MYPORT_3;
+# Connect the slave (server_3) to two masters (server_1 and server_2)
+connection server_3;
+CHANGE MASTER 'm1' TO master_port=MYPORT_1, master_host='127.0.0.1', master_user='root';
+CHANGE MASTER 'm2' TO master_port=MYPORT_2, master_host='127.0.0.1', master_user='root';
+# Apply events from server_1 (m1) into m1_test
+create database m1_test;
+SET @@global.'m1'.replicate_rewrite_db='test->m1_test';
+# Apply events from server_2 (m2) into m2_test
+create database m2_test;
+SET @@global.'m2'.replicate_rewrite_db='test->m2_test';
+start all slaves;
+Warnings:
+Note 1937 SLAVE 'm2' started
+Note 1937 SLAVE 'm1' started
+set default_master_connection = 'm1';
+include/wait_for_slave_to_start.inc
+set default_master_connection = 'm2';
+include/wait_for_slave_to_start.inc
+# Create test data for servers 1 and 2 with different data
+connection server_1;
+create table t (a int);
+insert into t values (1);
+insert into t values (2);
+insert into t values (3);
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_2;
+create table t (a int);
+insert into t values (4);
+insert into t values (5);
+insert into t values (6);
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+# Ensure the slave correctly replicates data from each master into its
+# respective database
+include/diff_tables.inc [server_1:test.t,server_3:m1_test.t]
+include/diff_tables.inc [server_2:test.t,server_3:m2_test.t]
+#
+# Cleanup
+connection server_1;
+DROP TABLE t;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_2;
+DROP TABLE t;
+include/save_master_gtid.inc
+connection server_3;
+include/sync_with_master_gtid.inc
+connection server_3;
+stop all slaves;
+Warnings:
+Note 1938 SLAVE 'm2' stopped
+Note 1938 SLAVE 'm1' stopped
+SET default_master_connection = "m1";
+include/wait_for_slave_to_stop.inc
+SET default_master_connection = "m2";
+include/wait_for_slave_to_stop.inc
+RESET SLAVE ALL;
+DROP DATABASE m1_test;
+DROP DATABASE m2_test;
+# End of replicate_rewrite_db_dynamic.test
diff --git a/mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.test b/mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.test
new file mode 100644
index 00000000000..e1bbfabe180
--- /dev/null
+++ b/mysql-test/suite/multi_source/replicate_rewrite_db_dynamic.test
@@ -0,0 +1,96 @@
+#
+# Test multi-source dynamically setting of replication filter
+# "replicate_rewrite_db"
+#
+# This test ensures that setting a replica's replicate_rewrite_db works on a
+# per-master basis. To ensure this, this test connects a replica to two
+# different primary server instances. Each primary uses the same database
+# name and table name. To ensure the data operations don't interfere with one
+# another on the replica, it sets replicate_rewrite_db individually per
+# connection to apply the events from each primary into a database specific to
+# that connection.
+#
+
+--source include/not_embedded.inc
+--source include/have_innodb.inc
+
+--connect (server_1,127.0.0.1,root,,,$SERVER_MYPORT_1)
+--connect (server_2,127.0.0.1,root,,,$SERVER_MYPORT_2)
+--connect (server_3,127.0.0.1,root,,,$SERVER_MYPORT_3)
+
+
+--echo # Connect the slave (server_3) to two masters (server_1 and server_2)
+--connection server_3
+--replace_result $SERVER_MYPORT_1 MYPORT_1
+eval CHANGE MASTER 'm1' TO master_port=$SERVER_MYPORT_1, master_host='127.0.0.1', master_user='root';
+--replace_result $SERVER_MYPORT_2 MYPORT_2
+eval CHANGE MASTER 'm2' TO master_port=$SERVER_MYPORT_2, master_host='127.0.0.1', master_user='root';
+
+--echo # Apply events from server_1 (m1) into m1_test
+create database m1_test;
+SET @@global.'m1'.replicate_rewrite_db='test->m1_test';
+
+--echo # Apply events from server_2 (m2) into m2_test
+create database m2_test;
+SET @@global.'m2'.replicate_rewrite_db='test->m2_test';
+
+start all slaves;
+set default_master_connection = 'm1';
+--source include/wait_for_slave_to_start.inc
+set default_master_connection = 'm2';
+--source include/wait_for_slave_to_start.inc
+
+--echo # Create test data for servers 1 and 2 with different data
+--connection server_1
+create table t (a int);
+insert into t values (1);
+insert into t values (2);
+insert into t values (3);
+--source include/save_master_gtid.inc
+--connection server_3
+--source include/sync_with_master_gtid.inc
+
+--connection server_2
+create table t (a int);
+insert into t values (4);
+insert into t values (5);
+insert into t values (6);
+--source include/save_master_gtid.inc
+--connection server_3
+--source include/sync_with_master_gtid.inc
+
+--echo # Ensure the slave correctly replicates data from each master into its
+--echo # respective database
+--let $diff_tables=server_1:test.t,server_3:m1_test.t
+--source include/diff_tables.inc
+
+--let $diff_tables=server_2:test.t,server_3:m2_test.t
+--source include/diff_tables.inc
+
+
+--echo #
+--echo # Cleanup
+
+--connection server_1
+DROP TABLE t;
+--source include/save_master_gtid.inc
+--connection server_3
+--source include/sync_with_master_gtid.inc
+
+--connection server_2
+DROP TABLE t;
+--source include/save_master_gtid.inc
+--connection server_3
+--source include/sync_with_master_gtid.inc
+
+--connection server_3
+stop all slaves;
+SET default_master_connection = "m1";
+--source include/wait_for_slave_to_stop.inc
+SET default_master_connection = "m2";
+--source include/wait_for_slave_to_stop.inc
+RESET SLAVE ALL;
+DROP DATABASE m1_test;
+DROP DATABASE m2_test;
+
+--echo # End of replicate_rewrite_db_dynamic.test
diff --git a/mysql-test/suite/multi_source/reset_slave.result b/mysql-test/suite/multi_source/reset_slave.result
index a55a6ec235f..2e9ce5e896f 100644
--- a/mysql-test/suite/multi_source/reset_slave.result
+++ b/mysql-test/suite/multi_source/reset_slave.result
@@ -13,15 +13,15 @@ insert into t1 values (1),(2);
connection slave;
stop slave 'master1';
show slave 'master1' status;
-Slave_IO_State 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups
- 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> mysqld-relay-bin-master1.000002 <relay_log_pos> master-bin.000001 No No 0 0 <read_master_log_pos> <relay_log_space> None 0 No NULL No 0 0 1 Slave_Pos 0-1-3 optimistic 0 NULL 2 1 0
+Slave_IO_State 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_Rewrite_DB 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups
+ 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> mysqld-relay-bin-master1.000002 <relay_log_pos> master-bin.000001 No No 0 0 <read_master_log_pos> <relay_log_space> None 0 No NULL No 0 0 1 Slave_Pos 0-1-3 optimistic 0 NULL 2 1 0
mysqld-relay-bin-master1.000001
mysqld-relay-bin-master1.000002
mysqld-relay-bin-master1.index
reset slave 'master1';
show slave 'master1' status;
-Slave_IO_State 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups
- 127.0.0.1 root MYPORT_1 60 4 <relay_log_pos> No No 0 0 0 <relay_log_space> None 0 No NULL No 0 0 1 Slave_Pos optimistic 0 NULL 2 1 0
+Slave_IO_State 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_Rewrite_DB 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups
+ 127.0.0.1 root MYPORT_1 60 4 <relay_log_pos> No No 0 0 0 <relay_log_space> None 0 No NULL No 0 0 1 Slave_Pos optimistic 0 NULL 2 1 0
reset slave 'master1' all;
show slave 'master1' status;
ERROR HY000: There is no master connection 'master1'
diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result
index 5a167907b3b..65c25b88e44 100644
--- a/mysql-test/suite/multi_source/simple.result
+++ b/mysql-test/suite/multi_source/simple.result
@@ -32,6 +32,7 @@ Relay_Log_Pos <relay_log_pos>
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
+Replicate_Rewrite_DB
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
@@ -93,6 +94,7 @@ Relay_Log_Pos <relay_log_pos>
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
+Replicate_Rewrite_DB
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
@@ -219,6 +221,7 @@ Relay_Log_Pos <relay_log_pos>
Relay_Master_Log_File master-bin.000001
Slave_IO_Running No
Slave_SQL_Running No
+Replicate_Rewrite_DB
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
@@ -276,6 +279,7 @@ Relay_Log_Pos <relay_log_pos>
Relay_Master_Log_File
Slave_IO_Running No
Slave_SQL_Running No
+Replicate_Rewrite_DB
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
@@ -337,6 +341,7 @@ Relay_Log_Pos <relay_log_pos>
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
+Replicate_Rewrite_DB
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
@@ -400,6 +405,7 @@ Relay_Log_Pos <relay_log_pos>
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
+Replicate_Rewrite_DB
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
@@ -465,6 +471,7 @@ Relay_Log_Pos <relay_log_pos>
Relay_Master_Log_File master-bin.000001
Slave_IO_Running No
Slave_SQL_Running No
+Replicate_Rewrite_DB
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
diff --git a/mysql-test/suite/multi_source/syntax.result b/mysql-test/suite/multi_source/syntax.result
index 35f4b3048ad..3c7c91c35c8 100644
--- a/mysql-test/suite/multi_source/syntax.result
+++ b/mysql-test/suite/multi_source/syntax.result
@@ -1,11 +1,11 @@
include/master-slave.inc
[connection master]
show slave status;
-Slave_IO_State 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups
+Slave_IO_State 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_Rewrite_DB 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups
show slave '' status;
-Slave_IO_State 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups
+Slave_IO_State 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_Rewrite_DB 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups
show all slaves status;
-Connection_name Slave_SQL_State Slave_IO_State 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
+Connection_name Slave_SQL_State Slave_IO_State 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_Rewrite_DB 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 Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
#
# Check error handling
#
diff --git a/mysql-test/suite/rpl/r/rpl_rewrite_db_sys_vars.result b/mysql-test/suite/rpl/r/rpl_rewrite_db_sys_vars.result
new file mode 100644
index 00000000000..5720f647b90
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_rewrite_db_sys_vars.result
@@ -0,0 +1,163 @@
+include/master-slave.inc
+[connection master]
+#
+# MDEV-15530 Variable replicate_rewrite_db cannot be found
+# in "show global variables"
+#
+# Create DBs and verify that slave has to be stopped before setting sys var
+connection slave;
+select @@session.server_id;
+@@session.server_id
+2
+create database replica_db1;
+create database y;
+create database test_replica;
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+primary_db1->replica_db1,x->y
+# Ensuring SHOW SLAVE STATUS produces correct value for Replicate_Rewrite_DB...
+# ...success
+# Create DBs and tables on primary
+connection master;
+create database primary_db1;
+create database x;
+use primary_db1;
+create table my_table (t int);
+insert into my_table values (2),(4);
+use x;
+create table my_table (t int);
+insert into my_table values (654),(532);
+include/save_master_gtid.inc
+# Check replica
+connection slave;
+include/sync_with_master_gtid.inc
+include/diff_tables.inc [master:primary_db1.my_table,slave:replica_db1.my_table]
+include/diff_tables.inc [master:x.my_table,slave:y.my_table]
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+primary_db1->replica_db1,x->y
+show tables from replica_db1;
+Tables_in_replica_db1
+my_table
+select * from replica_db1.my_table;
+t
+2
+4
+show tables from y;
+Tables_in_y
+my_table
+select * from y.my_table;
+t
+654
+532
+# Set replica sys var replicate_rewrite_db
+connection slave;
+SET @@GLOBAL.replicate_rewrite_db="test_master->test_replica";
+ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first
+include/stop_slave.inc
+SET @save_replicate_rewrite_db = @@GLOBAL.replicate_rewrite_db;
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+primary_db1->replica_db1,x->y
+SET @@GLOBAL.replicate_rewrite_db="test_master->test_replica";
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+test_master->test_replica
+SHOW DATABASES like 'test_replica';
+Database (test_replica)
+test_replica
+include/start_slave.inc
+# Ensuring SHOW SLAVE STATUS produces correct value for Replicate_Rewrite_DB...
+# ...success
+# Create DB and tables on primary
+connection master;
+create database test_master;
+use test_master;
+create table my_table (t int);
+insert into my_table values (1),(3);
+include/save_master_gtid.inc
+# Ensure that the replica receives all of the primary's events without
+# error
+connection slave;
+include/sync_with_master_gtid.inc
+Last_SQL_Error =
+Last_SQL_Errno = 0
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+test_master->test_replica
+SHOW tables from test_replica;
+Tables_in_test_replica
+my_table
+select * from test_replica.my_table;
+t
+1
+3
+include/diff_tables.inc [master:test_master.my_table,slave:test_replica.my_table]
+# Update of values on primary for DB not set in replication_rewrite_db
+connection master;
+use x;
+insert into my_table values (314);
+select * from my_table;
+t
+654
+532
+314
+include/save_master_gtid.inc
+connection slave;
+include/stop_slave.inc
+include/reset_slave.inc
+include/start_slave.inc
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+test_master->test_replica
+include/sync_with_master_gtid.inc
+select * from y.my_table;
+t
+654
+532
+# Dynamic updates to the replication filter should be lost after server restart
+connection slave;
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+test_master->test_replica
+connection master;
+use x;
+insert into my_table values (1000);
+select * from my_table;
+t
+654
+532
+314
+1000
+include/save_master_gtid.inc
+connection slave;
+include/stop_slave.inc
+include/reset_slave.inc
+include/rpl_restart_server.inc [server_number=2]
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_MYPORT, MASTER_USER='root';
+connection slave;
+include/start_slave.inc
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+primary_db1->replica_db1,x->y
+include/sync_with_master_gtid.inc
+select * from y.my_table;
+t
+654
+532
+314
+1000
+# Cleanup
+connection master;
+drop database test_master;
+drop database primary_db1;
+drop database x;
+include/save_master_gtid.inc
+connection slave;
+include/sync_with_master_gtid.inc
+drop database test_replica;
+drop database replica_db1;
+drop database y;
+include/stop_slave.inc
+include/start_slave.inc
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars-slave.opt b/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars-slave.opt
new file mode 100644
index 00000000000..5a8f8233a63
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars-slave.opt
@@ -0,0 +1,2 @@
+"--replicate-rewrite-db=primary_db1->replica_db1"
+"--replicate-rewrite-db=x->y"
diff --git a/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test b/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test
new file mode 100644
index 00000000000..b06899bb12e
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test
@@ -0,0 +1,163 @@
+-- source include/have_binlog_format_mixed.inc
+-- source include/master-slave.inc
+
+# Testing rpl option replicate_rewrite_db
+
+--echo #
+--echo # MDEV-15530 Variable replicate_rewrite_db cannot be found
+--echo # in "show global variables"
+--echo #
+
+--echo # Create DBs and verify that slave has to be stopped before setting sys var
+
+connection slave;
+--let $rpl_server_id= `select @@session.server_id`
+select @@session.server_id;
+
+# These DBs will be rewrited from opt file
+create database replica_db1;
+create database y;
+# This DB will be rewrited from test case
+create database test_replica;
+SELECT @@GLOBAL.replicate_rewrite_db;
+let $rewrite_db_sss= query_get_value(SHOW SLAVE STATUS, Replicate_Rewrite_DB, 1);
+--echo # Ensuring SHOW SLAVE STATUS produces correct value for Replicate_Rewrite_DB...
+if (`SELECT strcmp(@@global.replicate_rewrite_db, "$rewrite_db_sss") != 0`)
+{
+ die SHOW SLAVE STATUS Replicate_Rewrite_DB value $rewrite_db_sss does not match variable @@GLOBAL.replicate_rewrite_db;
+}
+--echo # ...success
+
+
+--echo # Create DBs and tables on primary
+connection master;
+--enable_warnings
+create database primary_db1;
+create database x;
+use primary_db1;
+create table my_table (t int);
+insert into my_table values (2),(4);
+use x;
+create table my_table (t int);
+insert into my_table values (654),(532);
+--source include/save_master_gtid.inc
+
+--echo # Check replica
+--connection slave
+--source include/sync_with_master_gtid.inc
+--let $diff_tables=master:primary_db1.my_table,slave:replica_db1.my_table
+--source include/diff_tables.inc
+--let $diff_tables=master:x.my_table,slave:y.my_table
+--source include/diff_tables.inc
+SELECT @@GLOBAL.replicate_rewrite_db;
+show tables from replica_db1;
+select * from replica_db1.my_table;
+show tables from y;
+select * from y.my_table;
+
+--echo # Set replica sys var replicate_rewrite_db
+connection slave;
+--error ER_SLAVE_MUST_STOP
+SET @@GLOBAL.replicate_rewrite_db="test_master->test_replica";
+source include/stop_slave.inc;
+SET @save_replicate_rewrite_db = @@GLOBAL.replicate_rewrite_db;
+SELECT @@GLOBAL.replicate_rewrite_db;
+SET @@GLOBAL.replicate_rewrite_db="test_master->test_replica";
+SELECT @@GLOBAL.replicate_rewrite_db;
+SHOW DATABASES like 'test_replica';
+source include/start_slave.inc;
+let $rewrite_db_sss= query_get_value(SHOW SLAVE STATUS, Replicate_Rewrite_DB, 1);
+--echo # Ensuring SHOW SLAVE STATUS produces correct value for Replicate_Rewrite_DB...
+if (`SELECT strcmp(@@global.replicate_rewrite_db, "$rewrite_db_sss") != 0`)
+{
+ die SHOW SLAVE STATUS Replicate_Rewrite_DB value $rewrite_db_sss does not match variable @@GLOBAL.replicate_rewrite_db;
+}
+--echo # ...success
+
+--echo # Create DB and tables on primary
+connection master;
+--enable_warnings
+create database test_master;
+use test_master;
+create table my_table (t int);
+insert into my_table values (1),(3);
+--source include/save_master_gtid.inc
+
+--echo # Ensure that the replica receives all of the primary's events without
+--echo # error
+--connection slave
+--source include/sync_with_master_gtid.inc
+let $error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1);
+--echo Last_SQL_Error = $error
+let $errno= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1);
+--echo Last_SQL_Errno = $errno
+
+SELECT @@GLOBAL.replicate_rewrite_db;
+SHOW tables from test_replica;
+select * from test_replica.my_table;
+
+# Additional check for tables
+--let $diff_tables=master:test_master.my_table,slave:test_replica.my_table
+--source include/diff_tables.inc
+
+--echo # Update of values on primary for DB not set in replication_rewrite_db
+connection master;
+use x;
+insert into my_table values (314);
+select * from my_table;
+--source include/save_master_gtid.inc
+
+connection slave;
+--source include/stop_slave.inc
+--source include/reset_slave.inc
+--source include/start_slave.inc
+SELECT @@GLOBAL.replicate_rewrite_db;
+--source include/sync_with_master_gtid.inc
+# This shouldn't get the new values from x DB on master
+select * from y.my_table;
+
+--echo # Dynamic updates to the replication filter should be lost after server restart
+# Old value
+connection slave;
+SELECT @@GLOBAL.replicate_rewrite_db;
+
+connection master;
+use x;
+insert into my_table values (1000);
+select * from my_table;
+--source include/save_master_gtid.inc
+
+connection slave;
+--source include/stop_slave.inc
+--source include/reset_slave.inc
+--let $rpl_server_number= 2
+--source include/rpl_restart_server.inc
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root';
+
+# New value
+connection slave;
+--source include/start_slave.inc
+SELECT @@GLOBAL.replicate_rewrite_db;
+--source include/sync_with_master_gtid.inc
+# This should update values with 314 and 1000 from primary
+select * from y.my_table;
+
+--echo # Cleanup
+connection master;
+drop database test_master;
+drop database primary_db1;
+drop database x;
+--source include/save_master_gtid.inc
+
+
+--connection slave
+--source include/sync_with_master_gtid.inc
+drop database test_replica;
+drop database replica_db1;
+drop database y;
+source include/stop_slave.inc;
+source include/start_slave.inc;
+
+--source include/rpl_end.inc
+# end of 10.11 tests
diff --git a/mysql-test/suite/sys_vars/r/replicate_rewrite_db.result b/mysql-test/suite/sys_vars/r/replicate_rewrite_db.result
new file mode 100644
index 00000000000..2dfe3a65133
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/replicate_rewrite_db.result
@@ -0,0 +1,99 @@
+#
+# MDEV-15530: Variable replicate_rewrite_db
+# cannot be found in "show global variables"
+#
+SET @save_replicate_rewrite_db = @@GLOBAL.replicate_rewrite_db;
+SELECT @save_replicate_rewrite_db;
+@save_replicate_rewrite_db
+test->rewrite,mysqltest1->test,a->b
+# Test session/Scope (it is global variable)
+select @@global.replicate_rewrite_db;
+@@global.replicate_rewrite_db
+test->rewrite,mysqltest1->test,a->b
+SELECT @@SESSION.replicate_rewrite_db;
+ERROR HY000: Variable 'replicate_rewrite_db' is a GLOBAL variable
+SET @@SESSION.replicate_rewrite_db = "";
+ERROR HY000: Variable 'replicate_rewrite_db' is a GLOBAL variable and should be set with SET GLOBAL
+show global variables like 'replicate_rewrite_db';
+Variable_name Value
+replicate_rewrite_db test->rewrite,mysqltest1->test,a->b
+show session variables like 'replicate_rewrite_db';
+Variable_name Value
+replicate_rewrite_db test->rewrite,mysqltest1->test,a->b
+select * from information_schema.global_variables where variable_name='replicate_rewrite_db';
+VARIABLE_NAME VARIABLE_VALUE
+REPLICATE_REWRITE_DB test->rewrite,mysqltest1->test,a->b
+select * from information_schema.session_variables where variable_name='replicate_rewrite_db';
+VARIABLE_NAME VARIABLE_VALUE
+REPLICATE_REWRITE_DB test->rewrite,mysqltest1->test,a->b
+# Incorrect type
+SET @@GLOBAL.replicate_rewrite_db=1;
+ERROR 42000: Incorrect argument type to variable 'replicate_rewrite_db'
+SET @@GLOBAL.replicate_rewrite_db="->";
+ERROR HY000: Incorrect arguments to SET
+SET @@GLOBAL.replicate_rewrite_db=" ";
+ERROR HY000: Incorrect arguments to SET
+SET @@GLOBAL.replicate_rewrite_db="a->";
+ERROR HY000: Incorrect arguments to SET
+SET @@GLOBAL.replicate_rewrite_db="->b";
+ERROR HY000: Incorrect arguments to SET
+# Check arguments
+set session replicate_rewrite_db=1;
+ERROR HY000: Variable 'replicate_rewrite_db' is a GLOBAL variable and should be set with SET GLOBAL
+set global replicate_rewrite_db=1;
+ERROR 42000: Incorrect argument type to variable 'replicate_rewrite_db'
+SET @@SESSION.replicate_do_db = "";
+ERROR HY000: Variable 'replicate_do_db' is a GLOBAL variable and should be set with SET GLOBAL
+SET @@GLOBAL.replicate_rewrite_db="";
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+
+SET @@GLOBAL.replicate_rewrite_db=null;
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+
+SET @@GLOBAL.replicate_rewrite_db=DEFAULT;
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+
+SET @@GLOBAL.replicate_rewrite_db="db1->db3";
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+db1->db3
+SET @@GLOBAL.replicate_rewrite_db="db2 ->db4";
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+db2->db4
+SET @@GLOBAL.replicate_rewrite_db=" db5 ->db7 ";
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+db5->db7
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_rewrite_db';
+VARIABLE_NAME VARIABLE_VALUE
+REPLICATE_REWRITE_DB db5->db7
+select * from information_schema.session_variables where variable_name='replicate_rewrite_db';
+VARIABLE_NAME VARIABLE_VALUE
+REPLICATE_REWRITE_DB db5->db7
+show global variables like 'replicate_rewrite_db';
+Variable_name Value
+replicate_rewrite_db db5->db7
+SET @@GLOBAL.replicate_rewrite_db="db1->db2, db3->db4";
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+db1->db2,db3->db4
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_rewrite_db';
+VARIABLE_NAME VARIABLE_VALUE
+REPLICATE_REWRITE_DB db1->db2,db3->db4
+# Check restart with appending the value
+# restart: --replicate_rewrite_db=X->Y
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+test->rewrite,mysqltest1->test,a->b,X->Y
+# Check restart with wrong value on CLI
+[ERROR] Bad syntax in replicate-rewrite-db.Expected syntax is FROM->TO.
+# restart:
+SELECT @@GLOBAL.replicate_rewrite_db;
+@@GLOBAL.replicate_rewrite_db
+test->rewrite,mysqltest1->test,a->b
+# Cleanup.
+SET @@GLOBAL.replicate_rewrite_db = @save_replicate_rewrite_db;
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index eab383a30ac..0221ecb3861 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -3382,6 +3382,16 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT NULL
+VARIABLE_NAME REPLICATE_REWRITE_DB
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE VARCHAR
+VARIABLE_COMMENT Tells the slave to replicate binlog events into a different database than their original target on the master.Example: replicate-rewrite-db=master_db_name->slave_db_name.
+NUMERIC_MIN_VALUE NULL
+NUMERIC_MAX_VALUE NULL
+NUMERIC_BLOCK_SIZE NULL
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT NULL
VARIABLE_NAME REPLICATE_WILD_DO_TABLE
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE VARCHAR
diff --git a/mysql-test/suite/sys_vars/t/replicate_rewrite_db.opt b/mysql-test/suite/sys_vars/t/replicate_rewrite_db.opt
new file mode 100644
index 00000000000..27468051e62
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/replicate_rewrite_db.opt
@@ -0,0 +1,3 @@
+"--replicate-rewrite-db=test->rewrite"
+"--replicate-rewrite-db= mysqltest1 -> test"
+"--replicate-rewrite-db=a -> b"
diff --git a/mysql-test/suite/sys_vars/t/replicate_rewrite_db.test b/mysql-test/suite/sys_vars/t/replicate_rewrite_db.test
new file mode 100644
index 00000000000..7fbaab1f260
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/replicate_rewrite_db.test
@@ -0,0 +1,84 @@
+--source include/not_embedded.inc
+
+--echo #
+--echo # MDEV-15530: Variable replicate_rewrite_db
+--echo # cannot be found in "show global variables"
+--echo #
+
+SET @save_replicate_rewrite_db = @@GLOBAL.replicate_rewrite_db;
+SELECT @save_replicate_rewrite_db;
+
+--echo # Test session/Scope (it is global variable)
+
+select @@global.replicate_rewrite_db;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@SESSION.replicate_rewrite_db;
+--error ER_GLOBAL_VARIABLE
+SET @@SESSION.replicate_rewrite_db = "";
+show global variables like 'replicate_rewrite_db';
+show session variables like 'replicate_rewrite_db';
+select * from information_schema.global_variables where variable_name='replicate_rewrite_db';
+select * from information_schema.session_variables where variable_name='replicate_rewrite_db';
+
+--echo # Incorrect type
+
+--error ER_WRONG_TYPE_FOR_VAR
+SET @@GLOBAL.replicate_rewrite_db=1;
+--error ER_WRONG_ARGUMENTS
+SET @@GLOBAL.replicate_rewrite_db="->";
+--error ER_WRONG_ARGUMENTS
+SET @@GLOBAL.replicate_rewrite_db=" ";
+--error ER_WRONG_ARGUMENTS
+SET @@GLOBAL.replicate_rewrite_db="a->";
+--error ER_WRONG_ARGUMENTS
+SET @@GLOBAL.replicate_rewrite_db="->b";
+
+--echo # Check arguments
+
+--error ER_GLOBAL_VARIABLE
+set session replicate_rewrite_db=1;
+--error ER_WRONG_TYPE_FOR_VAR
+set global replicate_rewrite_db=1;
+--error ER_GLOBAL_VARIABLE
+SET @@SESSION.replicate_do_db = "";
+# This should work
+SET @@GLOBAL.replicate_rewrite_db="";
+SELECT @@GLOBAL.replicate_rewrite_db;
+SET @@GLOBAL.replicate_rewrite_db=null;
+SELECT @@GLOBAL.replicate_rewrite_db;
+SET @@GLOBAL.replicate_rewrite_db=DEFAULT;
+SELECT @@GLOBAL.replicate_rewrite_db;
+SET @@GLOBAL.replicate_rewrite_db="db1->db3";
+SELECT @@GLOBAL.replicate_rewrite_db;
+SET @@GLOBAL.replicate_rewrite_db="db2 ->db4";
+SELECT @@GLOBAL.replicate_rewrite_db;
+SET @@GLOBAL.replicate_rewrite_db=" db5 ->db7 ";
+SELECT @@GLOBAL.replicate_rewrite_db;
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_rewrite_db';
+select * from information_schema.session_variables where variable_name='replicate_rewrite_db';
+show global variables like 'replicate_rewrite_db';
+
+SET @@GLOBAL.replicate_rewrite_db="db1->db2, db3->db4";
+SELECT @@GLOBAL.replicate_rewrite_db;
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_rewrite_db';
+
+--echo # Check restart with appending the value
+--let $restart_parameters = "--replicate_rewrite_db='X->Y'"
+--source include/restart_mysqld.inc
+SELECT @@GLOBAL.replicate_rewrite_db;
+
+--echo # Check restart with wrong value on CLI
+--source include/shutdown_mysqld.inc
+# Expect the server to fail to come up with these options
+--let $args="--replicate_rewrite_db=x-" --log-warnings=1 --silent-startup --help --verbose
+--error 1
+--exec $MYSQLD_CMD $args > $MYSQL_TMP_DIR/mysqld--replicate.txt 2> $MYSQL_TMP_DIR/mysqld--replicate.err
+--replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* //
+--cat_file $MYSQL_TMP_DIR/mysqld--replicate.err
+# Restart the server with the default options
+--let $restart_parameters = ""
+--source include/start_mysqld.inc
+SELECT @@GLOBAL.replicate_rewrite_db;
+
+--echo # Cleanup.
+SET @@GLOBAL.replicate_rewrite_db = @save_replicate_rewrite_db;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 609b8e26415..8e40149ee72 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -8091,45 +8091,11 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument,
case (int)OPT_REPLICATE_REWRITE_DB:
{
/* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */
- const char* key= argument, *ptr, *val;
-
- // Skipp pre-space in key
- while (*key && my_isspace(mysqld_charset, *key))
- key++;
-
- // Where val begins
- if (!(ptr= strstr(key, "->")))
+ if (cur_rpl_filter->add_rewrite_db(argument))
{
- sql_print_error("Bad syntax in replicate-rewrite-db: missing '->'");
+ sql_print_error("Bad syntax in replicate-rewrite-db.Expected syntax is FROM->TO.");
return 1;
}
- val= ptr+2;
-
- // Skip blanks at the end of key
- while (ptr > key && my_isspace(mysqld_charset, ptr[-1]))
- ptr--;
- if (ptr == key)
- {
- sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db");
- return 1;
- }
- key= strmake_root(&startup_root, key, (size_t) (ptr-key));
-
- /* Skipp pre space in value */
- while (*val && my_isspace(mysqld_charset, *val))
- val++;
-
- // Value ends with \0 or space
- for (ptr= val; *ptr && !my_isspace(&my_charset_latin1, *ptr) ; ptr++)
- {}
- if (ptr == val)
- {
- sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db");
- return 1;
- }
- val= strmake_root(&startup_root, val, (size_t) (ptr-val));
-
- cur_rpl_filter->add_db_rewrite(key, val);
break;
}
case (int)OPT_SLAVE_PARALLEL_MODE:
diff --git a/sql/privilege.h b/sql/privilege.h
index 57bbc95840e..89d77ae9a09 100644
--- a/sql/privilege.h
+++ b/sql/privilege.h
@@ -546,6 +546,8 @@ constexpr privilege_t PRIV_SET_SYSTEM_SESSION_VAR_GTID_DOMAIN_ID=
*/
constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_REPLICATE_EVENTS_MARKED_FOR_SKIP=
REPL_SLAVE_ADMIN_ACL | SUPER_ACL;
+constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_REPLICATE_REWRITE_DB=
+ REPL_SLAVE_ADMIN_ACL | SUPER_ACL;
constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_REPLICATE_DO_DB=
REPL_SLAVE_ADMIN_ACL | SUPER_ACL;
constexpr privilege_t PRIV_SET_SYSTEM_GLOBAL_VAR_REPLICATE_DO_TABLE=
diff --git a/sql/protocol.cc b/sql/protocol.cc
index eee6236ffe7..26bc94c1463 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -1374,21 +1374,49 @@ bool Protocol::store(I_List<i_string>* str_list)
{
char buf[256];
String tmp(buf, sizeof(buf), &my_charset_bin);
- uint32 len;
+ size_t len= 0;
I_List_iterator<i_string> it(*str_list);
i_string* s;
+ const char *delimiter= ",";
tmp.length(0);
while ((s=it++))
{
+ tmp.append(delimiter, len);
tmp.append(s->ptr, strlen(s->ptr));
- tmp.append(',');
+ len= 1;
}
- if ((len= tmp.length()))
- len--; // Remove last ','
- return store((char*) tmp.ptr(), len, tmp.charset());
+
+ return store((char*) tmp.ptr(), tmp.length(), tmp.charset());
+}
+
+
+/**
+ Send a set of strings as a string of key-value pairs with ',' in between.
+*/
+
+bool Protocol::store(I_List<i_string_pair>* str_list)
+{
+ char buf[256];
+ const char *delimiter= ",";
+ String tmp(buf, sizeof(buf), &my_charset_bin);
+ size_t delim_len= 0;
+ I_List_iterator<i_string_pair> it(*str_list);
+ i_string_pair* s;
+
+ tmp.length(0);
+ while ((s=it++))
+ {
+ tmp.append(delimiter, delim_len);
+ tmp.append(s->key, strlen(s->key));
+ tmp.append(STRING_WITH_LEN("->"));
+ tmp.append(s->val, strlen(s->val));
+ delim_len= 1;
+ }
+ return store((char*) tmp.ptr(), tmp.length(), tmp.charset());
}
+
/****************************************************************************
Functions to handle the simple (default) protocol where everything is
This protocol is the one that is used by default between the MySQL server
diff --git a/sql/protocol.h b/sql/protocol.h
index f095ad68a34..39569a825d5 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -99,6 +99,7 @@ public:
bool send_result_set_row(List<Item> *row_items);
bool store(I_List<i_string> *str_list);
+ bool store(I_List<i_string_pair> *str_list);
bool store_string_or_null(const char *from, CHARSET_INFO *cs);
bool store_warning(const char *from, size_t length);
String *storage_packet() { return packet; }
diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc
index 1e1f98c1e3e..982c0c9482d 100644
--- a/sql/rpl_filter.cc
+++ b/sql/rpl_filter.cc
@@ -48,7 +48,7 @@ Rpl_filter::~Rpl_filter()
free_string_array(&wild_ignore_table);
free_string_list(&do_db);
free_string_list(&ignore_db);
- free_list(&rewrite_db);
+ free_string_pair_list(&rewrite_db);
}
@@ -470,14 +470,6 @@ Rpl_filter::set_wild_ignore_table(const char* table_spec)
}
-void
-Rpl_filter::add_db_rewrite(const char* from_db, const char* to_db)
-{
- i_string_pair *db_pair = new i_string_pair(from_db, to_db);
- rewrite_db.push_back(db_pair);
-}
-
-
int
Rpl_filter::add_table_rule(HASH* h, const char* table_spec)
{
@@ -521,6 +513,70 @@ Rpl_filter::add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
int
+Rpl_filter::add_string_pair_list(const char* spec)
+{
+ /* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */
+ char* from_db, *to_db;
+ const char *ptr, *val_ptr;
+ size_t len;
+
+ // Remove pre-space in key
+ while(*spec && my_isspace(system_charset_info, (unsigned char)*spec)) spec++;
+
+ if (!(ptr= strstr(spec, "->")))
+ {
+ // Bad syntax, missing ->
+ return 1;
+ }
+
+ // value
+ val_ptr= ptr + 2;
+
+ // Skip blanks at the end of spec
+ while(ptr > spec && my_isspace(system_charset_info, ptr[-1])) ptr--;
+
+ if (ptr == spec)
+ {
+ // Bad syntax: empty FROM db (key)
+ return 1;
+ }
+
+ // key
+ len= (size_t)(ptr - spec);
+ if (! (from_db= (char *) my_malloc(PSI_NOT_INSTRUMENTED, len + 1, MYF(0))))
+ {
+ return 1;
+ }
+ memcpy(from_db, spec, len);
+ from_db[len]='\0';
+
+ // Remove pre-space in val
+ while(*val_ptr && my_isspace(system_charset_info, (unsigned char)*val_ptr)) val_ptr++;
+ // Value ends with \0 or space
+ if (!strlen(val_ptr))
+ {
+ // Bad syntax: Empty value \n"
+ my_free(from_db);
+ return 1;
+ }
+
+ for (ptr= val_ptr; *ptr && !my_isspace(system_charset_info, *ptr); ptr++){}
+ // value
+ len= (size_t)(ptr - val_ptr);
+ if(! (to_db= (char *) my_malloc(PSI_NOT_INSTRUMENTED, len + 1, MYF(0))))
+ {
+ my_free(from_db);
+ return 1;
+ }
+ memcpy(to_db, val_ptr, len);
+ to_db[len]='\0';
+ i_string_pair *db_pair = new i_string_pair(from_db, to_db);
+ rewrite_db.push_back(db_pair);
+ return false;
+}
+
+
+int
Rpl_filter::add_string_list(I_List<i_string> *list, const char* spec)
{
char *str;
@@ -542,6 +598,14 @@ Rpl_filter::add_string_list(I_List<i_string> *list, const char* spec)
int
+Rpl_filter::add_rewrite_db(const char* table_spec)
+{
+ DBUG_ENTER("Rpl_filter::add_rewrite_db");
+ DBUG_RETURN(add_string_pair_list(table_spec));
+}
+
+
+int
Rpl_filter::add_do_db(const char* table_spec)
{
DBUG_ENTER("Rpl_filter::add_do_db");
@@ -558,6 +622,14 @@ Rpl_filter::add_ignore_db(const char* table_spec)
int
+Rpl_filter::set_rewrite_db(const char* db_spec)
+{
+ free_string_pair_list(&rewrite_db);
+ return parse_filter_rule(db_spec, &Rpl_filter::add_rewrite_db);
+}
+
+
+int
Rpl_filter::set_do_db(const char* db_spec)
{
free_string_list(&do_db);
@@ -665,6 +737,21 @@ Rpl_filter::free_string_list(I_List<i_string> *l)
}
+void
+Rpl_filter::free_string_pair_list(I_List<i_string_pair> *l)
+{
+ i_string_pair *tmp;
+
+ while ((tmp= l->get()))
+ {
+ my_free((void *) tmp->key);
+ my_free((void *) tmp->val);
+ delete tmp;
+ }
+
+ l->empty();
+}
+
/*
Builds a String from a HASH of TABLE_RULE_ENT. Cannot be used for any other
hash, as it assumes that the hash entries are TABLE_RULE_ENT.
@@ -749,6 +836,34 @@ Rpl_filter::rewrite_db_is_empty()
}
+I_List<i_string_pair>*
+Rpl_filter::get_rewrite_db()
+{
+ return &rewrite_db;
+}
+
+
+void
+Rpl_filter::db_rewrite_rule_ent_list_to_str(String* str, I_List<i_string_pair>* list)
+{
+ I_List_iterator<i_string_pair> it(*list);
+ i_string_pair* s;
+
+ str->length(0);
+
+ const char *delimiter= ",";
+ size_t delim_len= 0;
+ while ((s= it++))
+ {
+ str->append(delimiter, delim_len);
+ str->append(s->key, strlen(s->key));
+ str->append(STRING_WITH_LEN("->"));
+ str->append(s->val, strlen(s->val));
+ delim_len= 1;
+ }
+}
+
+
const char*
Rpl_filter::get_rewrite_db(const char* db, size_t *new_len)
{
@@ -769,18 +884,6 @@ Rpl_filter::get_rewrite_db(const char* db, size_t *new_len)
}
-void
-Rpl_filter::copy_rewrite_db(Rpl_filter *from)
-{
- I_List_iterator<i_string_pair> it(from->rewrite_db);
- i_string_pair* tmp;
- DBUG_ASSERT(rewrite_db.is_empty());
-
- /* TODO: Add memory checking here and in all add_xxxx functions ! */
- while ((tmp=it++))
- add_db_rewrite(tmp->key, tmp->val);
-}
-
I_List<i_string>*
Rpl_filter::get_do_db()
{
@@ -816,6 +919,13 @@ Rpl_filter::db_rule_ent_list_to_str(String* str, I_List<i_string>* list)
void
+Rpl_filter::get_rewrite_db(String* str)
+{
+ db_rewrite_rule_ent_list_to_str(str, get_rewrite_db());
+}
+
+
+void
Rpl_filter::get_do_db(String* str)
{
db_rule_ent_list_to_str(str, get_do_db());
diff --git a/sql/rpl_filter.h b/sql/rpl_filter.h
index f22ec8a0ce4..ee3b9d516b7 100644
--- a/sql/rpl_filter.h
+++ b/sql/rpl_filter.h
@@ -71,9 +71,11 @@ public:
int set_wild_do_table(const char* table_spec);
int set_wild_ignore_table(const char* table_spec);
+ int add_rewrite_db(const char* table_spec);
int add_do_db(const char* db_spec);
int add_ignore_db(const char* db_spec);
+ int set_rewrite_db(const char* db_spec);
int set_do_db(const char* db_spec);
int set_ignore_db(const char* db_spec);
@@ -87,8 +89,6 @@ public:
return parallel_mode;
}
- void add_db_rewrite(const char* from_db, const char* to_db);
-
/* Getters - to get information about current rules */
void get_do_table(String* str);
@@ -98,8 +98,9 @@ public:
void get_wild_ignore_table(String* str);
bool rewrite_db_is_empty();
+ I_List<i_string_pair>* get_rewrite_db();
+ void get_rewrite_db(String *str);
const char* get_rewrite_db(const char* db, size_t *new_len);
- void copy_rewrite_db(Rpl_filter *from);
I_List<i_string>* get_do_db();
I_List<i_string>* get_ignore_db();
@@ -121,15 +122,17 @@ private:
void free_string_array(DYNAMIC_ARRAY *a);
void free_string_list(I_List<i_string> *l);
+ void free_string_pair_list(I_List<i_string_pair> *l);
void table_rule_ent_hash_to_str(String* s, HASH* h, bool inited);
void table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a,
bool inited);
+ void db_rewrite_rule_ent_list_to_str(String*, I_List<i_string_pair>*);
void db_rule_ent_list_to_str(String* s, I_List<i_string>* l);
TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len);
int add_string_list(I_List<i_string> *list, const char* spec);
-
+ int add_string_pair_list(const char* my_spec);
/*
Those 4 structures below are uninitialized memory unless the
corresponding *_inited variables are "true".
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index ab2523d960b..3c698f27a19 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -1024,10 +1024,12 @@ void copy_filter_setting(Rpl_filter* dst_filter, Rpl_filter* src_filter)
dst_filter->set_wild_ignore_table(tmp.ptr());
}
- if (dst_filter->rewrite_db_is_empty())
+ dst_filter->get_rewrite_db(&tmp);
+ if (tmp.is_empty())
{
- if (!src_filter->rewrite_db_is_empty())
- dst_filter->copy_rewrite_db(src_filter);
+ src_filter->get_rewrite_db(&tmp);
+ if (!tmp.is_empty())
+ dst_filter->set_rewrite_db(tmp.ptr());
}
}
diff --git a/sql/slave.cc b/sql/slave.cc
index e39efcc6bbc..a9a3189ec0f 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2955,6 +2955,9 @@ void show_master_info_get_fields(THD *thd, List<Item> *field_list,
Item_empty_string(thd, "Slave_SQL_Running", 3),
mem_root);
field_list->push_back(new (mem_root)
+ Item_empty_string(thd, "Replicate_Rewrite_DB", 23),
+ mem_root);
+ field_list->push_back(new (mem_root)
Item_empty_string(thd, "Replicate_Do_DB", 20),
mem_root);
field_list->push_back(new (mem_root)
@@ -3209,6 +3212,7 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full,
&my_charset_bin);
protocol->store(&slave_running[mi->slave_running], &my_charset_bin);
protocol->store(mi->rli.slave_running ? &msg_yes : &msg_no, &my_charset_bin);
+ protocol->store(rpl_filter->get_rewrite_db());
protocol->store(rpl_filter->get_do_db());
protocol->store(rpl_filter->get_ignore_db());
diff --git a/sql/sql_list.cc b/sql/sql_list.cc
index 92664898718..6ccec9b5f2a 100644
--- a/sql/sql_list.cc
+++ b/sql/sql_list.cc
@@ -23,13 +23,6 @@
list_node end_of_list;
-void free_list(I_List <i_string_pair> *list)
-{
- i_string_pair *tmp;
- while ((tmp= list->get()))
- delete tmp;
-}
-
void free_list(I_List <i_string> *list)
{
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 9d159071ff3..edecb0f0be4 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -869,7 +869,6 @@ list_copy_and_replace_each_value(List<T> &list, MEM_ROOT *mem_root)
it.replace(el->clone(mem_root));
}
-void free_list(I_List <i_string_pair> *list);
void free_list(I_List <i_string> *list);
#endif // INCLUDES_MYSQL_SQL_LIST_H
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index e3a8261ca10..de7390f9500 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -5460,6 +5460,9 @@ bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi)
/* Proctect against other threads */
mysql_mutex_lock(&LOCK_active_mi);
switch (opt_id) {
+ case OPT_REPLICATE_REWRITE_DB:
+ status= rpl_filter->set_rewrite_db(value);
+ break;
case OPT_REPLICATE_DO_DB:
status= rpl_filter->set_do_db(value);
break;
@@ -5508,6 +5511,9 @@ Sys_var_rpl_filter::global_value_ptr(THD *thd,
mysql_mutex_lock(&LOCK_active_mi);
switch (opt_id) {
+ case OPT_REPLICATE_REWRITE_DB:
+ rpl_filter->get_rewrite_db(&tmp);
+ break;
case OPT_REPLICATE_DO_DB:
rpl_filter->get_do_db(&tmp);
break;
@@ -5547,6 +5553,13 @@ static Sys_var_rpl_filter Sys_replicate_do_db(
"actual names of table(s) being updated are checked.",
PRIV_SET_SYSTEM_GLOBAL_VAR_REPLICATE_DO_DB);
+static Sys_var_rpl_filter Sys_replicate_rewrite_db(
+ "replicate_rewrite_db", OPT_REPLICATE_REWRITE_DB,
+ "Tells the slave to replicate binlog events "
+ "into a different database than their original target on the master."
+ "Example: replicate-rewrite-db=master_db_name->slave_db_name.",
+ PRIV_SET_SYSTEM_GLOBAL_VAR_REPLICATE_REWRITE_DB);
+
static Sys_var_rpl_filter Sys_replicate_do_table(
"replicate_do_table", OPT_REPLICATE_DO_TABLE,
"Tells the slave to restrict replication to tables in the "
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index e342aad532b..29aa2d001dd 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -469,7 +469,7 @@ static void test_prepare_simple()
strmov(query, "SHOW SLAVE STATUS");
stmt= mysql_simple_prepare(mysql, query);
check_stmt(stmt);
- DIE_UNLESS(mysql_stmt_field_count(stmt) == 53);
+ DIE_UNLESS(mysql_stmt_field_count(stmt) == 54);
mysql_stmt_close(stmt);
/* show master status */