diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d90038d44a9e1..6e00e322955c8 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3697,7 +3697,7 @@ static MYSQL_SYSVAR_SIZE_T(buffer_pool_size_max, buf_pool.size_in_bytes_max, static MYSQL_SYSVAR_UINT(log_write_ahead_size, log_sys.write_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Redo log write size to avoid read-on-write; must be a power of two", - nullptr, nullptr, 512, 512, 4096, 1); + nullptr, nullptr, 512, 512, log_sys.WRITE_SIZE_MAX, 1); /****************************************************************//** Gives the file extension of an InnoDB single-table tablespace. */ diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 7685fce733383..b728ac8d823bd 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -268,6 +268,8 @@ struct log_t public: /** current innodb_log_write_ahead_size */ uint write_size; + /** maximum write_size */ + static constexpr uint WRITE_SIZE_MAX{4096}; /** format of the redo log: e.g., FORMAT_10_8 */ uint32_t format; /** whether the memory-mapped interface is enabled for the log */ diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 072e8696cf82c..f9afd462a724a 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1247,22 +1247,31 @@ void log_t::clear_mmap() noexcept ut_ad(write_lsn == get_lsn()); ut_ad(write_lsn == get_flushed_lsn(std::memory_order_relaxed)); - if (buf) /* this may be invoked while creating a new database */ { - alignas(16) byte log_block[4096]; - const size_t bs{write_size}; + if (buf) /* this may be invoked while creating a new database */ { - const size_t bf= - size_t(write_lsn - base_lsn.load(std::memory_order_relaxed)); - memcpy_aligned<16>(log_block, buf + (bf & ~(bs - 1)), bs); - } + alignas(16) byte log_block[log_t::WRITE_SIZE_MAX]; + const size_t bs{write_size}; + { + ut_ad(write_lsn >= first_lsn); + uint64_t bf{write_lsn - first_lsn}; + if (bf > capacity()) + bf%= capacity(); + bf+= START_OFFSET; + const size_t bs_1{bs - 1}; + write_lsn_offset= bf & bs_1; + base_lsn.store(write_lsn - write_lsn_offset, + std::memory_order_relaxed); + memcpy_aligned<16>(log_block, buf + (bf & ~uint64_t{bs_1}), bs); + } - close_file(false); - log_mmap= false; - ut_a(attach(log, file_size)); - ut_ad(!is_mmap()); + close_file(false); + log_mmap= false; + ut_a(attach(log, file_size)); + ut_ad(!is_mmap()); - memcpy_aligned<16>(buf, log_block, bs); + memcpy_aligned<16>(buf, log_block, bs); + } } log_resize_release(); }