diff options
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 11 | ||||
-rw-r--r-- | storage/innobase/include/log0log.h | 18 | ||||
-rw-r--r-- | storage/innobase/log/log0log.cc | 59 | ||||
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 1 |
4 files changed, 38 insertions, 51 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index cff6dcb50a6..f37411f17a7 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1246,11 +1246,12 @@ buf_madvise_do_dump() /* mirrors allocation in log_t::create() */ if (log_sys.buf) { - ret+= madvise(log_sys.first_in_use - ? log_sys.buf - : log_sys.buf - srv_log_buffer_size, - srv_log_buffer_size * 2, - MADV_DODUMP); + ret += madvise(log_sys.buf, + srv_log_buffer_size, + MADV_DODUMP); + ret += madvise(log_sys.flush_buf, + srv_log_buffer_size, + MADV_DODUMP); } /* mirrors recv_sys_init() */ if (recv_sys->buf) diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 96202a23a63..133b1692d31 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -524,19 +524,11 @@ struct log_t{ mtr_commit and still ensure that insertions in the flush_list happen in the LSN order. */ - byte* buf; /*!< Memory of double the - srv_log_buffer_size is - allocated here. This pointer will change - however to either the first half or the - second half in turns, so that log - write/flush to disk don't block - concurrent mtrs which will write - log to this buffer. Care to switch back - to the first half before freeing/resizing - must be undertaken. */ - bool first_in_use; /*!< true if buf points to the first - half of the buffer, false - if the second half */ + /** log_buffer, append data here */ + byte* buf; + /** log_buffer, writing data to file from this buffer. + Before flushing write_buf is swapped with flush_buf */ + byte* flush_buf; ulong max_buf_free; /*!< recommended maximum value of buf_free for the buffer in use, after which the buffer is flushed */ diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 6d0b3baa5a3..c61ba742ff5 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -162,16 +162,19 @@ log_buf_pool_get_oldest_modification(void) void log_buffer_extend(ulong len) { const ulong new_buf_size = ut_calc_align(len, srv_page_size); - byte* new_buf = static_cast<byte*>( - ut_malloc_dontdump(new_buf_size * 2)); - TRASH_ALLOC(new_buf, new_buf_size * 2); + byte* new_buf = static_cast<byte*>(ut_malloc_dontdump(new_buf_size)); + TRASH_ALLOC(new_buf, new_buf_size); + byte* new_flush_buf = + static_cast<byte*>(ut_malloc_dontdump(new_buf_size)); + TRASH_ALLOC(new_flush_buf, new_buf_size); log_mutex_enter(); if (len <= srv_log_buffer_size) { /* Already extended enough by the others */ log_mutex_exit(); - ut_free_dodump(new_buf, new_buf_size * 2); + ut_free_dodump(new_buf, new_buf_size); + ut_free_dodump(new_flush_buf, new_buf_size); return; } @@ -179,14 +182,14 @@ void log_buffer_extend(ulong len) " exceeds innodb_log_buffer_size=" << srv_log_buffer_size << " / 2). Trying to extend it."; - const byte* old_buf_begin = log_sys.buf; + byte* old_buf = log_sys.buf; + byte* old_flush_buf = log_sys.flush_buf; const ulong old_buf_size = srv_log_buffer_size; - byte* old_buf = log_sys.first_in_use - ? log_sys.buf : log_sys.buf - old_buf_size; + srv_log_buffer_size = new_buf_size; log_sys.buf = new_buf; - log_sys.first_in_use = true; - memcpy(log_sys.buf, old_buf_begin, log_sys.buf_free); + log_sys.flush_buf = new_flush_buf; + memcpy(new_buf, old_buf, log_sys.buf_free); log_sys.max_buf_free = new_buf_size / LOG_BUF_FLUSH_RATIO - LOG_BUF_FLUSH_MARGIN; @@ -194,6 +197,7 @@ void log_buffer_extend(ulong len) log_mutex_exit(); ut_free_dodump(old_buf, old_buf_size); + ut_free_dodump(old_flush_buf, old_buf_size); ib::info() << "innodb_log_buffer_size was extended to " << new_buf_size << "."; @@ -547,10 +551,10 @@ void log_t::create() ut_ad(srv_log_buffer_size >= 16 * OS_FILE_LOG_BLOCK_SIZE); ut_ad(srv_log_buffer_size >= 4U << srv_page_size_shift); - buf= static_cast<byte*>(ut_malloc_dontdump(srv_log_buffer_size * 2)); - TRASH_ALLOC(buf, srv_log_buffer_size * 2); - - first_in_use= true; + buf= static_cast<byte*>(ut_malloc_dontdump(srv_log_buffer_size)); + TRASH_ALLOC(buf, srv_log_buffer_size); + flush_buf= static_cast<byte*>(ut_malloc_dontdump(srv_log_buffer_size)); + TRASH_ALLOC(flush_buf, srv_log_buffer_size); max_buf_free= srv_log_buffer_size / LOG_BUF_FLUSH_RATIO - LOG_BUF_FLUSH_MARGIN; @@ -824,8 +828,8 @@ log_write_flush_to_disk_low() os_event_set(log_sys.flush_event); } -/** Switch the log buffer in use, and copy the content of last block -from old log buffer to the head of the to be used one. Thus, buf_free and +/** Swap log buffers, and copy the content of last block +from old buf to the head of the new buf. Thus, buf_free and buf_next_to_write would be changed accordingly */ static inline void @@ -834,27 +838,16 @@ log_buffer_switch() ut_ad(log_mutex_own()); ut_ad(log_write_mutex_own()); - const byte* old_buf = log_sys.buf; ulong area_end = ut_calc_align( log_sys.buf_free, ulong(OS_FILE_LOG_BLOCK_SIZE)); - if (log_sys.first_in_use) { - log_sys.first_in_use = false; - ut_ad(log_sys.buf == ut_align(log_sys.buf, - OS_FILE_LOG_BLOCK_SIZE)); - log_sys.buf += srv_log_buffer_size; - } else { - log_sys.first_in_use = true; - log_sys.buf -= srv_log_buffer_size; - ut_ad(log_sys.buf == ut_align(log_sys.buf, - OS_FILE_LOG_BLOCK_SIZE)); - } - /* Copy the last block to new buf */ - ut_memcpy(log_sys.buf, - old_buf + area_end - OS_FILE_LOG_BLOCK_SIZE, + ut_memcpy(log_sys.flush_buf, + log_sys.buf + area_end - OS_FILE_LOG_BLOCK_SIZE, OS_FILE_LOG_BLOCK_SIZE); + std::swap(log_sys.buf, log_sys.flush_buf); + log_sys.buf_free %= OS_FILE_LOG_BLOCK_SIZE; log_sys.buf_next_to_write = log_sys.buf_free; } @@ -1942,10 +1935,10 @@ void log_t::close() m_initialised = false; log.close(); - if (!first_in_use) - buf -= srv_log_buffer_size; - ut_free_dodump(buf, srv_log_buffer_size * 2); + ut_free_dodump(buf, srv_log_buffer_size); buf = NULL; + ut_free_dodump(flush_buf, srv_log_buffer_size); + flush_buf = NULL; os_event_destroy(flush_event); rw_lock_free(&checkpoint_lock); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 2a77003a5ee..2f1238d5361 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -502,6 +502,7 @@ create_log_files( memset(log_sys.buf, 0, srv_log_buffer_size); log_block_init(log_sys.buf, log_sys.lsn); log_block_set_first_rec_group(log_sys.buf, LOG_BLOCK_HDR_SIZE); + memset(log_sys.flush_buf, 0, srv_log_buffer_size); log_sys.buf_free = LOG_BLOCK_HDR_SIZE; log_sys.lsn += LOG_BLOCK_HDR_SIZE; |