Skip to content
8 changes: 8 additions & 0 deletions mysql-test/main/rpl_info_file_line_count.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CHANGE MASTER TO master_host='127.0.0.1';
# restart: --skip-slave-start
Master_SSL_Key = ''
Using_Gtid = 'Current_Pos'
SQL_Delay = '0'
RESET SLAVE ALL;
Warnings:
Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'Current_Pos' to 'Slave_Pos'
74 changes: 74 additions & 0 deletions mysql-test/main/rpl_info_file_line_count.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Line count / upgrading test for `@@master_info_file` & `@@relay_log_info_file`
#
# This regression test reminds that the line count includes the line count line.
#
# Reference:
# MDEV-39788 CHANGE MASTER savefiles read and write one line to many

--source include/have_binlog_format_mixed.inc # format-agnostic
CHANGE MASTER TO master_host='127.0.0.1'; # have_info_files

--let $MYSQLD_DATADIR= `SELECT @@datadir`


# `using_gtid` is the key-value section, not the 33rd option.
--remove_file $MYSQLD_DATADIR/master.info
Comment on lines +13 to +15
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Modifying master.info and relay-log.info while the server is running can cause test flakiness and failures:

  1. Windows File Locking: On Windows, the running mysqld process may hold active file locks on these files, causing --remove_file or --write_file to fail with permission errors.
  2. Shutdown Overwrite: When the server is restarted via restart_mysqld.inc, it first performs a shutdown. During shutdown, mysqld may flush its active replication state and overwrite the custom master.info and relay-log.info files you just wrote.

To avoid these issues, shut down the server before modifying the files, and then start it back up.

--source include/shutdown_mysqld.inc

# `using_gtid` is the key-value section, not the 33rd option.
--remove_file $MYSQLD_DATADIR/master.info

--write_file $MYSQLD_DATADIR/master.info
33

4
127.0.0.1
root

3306
60
1





1
60.000

0

100000













using_gtid=1
EOF

# This file does not have the 6th option
# (neither does the current `@@relay_log_info_file`).
--remove_file $MYSQLD_DATADIR/relay-log.info
--write_file $MYSQLD_DATADIR/relay-log.info
6
./mysqld-relay-bin.000001
4

0
0
EOF


--let $restart_parameters= --skip-slave-start
--source include/restart_mysqld.inc
Comment on lines +66 to +67
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Since the server should be shut down before modifying the info files, use start_mysqld.inc here instead of restart_mysqld.inc to bring the server back up with the --skip-slave-start parameter.

--let $start_parameters= --skip-slave-start
--source include/start_mysqld.inc


--let $status_items= Master_SSL_Key, Using_Gtid, SQL_Delay
--source include/show_slave_status.inc


# Reset
RESET SLAVE ALL;
14 changes: 8 additions & 6 deletions sql/rpl_info_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,9 @@ struct Info_file
auto &line1= dynamic_cast<String_value<> &>(values[0](this));
if (line1.load_from(&file))
return true;
char *end= str2int(line1.buf, 10, 0, INT32_MAX, &val);
char *end= str2int(line1.buf, 10, 1, INT32_MAX, &val);
/**
If this first line was not a number - the line count,
If this first line was not a positive number - the line count,
then it was the first value for real,
so the for loop should then skip over it, the index 0 of the list.
*/
Expand All @@ -305,7 +305,8 @@ struct Info_file
Set the default after parsing: While std::from_chars() does not replace
the output if it failed, it does replace if the line is not fully spent.
*/
size_t line_count= i ? default_line_count: static_cast<size_t>(val);
size_t line_count= i ? default_line_count :
static_cast<size_t>(val - 1); // remove the line count line from the count
for (; i < line_count; ++i)
{
int c;
Expand Down Expand Up @@ -355,10 +356,11 @@ struct Info_file
}
/*
Pad additional reserved lines:
(1 for the line count line + line count) inclusive -> max line inclusive
= line count exclusive <- max line inclusive
(1 for the line count line + line count) exclusive -> max line inclusive
= line count exclusive -> max line exclusive
*/
for (; total_line_count > size; --total_line_count)
// Pad additional reserved lines
while ((++size) < total_line_count)
my_b_write_byte(&file, '\n');
}

Expand Down
Loading