diff options
Diffstat (limited to 'storage/innobase')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 10 | ||||
-rw-r--r-- | storage/innobase/buf/buf0dblwr.cc | 15 | ||||
-rw-r--r-- | storage/innobase/buf/buf0flu.cc | 28 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 46 | ||||
-rw-r--r-- | storage/innobase/include/buf0buf.h | 10 | ||||
-rw-r--r-- | storage/innobase/include/buf0flu.h | 10 | ||||
-rw-r--r-- | storage/innobase/include/fil0fil.h | 10 |
7 files changed, 72 insertions, 57 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index b15e8d431bc..1326ec2ff71 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -5887,9 +5887,9 @@ buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) } /** Complete a read or write request of a file page to or from the buffer pool. -@param[in,out] bpage Page to complete -@param[in] evict whether or not to evict the page - from LRU list. +@param[in,out] bpage page to complete +@param[in] dblwr whether the doublewrite buffer was used (on write) +@param[in] evict whether or not to evict the page from LRU list @return whether the operation succeeded @retval DB_SUCCESS always when writing, or if a read page was OK @retval DB_TABLESPACE_DELETED if the tablespace does not exist @@ -5899,7 +5899,7 @@ buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) not match */ UNIV_INTERN dberr_t -buf_page_io_complete(buf_page_t* bpage, bool evict) +buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict) { enum buf_io_fix io_type; buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); @@ -6132,7 +6132,7 @@ database_corrupted: /* Write means a flush operation: call the completion routine in the flush system */ - buf_flush_write_complete(bpage); + buf_flush_write_complete(bpage, dblwr); if (uncompressed) { rw_lock_sx_unlock_gen(&((buf_block_t*) bpage)->lock, diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 2bc3630d3f5..96000c4eb92 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -107,9 +107,6 @@ buf_dblwr_sync_datafiles() /* Wait that all async writes to tablespaces have been posted to the OS */ os_aio_wait_until_no_pending_writes(); - - /* Now we flush the data to disk (for example, with fsync) */ - fil_flush_file_spaces(FIL_TYPE_TABLESPACE); } /****************************************************************//** @@ -724,12 +721,9 @@ buf_dblwr_update( const buf_page_t* bpage, /*!< in: buffer block descriptor */ buf_flush_t flush_type)/*!< in: flush type */ { - if (!srv_use_doublewrite_buf - || buf_dblwr == NULL - || fsp_is_system_temporary(bpage->id.space())) { - return; - } - + ut_ad(srv_use_doublewrite_buf); + ut_ad(buf_dblwr); + ut_ad(!fsp_is_system_temporary(bpage->id.space())); ut_ad(!srv_read_only_mode); switch (flush_type) { @@ -957,6 +951,8 @@ buf_dblwr_flush_buffered_writes() if (!srv_use_doublewrite_buf || buf_dblwr == NULL) { /* Sync the writes to the disk. */ buf_dblwr_sync_datafiles(); + /* Now we flush the data to disk (for example, with fsync) */ + fil_flush_file_spaces(FIL_TYPE_TABLESPACE); return; } @@ -992,7 +988,6 @@ try_again: goto try_again; } - ut_a(!buf_dblwr->batch_running); ut_ad(buf_dblwr->first_free == buf_dblwr->b_reserved); /* Disallow anyone else to post to doublewrite buffer or to diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 76f1dd22aae..ca647368908 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -776,12 +776,10 @@ buf_flush_relocate_on_flush_list( buf_flush_list_mutex_exit(buf_pool); } -/********************************************************************//** -Updates the flush system data structures when a write is completed. */ -void -buf_flush_write_complete( -/*=====================*/ - buf_page_t* bpage) /*!< in: pointer to the block in question */ +/** Update the flush system data structures when a write is completed. +@param[in,out] bpage flushed page +@param[in] dblwr whether the doublewrite buffer was used */ +void buf_flush_write_complete(buf_page_t* bpage, bool dblwr) { buf_flush_t flush_type; buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); @@ -804,7 +802,9 @@ buf_flush_write_complete( os_event_set(buf_pool->no_flush[flush_type]); } - buf_dblwr_update(bpage, flush_type); + if (dblwr) { + buf_dblwr_update(bpage, flush_type); + } } /** Calculate the checksum of a page from compressed table and update @@ -1076,15 +1076,9 @@ buf_flush_write_block_low( frame = buf_page_encrypt_before_write(space, bpage, frame); - /* Disable use of double-write buffer for temporary tablespace. - Given the nature and load of temporary tablespace doublewrite buffer - adds an overhead during flushing. */ - - if (space->purpose == FIL_TYPE_TEMPORARY - || space->atomic_write_supported - || !srv_use_doublewrite_buf - || buf_dblwr == NULL) { - + ut_ad(space->purpose == FIL_TYPE_TABLESPACE + || space->atomic_write_supported); + if (!space->use_doublewrite()) { ulint type = IORequest::WRITE | IORequest::DO_NOT_WAKE; IORequest request(type, bpage); @@ -1124,7 +1118,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, true); + buf_page_io_complete(bpage, space->use_doublewrite(), true); ut_ad(err == DB_SUCCESS); } diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index abcdb90c375..dc8952f8bdf 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -433,10 +433,15 @@ fil_space_set_imported( mutex_enter(&fil_system->mutex); fil_space_t* space = fil_space_get_by_id(id); + const fil_node_t* node = UT_LIST_GET_FIRST(space->chain); ut_ad(space->purpose == FIL_TYPE_IMPORT); space->purpose = FIL_TYPE_TABLESPACE; - + space->atomic_write_supported = node->atomic_write + && srv_use_atomic_writes + && my_test_if_atomic_write(node->handle, + int(page_size_t(space->flags) + .physical())); mutex_exit(&fil_system->mutex); } @@ -574,7 +579,7 @@ fil_node_open_file( ut_a(node->n_pending == 0); ut_a(!node->is_open()); - read_only_mode = !fsp_is_system_temporary(space->id) + read_only_mode = space->purpose != FIL_TYPE_TEMPORARY && srv_read_only_mode; const bool first_time_open = node->size == 0; @@ -582,8 +587,8 @@ fil_node_open_file( if (first_time_open || (space->purpose == FIL_TYPE_TABLESPACE && node == UT_LIST_GET_FIRST(space->chain) - && !undo::Truncate::was_tablespace_truncated(space->id) - && srv_startup_is_before_trx_rollback_phase)) { + && srv_startup_is_before_trx_rollback_phase + && !undo::Truncate::was_tablespace_truncated(space->id))) { /* We do not know the size of the file yet. First we open the file in the normal mode, no async I/O here, for simplicity. Then do some checks, and close the @@ -732,6 +737,11 @@ retry: if (first_time_open) { /* + For the temporary tablespace and during the + non-redo-logged adjustments in + IMPORT TABLESPACE, we do not care about + the atomicity of writes. + Atomic writes is supported if the file can be used with atomic_writes (not log file), O_DIRECT is used (tested in ha_innodb.cc) and the file is @@ -739,12 +749,14 @@ retry: for the given block size */ space->atomic_write_supported - = srv_use_atomic_writes - && node->atomic_write - && my_test_if_atomic_write( - node->handle, - int(page_size_t(space->flags) - .physical())); + = space->purpose == FIL_TYPE_TEMPORARY + || space->purpose == FIL_TYPE_IMPORT + || (node->atomic_write + && srv_use_atomic_writes + && my_test_if_atomic_write( + node->handle, + int(page_size_t(space->flags) + .physical()))); } } @@ -1552,6 +1564,13 @@ fil_space_create( if (space->purpose == FIL_TYPE_TEMPORARY) { ut_d(space->latch.set_temp_fsp()); + /* SysTablespace::open_or_create() would pass + size!=0 to fil_node_create(), so first_time_open + would not hold in fil_node_open_file(), and we + must assign this manually. We do not care about + the durability or atomicity of writes to the + temporary tablespace files. */ + space->atomic_write_supported = true; } HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space); @@ -5342,8 +5361,9 @@ fil_aio_wait( mutex_enter(&fil_system->mutex); fil_node_complete_io(node, type); - const fil_type_t purpose = node->space->purpose; - const ulint space_id = node->space->id; + const fil_type_t purpose = node->space->purpose; + const ulint space_id= node->space->id; + const bool dblwr = node->space->use_doublewrite(); mutex_exit(&fil_system->mutex); @@ -5373,7 +5393,7 @@ fil_aio_wait( } ulint offset = bpage->id.page_no(); - dberr_t err = buf_page_io_complete(bpage); + dberr_t err = buf_page_io_complete(bpage, dblwr); if (err == DB_SUCCESS) { return; } diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 063eb6b6fab..1001f2ca807 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1271,9 +1271,9 @@ buf_page_init_for_read( bool unzip); /** Complete a read or write request of a file page to or from the buffer pool. -@param[in,out] bpage Page to complete -@param[in] evict whether or not to evict the page - from LRU list. +@param[in,out] bpage page to complete +@param[in] dblwr whether the doublewrite buffer was used (on write) +@param[in] evict whether or not to evict the page from LRU list @return whether the operation succeeded @retval DB_SUCCESS always when writing, or if a read page was OK @retval DB_PAGE_CORRUPTED if the checksum fails on a page read @@ -1282,7 +1282,7 @@ buf_page_init_for_read( not match */ UNIV_INTERN dberr_t -buf_page_io_complete(buf_page_t* bpage, bool evict = false) +buf_page_io_complete(buf_page_t* bpage, bool dblwr = false, bool evict = false) MY_ATTRIBUTE((nonnull)); /********************************************************************//** diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index ccf1d991b09..c3b518c4295 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -70,12 +70,10 @@ buf_flush_relocate_on_flush_list( /*=============================*/ buf_page_t* bpage, /*!< in/out: control block being moved */ buf_page_t* dpage); /*!< in/out: destination block */ -/********************************************************************//** -Updates the flush system data structures when a write is completed. */ -void -buf_flush_write_complete( -/*=====================*/ - buf_page_t* bpage); /*!< in: pointer to the block in question */ +/** Update the flush system data structures when a write is completed. +@param[in,out] bpage flushed page +@param[in] dblwr whether the doublewrite buffer was used */ +void buf_flush_write_complete(buf_page_t* bpage, bool dblwr); /** Initialize a page for writing to the tablespace. @param[in] block buffer block; NULL if bypassing the buffer pool @param[in,out] page page frame diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index c2152ce11d0..249755f1ff6 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -36,9 +36,10 @@ Created 10/25/1995 Heikki Tuuri #include "ibuf0types.h" #include <list> -#include <vector> // Forward declaration +extern ibool srv_use_doublewrite_buf; +extern struct buf_dblwr_t* buf_dblwr; struct trx_t; class page_id_t; class truncate_t; @@ -200,6 +201,13 @@ struct fil_space_t { { return stop_new_ops || is_being_truncated; } + + /** @return whether doublewrite buffering is needed */ + bool use_doublewrite() const + { + return !atomic_write_supported + && srv_use_doublewrite_buf && buf_dblwr; + } }; /** Value of fil_space_t::magic_n */ |