diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-03-13 08:15:06 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-03-13 08:15:06 +0200 |
commit | 7fb03d7abf4e668d76aded38378120361c218ba4 (patch) | |
tree | ab6a8f7d29479970e5d3b48b0d671d1dc07c166e /storage/innobase | |
parent | 09c5c335e3e8447e7d07c987293042175b51b495 (diff) | |
parent | 1c4b6afbaaf7dbcee4b035d1bf79156fa68a6475 (diff) | |
download | mariadb-git-7fb03d7abf4e668d76aded38378120361c218ba4.tar.gz |
Merge bb-10.2-ext into 10.3
Diffstat (limited to 'storage/innobase')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 34 | ||||
-rw-r--r-- | storage/innobase/buf/buf0dblwr.cc | 15 | ||||
-rw-r--r-- | storage/innobase/buf/buf0flu.cc | 221 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 46 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0fsp.cc | 7 | ||||
-rw-r--r-- | storage/innobase/fts/fts0fts.cc | 8 | ||||
-rw-r--r-- | storage/innobase/include/buf0buf.h | 10 | ||||
-rw-r--r-- | storage/innobase/include/buf0flu.h | 16 | ||||
-rw-r--r-- | storage/innobase/include/fil0fil.h | 9 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.h | 13 |
10 files changed, 185 insertions, 194 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 437e3390b86..b2b13a9bab3 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -5930,9 +5930,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 @@ -5942,7 +5942,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); @@ -6136,8 +6136,9 @@ database_corrupted: } } + BPageMutex* block_mutex = buf_page_get_mutex(bpage); buf_pool_mutex_enter(buf_pool); - mutex_enter(buf_page_get_mutex(bpage)); + mutex_enter(block_mutex); #ifdef UNIV_IBUF_COUNT_DEBUG if (io_type == BUF_IO_WRITE || uncompressed) { @@ -6155,8 +6156,7 @@ database_corrupted: buf_page_set_io_fix(bpage, BUF_IO_NONE); buf_page_monitor(bpage, io_type); - switch (io_type) { - case BUF_IO_READ: + if (io_type == BUF_IO_READ) { /* NOTE that the call to ibuf may have moved the ownership of the x-latch to this OS thread: do not let this confuse you in debugging! */ @@ -6170,15 +6170,12 @@ database_corrupted: BUF_IO_READ); } - mutex_exit(buf_page_get_mutex(bpage)); - - break; - - case BUF_IO_WRITE: + mutex_exit(block_mutex); + } else { /* 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, @@ -6197,18 +6194,11 @@ database_corrupted: evict = true; } + mutex_exit(block_mutex); + if (evict) { - mutex_exit(buf_page_get_mutex(bpage)); buf_LRU_free_page(bpage, true); - } else { - mutex_exit(buf_page_get_mutex(bpage)); } - - - break; - - default: - ut_error; } DBUG_PRINT("ib_buf", ("%s page %u:%u", diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 8594efd0c8d..eb36476cdd3 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 71e78172048..490a66a1f2e 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -777,12 +777,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); @@ -805,7 +803,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 @@ -833,18 +833,14 @@ buf_flush_update_zip_checksum( @param[in] block buffer block; NULL if bypassing the buffer pool @param[in,out] page page frame @param[in,out] page_zip_ compressed page, or NULL if uncompressed -@param[in] newest_lsn newest modification LSN to the page -@param[in] skip_checksum whether to disable the page checksum */ +@param[in] newest_lsn newest modification LSN to the page */ void buf_flush_init_for_writing( const buf_block_t* block, byte* page, void* page_zip_, - lsn_t newest_lsn, - bool skip_checksum) + lsn_t newest_lsn) { - ib_uint32_t checksum = BUF_NO_CHECKSUM_MAGIC; - ut_ad(block == NULL || block->frame == page); ut_ad(block == NULL || page_zip_ == NULL || &block->page.zip == page_zip_); @@ -896,112 +892,98 @@ buf_flush_init_for_writing( mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, newest_lsn); - if (skip_checksum) { - ut_ad(block == NULL - || block->page.id.space() == SRV_TMP_SPACE_ID); - ut_ad(page_get_space_id(page) == SRV_TMP_SPACE_ID); - mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum); - } else { - if (block != NULL && UNIV_PAGE_SIZE == 16384) { - /* The page type could be garbage in old files - created before MySQL 5.5. Such files always - had a page size of 16 kilobytes. */ - ulint page_type = fil_page_get_type(page); - ulint reset_type = page_type; - - switch (block->page.id.page_no() % 16384) { - case 0: - reset_type = block->page.id.page_no() == 0 - ? FIL_PAGE_TYPE_FSP_HDR - : FIL_PAGE_TYPE_XDES; + if (block && srv_page_size == 16384) { + /* The page type could be garbage in old files + created before MySQL 5.5. Such files always + had a page size of 16 kilobytes. */ + ulint page_type = fil_page_get_type(page); + ulint reset_type = page_type; + + switch (block->page.id.page_no() % 16384) { + case 0: + reset_type = block->page.id.page_no() == 0 + ? FIL_PAGE_TYPE_FSP_HDR + : FIL_PAGE_TYPE_XDES; + break; + case 1: + reset_type = FIL_PAGE_IBUF_BITMAP; + break; + case FSP_TRX_SYS_PAGE_NO: + if (block->page.id.page_no() + == TRX_SYS_PAGE_NO + && block->page.id.space() + == TRX_SYS_SPACE) { + reset_type = FIL_PAGE_TYPE_TRX_SYS; break; - case 1: - reset_type = FIL_PAGE_IBUF_BITMAP; + } + /* fall through */ + default: + switch (page_type) { + case FIL_PAGE_INDEX: + case FIL_PAGE_TYPE_INSTANT: + case FIL_PAGE_RTREE: + case FIL_PAGE_UNDO_LOG: + case FIL_PAGE_INODE: + case FIL_PAGE_IBUF_FREE_LIST: + case FIL_PAGE_TYPE_ALLOCATED: + case FIL_PAGE_TYPE_SYS: + case FIL_PAGE_TYPE_TRX_SYS: + case FIL_PAGE_TYPE_BLOB: + case FIL_PAGE_TYPE_ZBLOB: + case FIL_PAGE_TYPE_ZBLOB2: break; - case FSP_TRX_SYS_PAGE_NO: - if (block->page.id.page_no() - == TRX_SYS_PAGE_NO - && block->page.id.space() - == TRX_SYS_SPACE) { - reset_type = FIL_PAGE_TYPE_TRX_SYS; - break; - } - /* fall through */ + case FIL_PAGE_TYPE_FSP_HDR: + case FIL_PAGE_TYPE_XDES: + case FIL_PAGE_IBUF_BITMAP: + /* These pages should have + predetermined page numbers + (see above). */ default: - switch (page_type) { - case FIL_PAGE_INDEX: - case FIL_PAGE_TYPE_INSTANT: - case FIL_PAGE_RTREE: - case FIL_PAGE_UNDO_LOG: - case FIL_PAGE_INODE: - case FIL_PAGE_IBUF_FREE_LIST: - case FIL_PAGE_TYPE_ALLOCATED: - case FIL_PAGE_TYPE_SYS: - case FIL_PAGE_TYPE_TRX_SYS: - case FIL_PAGE_TYPE_BLOB: - case FIL_PAGE_TYPE_ZBLOB: - case FIL_PAGE_TYPE_ZBLOB2: - break; - case FIL_PAGE_TYPE_FSP_HDR: - case FIL_PAGE_TYPE_XDES: - case FIL_PAGE_IBUF_BITMAP: - /* These pages should have - predetermined page numbers - (see above). */ - default: - reset_type = FIL_PAGE_TYPE_UNKNOWN; - break; - } - } - - if (UNIV_UNLIKELY(page_type != reset_type)) { - ib::info() - << "Resetting invalid page " - << block->page.id << " type " - << page_type << " to " - << reset_type << " when flushing."; - fil_page_set_type(page, reset_type); + reset_type = FIL_PAGE_TYPE_UNKNOWN; + break; } } - switch ((srv_checksum_algorithm_t) srv_checksum_algorithm) { - case SRV_CHECKSUM_ALGORITHM_CRC32: - case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: - checksum = buf_calc_page_crc32(page); - mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, - checksum); - break; - case SRV_CHECKSUM_ALGORITHM_INNODB: - case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: - checksum = (ib_uint32_t) buf_calc_page_new_checksum( - page); - mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, - checksum); - checksum = (ib_uint32_t) buf_calc_page_old_checksum( - page); - break; - case SRV_CHECKSUM_ALGORITHM_NONE: - case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: - mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, - checksum); - break; - /* no default so the compiler will emit a warning if - new enum is added and not handled here */ + if (UNIV_UNLIKELY(page_type != reset_type)) { + ib::info() + << "Resetting invalid page " + << block->page.id << " type " + << page_type << " to " + << reset_type << " when flushing."; + fil_page_set_type(page, reset_type); } } - /* With the InnoDB checksum, we overwrite the first 4 bytes of - the end lsn field to store the old formula checksum. Since it - depends also on the field FIL_PAGE_SPACE_OR_CHKSUM, it has to - be calculated after storing the new formula checksum. + uint32_t checksum; - In other cases we write the same value to both fields. - If CRC32 is used then it is faster to use that checksum - (calculated above) instead of calculating another one. - We can afford to store something other than - buf_calc_page_old_checksum() or BUF_NO_CHECKSUM_MAGIC in - this field because the file will not be readable by old - versions of MySQL/InnoDB anyway (older than MySQL 5.6.3) */ + switch (srv_checksum_algorithm_t(srv_checksum_algorithm)) { + case SRV_CHECKSUM_ALGORITHM_INNODB: + case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: + checksum = buf_calc_page_new_checksum(page); + mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, + checksum); + /* With the InnoDB checksum, we overwrite the first 4 bytes of + the end lsn field to store the old formula checksum. Since it + depends also on the field FIL_PAGE_SPACE_OR_CHKSUM, it has to + be calculated after storing the new formula checksum. */ + checksum = buf_calc_page_old_checksum(page); + break; + case SRV_CHECKSUM_ALGORITHM_CRC32: + case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: + /* In other cases we write the same checksum to both fields. */ + checksum = buf_calc_page_crc32(page); + mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, + checksum); + break; + case SRV_CHECKSUM_ALGORITHM_NONE: + case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: + checksum = BUF_NO_CHECKSUM_MAGIC; + mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, + checksum); + break; + /* no default so the compiler will emit a warning if + new enum is added and not handled here */ + } mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, checksum); @@ -1027,8 +1009,8 @@ buf_flush_write_block_low( ut_ad(space->purpose == FIL_TYPE_TEMPORARY || space->purpose == FIL_TYPE_IMPORT || space->purpose == FIL_TYPE_TABLESPACE); - const bool is_temp = space->purpose == FIL_TYPE_TEMPORARY; - ut_ad(is_temp == fsp_is_system_temporary(space->id)); + ut_ad((space->purpose == FIL_TYPE_TEMPORARY) + == fsp_is_system_temporary(space->id)); page_t* frame = NULL; #ifdef UNIV_DEBUG buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); @@ -1090,20 +1072,15 @@ buf_flush_write_block_low( reinterpret_cast<const buf_block_t*>(bpage), reinterpret_cast<const buf_block_t*>(bpage)->frame, bpage->zip.data ? &bpage->zip : NULL, - bpage->newest_modification, is_temp); + bpage->newest_modification); break; } 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 (is_temp || 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); @@ -1128,7 +1105,7 @@ buf_flush_write_block_low( are working on. */ if (sync) { ut_ad(flush_type == BUF_FLUSH_SINGLE_PAGE); - if (!is_temp) { + if (space->purpose != FIL_TYPE_TEMPORARY) { fil_flush(space); } @@ -1143,7 +1120,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 b66ad9a86cf..d965fb06a4c 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); @@ -5315,8 +5334,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); @@ -5346,7 +5366,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/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index dd0148a3275..c8e71381491 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -600,17 +600,14 @@ fsp_init_file_page_low( buf_block_t* block) /*!< in: pointer to a page */ { page_t* page = buf_block_get_frame(block); - page_zip_des_t* page_zip= buf_block_get_page_zip(block); - if (!fsp_is_system_temporary(block->page.id.space())) { - memset(page, 0, UNIV_PAGE_SIZE); - } + memset(page, 0, UNIV_PAGE_SIZE); mach_write_to_4(page + FIL_PAGE_OFFSET, block->page.id.page_no()); mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, block->page.id.space()); - if (page_zip) { + if (page_zip_des_t* page_zip= buf_block_get_page_zip(block)) { memset(page_zip->data, 0, page_zip_get_size(page_zip)); memcpy(page_zip->data + FIL_PAGE_OFFSET, page + FIL_PAGE_OFFSET, 4); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index d1c3d004456..b4bf70e6943 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -4458,6 +4458,7 @@ begin_sync: ib_vector_get(cache->indexes, i)); if (index_cache->index->to_be_dropped + || index_cache->index->table->to_be_dropped || fts_sync_index_check(index_cache)) { continue; } @@ -4476,10 +4477,9 @@ end_sync: /* Clear fts syncing flags of any indexes incase sync is interrupeted */ for (i = 0; i < ib_vector_size(cache->indexes); ++i) { - fts_index_cache_t* index_cache; - index_cache = static_cast<fts_index_cache_t*>( - ib_vector_get(cache->indexes, i)); - index_cache->index->index_fts_syncing = false; + static_cast<fts_index_cache_t*>( + ib_vector_get(cache->indexes, i)) + ->index->index_fts_syncing = false; } sync->interrupted = false; diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 0cef7862332..32b964c406d 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 38996a37fc6..76fa65c70f4 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -70,25 +70,21 @@ 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 @param[in,out] page_zip_ compressed page, or NULL if uncompressed -@param[in] newest_lsn newest modification LSN to the page -@param[in] skip_checksum whether to disable the page checksum */ +@param[in] newest_lsn newest modification LSN to the page */ void buf_flush_init_for_writing( const buf_block_t* block, byte* page, void* page_zip_, - lsn_t newest_lsn, - bool skip_checksum = false); + lsn_t newest_lsn); # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG /********************************************************************//** diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 724deb4e6bc..a3fac6d4096 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -36,6 +36,8 @@ Created 10/25/1995 Heikki Tuuri #include "ibuf0types.h" // 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; @@ -195,6 +197,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 */ diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 685208853ee..5e3a1dd4a7e 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -1488,8 +1488,12 @@ private: } /* Avoid excessive mutex acquire/release */ - if (trx->in_depth++) { - /* The transaction is already inside InnoDB. */ + ++trx->in_depth; + + /* If trx->in_depth is greater than 1 then + transaction is already in InnoDB. */ + if (trx->in_depth > 1) { + return; } @@ -1517,7 +1521,10 @@ private: ut_ad(trx->in_depth > 0); - if (--trx->in_depth) { + --trx->in_depth; + + if (trx->in_depth > 0) { + return; } |