Commit 0fdbdde4 authored by unknown's avatar unknown

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().
parent cb65cee8
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
--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
......@@ -2928,7 +2928,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period)
bytes_written(0), file_id(1), open_count(1),
group_commit_queue(0), group_commit_queue_busy(FALSE),
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),
checksum_alg_reset(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_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 &&
start_binlog_background_thread())
DBUG_RETURN(1);
......@@ -5435,6 +5438,10 @@ MYSQL_BIN_LOG::read_state_from_file()
bool opened= false;
bool inited= false;
if (state_read)
return 0;
state_read= true;
fn_format(buf, opt_bin_logname, mysql_data_home, ".state",
MY_UNPACK_FILENAME);
if ((file_no= mysql_file_open(key_file_binlog_state, buf,
......@@ -5447,16 +5454,11 @@ MYSQL_BIN_LOG::read_state_from_file()
}
else
{
rpl_gtid gtid;
/*
If the state file does not exist, this is the first server startup
with GTID enabled. So initialize to empty state.
*/
gtid.domain_id= global_system_variables.gtid_domain_id;
gtid.server_id= global_system_variables.server_id;
gtid.seq_no= 0;
rpl_global_gtid_binlog_state.update(&gtid);
rpl_global_gtid_binlog_state.reset();
err= 0;
goto end;
}
......@@ -5477,6 +5479,9 @@ end:
end_io_cache(&cache);
if (opened)
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;
}
......@@ -8220,12 +8225,12 @@ int TC_LOG_BINLOG::open(const char *opt_name)
sql_print_information("Recovering after a crash using %s", opt_name);
error= recover(&log_info, log_name, &log,
(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
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;
end_io_cache(&log);
......
......@@ -507,6 +507,8 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
*/
uint *sync_period_ptr;
uint sync_counter;
/* Protect against reading the binlog state file twice. */
bool state_read;
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
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()
{
my_hash_free(&hash);
......
......@@ -936,11 +936,8 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name)
binlog_file_entry *list;
Gtid_list_log_event *glev= NULL;
const char *errormsg= NULL;
IO_CACHE cache;
File file = (File)-1;
char buf[FN_REFLEN];
bzero((char*) &cache, sizeof(cache));
init_alloc_root(&memroot, 10*(FN_REFLEN+sizeof(binlog_file_entry)), 0,
MYF(MY_THREAD_SPECIFIC));
if (!(list= get_binlog_list(&memroot)))
......@@ -951,6 +948,9 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name)
while (list)
{
File file;
IO_CACHE cache;
if (!list->next)
{
/*
......@@ -971,8 +971,13 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name)
"GTID position in binlog";
goto end;
}
if ((file= open_binlog(&cache, buf, &errormsg)) == (File)-1 ||
(errormsg= get_gtid_list_event(&cache, &glev)))
bzero((char*) &cache, sizeof(cache));
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;
if (!glev || contains_all_slave_gtid(state, glev))
......@@ -1023,11 +1028,6 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name)
end:
if (glev)
delete glev;
if (file != (File)-1)
{
end_io_cache(&cache);
mysql_file_close(file, MYF(MY_WME));
}
free_root(&memroot, MYF(0));
return errormsg;
......
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