diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-09-05 13:14:37 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-09-05 13:14:37 +0200 |
commit | 6af914f8b94b98a5aa648f69383398741dcd9754 (patch) | |
tree | 899fb248b22fe3cf16cc940a80f867110d8f4ce7 /storage/xtradb/buf | |
parent | 1f92707978d411a051b2bfa46ed361f60861ff73 (diff) | |
parent | 0352f09a2e3e17470ab75678265b98a275cb25a0 (diff) | |
download | mariadb-git-6af914f8b94b98a5aa648f69383398741dcd9754.tar.gz |
XtraDB from Percona-Server-5.5.27-rel28.1
Diffstat (limited to 'storage/xtradb/buf')
-rw-r--r-- | storage/xtradb/buf/buf0buf.c | 11 | ||||
-rw-r--r-- | storage/xtradb/buf/buf0lru.c | 51 | ||||
-rw-r--r-- | storage/xtradb/buf/buf0rea.c | 47 |
3 files changed, 90 insertions, 19 deletions
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c index fd7b8959473..a2ff171e0c5 100644 --- a/storage/xtradb/buf/buf0buf.c +++ b/storage/xtradb/buf/buf0buf.c @@ -344,7 +344,6 @@ be effective only if PFS_GROUP_BUFFER_SYNC is defined. */ // was allocated for the frames */ // buf_block_t* blocks; /*!< array of buffer control blocks */ //}; -#endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Gets the smallest oldest_modification lsn for any page in the pool. Returns @@ -482,6 +481,7 @@ buf_block_alloc( return(block); } +#endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Calculates a page checksum which is stored to the page when it is written @@ -3907,9 +3907,10 @@ buf_mark_space_corrupt( /********************************************************************//** Completes an asynchronous read or write request of a file page to or from -the buffer pool. */ +the buffer pool. +@return TRUE if successful */ UNIV_INTERN -void +ibool buf_page_io_complete( /*=================*/ buf_page_t* bpage) /*!< in: pointer to the block in question */ @@ -4057,7 +4058,7 @@ corrupt: table as corrupted instead of crashing server */ if (bpage->space > TRX_SYS_SPACE && buf_mark_space_corrupt(bpage)) { - return; + return(FALSE); } else { fputs("InnoDB: Ending processing" " because of" @@ -4176,6 +4177,8 @@ retry_mutex: buf_pool_mutex_exit(buf_pool); mutex_exit(block_mutex); + + return(TRUE); } /********************************************************************//** diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c index f7b5db2d0cc..16a91358080 100644 --- a/storage/xtradb/buf/buf0lru.c +++ b/storage/xtradb/buf/buf0lru.c @@ -374,7 +374,7 @@ next_page: /******************************************************************//** While flushing (or removing dirty) pages from a tablespace we don't -want to hog the CPU and resources. Release the buffer pool and block +want to hog the CPU and resources. Release the LRU list and block mutex and try to force a context switch. Then reacquire the same mutexes. The current page is "fixed" before the release of the mutexes and then "unfixed" again once we have reacquired the mutexes. */ @@ -387,7 +387,7 @@ buf_flush_yield( { mutex_t* block_mutex; - ut_ad(buf_pool_mutex_own(buf_pool)); + ut_ad(mutex_own(&buf_pool->LRU_list_mutex)); ut_ad(buf_page_in_file(bpage)); block_mutex = buf_page_get_mutex(bpage); @@ -399,13 +399,13 @@ buf_flush_yield( buf_page_set_sticky(bpage); /* Now it is safe to release the buf_pool->mutex. */ - buf_pool_mutex_exit(buf_pool); + mutex_exit(&buf_pool->LRU_list_mutex); mutex_exit(block_mutex); /* Try and force a context switch. */ os_thread_yield(); - buf_pool_mutex_enter(buf_pool); + mutex_enter(&buf_pool->LRU_list_mutex); mutex_enter(block_mutex); /* "Unfix" the block now that we have both the @@ -415,9 +415,9 @@ buf_flush_yield( } /******************************************************************//** -If we have hogged the resources for too long then release the buffer -pool and flush list mutex and do a thread yield. Set the current page -to "sticky" so that it is not relocated during the yield. +If we have hogged the resources for too long then release the LRU list +and flush list mutex and do a thread yield. Set the current page to +"sticky" so that it is not relocated during the yield. @return TRUE if yielded */ static ibool @@ -439,7 +439,7 @@ buf_flush_try_yield( buf_flush_list_mutex_exit(buf_pool); - /* Release the buffer pool and block mutex + /* Release the LRU list and block mutex to give the other threads a go. */ buf_flush_yield(buf_pool, bpage); @@ -472,7 +472,7 @@ buf_flush_or_remove_page( mutex_t* block_mutex; ibool processed = FALSE; - ut_ad(buf_pool_mutex_own(buf_pool)); + ut_ad(mutex_own(&buf_pool->LRU_list_mutex)); ut_ad(buf_flush_list_mutex_own(buf_pool)); block_mutex = buf_page_get_mutex(bpage); @@ -595,11 +595,11 @@ buf_flush_dirty_pages( ibool all_freed; do { - buf_pool_mutex_enter(buf_pool); + mutex_enter(&buf_pool->LRU_list_mutex); all_freed = buf_flush_or_remove_pages(buf_pool, id); - buf_pool_mutex_exit(buf_pool); + mutex_exit(&buf_pool->LRU_list_mutex); ut_ad(buf_flush_validate(buf_pool)); @@ -659,8 +659,16 @@ scan_again: goto next_page; } else { - block_mutex = buf_page_get_mutex(bpage); - mutex_enter(block_mutex); + block_mutex = buf_page_get_mutex_enter(bpage); + + if (!block_mutex) { + /* It may be impossible case... + Something wrong, so will be scan_again */ + + all_freed = FALSE; + goto next_page; + } + if (bpage->buf_fix_count > 0) { @@ -694,7 +702,8 @@ scan_again: ulint page_no; ulint zip_size; - buf_pool_mutex_exit(buf_pool); + mutex_exit(&buf_pool->LRU_list_mutex); + rw_lock_x_unlock(&buf_pool->page_hash_latch); zip_size = buf_page_get_zip_size(bpage); page_no = buf_page_get_page_no(bpage); @@ -2370,9 +2379,23 @@ buf_LRU_free_one_page( be in a state where it can be freed; there may or may not be a hash index to the page */ { +#ifdef UNIV_DEBUG + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); +#endif + mutex_t* block_mutex = buf_page_get_mutex(bpage); + + ut_ad(buf_pool_mutex_own(buf_pool)); + ut_ad(mutex_own(block_mutex)); + if (buf_LRU_block_remove_hashed_page(bpage, TRUE) != BUF_BLOCK_ZIP_FREE) { buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE); + } else { + /* The block_mutex should have been released by + buf_LRU_block_remove_hashed_page() when it returns + BUF_BLOCK_ZIP_FREE. */ + ut_ad(block_mutex == &buf_pool->zip_mutex); + mutex_enter(block_mutex); } } diff --git a/storage/xtradb/buf/buf0rea.c b/storage/xtradb/buf/buf0rea.c index 4ba0d2cf577..c29dcbf0444 100644 --- a/storage/xtradb/buf/buf0rea.c +++ b/storage/xtradb/buf/buf0rea.c @@ -51,6 +51,44 @@ i/o-fixed buffer blocks */ #define BUF_READ_AHEAD_PEND_LIMIT 2 /********************************************************************//** +Unfixes the pages, unlatches the page, +removes it from page_hash and removes it from LRU. */ +static +void +buf_read_page_handle_error( +/*=======================*/ + buf_page_t* bpage) /*!< in: pointer to the block */ +{ + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + const ibool uncompressed = (buf_page_get_state(bpage) + == BUF_BLOCK_FILE_PAGE); + + /* First unfix and release lock on the bpage */ + buf_pool_mutex_enter(buf_pool); + mutex_enter(buf_page_get_mutex(bpage)); + ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ); + ut_ad(bpage->buf_fix_count == 0); + + /* Set BUF_IO_NONE before we remove the block from LRU list */ + buf_page_set_io_fix(bpage, BUF_IO_NONE); + + if (uncompressed) { + rw_lock_x_unlock_gen( + &((buf_block_t*) bpage)->lock, + BUF_IO_READ); + } + + /* remove the block from LRU list */ + buf_LRU_free_one_page(bpage); + + ut_ad(buf_pool->n_pend_reads > 0); + buf_pool->n_pend_reads--; + + mutex_exit(buf_page_get_mutex(bpage)); + buf_pool_mutex_exit(buf_pool); +} + +/********************************************************************//** Low-level function which reads a page asynchronously from a file to the buffer buf_pool if it is not already there, in which case does nothing. Sets the io_fix flag and sets an exclusive lock on the buffer frame. The @@ -198,6 +236,11 @@ not_to_recover: ((buf_block_t*) bpage)->frame, bpage, trx); } + if (*err == DB_TABLESPACE_DELETED) { + buf_read_page_handle_error(bpage); + return(0); + } + if (srv_pass_corrupt_table) { if (*err != DB_SUCCESS) { bpage->is_corrupt = TRUE; @@ -210,7 +253,9 @@ not_to_recover: thd_wait_end(NULL); /* The i/o is already completed when we arrive from fil_read */ - buf_page_io_complete(bpage); + if (!buf_page_io_complete(bpage)) { + return(0); + } } return(1); |