mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-26: Global transaction ID.
Implement test case rpl_gtid_stop_start.test to test normal stop and restart of master and slave mysqld servers. Fix a couple bugs found with the test: - When InnoDB is disabled (no XA), the binlog state was not read when master mysqld starts. - Remove old code that puts a bogus D-S-0 into the initial binlog state, it is not correct in current design. - Fix memory leak in gtid_find_binlog_file().
This commit is contained in:
54
mysql-test/suite/rpl/r/rpl_gtid_stop_start.result
Normal file
54
mysql-test/suite/rpl/r/rpl_gtid_stop_start.result
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
include/rpl_init.inc [topology=1->2]
|
||||||
|
*** Test normal shutdown/restart of slave server configured as a GTID slave. ***
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
include/stop_slave.inc
|
||||||
|
Master_Log_File = 'master-bin.000001'
|
||||||
|
Using_Gtid = '0'
|
||||||
|
CHANGE MASTER TO master_gtid_pos=AUTO;
|
||||||
|
FLUSH LOGS;
|
||||||
|
PURGE BINARY LOGS TO 'master-bin.000002';
|
||||||
|
show binary logs;
|
||||||
|
Log_name File_size
|
||||||
|
master-bin.000002 #
|
||||||
|
INSERT INTO t1 VALUES (2);
|
||||||
|
FLUSH LOGS;
|
||||||
|
INSERT INTO t1 VALUES (3);
|
||||||
|
show binary logs;
|
||||||
|
Log_name File_size
|
||||||
|
master-bin.000002 #
|
||||||
|
master-bin.000003 #
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
*** Test normal shutdown/restart of master server, check binlog state is preserved. ***
|
||||||
|
SET SESSION gtid_domain_id= 1;
|
||||||
|
INSERT INTO t1 VALUES (4);
|
||||||
|
SHOW BINLOG EVENTS IN 'master-bin.000003' LIMIT 1,1;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000003 # Gtid_list # # [0-1-3]
|
||||||
|
FLUSH LOGS;
|
||||||
|
SHOW BINLOG EVENTS IN 'master-bin.000004' LIMIT 1,1;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000004 # Gtid_list # # [1-1-5,0-1-4]
|
||||||
|
SHOW BINLOG EVENTS IN 'master-bin.000005' LIMIT 1,1;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000005 # Gtid_list # # [1-1-5,0-1-4]
|
||||||
|
show binary logs;
|
||||||
|
Log_name File_size
|
||||||
|
master-bin.000002 #
|
||||||
|
master-bin.000003 #
|
||||||
|
master-bin.000004 #
|
||||||
|
master-bin.000005 #
|
||||||
|
INSERT INTO t1 VALUES(5);
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
DROP TABLE t1;
|
||||||
|
include/rpl_end.inc
|
101
mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
Normal file
101
mysql-test/suite/rpl/t/rpl_gtid_stop_start.test
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
--let $rpl_topology=1->2
|
||||||
|
--source include/rpl_init.inc
|
||||||
|
|
||||||
|
--echo *** Test normal shutdown/restart of slave server configured as a GTID slave. ***
|
||||||
|
|
||||||
|
--connection server_1
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
--save_master_pos
|
||||||
|
|
||||||
|
--connection server_2
|
||||||
|
--sync_with_master
|
||||||
|
--source include/stop_slave.inc
|
||||||
|
|
||||||
|
--let $status_items= Master_Log_File,Using_Gtid
|
||||||
|
--source include/show_slave_status.inc
|
||||||
|
|
||||||
|
CHANGE MASTER TO master_gtid_pos=AUTO;
|
||||||
|
|
||||||
|
# Now try to restart the slave mysqld server without starting the slave first
|
||||||
|
# threads after the CHANGE MASTER.
|
||||||
|
# When the slave restarts, it should reconnect using GTID.
|
||||||
|
# We test that it really uses GTID by purging on the master the
|
||||||
|
# old binlog the slave would need if connecting with old style
|
||||||
|
# file name/offset.
|
||||||
|
|
||||||
|
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||||
|
wait
|
||||||
|
EOF
|
||||||
|
--shutdown_server 30
|
||||||
|
--source include/wait_until_disconnected.inc
|
||||||
|
|
||||||
|
--connection server_1
|
||||||
|
FLUSH LOGS;
|
||||||
|
PURGE BINARY LOGS TO 'master-bin.000002';
|
||||||
|
--source include/show_binary_logs.inc
|
||||||
|
INSERT INTO t1 VALUES (2);
|
||||||
|
FLUSH LOGS;
|
||||||
|
INSERT INTO t1 VALUES (3);
|
||||||
|
--source include/show_binary_logs.inc
|
||||||
|
|
||||||
|
# Let the slave mysqld server start again.
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||||
|
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||||
|
restart: --skip-slave-start=0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
--connection server_2
|
||||||
|
--enable_reconnect
|
||||||
|
--source include/wait_until_connected_again.inc
|
||||||
|
|
||||||
|
--let $wait_condition= SELECT COUNT(*) = 3 FROM t1
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
|
||||||
|
|
||||||
|
--echo *** Test normal shutdown/restart of master server, check binlog state is preserved. ***
|
||||||
|
|
||||||
|
--connection server_1
|
||||||
|
SET SESSION gtid_domain_id= 1;
|
||||||
|
INSERT INTO t1 VALUES (4);
|
||||||
|
--replace_column 2 # 4 # 5 #
|
||||||
|
SHOW BINLOG EVENTS IN 'master-bin.000003' LIMIT 1,1;
|
||||||
|
FLUSH LOGS;
|
||||||
|
--replace_column 2 # 4 # 5 #
|
||||||
|
SHOW BINLOG EVENTS IN 'master-bin.000004' LIMIT 1,1;
|
||||||
|
|
||||||
|
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
wait
|
||||||
|
EOF
|
||||||
|
--shutdown_server 30
|
||||||
|
--source include/wait_until_disconnected.inc
|
||||||
|
|
||||||
|
--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
restart
|
||||||
|
EOF
|
||||||
|
|
||||||
|
--connection default
|
||||||
|
--enable_reconnect
|
||||||
|
--source include/wait_until_connected_again.inc
|
||||||
|
--connection server_1
|
||||||
|
--enable_reconnect
|
||||||
|
--source include/wait_until_connected_again.inc
|
||||||
|
|
||||||
|
--replace_column 2 # 4 # 5 #
|
||||||
|
SHOW BINLOG EVENTS IN 'master-bin.000005' LIMIT 1,1;
|
||||||
|
--source include/show_binary_logs.inc
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES(5);
|
||||||
|
|
||||||
|
--connection server_2
|
||||||
|
--let $wait_condition= SELECT COUNT(*) = 5 FROM t1
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
SELECT * FROM t1 ORDER BY a;
|
||||||
|
|
||||||
|
|
||||||
|
--connection server_1
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--source include/rpl_end.inc
|
25
sql/log.cc
25
sql/log.cc
@@ -2928,7 +2928,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period)
|
|||||||
bytes_written(0), file_id(1), open_count(1),
|
bytes_written(0), file_id(1), open_count(1),
|
||||||
group_commit_queue(0), group_commit_queue_busy(FALSE),
|
group_commit_queue(0), group_commit_queue_busy(FALSE),
|
||||||
num_commits(0), num_group_commits(0),
|
num_commits(0), num_group_commits(0),
|
||||||
sync_period_ptr(sync_period), sync_counter(0),
|
sync_period_ptr(sync_period), sync_counter(0), state_read(false),
|
||||||
is_relay_log(0), signal_cnt(0),
|
is_relay_log(0), signal_cnt(0),
|
||||||
checksum_alg_reset(BINLOG_CHECKSUM_ALG_UNDEF),
|
checksum_alg_reset(BINLOG_CHECKSUM_ALG_UNDEF),
|
||||||
relay_log_checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF),
|
relay_log_checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF),
|
||||||
@@ -3122,6 +3122,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
|
|||||||
DBUG_ENTER("MYSQL_BIN_LOG::open");
|
DBUG_ENTER("MYSQL_BIN_LOG::open");
|
||||||
DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
|
DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
|
||||||
|
|
||||||
|
if (!is_relay_log && read_state_from_file())
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
if (!is_relay_log && !binlog_background_thread_started &&
|
if (!is_relay_log && !binlog_background_thread_started &&
|
||||||
start_binlog_background_thread())
|
start_binlog_background_thread())
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
@@ -5435,6 +5438,10 @@ MYSQL_BIN_LOG::read_state_from_file()
|
|||||||
bool opened= false;
|
bool opened= false;
|
||||||
bool inited= false;
|
bool inited= false;
|
||||||
|
|
||||||
|
if (state_read)
|
||||||
|
return 0;
|
||||||
|
state_read= true;
|
||||||
|
|
||||||
fn_format(buf, opt_bin_logname, mysql_data_home, ".state",
|
fn_format(buf, opt_bin_logname, mysql_data_home, ".state",
|
||||||
MY_UNPACK_FILENAME);
|
MY_UNPACK_FILENAME);
|
||||||
if ((file_no= mysql_file_open(key_file_binlog_state, buf,
|
if ((file_no= mysql_file_open(key_file_binlog_state, buf,
|
||||||
@@ -5447,16 +5454,11 @@ MYSQL_BIN_LOG::read_state_from_file()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rpl_gtid gtid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the state file does not exist, this is the first server startup
|
If the state file does not exist, this is the first server startup
|
||||||
with GTID enabled. So initialize to empty state.
|
with GTID enabled. So initialize to empty state.
|
||||||
*/
|
*/
|
||||||
gtid.domain_id= global_system_variables.gtid_domain_id;
|
rpl_global_gtid_binlog_state.reset();
|
||||||
gtid.server_id= global_system_variables.server_id;
|
|
||||||
gtid.seq_no= 0;
|
|
||||||
rpl_global_gtid_binlog_state.update(>id);
|
|
||||||
err= 0;
|
err= 0;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -5477,6 +5479,9 @@ end:
|
|||||||
end_io_cache(&cache);
|
end_io_cache(&cache);
|
||||||
if (opened)
|
if (opened)
|
||||||
mysql_file_close(file_no, MYF(0));
|
mysql_file_close(file_no, MYF(0));
|
||||||
|
/* Pick the next unused seq_no from the loaded binlog state. */
|
||||||
|
bump_seq_no_counter_if_needed(
|
||||||
|
rpl_global_gtid_binlog_state.seq_no_from_state());
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -8220,12 +8225,12 @@ int TC_LOG_BINLOG::open(const char *opt_name)
|
|||||||
sql_print_information("Recovering after a crash using %s", opt_name);
|
sql_print_information("Recovering after a crash using %s", opt_name);
|
||||||
error= recover(&log_info, log_name, &log,
|
error= recover(&log_info, log_name, &log,
|
||||||
(Format_description_log_event *)ev);
|
(Format_description_log_event *)ev);
|
||||||
|
/* Pick the next unused seq_no from the recovered binlog state. */
|
||||||
|
bump_seq_no_counter_if_needed(
|
||||||
|
rpl_global_gtid_binlog_state.seq_no_from_state());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error= read_state_from_file();
|
error= read_state_from_file();
|
||||||
/* Pick the next unused seq_no from the loaded/recovered binlog state. */
|
|
||||||
bump_seq_no_counter_if_needed(
|
|
||||||
rpl_global_gtid_binlog_state.seq_no_from_state());
|
|
||||||
|
|
||||||
delete ev;
|
delete ev;
|
||||||
end_io_cache(&log);
|
end_io_cache(&log);
|
||||||
|
@@ -507,6 +507,8 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
|
|||||||
*/
|
*/
|
||||||
uint *sync_period_ptr;
|
uint *sync_period_ptr;
|
||||||
uint sync_counter;
|
uint sync_counter;
|
||||||
|
/* Protect against reading the binlog state file twice. */
|
||||||
|
bool state_read;
|
||||||
|
|
||||||
inline uint get_sync_period()
|
inline uint get_sync_period()
|
||||||
{
|
{
|
||||||
|
@@ -881,14 +881,6 @@ rpl_binlog_state::find(uint32 domain_id, uint32 server_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
slave_connection_state::slave_connection_state()
|
|
||||||
{
|
|
||||||
my_hash_init(&hash, &my_charset_bin, 32,
|
|
||||||
offsetof(rpl_gtid, domain_id), sizeof(uint32), NULL, my_free,
|
|
||||||
HASH_UNIQUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
rpl_binlog_state::count()
|
rpl_binlog_state::count()
|
||||||
{
|
{
|
||||||
@@ -961,6 +953,14 @@ rpl_binlog_state::get_most_recent_gtid_list(rpl_gtid **list, uint32 *size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
slave_connection_state::slave_connection_state()
|
||||||
|
{
|
||||||
|
my_hash_init(&hash, &my_charset_bin, 32,
|
||||||
|
offsetof(rpl_gtid, domain_id), sizeof(uint32), NULL, my_free,
|
||||||
|
HASH_UNIQUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
slave_connection_state::~slave_connection_state()
|
slave_connection_state::~slave_connection_state()
|
||||||
{
|
{
|
||||||
my_hash_free(&hash);
|
my_hash_free(&hash);
|
||||||
|
@@ -936,11 +936,8 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name)
|
|||||||
binlog_file_entry *list;
|
binlog_file_entry *list;
|
||||||
Gtid_list_log_event *glev= NULL;
|
Gtid_list_log_event *glev= NULL;
|
||||||
const char *errormsg= NULL;
|
const char *errormsg= NULL;
|
||||||
IO_CACHE cache;
|
|
||||||
File file = (File)-1;
|
|
||||||
char buf[FN_REFLEN];
|
char buf[FN_REFLEN];
|
||||||
|
|
||||||
bzero((char*) &cache, sizeof(cache));
|
|
||||||
init_alloc_root(&memroot, 10*(FN_REFLEN+sizeof(binlog_file_entry)), 0,
|
init_alloc_root(&memroot, 10*(FN_REFLEN+sizeof(binlog_file_entry)), 0,
|
||||||
MYF(MY_THREAD_SPECIFIC));
|
MYF(MY_THREAD_SPECIFIC));
|
||||||
if (!(list= get_binlog_list(&memroot)))
|
if (!(list= get_binlog_list(&memroot)))
|
||||||
@@ -951,6 +948,9 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name)
|
|||||||
|
|
||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
|
File file;
|
||||||
|
IO_CACHE cache;
|
||||||
|
|
||||||
if (!list->next)
|
if (!list->next)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -971,8 +971,13 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name)
|
|||||||
"GTID position in binlog";
|
"GTID position in binlog";
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if ((file= open_binlog(&cache, buf, &errormsg)) == (File)-1 ||
|
bzero((char*) &cache, sizeof(cache));
|
||||||
(errormsg= get_gtid_list_event(&cache, &glev)))
|
if ((file= open_binlog(&cache, buf, &errormsg)) == (File)-1)
|
||||||
|
goto end;
|
||||||
|
errormsg= get_gtid_list_event(&cache, &glev);
|
||||||
|
end_io_cache(&cache);
|
||||||
|
mysql_file_close(file, MYF(MY_WME));
|
||||||
|
if (errormsg)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (!glev || contains_all_slave_gtid(state, glev))
|
if (!glev || contains_all_slave_gtid(state, glev))
|
||||||
@@ -1023,11 +1028,6 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name)
|
|||||||
end:
|
end:
|
||||||
if (glev)
|
if (glev)
|
||||||
delete glev;
|
delete glev;
|
||||||
if (file != (File)-1)
|
|
||||||
{
|
|
||||||
end_io_cache(&cache);
|
|
||||||
mysql_file_close(file, MYF(MY_WME));
|
|
||||||
}
|
|
||||||
|
|
||||||
free_root(&memroot, MYF(0));
|
free_root(&memroot, MYF(0));
|
||||||
return errormsg;
|
return errormsg;
|
||||||
|
Reference in New Issue
Block a user