summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-06-12 19:36:54 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-06-12 20:18:01 +0300
commit8bb4ea2e6f97a5d93e2c759bd6b2a0a538eaabc1 (patch)
tree7d745bb0b4735205f42e017e036d8522c4839a64
parent38018f48b623688f29ec6dd04823235dca86f483 (diff)
downloadmariadb-git-8bb4ea2e6f97a5d93e2c759bd6b2a0a538eaabc1.tar.gz
MDEV-19738: Doublewrite buffer is unnecessarily used for newly (re)initialized pages
Thanks to MDEV-12699, the doublewrite buffer will only be needed in those cases when a page is being updated in the data file. If the page had never been written to the data file since it was initialized, then recovery will be able to reconstruct the page based solely on the contents of the redo log files. The doublewrite buffer is only really needed when recovery needs to read the page in order to apply redo log. Note: As noted in MDEV-19739, we cannot safely disable the doublewrite buffer if any MLOG_INDEX_LOAD records were written in the past or will be written in the future. These records denote that redo logging was disabled for some pages in a tablespace. Ideally, we would have the setting innodb_log_optimize_ddl=OFF by default, and would not allow it to be set while the server is running. If we wanted to make this safe, assignments with SET GLOBAL innodb_log_optimize_ddl=... should not only issue a redo log checkpoint (including a write of all dirty pages from the entire buffer pool), but it should also wait for all pending ALTER TABLE activity to complete. We elect not to do this. Avoiding unnecessary use of the doublewrite buffer should improve the write performance of InnoDB. buf_page_t::init_on_flush: A new flag to indicate whether it is safe to skip doublewrite buffering when writing the page. fsp_init_file_page(): When writing a MLOG_INIT_FILE_PAGE2 record, set the init_on_flush flag if innodb_log_optimize_ddl=OFF. This is the only function that writes that log record. buf_flush_write_block_low(): Skip doublewrite if init_on_flush is set. fil_aio_wait(): Clear init_on_flush.
-rw-r--r--storage/innobase/buf/buf0buf.cc2
-rw-r--r--storage/innobase/buf/buf0flu.cc7
-rw-r--r--storage/innobase/fil/fil0fil.cc6
-rw-r--r--storage/innobase/include/btr0bulk.h2
-rw-r--r--storage/innobase/include/buf0buf.h7
-rw-r--r--storage/innobase/include/fil0fil.h2
-rw-r--r--storage/innobase/include/fsp0fsp.h12
7 files changed, 32 insertions, 6 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index bfd3ffce69b..eeabc6aa8ab 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -1523,6 +1523,7 @@ buf_block_init(
block->page.io_fix = BUF_IO_NONE;
block->page.flush_observer = NULL;
block->page.encrypted = false;
+ block->page.init_on_flush = false;
block->page.real_size = 0;
block->page.write_size = 0;
block->modify_clock = 0;
@@ -5471,6 +5472,7 @@ buf_page_init_for_read(
bpage->state = BUF_BLOCK_ZIP_PAGE;
bpage->id = page_id;
bpage->flush_observer = NULL;
+ bpage->init_on_flush = false;
ut_d(bpage->in_page_hash = FALSE);
ut_d(bpage->in_zip_hash = FALSE);
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 373f6eb4539..aa44a1c5e4c 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1040,7 +1040,10 @@ buf_flush_write_block_low(
ut_ad(space->purpose == FIL_TYPE_TABLESPACE
|| space->atomic_write_supported);
- if (!space->use_doublewrite()) {
+ const bool use_doublewrite = !bpage->init_on_flush
+ && space->use_doublewrite();
+
+ if (!use_doublewrite) {
ulint type = IORequest::WRITE | IORequest::DO_NOT_WAKE;
IORequest request(type, bpage);
@@ -1081,7 +1084,7 @@ buf_flush_write_block_low(
#endif
/* true means we want to evict this page from the
LRU list as well. */
- buf_page_io_complete(bpage, space->use_doublewrite(), true);
+ buf_page_io_complete(bpage, use_doublewrite, true);
ut_ad(err == DB_SUCCESS);
}
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index be422c7c467..d395e21f79f 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -4357,7 +4357,7 @@ fil_aio_wait(
fil_node_complete_io(node, type);
const fil_type_t purpose = node->space->purpose;
const ulint space_id= node->space->id;
- const bool dblwr = node->space->use_doublewrite();
+ bool dblwr = node->space->use_doublewrite();
mutex_exit(&fil_system.mutex);
@@ -4406,6 +4406,10 @@ fil_aio_wait(
}
ulint offset = bpage->id.page_no();
+ if (dblwr && bpage->init_on_flush) {
+ bpage->init_on_flush = false;
+ dblwr = false;
+ }
dberr_t err = buf_page_io_complete(bpage, dblwr);
if (err == DB_SUCCESS) {
return;
diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h
index 0fcf4a36d6b..d1a8af22d68 100644
--- a/storage/innobase/include/btr0bulk.h
+++ b/storage/innobase/include/btr0bulk.h
@@ -34,8 +34,6 @@ Created 03/11/2014 Shaohua Wang
/** Innodb B-tree index fill factor for bulk load. */
extern uint innobase_fill_factor;
-/** whether to reduce redo logging during ALTER TABLE */
-extern my_bool innodb_log_optimize_ddl;
/*
The proper function call sequence of PageBulk is as below:
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index ea2348d61fd..fa22da5192c 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1493,6 +1493,13 @@ public:
bool encrypted; /*!< page is still encrypted */
+ /** whether the page will be (re)initialized at the time it will
+ be written to the file, that is, whether the doublewrite buffer
+ can be safely skipped. Protected under similar conditions as
+ buf_block_t::frame. Can be set while holding buf_block_t::lock
+ X-latch and reset during page flush, while io_fix is in effect. */
+ bool init_on_flush;
+
ulint real_size; /*!< Real size of the page
Normal pages == srv_page_size
page compressed pages, payload
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 3e04d90e04e..ea6d8e235c7 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -38,6 +38,8 @@ Created 10/25/1995 Heikki Tuuri
# include <set>
#endif
+/** whether to reduce redo logging during ALTER TABLE */
+extern my_bool innodb_log_optimize_ddl;
// Forward declaration
extern my_bool srv_use_doublewrite_buf;
extern struct buf_dblwr_t* buf_dblwr;
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 75c448c956d..26da55bb2ad 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -625,7 +625,17 @@ inline void fsp_init_file_page(
ut_d(space->modify_check(*mtr));
ut_ad(space->id == block->page.id.space());
fsp_apply_init_file_page(block);
- mlog_write_initial_log_record(block->frame, MLOG_INIT_FILE_PAGE2, mtr);
+
+ if (byte* log_ptr = mlog_open(mtr, 11)) {
+ log_ptr = mlog_write_initial_log_record_low(
+ MLOG_INIT_FILE_PAGE2,
+ block->page.id.space(), block->page.id.page_no(),
+ log_ptr, mtr);
+ mlog_close(mtr, log_ptr);
+ if (!innodb_log_optimize_ddl) {
+ block->page.init_on_flush = true;
+ }
+ }
}
#ifndef UNIV_DEBUG