mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
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.
This commit is contained in:
parent
409e210e74
commit
56976e60f5
2 changed files with 32 additions and 88 deletions
|
|
@ -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();
|
||||
log_mutex_enter();
|
||||
|
||||
while (log_sys->is_extending) {
|
||||
/* Another thread is trying to extend already.
|
||||
Needs to wait for. */
|
||||
log_mutex_exit_all();
|
||||
const ulint size = srv_log_buffer_size << srv_page_size_shift;
|
||||
|
||||
log_buffer_flush_to_disk();
|
||||
|
||||
log_mutex_enter_all();
|
||||
|
||||
if (srv_log_buffer_size > len / UNIV_PAGE_SIZE) {
|
||||
/* Already extended enough by the others */
|
||||
log_mutex_exit_all();
|
||||
return;
|
||||
}
|
||||
if (len <= size) {
|
||||
/* Already extended enough by the others */
|
||||
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(););
|
||||
ib::warn() << "The transaction log size is too large"
|
||||
" for innodb_log_buffer_size (" << len
|
||||
<< " >= " << size << " / 2). Trying to extend it.";
|
||||
|
||||
/* 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.";
|
||||
byte* old_buf_ptr = log_sys->buf_ptr;
|
||||
const byte* begin = log_sys->buf;
|
||||
const byte* end = begin + log_sys->buf_free;
|
||||
|
||||
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));
|
||||
|
||||
if (!log_sys->first_in_use) {
|
||||
log_sys->buf += size;
|
||||
}
|
||||
|
||||
log_sys->is_extending = true;
|
||||
memcpy(log_sys->buf, begin, end - begin);
|
||||
|
||||
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_mutex_enter_all();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
log_mutex_exit();
|
||||
|
||||
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 "
|
||||
<< 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));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue