Bug #76901 binlog_max_flush_queue_time variable is not used in current MySQL 5.7
Submitted: 30 Apr 2015 9:42 Modified: 25 Aug 2015 10:19
Reporter: Valeriy Kravchuk Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Options Severity:S3 (Non-critical)
Version:5.7.6 OS:Any
Assigned to: CPU Architecture:Any
Tags: binlog_max_flush_queue_time

[30 Apr 2015 9:42] Valeriy Kravchuk
Description:
Manual (http://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html#sysvar_binlog_m...) still says:

"How long in microseconds to keep reading transactions from the flush queue before proceeding with the group commit (and syncing the log to disk, if sync_binlog is greater than 0). If the value is 0 (the default), there is no timeout and the server keeps reading new transactions until the queue is empty."

and it says nothing about deprecation or change 9text is the same as for 5.6).

But look at the code:

[openxs@centos mysql-server]$ grep -rn flush_queue_time * | grep -v mysql-test
sql/mysqld.cc:454:int32 opt_binlog_max_flush_queue_time= 0;
sql/sys_vars.cc:730:static Sys_var_int32 Sys_binlog_max_flush_queue_time(
sql/sys_vars.cc:731:       "binlog_max_flush_queue_time",
sql/sys_vars.cc:735:       GLOBAL_VAR(opt_binlog_max_flush_queue_time),
sql/mysqld.h:234:extern int32 opt_binlog_max_flush_queue_time;
[openxs@centos mysql-server]$

The variable is recognized and set, but never used. In 5.6 it was used (from similar grep):

...
sql/binlog.cc:6839:  my_atomic_rwlock_rdlock(&opt_binlog_max_flush_queue_time_lock);
sql/binlog.cc:6840:  const ulonglong max_udelay= my_atomic_load32(&opt_binlog_max_flush_queue_time);
sql/binlog.cc:6841:  my_atomic_rwlock_rdunlock(&opt_binlog_max_flush_queue_time_lock);
...

in the MYSQL_BIN_LOG:::process_flush_stage_queue() function:

...
6839   my_atomic_rwlock_rdlock(&opt_binlog_max_flush_queue_time_lock);
6840   const ulonglong max_udelay= my_atomic_load32(&opt_binlog_max_flush_queue_     time);
6841   my_atomic_rwlock_rdunlock(&opt_binlog_max_flush_queue_time_lock);
6842   const ulonglong start_utime= max_udelay > 0 ? my_micro_time() : 0;
6843
6844   /*
6845     First we read the queue until it either is empty or the difference
6846     between the time we started and the current time is too large.
6847
6848     We remember the first thread we unqueued, because this will be the
6849     beginning of the out queue.
6850    */
6851   bool has_more= true;
6852   THD *first_seen= NULL;
6853   while ((max_udelay == 0 || my_micro_time() < start_utime + max_udelay) &&      has_more)
6854   {
6855     std::pair<bool,THD*> current= stage_manager.pop_front(Stage_manager::FL     USH_STAGE);
6856     std::pair<int,my_off_t> result= flush_thread_caches(current.second);
...

But in 5.7 this function looks different:

int
MYSQL_BIN_LOG::process_flush_stage_queue(my_off_t *total_bytes_var,
                                         bool *rotate_var,
                                         THD **out_queue_var)
{
  DBUG_ENTER("MYSQL_BIN_LOG::process_flush_stage_queue");
  #ifndef DBUG_OFF
  // number of flushes per group.
  int no_flushes= 0;
  #endif
  DBUG_ASSERT(total_bytes_var && rotate_var && out_queue_var);
  my_off_t total_bytes= 0;
  int flush_error= 1;
  mysql_mutex_assert_owner(&LOCK_log);

  /*
    Fetch the entire flush queue and empty it, so that the next batch
    has a leader. We must do this before invoking ha_flush_logs(...)
    for guaranteeing to flush prepared records of transactions before
    flushing them to binary log, which is required by crash recovery.
  */
  THD *first_seen= stage_manager.fetch_queue_for(Stage_manager::FLUSH_STAGE);
  DBUG_ASSERT(first_seen != NULL);
...

So, the code in 5.7 is totally different and it does not rely on the variable any more.

How to repeat:
Read the code and try to find out where and how binlog_max_flush_queue_time variable is used in MySQL 5.7. Then compare your findings to what manual says about it.

Suggested fix:
Please, fix the manual to describe current implementation. If it's not final, still add a note explaining that in current MySQL 5.7 the variable is just ignored.
[3 May 2015 13:00] MySQL Verification Team
Hello Valeriy,

Thank you for the report.

Thanks,
Umesh
[12 Aug 2015 8:04] Jon Stephens
A developer who is familiar with the code needs to confirm that the behaviour described is intentional. Otherwise this is a Server bug and needs to be fixed.

Since I don't see that this has been done, I'm setting this back to Open for further analysis.

Please do not return to Docs unless the *origin* of the problem can be shown to lie with the docs, and not with the code. Thanks!
[25 Aug 2015 10:19] Erlend Dahl
Fixed in 5.7.9 through WL#8756 "Deprecate binlog_max_flush_queue_time in 5.7".