diff options
Diffstat (limited to 'storage/innobase/buf/buf0dblwr.cc')
-rw-r--r-- | storage/innobase/buf/buf0dblwr.cc | 65 |
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)); |