Commit c2cbc9ce authored by unknown's avatar unknown

MDEV-26: Global transaction ID.

Move combining slave and gtid binlog state into a separate function.

Make SHOW ALL SLAVES STATUS use the same function, so it shows the
same value used by slave connect.

Add a test case.
parent bdf6367d
...@@ -149,5 +149,39 @@ a ...@@ -149,5 +149,39 @@ a
3 3
4 4
5 5
*** Test modifying binlog on slave and the effect on GTID state. ***
include/stop_slave.inc
RESET MASTER;
CHANGE MASTER TO master_gtid_pos='';
RESET MASTER;
TRUNCATE TABLE t1;
INSERT INTO t1 VALUES (10);
include/start_slave.inc
SELECT * FROM t1;
a
10
SELECT '1' AS Using_Gtid;
Using_Gtid
1
SELECT '0-1-2' AS Gtid_Pos;
Gtid_Pos
0-1-2
UPDATE t1 SET a=9 WHERE a=10;
UPDATE t1 SET a=10 WHERE a=9;
SELECT '0-2-4' AS Gtid_Pos;
Gtid_Pos
0-2-4
include/stop_slave.inc
CHANGE MASTER TO master_gtid_pos= '0-1-2';
ERROR HY000: Requested MASTER_GTID_POS 0-1-2 conflicts with the binary log which contains a more recent GTID 0-2-4. To use the requested MASTER_GTID_POS, the old binlog must be removed with RESET MASTER to avoid out-of-order binlog
RESET MASTER;
SELECT '0-1-2' AS Gtid_Pos;
Gtid_Pos
0-1-2
CHANGE MASTER TO master_gtid_pos= '0-1-2';
include/start_slave.inc
SELECT '0-1-2' AS Gtid_Pos;
Gtid_Pos
0-1-2
DROP TABLE t1; DROP TABLE t1;
include/rpl_end.inc include/rpl_end.inc
...@@ -240,6 +240,46 @@ eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT; ...@@ -240,6 +240,46 @@ eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT;
SELECT * FROM t1 ORDER BY a; SELECT * FROM t1 ORDER BY a;
--echo *** Test modifying binlog on slave and the effect on GTID state. ***
--connection server_2
--source include/stop_slave.inc
RESET MASTER;
CHANGE MASTER TO master_gtid_pos='';
--connection server_1
RESET MASTER;
TRUNCATE TABLE t1;
INSERT INTO t1 VALUES (10); # Will be GTID 0-1-2
--save_master_pos
--connection server_2
--source include/start_slave.inc
--sync_with_master
SELECT * FROM t1;
--let $value= query_get_value(SHOW SLAVE STATUS, "Using_Gtid", 1)
eval SELECT '$value' AS Using_Gtid;
--let $value= query_get_value(SHOW ALL SLAVES STATUS, "Gtid_Pos", 1)
eval SELECT '$value' AS Gtid_Pos;
UPDATE t1 SET a=9 WHERE a=10;
UPDATE t1 SET a=10 WHERE a=9;
--let $value= query_get_value(SHOW ALL SLAVES STATUS, "Gtid_Pos", 1)
eval SELECT '$value' AS Gtid_Pos;
--source include/stop_slave.inc
--error ER_MASTER_GTID_POS_CONFLICTS_WITH_BINLOG
CHANGE MASTER TO master_gtid_pos= '0-1-2';
RESET MASTER;
--let $value= query_get_value(SHOW ALL SLAVES STATUS, "Gtid_Pos", 1)
eval SELECT '$value' AS Gtid_Pos;
CHANGE MASTER TO master_gtid_pos= '0-1-2';
--source include/start_slave.inc
--let $value= query_get_value(SHOW ALL SLAVES STATUS, "Gtid_Pos", 1)
eval SELECT '$value' AS Gtid_Pos;
# Clean up. # Clean up.
--connection server_1 --connection server_1
DROP TABLE t1; DROP TABLE t1;
......
...@@ -1820,8 +1820,6 @@ when it try to get the value of TIME_ZONE global variable from master."; ...@@ -1820,8 +1820,6 @@ when it try to get the value of TIME_ZONE global variable from master.";
char str_buf[256]; char str_buf[256];
String connect_state(str_buf, sizeof(str_buf), system_charset_info); String connect_state(str_buf, sizeof(str_buf), system_charset_info);
connect_state.length(0); connect_state.length(0);
rpl_gtid *binlog_gtid_list= NULL;
uint32 num_binlog_gtids= 0;
/* /*
Read the master @@GLOBAL.gtid_domain_id variable. Read the master @@GLOBAL.gtid_domain_id variable.
...@@ -1844,11 +1842,9 @@ when it try to get the value of TIME_ZONE global variable from master."; ...@@ -1844,11 +1842,9 @@ when it try to get the value of TIME_ZONE global variable from master.";
mysql_free_result(master_res); mysql_free_result(master_res);
master_res= NULL; master_res= NULL;
if (opt_bin_log) connect_state.append(STRING_WITH_LEN("SET @slave_connect_state='"),
{ system_charset_info);
int err= mysql_bin_log.get_most_recent_gtid_list(&binlog_gtid_list, if (rpl_append_gtid_state(&connect_state, true))
&num_binlog_gtids);
if (err)
{ {
err_code= ER_OUTOFMEMORY; err_code= ER_OUTOFMEMORY;
errmsg= "The slave I/O thread stops because a fatal out-of-memory " errmsg= "The slave I/O thread stops because a fatal out-of-memory "
...@@ -1856,15 +1852,8 @@ when it try to get the value of TIME_ZONE global variable from master."; ...@@ -1856,15 +1852,8 @@ when it try to get the value of TIME_ZONE global variable from master.";
sprintf(err_buff, "%s Error: Out of memory", errmsg); sprintf(err_buff, "%s Error: Out of memory", errmsg);
goto err; goto err;
} }
}
connect_state.append(STRING_WITH_LEN("SET @slave_connect_state='"),
system_charset_info);
rpl_global_gtid_slave_state.tostring(&connect_state, binlog_gtid_list,
num_binlog_gtids);
if (binlog_gtid_list)
my_free(binlog_gtid_list);
connect_state.append(STRING_WITH_LEN("'"), system_charset_info); connect_state.append(STRING_WITH_LEN("'"), system_charset_info);
rc= mysql_real_query(mysql, connect_state.ptr(), connect_state.length()); rc= mysql_real_query(mysql, connect_state.ptr(), connect_state.length());
if (rc) if (rc)
{ {
...@@ -2511,7 +2500,12 @@ bool show_all_master_info(THD* thd) ...@@ -2511,7 +2500,12 @@ bool show_all_master_info(THD* thd)
DBUG_ENTER("show_master_info"); DBUG_ENTER("show_master_info");
mysql_mutex_assert_owner(&LOCK_active_mi); mysql_mutex_assert_owner(&LOCK_active_mi);
rpl_global_gtid_slave_state.tostring(&gtid_pos, NULL, 0); gtid_pos.length(0);
if (rpl_append_gtid_state(&gtid_pos, true))
{
my_error(ER_OUT_OF_RESOURCES, MYF(0));
DBUG_RETURN(TRUE);
}
if (send_show_master_info_header(thd, 1, gtid_pos.length())) if (send_show_master_info_header(thd, 1, gtid_pos.length()))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
......
...@@ -3360,4 +3360,30 @@ rpl_deinit_gtid_slave_state() ...@@ -3360,4 +3360,30 @@ rpl_deinit_gtid_slave_state()
rpl_global_gtid_slave_state.deinit(); rpl_global_gtid_slave_state.deinit();
} }
/*
Format the current GTID state as a string, for use when connecting to a
master server with GTID, or for returning the value of @@global.gtid_state.
If the flag use_binlog is true, then the contents of the binary log (if
enabled) is merged into the current GTID state.
*/
int
rpl_append_gtid_state(String *dest, bool use_binlog)
{
int err;
rpl_gtid *gtid_list= NULL;
uint32 num_gtids= 0;
if (opt_bin_log &&
(err= mysql_bin_log.get_most_recent_gtid_list(&gtid_list, &num_gtids)))
return err;
rpl_global_gtid_slave_state.tostring(dest, gtid_list, num_gtids);
my_free(gtid_list);
return 0;
}
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
...@@ -69,6 +69,7 @@ extern PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state; ...@@ -69,6 +69,7 @@ extern PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state;
void rpl_init_gtid_slave_state(); void rpl_init_gtid_slave_state();
void rpl_deinit_gtid_slave_state(); void rpl_deinit_gtid_slave_state();
int gtid_state_from_binlog_pos(const char *name, uint32 pos, String *out_str); int gtid_state_from_binlog_pos(const char *name, uint32 pos, String *out_str);
int rpl_append_gtid_state(String *dest, bool use_binlog);
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment