From 6d182c9ce59080956eb337a3a0c858364fab7d5f Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Sun, 28 Jun 2026 13:01:44 -0600 Subject: [PATCH 1/2] Test for MDEV-39788 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MDEV-39788 found that the recent refactor on the `main` (now 12.3) branch missed the (inconsistent) detail that, unlike `@@relay_log_info`, `@@master_info`’s line count _includes_ the line-count line itself. This commit extends and simplifies the test `rpl.rpl_read_new_relay_log_info` to `main.rpl_read_new_info` so it * Checks this detail to remind future changes of this type of mistake. * Covers `@@master_info` as well. While here, this commit also includes a new-format version of MDEV-38020’s test to double as the value read check. --- debian/mariadb-test-data.lintian-overrides | 1 + mysql-test/main/rpl_read_new_info.result | 10 ++++ mysql-test/main/rpl_read_new_info.test | 41 ++++++++++++++++ mysql-test/std_data/new-format-master.info | 34 +++++++++++++ .../std_data/new-format-relay-log-win.info | 8 ++-- mysql-test/std_data/new-format-relay-log.info | 8 ++-- .../rpl/r/rpl_read_new_relay_log_info.result | 15 ------ .../rpl/t/rpl_read_new_relay_log_info.test | 48 ------------------- 8 files changed, 94 insertions(+), 71 deletions(-) create mode 100644 mysql-test/main/rpl_read_new_info.result create mode 100644 mysql-test/main/rpl_read_new_info.test create mode 100644 mysql-test/std_data/new-format-master.info delete mode 100644 mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result delete mode 100644 mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test diff --git a/debian/mariadb-test-data.lintian-overrides b/debian/mariadb-test-data.lintian-overrides index cbd77e0283090..fd868b03c3d9e 100644 --- a/debian/mariadb-test-data.lintian-overrides +++ b/debian/mariadb-test-data.lintian-overrides @@ -411,6 +411,7 @@ package-contains-documentation-outside-usr-share-doc [usr/share/mysql/mysql-test package-contains-documentation-outside-usr-share-doc [usr/share/mysql/mysql-test/std_data/mariadb-conv/file01.utf8.txt] package-contains-documentation-outside-usr-share-doc [usr/share/mysql/mysql-test/std_data/mariadb-conv/file02.latin1.txt] package-contains-documentation-outside-usr-share-doc [usr/share/mysql/mysql-test/std_data/mysql5613mysql/README] +package-contains-documentation-outside-usr-share-doc [usr/share/mysql/mysql-test/std_data/new-format-master.info] package-contains-documentation-outside-usr-share-doc [usr/share/mysql/mysql-test/std_data/new-format-relay-log-win.info] package-contains-documentation-outside-usr-share-doc [usr/share/mysql/mysql-test/std_data/new-format-relay-log.info] package-contains-documentation-outside-usr-share-doc [usr/share/mysql/mysql-test/std_data/numbers.txt] diff --git a/mysql-test/main/rpl_read_new_info.result b/mysql-test/main/rpl_read_new_info.result new file mode 100644 index 0000000000000..09a866b1eeed7 --- /dev/null +++ b/mysql-test/main/rpl_read_new_info.result @@ -0,0 +1,10 @@ +CHANGE MASTER TO master_host='127.0.0.1'; +# restart: --skip-slave-start +Master_Log_File = 'mysqld-bin.000002' +Read_Master_Log_Pos = '2147483648' +Master_SSL_Key = '' +Using_Gtid = 'Current_Pos' +Relay_Master_Log_File = 'mysqld-bin.000001' +Exec_Master_Log_Pos = '2147483648' +SQL_Delay = '5' +RESET SLAVE ALL; diff --git a/mysql-test/main/rpl_read_new_info.test b/mysql-test/main/rpl_read_new_info.test new file mode 100644 index 0000000000000..e2074b0a6412a --- /dev/null +++ b/mysql-test/main/rpl_read_new_info.test @@ -0,0 +1,41 @@ +# Verify that the post-WL#344 format of `*.info` can be parsed. +# * Verify that the line count includes the line-count line in +# `@@master_info_file` while excludes it in `@@relay_log_info_file` +# (Reference: MDEV-39788 master.info is read and +# written one line too many compared to before) +# * Verify that position values > 2^31 can be read +# (MDEV-38020: Master & relay log info files read 2^31 and above incorrectly) + +--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` + +# the new version of relay_log.info comes in two versions: with path +# separator '/' (most systems) and with path separator '\' (windows) +if ($SYSTEM_PATH_SEPARATOR != /) { + --let $file_suffix= -win +} + + +--source include/shutdown_mysqld.inc + + --remove_file $MYSQLD_DATADIR/master.info + # `Using_Gtid` is the key-value section, not the 33rd option. + --copy_file $MYSQL_TEST_DIR/std_data/new-format-master.info $MYSQLD_DATADIR/master.info + + # Check that the 5th option (`SQL_Delay`) is included. + --remove_file $MYSQLD_DATADIR/relay-log.info + --copy_file $MYSQL_TEST_DIR/std_data/new-format-relay-log$file_suffix.info $MYSQLD_DATADIR/relay-log.info + +--let $restart_parameters= --skip-slave-start +--source include/start_mysqld.inc + +--let $status_items= Master_Log_File, Read_Master_Log_Pos, Master_SSL_Key, Using_Gtid, Relay_Master_Log_File, Exec_Master_Log_Pos, SQL_Delay +--source include/show_slave_status.inc + + +# Reset +--disable_warnings + RESET SLAVE ALL; +--enable_warnings diff --git a/mysql-test/std_data/new-format-master.info b/mysql-test/std_data/new-format-master.info new file mode 100644 index 0000000000000..5048b1ed1dc39 --- /dev/null +++ b/mysql-test/std_data/new-format-master.info @@ -0,0 +1,34 @@ +33 +mysqld-bin.000002 +2147483648 +127.0.0.1 +root + +3306 +60 +1 + + + + + +1 +60.000 + +0 + +100000 + + + + + + + + + + + + + +using_gtid=1 diff --git a/mysql-test/std_data/new-format-relay-log-win.info b/mysql-test/std_data/new-format-relay-log-win.info index e00383b556512..2c1b588422b20 100644 --- a/mysql-test/std_data/new-format-relay-log-win.info +++ b/mysql-test/std_data/new-format-relay-log-win.info @@ -1,6 +1,6 @@ 5 -.\slave-relay-bin.000001 +.\mysqld-relay-bin.000001 4 - -0 -0 +mysqld-bin.000001 +2147483648 +5 diff --git a/mysql-test/std_data/new-format-relay-log.info b/mysql-test/std_data/new-format-relay-log.info index 883dec1f66b6b..a6ade93dce9a9 100644 --- a/mysql-test/std_data/new-format-relay-log.info +++ b/mysql-test/std_data/new-format-relay-log.info @@ -1,6 +1,6 @@ 5 -./slave-relay-bin.000001 +./mysqld-relay-bin.000001 4 - -0 -0 +mysqld-bin.000001 +2147483648 +5 diff --git a/mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result b/mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result deleted file mode 100644 index e193a7e1126c2..0000000000000 --- a/mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result +++ /dev/null @@ -1,15 +0,0 @@ -include/master-slave.inc -[connection master] -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (1); -DROP TABLE t1; -connection slave; -==== Check that we can understand the new format of relay-log.info ==== -include/stop_slave.inc -include/reset_slave.inc -# Read relay-log.info -START SLAVE IO_THREAD; -include/wait_for_slave_io_to_start.inc -# Check that relay log coordinates are equal to those saved in new-format_relay-log.info -= , 0, slave-relay-bin.000001, 4 -include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test b/mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test deleted file mode 100644 index 350071bf3dc7a..0000000000000 --- a/mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test +++ /dev/null @@ -1,48 +0,0 @@ -# ==== Purpose ==== -# -# - Verify that the post-WL#344 format of relay_log.info can be parsed. - ---source include/master-slave.inc - -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (1); -DROP TABLE t1; ---sync_slave_with_master - ---echo ==== Check that we can understand the new format of relay-log.info ==== ---source include/stop_slave.inc - ---let $master_use_gtid_option= No ---source include/reset_slave.inc ---let $MYSQLD_DATADIR= `select @@datadir` - -# the new version of relay_log.info comes in two versions: with path -# separator '/' (most systems) and with path separator '\' (windows) -if ($SYSTEM_PATH_SEPARATOR != /) { - --let $file_suffix= -win -} - -# MDEV-19801 changed the default Using_Gtid to Slave_Pos which doesn't -# automatically purge relay-log.info ---remove_file $MYSQLD_DATADIR/relay-log.info ---copy_file $MYSQL_TEST_DIR/std_data/new-format-relay-log$file_suffix.info $MYSQLD_DATADIR/relay-log.info - ---echo # Read relay-log.info -START SLAVE IO_THREAD; ---source include/wait_for_slave_io_to_start.inc ---echo # Check that relay log coordinates are equal to those saved in new-format_relay-log.info ---let $master_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1) ---let $master_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) ---let $relay_log_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) ---let $relay_log_pos= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) ---echo $master_file= $master_file, $master_pos, $relay_log_file, $relay_log_pos -if (`SELECT "$master_file" != "" OR - "$master_pos" != "0" OR - "$relay_log_file" != "slave-relay-bin.000001" OR - "$relay_log_pos" != "4"`) { - --echo ERROR: log coordinates changed - --die log coordinates changed -} - ---let $rpl_only_running_threads= 1 ---source include/rpl_end.inc From 972e1cbaafd2c4a151135090713959e0e4a5706c Mon Sep 17 00:00:00 2001 From: ParadoxV5 Date: Mon, 29 Jun 2026 18:20:35 -0600 Subject: [PATCH 2/2] MDEV-39788: Fix `master.info` not upgrading `master_use_gtid` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The line-count line in `master.info` and `relay-log.info` has been inconsistent (off by one) since its introduction. MDEV-37530 corrected this by changing `master.info` to use `relay-log.info`’s line-count definition by chance, but at the cost of an upgrade incompatibility. It now reads one more line beyond the pre-upgraded file’s line-based section, which for MariaDB 10.0–12.2 means an upgrade doesn’t carry over the first option stored in `key=value`, `master_use_gtid`. Since older versions can read the new format in a downgrade, rather than encouraging the old inconsistency, this commit focuses on the upgrade problem by adding a shim entry to `master.info`’s list to emulate prior versions’ reading behaviour. Although this implementation can only restore compatibility with versions 10.0+, versions before MariaDB 10 have long been EOL. While here, this commit also fixes code and comments that contradict the actual effect. --- sql/rpl_info_file.h | 26 +++++++++++--------------- sql/rpl_master_info_file.h | 23 ++++++++++++++++++++++- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/sql/rpl_info_file.h b/sql/rpl_info_file.h index 493598f7bf5a8..16d5f587f9797 100644 --- a/sql/rpl_info_file.h +++ b/sql/rpl_info_file.h @@ -250,15 +250,15 @@ struct Info_file (Re)load the MySQL line-based section from the @ref file @param value_list List of wrapped member pointers to values. The first element must be a - file name @ref String_value to be unambiguous with the line count line. + file name @ref String_value to be unambiguous with the line-count line. @param default_line_count We cannot simply read lines until EOF as all versions of MySQL/MariaDB may generate more lines than needed. Therefore, starting with MySQL/MariaDB 4.1.x for @ref Master_info_file and - 5.6.x for @ref Relay_log_info_file, the first line of the file is number - of one-line-per-value lines in the file, including this line count itself. + 5.6.x/10.0.x for @ref Relay_log_info_file, the first line of the file is + the number of one-line-per-value lines in the file. This parameter specifies the number of effective lines before those - versions (i.e., not counting the line count line if it was to have one), + versions (i.e., not counting the line-count line if it was to have one), where the first line is a filename with extension (either contains a `.` or is entirely empty) rather than an integer. @return `false` if the file has parsed successfully or `true` if error @@ -273,13 +273,13 @@ struct Info_file @param total_line_count The number of lines to describe the file as on the first line of the file. If this is larger than `value_list.size()`, suffix the file with empty - lines until the line count (including the line count line) is this many. - This reservation provides compatibility with MySQL, - who has added more old-style lines while MariaDB innovated. + lines until the line count (*excluding* the line-count line) is this many. + This reservation provides compatibility + with older versions of MySQL and MariaDB. */ template void save_to_file( const Mem_fn (&value_list)[size], - size_t total_line_count= size + /* line count line */ 1 + size_t total_line_count= size ) { return save_to_file(value_list, size, total_line_count); } private: @@ -336,7 +336,7 @@ struct Info_file void save_to_file(const Mem_fn *values, size_t size, size_t total_line_count) { - DBUG_ASSERT(total_line_count > size); + DBUG_ASSERT(total_line_count >= size); my_b_seek(&file, 0); /* If the new contents take less space than the previous file contents, @@ -353,12 +353,8 @@ struct Info_file pm(this).save_to(&file); my_b_write_byte(&file, '\n'); } - /* - Pad additional reserved lines: - (1 for the line count line + line count) inclusive -> max line inclusive - = line count exclusive <- max line inclusive - */ - for (; total_line_count > size; --total_line_count) + // Pad additional reserved lines + for (; size < total_line_count; ++size) my_b_write_byte(&file, '\n'); } diff --git a/sql/rpl_master_info_file.h b/sql/rpl_master_info_file.h index 292f6469b6c69..c3fd97745d5b4 100644 --- a/sql/rpl_master_info_file.h +++ b/sql/rpl_master_info_file.h @@ -540,6 +540,25 @@ struct Master_info_file: Info_file /// }@ +protected: + /** + @ref Master_info_file has been inconsistent that its line count included + the line-count "value", while @ref Relay_log_info_file's excludes it. + Although the use common code now makes @ref Master_info_file match, + files from older versions are now off-by-one to Info_file::load_from_file(). + The presence of this non-reading pseudo-value restores + compatibility with files generated by MariaDB 10.0+, + as the driver loop will increment the line counter for it, + thus emulating counting the line-count "value". + @deprecated This is not needed after all pre-12.3 versions go EoL. + */ + struct: Persistent + { + bool load_from(IO_CACHE *file) override { return false; } ///< No-op + void save_to(IO_CACHE *file) override {} ///< No-op + } LINE_COUNT_FIX; +public: + inline static const Mem_fn VALUE_LIST[] { &Master_info_file::master_log_file, &Master_info_file::master_log_pos, @@ -561,7 +580,9 @@ struct Master_info_file: Info_file nullptr, // MySQL `master_uuid`, which MariaDB ignores. &Master_info_file::master_retry_count, &Master_info_file::master_ssl_crl, - &Master_info_file::master_ssl_crlpath + &Master_info_file::master_ssl_crlpath, + // This must be last, so its blank line blend into trailing blank line(s). + &Master_info_file::LINE_COUNT_FIX }; /**