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; ...@@ -411,8 +411,6 @@ extern my_bool innodb_log_checksums;
/* The counting of lsn's starts from this value: this must be non-zero */ /* 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_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 */ /* Offsets of a log block header */
#define LOG_BLOCK_HDR_NO 0 /* block number which must be > 0 and #define LOG_BLOCK_HDR_NO 0 /* block number which must be > 0 and
is allowed to wrap around at 2G; the is allowed to wrap around at 2G; the
...@@ -644,8 +642,6 @@ struct log_t{ ...@@ -644,8 +642,6 @@ struct log_t{
later; this is advanced when a flush later; this is advanced when a flush
operation is completed to all the log operation is completed to all the log
groups */ 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 write_lsn; /*!< last written lsn */
lsn_t current_flush_lsn;/*!< end lsn for the current running lsn_t current_flush_lsn;/*!< end lsn for the current running
write + flush operation */ write + flush operation */
......
...@@ -169,89 +169,52 @@ void ...@@ -169,89 +169,52 @@ void
log_buffer_extend( log_buffer_extend(
ulint len) ulint len)
{ {
ulint move_start; const ulint new_log_buffer_size = (len >> srv_page_size_shift) + 1;
ulint move_end; const ulint new_buf_size = (new_log_buffer_size
byte tmp_buf[OS_FILE_LOG_BLOCK_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(); log_mutex_enter();
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_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 */ /* Already extended enough by the others */
log_mutex_exit_all(); log_mutex_exit();
ut_free(new_buf_ptr);
return; 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" ib::warn() << "The transaction log size is too large"
" for innodb_log_buffer_size (" << len << " >= " " for innodb_log_buffer_size (" << len
<< LOG_BUFFER_SIZE << " / 2). Trying to extend it."; << " >= " << 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) log_sys->buf_ptr = new_buf_ptr;
& (OS_FILE_LOG_BLOCK_SIZE - 1)) { srv_log_buffer_size = new_log_buffer_size;
/* Buffer might have >1 blocks to write still. */ log_sys->buf_size = size;
log_mutex_exit_all(); log_sys->buf
= static_cast<byte*>(ut_align(new_buf_ptr, OS_FILE_LOG_BLOCK_SIZE));
log_buffer_flush_to_disk();
log_mutex_enter_all(); if (!log_sys->first_in_use) {
log_sys->buf += size;
} }
move_start = ut_2pow_round(log_sys->buf_free, memcpy(log_sys->buf, begin, end - begin);
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;
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; - LOG_BUF_FLUSH_MARGIN;
/* restore the last log block */ log_mutex_exit();
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_all(); ut_free(old_buf_ptr);
ib::info() << "innodb_log_buffer_size was extended to " ib::info() << "innodb_log_buffer_size was extended to "
<< LOG_BUFFER_SIZE << "."; << size << ".";
} }
/** Calculate actual length in redo buffer and file including /** Calculate actual length in redo buffer and file including
...@@ -360,20 +323,6 @@ log_reserve_and_open( ...@@ -360,20 +323,6 @@ log_reserve_and_open(
loop: loop:
ut_ad(log_mutex_own()); 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 /* Calculate an upper limit for the space the string may take in the
log buffer */ log buffer */
...@@ -718,10 +667,9 @@ log_sys_init() ...@@ -718,10 +667,9 @@ log_sys_init()
log_sys->lsn = LOG_START_LSN; log_sys->lsn = LOG_START_LSN;
ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE); ut_ad(srv_log_buffer_size >= 4);
ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);
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*>( log_sys->buf_ptr = static_cast<byte*>(
ut_zalloc_nokey(log_sys->buf_size * 2 + OS_FILE_LOG_BLOCK_SIZE)); 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