diff --git a/sql/rpl_info_file.h b/sql/rpl_info_file.h index 493598f7bf5a8..e61fa833a043f 100644 --- a/sql/rpl_info_file.h +++ b/sql/rpl_info_file.h @@ -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 @@ 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 @@ -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 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 @@ 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, @@ -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'); } diff --git a/sql/rpl_master_info_file.h b/sql/rpl_master_info_file.h index 292f6469b6c69..e49d0f9c55ca5 100644 --- a/sql/rpl_master_info_file.h +++ b/sql/rpl_master_info_file.h @@ -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 }; /** diff --git a/sql/rpl_relay_log_info_file.h b/sql/rpl_relay_log_info_file.h index 3dbfb2028d14a..9316ad3d42637 100644 --- a/sql/rpl_relay_log_info_file.h +++ b/sql/rpl_relay_log_info_file.h @@ -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 { /**