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
3
4
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;
include/rpl_end.inc
......@@ -240,6 +240,46 @@ eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT;
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.
--connection server_1
DROP TABLE t1;
......
......@@ -1820,8 +1820,6 @@ after_set_capability:
char str_buf[256];
String connect_state(str_buf, sizeof(str_buf), system_charset_info);
connect_state.length(0);
rpl_gtid *binlog_gtid_list= NULL;
uint32 num_binlog_gtids= 0;
/*
Read the master @@GLOBAL.gtid_domain_id variable.
......@@ -1844,27 +1842,18 @@ after_set_capability:
mysql_free_result(master_res);
master_res= NULL;
if (opt_bin_log)
{
int err= mysql_bin_log.get_most_recent_gtid_list(&binlog_gtid_list,
&num_binlog_gtids);
if (err)
{
err_code= ER_OUTOFMEMORY;
errmsg= "The slave I/O thread stops because a fatal out-of-memory "
"error is encountered when it tries to compute @slave_connect_state.";
sprintf(err_buff, "%s Error: Out of memory", errmsg);
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);
if (rpl_append_gtid_state(&connect_state, true))
{
err_code= ER_OUTOFMEMORY;
errmsg= "The slave I/O thread stops because a fatal out-of-memory "
"error is encountered when it tries to compute @slave_connect_state.";
sprintf(err_buff, "%s Error: Out of memory", errmsg);
goto err;
}
connect_state.append(STRING_WITH_LEN("'"), system_charset_info);
rc= mysql_real_query(mysql, connect_state.ptr(), connect_state.length());
if (rc)
{
......@@ -2511,7 +2500,12 @@ bool show_all_master_info(THD* thd)
DBUG_ENTER("show_master_info");
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()))
DBUG_RETURN(TRUE);
......
......@@ -3360,4 +3360,30 @@ rpl_deinit_gtid_slave_state()
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 */
......@@ -69,6 +69,7 @@ extern PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state;
void rpl_init_gtid_slave_state();
void rpl_deinit_gtid_slave_state();
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 */
......
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