summaryrefslogtreecommitdiff
path: root/storage/innobase/buf/buf0dblwr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/buf/buf0dblwr.cc')
-rw-r--r--storage/innobase/buf/buf0dblwr.cc65
1 files changed, 42 insertions, 23 deletions
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index f99fc6434de..b770e8483d9 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -162,11 +162,11 @@ buf_dblwr_init(
ut_zalloc_nokey(buf_size * sizeof(void*)));
}
-/****************************************************************//**
-Creates the doublewrite buffer to a new InnoDB installation. The header of the
-doublewrite buffer is placed on the trx system header page.
-@return true if successful, false if not. */
-MY_ATTRIBUTE((warn_unused_result))
+/** Create the doublewrite buffer if the doublewrite buffer header
+is not present in the TRX_SYS page.
+@return whether the operation succeeded
+@retval true if the doublewrite buffer exists or was created
+@retval false if the creation failed (too small first data file) */
bool
buf_dblwr_create()
{
@@ -181,12 +181,11 @@ buf_dblwr_create()
if (buf_dblwr) {
/* Already inited */
-
return(true);
}
start_again:
- mtr_start(&mtr);
+ mtr.start();
buf_dblwr_being_created = TRUE;
doublewrite = buf_dblwr_get(&mtr);
@@ -198,33 +197,49 @@ start_again:
buf_dblwr_init(doublewrite);
- mtr_commit(&mtr);
+ mtr.commit();
buf_dblwr_being_created = FALSE;
return(true);
- }
+ } else {
+ fil_space_t* space = fil_space_acquire(TRX_SYS_SPACE);
+ const bool fail = UT_LIST_GET_FIRST(space->chain)->size
+ < 3 * FSP_EXTENT_SIZE;
+ fil_space_release(space);
- ib::info() << "Doublewrite buffer not found: creating new";
+ if (fail) {
+ goto too_small;
+ }
+ }
block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
TRX_SYS_DOUBLEWRITE
+ TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
- /* fseg_create acquires a second latch on the page,
- therefore we must declare it: */
-
- buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
-
if (block2 == NULL) {
- ib::error() << "Cannot create doublewrite buffer: you must"
- " increase your tablespace size."
- " Cannot continue operation.";
-
- /* The mini-transaction did not write anything yet;
- we merely failed to allocate a page. */
+too_small:
+ ib::error()
+ << "Cannot create doublewrite buffer: "
+ "the first file in innodb_data_file_path"
+ " must be at least "
+ << (3 * (FSP_EXTENT_SIZE * UNIV_PAGE_SIZE) >> 20)
+ << "M.";
mtr.commit();
return(false);
}
+ ib::info() << "Doublewrite buffer not found: creating new";
+
+ /* FIXME: After this point, the doublewrite buffer creation
+ is not atomic. The doublewrite buffer should not exist in
+ the InnoDB system tablespace file in the first place.
+ It could be located in separate optional file(s) in a
+ user-specified location. */
+
+ /* fseg_create acquires a second latch on the page,
+ therefore we must declare it: */
+
+ buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
+
fseg_header = doublewrite + TRX_SYS_DOUBLEWRITE_FSEG;
prev_page_no = 0;
@@ -338,7 +353,7 @@ recovery, this function loads the pages from double write buffer into memory.
@return DB_SUCCESS or error code */
dberr_t
buf_dblwr_init_or_load_pages(
- os_file_t file,
+ pfs_os_file_t file,
const char* path)
{
byte* buf;
@@ -516,6 +531,10 @@ buf_dblwr_process()
byte* unaligned_read_buf;
recv_dblwr_t& recv_dblwr = recv_sys->dblwr;
+ if (!buf_dblwr) {
+ return;
+ }
+
unaligned_read_buf = static_cast<byte*>(
ut_malloc_nokey(2 * UNIV_PAGE_SIZE));