Commit 56976e60 authored by Eugene Kosov's avatar Eugene Kosov Committed by Marko Mäkelä

MDEV-13080 [ERROR] InnoDB: Missing MLOG_CHECKPOINT between the checkpoint x and the end y

log_buffer_extend(): Do not write to disk. Just allocate new bigger
buffer and copy contents of old one to it. Do not acquire write_mutex.

log_t::is_extending: Removed as unneeded now.

LOG_BUFFER_SIZE: Removed to make the dependence on srv_log_buffer_size
visible.
parent 409e210e
......@@ -411,8 +411,6 @@ extern my_bool innodb_log_checksums;
/* The counting of lsn's starts from this value: this must be non-zero */
#define LOG_START_LSN ((lsn_t) (16 * OS_FILE_LOG_BLOCK_SIZE))
#define LOG_BUFFER_SIZE (srv_log_buffer_size * UNIV_PAGE_SIZE)
/* Offsets of a log block header */
#define LOG_BLOCK_HDR_NO 0 /* block number which must be > 0 and
is allowed to wrap around at 2G; the
......@@ -644,8 +642,6 @@ struct log_t{
later; this is advanced when a flush
operation is completed to all the log
groups */
volatile bool is_extending; /*!< this is set to true during extend
the log buffer size */
lsn_t write_lsn; /*!< last written lsn */
lsn_t current_flush_lsn;/*!< end lsn for the current running
write + flush operation */
......
......@@ -169,89 +169,52 @@ void
log_buffer_extend(
ulint len)
{
ulint move_start;
ulint move_end;
byte tmp_buf[OS_FILE_LOG_BLOCK_SIZE];
const ulint new_log_buffer_size = (len >> srv_page_size_shift) + 1;
const ulint new_buf_size = (new_log_buffer_size
<< (srv_page_size_shift + 1))
+ OS_FILE_LOG_BLOCK_SIZE;
byte* new_buf_ptr = static_cast<byte*>(ut_malloc_nokey(new_buf_size));
log_mutex_enter_all();
while (log_sys->is_extending) {
/* Another thread is trying to extend already.
Needs to wait for. */
log_mutex_exit_all();
log_buffer_flush_to_disk();
log_mutex_enter();
log_mutex_enter_all();
const ulint size = srv_log_buffer_size << srv_page_size_shift;
if (srv_log_buffer_size > len / UNIV_PAGE_SIZE) {
if (len <= size) {
/* Already extended enough by the others */
log_mutex_exit_all();
log_mutex_exit();
ut_free(new_buf_ptr);
return;
}
}
if (len >= log_sys->buf_size / 2) {
DBUG_EXECUTE_IF("ib_log_buffer_is_short_crash",
DBUG_SUICIDE(););
/* log_buffer is too small. try to extend instead of crash. */
ib::warn() << "The transaction log size is too large"
" for innodb_log_buffer_size (" << len << " >= "
<< LOG_BUFFER_SIZE << " / 2). Trying to extend it.";
}
" for innodb_log_buffer_size (" << len
<< " >= " << size << " / 2). Trying to extend it.";
log_sys->is_extending = true;
byte* old_buf_ptr = log_sys->buf_ptr;
const byte* begin = log_sys->buf;
const byte* end = begin + log_sys->buf_free;
while ((log_sys->buf_free ^ log_sys->buf_next_to_write)
& (OS_FILE_LOG_BLOCK_SIZE - 1)) {
/* Buffer might have >1 blocks to write still. */
log_mutex_exit_all();
log_buffer_flush_to_disk();
log_sys->buf_ptr = new_buf_ptr;
srv_log_buffer_size = new_log_buffer_size;
log_sys->buf_size = size;
log_sys->buf
= static_cast<byte*>(ut_align(new_buf_ptr, OS_FILE_LOG_BLOCK_SIZE));
log_mutex_enter_all();
if (!log_sys->first_in_use) {
log_sys->buf += size;
}
move_start = ut_2pow_round(log_sys->buf_free,
ulint(OS_FILE_LOG_BLOCK_SIZE));
move_end = log_sys->buf_free;
/* store the last log block in buffer */
ut_memcpy(tmp_buf, log_sys->buf + move_start,
move_end - move_start);
log_sys->buf_free -= move_start;
log_sys->buf_next_to_write -= move_start;
/* reallocate log buffer */
srv_log_buffer_size = len / UNIV_PAGE_SIZE + 1;
ut_free(log_sys->buf_ptr);
log_sys->buf_size = LOG_BUFFER_SIZE;
log_sys->buf_ptr = static_cast<byte*>(
ut_zalloc_nokey(log_sys->buf_size * 2 + OS_FILE_LOG_BLOCK_SIZE));
TRASH_ALLOC(log_sys->buf_ptr,
log_sys->buf_size * 2 + OS_FILE_LOG_BLOCK_SIZE);
log_sys->buf = static_cast<byte*>(
ut_align(log_sys->buf_ptr, OS_FILE_LOG_BLOCK_SIZE));
log_sys->first_in_use = true;
memcpy(log_sys->buf, begin, end - begin);
log_sys->max_buf_free = log_sys->buf_size / LOG_BUF_FLUSH_RATIO
log_sys->max_buf_free = size / LOG_BUF_FLUSH_RATIO
- LOG_BUF_FLUSH_MARGIN;
/* restore the last log block */
ut_memcpy(log_sys->buf, tmp_buf, move_end - move_start);
ut_ad(log_sys->is_extending);
log_sys->is_extending = false;
log_mutex_exit();
log_mutex_exit_all();
ut_free(old_buf_ptr);
ib::info() << "innodb_log_buffer_size was extended to "
<< LOG_BUFFER_SIZE << ".";
<< size << ".";
}
/** Calculate actual length in redo buffer and file including
......@@ -360,20 +323,6 @@ log_reserve_and_open(
loop:
ut_ad(log_mutex_own());
if (log_sys->is_extending) {
log_mutex_exit();
/* Log buffer size is extending. Writing up to the next block
should wait for the extending finished. */
os_thread_sleep(100000);
ut_ad(++count < 50);
log_mutex_enter();
goto loop;
}
/* Calculate an upper limit for the space the string may take in the
log buffer */
......@@ -718,10 +667,9 @@ log_sys_init()
log_sys->lsn = LOG_START_LSN;
ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE);
ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);
ut_ad(srv_log_buffer_size >= 4);
log_sys->buf_size = LOG_BUFFER_SIZE;
log_sys->buf_size = srv_log_buffer_size << srv_page_size_shift;
log_sys->buf_ptr = static_cast<byte*>(
ut_zalloc_nokey(log_sys->buf_size * 2 + OS_FILE_LOG_BLOCK_SIZE));
......
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