Commit 881918bf authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-27754 : Assertion with innodb_flush_method=O_DSYNC

If innodb_flush_method=O_DSYNC, log_sys.flushed_to_disk_lsn  is changed
without 'flush_lock' protection inside log_write().

This leads to a race condition, if there are 2 threads running in parallel,
doing log_write_up_to() with different values for 'flush_to_disk'

In this case, log_write() and log_write_flush_to_disk_low() can execute at
the same time, and both would change flushed_lsn.

The fix is to remove special treatment of durable writes from log_write().
There is no apparent reason for this special treatment, log_write_flush_to_disk_low()
is already optimized for durable writes.

Nor there is an apparent reason to call log_flush_notify() more often in
for O_DSYNC.
parent fb40a2fa
...@@ -639,8 +639,7 @@ log_write_buf( ...@@ -639,8 +639,7 @@ log_write_buf(
} }
} }
/** Flush the recently written changes to the log file. /** Flush the recently written changes to the log file.*/
and invoke mysql_mutex_lock(&log_sys.mutex). */
static void log_write_flush_to_disk_low(lsn_t lsn) static void log_write_flush_to_disk_low(lsn_t lsn)
{ {
if (!log_sys.log.writes_are_durable()) if (!log_sys.log.writes_are_durable())
...@@ -780,10 +779,6 @@ static void log_write(bool rotate_key) ...@@ -780,10 +779,6 @@ static void log_write(bool rotate_key)
start_offset - area_start); start_offset - area_start);
srv_stats.log_padded.add(pad_size); srv_stats.log_padded.add(pad_size);
log_sys.write_lsn = write_lsn; log_sys.write_lsn = write_lsn;
if (log_sys.log.writes_are_durable()) {
log_sys.set_flushed_lsn(write_lsn);
log_flush_notify(write_lsn);
}
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment