1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-39788: Remove added line in master.info format

The line-count lines in `master.info` and `relay-log.info`
have been inconsistent (off by one) since their introduction.
MDEV-37530 “fixed” this with its common code merger by chance,
changing `master.info` to use `relay-log.info`’s line-count definition.
This change, howëver, affected backward compatibility,
as `master.info` now expects an ignored MySQL-only line
where the first `key=value` option, `master_use_gtid`, is.

Since this legacy text-based format has limitations that make
it due for replacement, only code reüsablility is valuable,
and its consistency does not outweigh its compatibility.
Therefore, this commit solves this problem without reverting code by:
* Changing the writing code to be compatible with both interpretations
  (albeit inconsistent with the reading code)
* Adding a shim entry to `master.info`’s list
  to emulate prior versions’ reading behaviour
  * Although this solution can only restore upgrade 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.

[P.S.] The test for this regression is pushed to 10.11 in PR #5147.

Reviewed-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
This commit is contained in:
ParadoxV5
2026-07-14 22:52:36 -06:00
parent 9b075b2cb5
commit 8436fe3f48
3 changed files with 45 additions and 14 deletions

View File

@@ -131,6 +131,14 @@ namespace Int_IO_CACHE
Other files may include these files directly.
[C++20 modules](https://en.cppreference.com/w/cpp/language/modules.html)
can supercede the header-only design as well as headers' `#include` guards.
@note
It's an old inconsistency that @ref Master_info_file's line count includes
the line-count "value" while @ref Relay_log_info_file's excludes it.
This is reason that Info_file::load_from_file() and
Info_file::save_to_file() defines the line-count lines differently -
It is so the two subclasses can implement either interpretation
on top of the indifferent common code in this superclass.
*/
struct Info_file
{
@@ -250,15 +258,15 @@ protected:
(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 (excluding itself) 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
@@ -272,14 +280,15 @@ protected:
@param value_list List of wrapped member pointers to values.
@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.
If this is larger than `size`, suffix the file with empty
lines until the line count (*including* the line-count line) is this many.
(No correction is done if it is less than `size` + 1 for the line-count.)
This reservation provides compatibility
with older versions of MySQL and MariaDB.
*/
template<size_t size> 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 +345,6 @@ private:
void save_to_file(const Mem_fn *values, size_t size, size_t total_line_count)
{
DBUG_ASSERT(total_line_count > size);
my_b_seek(&file, 0);
/*
If the new contents take less space than the previous file contents,
@@ -355,10 +363,10 @@ private:
}
/*
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)
while (--total_line_count > size)
my_b_write_byte(&file, '\n');
}

View File

@@ -88,6 +88,11 @@ inline uint64_t master_retry_count= 100000;
/// }@
/**
@note The line count includes the line-count line.
Master_info_file::load_from_file() implements this
using @ref Master_info_file::LINE_COUNT_FIX.
*/
struct Master_info_file: Info_file
{
@@ -540,6 +545,21 @@ struct Master_info_file: Info_file
/// }@
protected:
/**
Info_file::load_from_file() does not include
the line-count "value" in the line count.
The Master_info_file::load_from_file() overload utilizes the presence
of this no-op pseudo-value to emulating counting the line-count "value" -
The driver loop will increment the line counter while this reads nothing.
*/
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 +581,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
};
/**

View File

@@ -20,6 +20,7 @@
#include "rpl_info_file.h"
/// @note The line count excludes the line-count line.
struct Relay_log_info_file: Info_file
{
/**