summaryrefslogtreecommitdiff
path: root/storage/xtradb/buf
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-09-05 13:14:37 +0200
committerSergei Golubchik <sergii@pisem.net>2012-09-05 13:14:37 +0200
commit6af914f8b94b98a5aa648f69383398741dcd9754 (patch)
tree899fb248b22fe3cf16cc940a80f867110d8f4ce7 /storage/xtradb/buf
parent1f92707978d411a051b2bfa46ed361f60861ff73 (diff)
parent0352f09a2e3e17470ab75678265b98a275cb25a0 (diff)
downloadmariadb-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.c11
-rw-r--r--storage/xtradb/buf/buf0lru.c51
-rw-r--r--storage/xtradb/buf/buf0rea.c47
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);