Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions sql/rpl_info_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -250,15 +258,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 (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
Expand All @@ -272,14 +280,15 @@ struct Info_file
@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:
Expand Down Expand Up @@ -336,7 +345,6 @@ 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);
my_b_seek(&file, 0);
/*
If the new contents take less space than the previous file contents,
Expand All @@ -355,10 +363,10 @@ 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)
while (--total_line_count > size)
my_b_write_byte(&file, '\n');
}

Expand Down
24 changes: 23 additions & 1 deletion sql/rpl_master_info_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{

Expand Down Expand Up @@ -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;
Comment on lines +548 to +560

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Naming the unnamed struct Line_count_fix_t improves code readability and avoids potential compiler-specific issues with unnamed classes overriding virtual functions or being used in template-based pointer-to-member wrappers. Additionally, there is a minor typo in the comment: 'use common code' should be 'use of common code'.

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 of 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 Line_count_fix_t : 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,
Expand All @@ -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
};

/**
Expand Down
1 change: 1 addition & 0 deletions sql/rpl_relay_log_info_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
/**
Expand Down