diff options
author | Brandon Nesterenko <brandon.nesterenko@mariadb.com> | 2021-05-21 14:53:43 -0600 |
---|---|---|
committer | Brandon Nesterenko <brandon.nesterenko@mariadb.com> | 2021-08-13 10:53:19 -0600 |
commit | 46c3e7e3537c31a94289033bfeccf3faf8d4069e (patch) | |
tree | 5c676e739db8272f3b25fa2e93d5344898a43a0d /sql/sql_repl.cc | |
parent | 38b79d7295e7a9ed2e4fdd72e6a63505a32c806f (diff) | |
download | mariadb-git-46c3e7e3537c31a94289033bfeccf3faf8d4069e.tar.gz |
MDEV-20215: binlog.show_concurrent_rotate failed in buildbot with wrong result
Problem:
=======
There are two issues that are addressed in this patch:
1) SHOW BINARY LOGS uses caching to store the binary logs that exist
in the log directory; however, if new events are written to the logs,
the caching strategy is unaware. This is okay for users, as it is
okay for SHOW to return slightly old data. The test, however, can
result in inconsistent data. It runs two connections concurrently,
where one shows the logs, and the other adds a new file. The output
of SHOW BINARY LOGS then depends on when the cache is built, with
respect to the time that the second connection rotates the logs.
2) There is a race condition between RESET MASTER and SHOW BINARY
LOGS. More specifically, where they both need the binary log lock to
begin, SHOW BINARY LOGS only needs the lock to build its cache. If
RESET MASTER is issued after SHOW BINARY LOGS has built its cache and
before it has returned the results, the presented data may be
incorrect.
Solution:
========
1) As it is okay for users to see stale data, to make the test
consistent, use DEBUG_SYNC to force the race condition (problem 2) to
make SHOW BINARY LOGS build a cache before RESET MASTER is called.
Then, use additional logic from the next part of the solution to
rebuild the cache.
2) Use an Atomic_counter to keep track of the number of times RESET
MASTER has been called. If the value of the counter changes after
building the cache, the cache should be rebuilt and the analysis
should be restarted.
Reviewed By:
============
Andrei Elkin: <andrei.elkin@mariadb.com>
Diffstat (limited to 'sql/sql_repl.cc')
-rw-r--r-- | sql/sql_repl.cc | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 841ff561502..e96129465fe 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -4374,6 +4374,7 @@ bool show_binlogs(THD* thd) Protocol *protocol= thd->protocol; uint retry_count= 0; size_t cur_dir_len; + uint64 expected_reset_masters; DBUG_ENTER("show_binlogs"); if (!mysql_bin_log.is_open()) @@ -4399,6 +4400,7 @@ retry: mysql_mutex_lock(mysql_bin_log.get_log_lock()); mysql_bin_log.lock_index(); mysql_bin_log.raw_get_current_log(&cur); + expected_reset_masters= mysql_bin_log.get_reset_master_count(); mysql_mutex_unlock(mysql_bin_log.get_log_lock()); /* The following call unlocks lock_index */ @@ -4419,6 +4421,16 @@ retry: cur_link->name.str+= dir_len; cur_link->name.length-= dir_len; + if (mysql_bin_log.get_reset_master_count() > expected_reset_masters) + { + /* + Reset master was called after we cached filenames. + Reinitialize the cache. + */ + free_root(&mem_root, MYF(MY_MARK_BLOCKS_FREE)); + goto retry; + } + if (!(strncmp(fname+dir_len, cur.log_file_name+cur_dir_len, length))) cur_link->size= cur.pos; /* The active log, use the active position */ else |