Commit a26c0f5c authored by Marko Mäkelä's avatar Marko Mäkelä

Merge mysql-5.1-innodb to mysql-5.5-innodb.

parents 8d8784e9 0f8ae318
...@@ -1213,8 +1213,8 @@ btr_search_drop_page_hash_when_freed( ...@@ -1213,8 +1213,8 @@ btr_search_drop_page_hash_when_freed(
having to fear a deadlock. */ having to fear a deadlock. */
block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, NULL, block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, NULL,
BUF_GET_IF_IN_POOL, __FILE__, __LINE__, BUF_PEEK_IF_IN_POOL, __FILE__, __LINE__,
&mtr); &mtr);
/* Because the buffer pool mutex was released by /* Because the buffer pool mutex was released by
buf_page_peek_if_search_hashed(), it is possible that the buf_page_peek_if_search_hashed(), it is possible that the
block was removed from the buffer pool by another thread block was removed from the buffer pool by another thread
......
...@@ -2722,7 +2722,7 @@ buf_page_get_gen( ...@@ -2722,7 +2722,7 @@ buf_page_get_gen(
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
buf_block_t* guess, /*!< in: guessed block or NULL */ buf_block_t* guess, /*!< in: guessed block or NULL */
ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL, ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
BUF_GET_NO_LATCH, or BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or
BUF_GET_IF_IN_POOL_OR_WATCH */ BUF_GET_IF_IN_POOL_OR_WATCH */
const char* file, /*!< in: file name */ const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */ ulint line, /*!< in: line where called */
...@@ -2741,11 +2741,20 @@ buf_page_get_gen( ...@@ -2741,11 +2741,20 @@ buf_page_get_gen(
ut_ad((rw_latch == RW_S_LATCH) ut_ad((rw_latch == RW_S_LATCH)
|| (rw_latch == RW_X_LATCH) || (rw_latch == RW_X_LATCH)
|| (rw_latch == RW_NO_LATCH)); || (rw_latch == RW_NO_LATCH));
ut_ad((mode != BUF_GET_NO_LATCH) || (rw_latch == RW_NO_LATCH)); #ifdef UNIV_DEBUG
ut_ad(mode == BUF_GET switch (mode) {
|| mode == BUF_GET_IF_IN_POOL case BUF_GET_NO_LATCH:
|| mode == BUF_GET_NO_LATCH ut_ad(rw_latch == RW_NO_LATCH);
|| mode == BUF_GET_IF_IN_POOL_OR_WATCH); break;
case BUF_GET:
case BUF_GET_IF_IN_POOL:
case BUF_PEEK_IF_IN_POOL:
case BUF_GET_IF_IN_POOL_OR_WATCH:
break;
default:
ut_error;
}
#endif /* UNIV_DEBUG */
ut_ad(zip_size == fil_space_get_zip_size(space)); ut_ad(zip_size == fil_space_get_zip_size(space));
ut_ad(ut_is_2pow(zip_size)); ut_ad(ut_is_2pow(zip_size));
#ifndef UNIV_LOG_DEBUG #ifndef UNIV_LOG_DEBUG
...@@ -2805,6 +2814,7 @@ loop2: ...@@ -2805,6 +2814,7 @@ loop2:
buf_pool_mutex_exit(buf_pool); buf_pool_mutex_exit(buf_pool);
if (mode == BUF_GET_IF_IN_POOL if (mode == BUF_GET_IF_IN_POOL
|| mode == BUF_PEEK_IF_IN_POOL
|| mode == BUF_GET_IF_IN_POOL_OR_WATCH) { || mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
return(NULL); return(NULL);
...@@ -2845,7 +2855,8 @@ got_block: ...@@ -2845,7 +2855,8 @@ got_block:
must_read = buf_block_get_io_fix(block) == BUF_IO_READ; must_read = buf_block_get_io_fix(block) == BUF_IO_READ;
if (must_read && mode == BUF_GET_IF_IN_POOL) { if (must_read && (mode == BUF_GET_IF_IN_POOL
|| mode == BUF_PEEK_IF_IN_POOL)) {
/* The page is being read to buffer pool, /* The page is being read to buffer pool,
but we cannot wait around for the read to but we cannot wait around for the read to
...@@ -2968,6 +2979,7 @@ wait_until_unfixed: ...@@ -2968,6 +2979,7 @@ wait_until_unfixed:
mutex_exit(&buf_pool->zip_mutex); mutex_exit(&buf_pool->zip_mutex);
buf_pool->n_pend_unzip++; buf_pool->n_pend_unzip++;
bpage->state = BUF_BLOCK_ZIP_FREE;
buf_buddy_free(buf_pool, bpage, sizeof *bpage); buf_buddy_free(buf_pool, bpage, sizeof *bpage);
buf_pool_mutex_exit(buf_pool); buf_pool_mutex_exit(buf_pool);
...@@ -3061,7 +3073,9 @@ wait_until_unfixed: ...@@ -3061,7 +3073,9 @@ wait_until_unfixed:
buf_pool_mutex_exit(buf_pool); buf_pool_mutex_exit(buf_pool);
buf_page_set_accessed_make_young(&block->page, access_time); if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
buf_page_set_accessed_make_young(&block->page, access_time);
}
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!block->page.file_page_was_freed); ut_a(!block->page.file_page_was_freed);
...@@ -3114,7 +3128,7 @@ wait_until_unfixed: ...@@ -3114,7 +3128,7 @@ wait_until_unfixed:
mtr_memo_push(mtr, block, fix_type); mtr_memo_push(mtr, block, fix_type);
if (!access_time) { if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL) && !access_time) {
/* In the case of a first access, try to apply linear /* In the case of a first access, try to apply linear
read-ahead */ read-ahead */
...@@ -3703,6 +3717,7 @@ err_exit: ...@@ -3703,6 +3717,7 @@ err_exit:
/* The block was added by some other thread. */ /* The block was added by some other thread. */
watch_page = NULL; watch_page = NULL;
bpage->state = BUF_BLOCK_ZIP_FREE;
buf_buddy_free(buf_pool, bpage, sizeof *bpage); buf_buddy_free(buf_pool, bpage, sizeof *bpage);
buf_buddy_free(buf_pool, data, zip_size); buf_buddy_free(buf_pool, data, zip_size);
......
...@@ -247,74 +247,78 @@ buf_LRU_drop_page_hash_for_tablespace( ...@@ -247,74 +247,78 @@ buf_LRU_drop_page_hash_for_tablespace(
sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE); sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE);
buf_pool_mutex_enter(buf_pool); buf_pool_mutex_enter(buf_pool);
num_entries = 0;
scan_again: scan_again:
num_entries = 0;
bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) { while (bpage != NULL) {
mutex_t* block_mutex = buf_page_get_mutex(bpage);
buf_page_t* prev_bpage; buf_page_t* prev_bpage;
ibool is_fixed;
mutex_enter(block_mutex);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage); prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
ut_a(buf_page_in_file(bpage)); ut_a(buf_page_in_file(bpage));
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
|| bpage->space != id || bpage->space != id
|| bpage->buf_fix_count > 0
|| bpage->io_fix != BUF_IO_NONE) { || bpage->io_fix != BUF_IO_NONE) {
/* We leave the fixed pages as is in this scan. /* Compressed pages are never hashed.
To be dealt with later in the final scan. */ Skip blocks of other tablespaces.
mutex_exit(block_mutex); Skip I/O-fixed blocks (to be dealt with later). */
next_page:
bpage = prev_bpage;
continue;
}
mutex_enter(&((buf_block_t*) bpage)->mutex);
is_fixed = bpage->buf_fix_count > 0
|| !((buf_block_t*) bpage)->is_hashed;
mutex_exit(&((buf_block_t*) bpage)->mutex);
if (is_fixed) {
goto next_page; goto next_page;
} }
if (((buf_block_t*) bpage)->is_hashed) { /* Store the page number so that we can drop the hash
index in a batch later. */
page_arr[num_entries] = bpage->offset;
ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
++num_entries;
/* Store the offset(i.e.: page_no) in the array if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
so that we can drop hash index in a batch goto next_page;
later. */ }
page_arr[num_entries] = bpage->offset;
mutex_exit(block_mutex);
ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
++num_entries;
if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) { /* Array full. We release the buf_pool->mutex to obey
goto next_page; the latching order. */
} buf_pool_mutex_exit(buf_pool);
/* Array full. We release the buf_pool->mutex to buf_LRU_drop_page_hash_batch(
obey the latching order. */ id, zip_size, page_arr, num_entries);
buf_pool_mutex_exit(buf_pool);
buf_LRU_drop_page_hash_batch( num_entries = 0;
id, zip_size, page_arr, num_entries);
num_entries = 0; buf_pool_mutex_enter(buf_pool);
buf_pool_mutex_enter(buf_pool); /* Note that we released the buf_pool mutex above
} else { after reading the prev_bpage during processing of a
mutex_exit(block_mutex); page_hash_batch (i.e.: when the array was full).
} Because prev_bpage could belong to a compressed-only
block, it may have been relocated, and thus the
pointer cannot be trusted. Because bpage is of type
buf_block_t, it is safe to dereference.
next_page: bpage can change in the LRU list. This is OK because
/* Note that we may have released the buf_pool mutex this function is a 'best effort' to drop as many
above after reading the prev_bpage during processing search hash entries as possible and it does not
of a page_hash_batch (i.e.: when the array was full). guarantee that ALL such entries will be dropped. */
This means that prev_bpage can change in LRU list.
This is OK because this function is a 'best effort'
to drop as many search hash entries as possible and
it does not guarantee that ALL such entries will be
dropped. */
bpage = prev_bpage;
/* If, however, bpage has been removed from LRU list /* If, however, bpage has been removed from LRU list
to the free list then we should restart the scan. to the free list then we should restart the scan.
bpage->state is protected by buf_pool mutex. */ bpage->state is protected by buf_pool mutex. */
if (bpage && !buf_page_in_file(bpage)) { if (bpage
ut_a(num_entries == 0); && buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
goto scan_again; goto scan_again;
} }
} }
...@@ -1889,6 +1893,7 @@ buf_LRU_block_remove_hashed_page( ...@@ -1889,6 +1893,7 @@ buf_LRU_block_remove_hashed_page(
buf_pool, bpage->zip.data, buf_pool, bpage->zip.data,
page_zip_get_size(&bpage->zip)); page_zip_get_size(&bpage->zip));
bpage->state = BUF_BLOCK_ZIP_FREE;
buf_buddy_free(buf_pool, bpage, sizeof(*bpage)); buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
buf_pool_mutex_exit_allow(buf_pool); buf_pool_mutex_exit_allow(buf_pool);
......
...@@ -41,6 +41,8 @@ Created 11/5/1995 Heikki Tuuri ...@@ -41,6 +41,8 @@ Created 11/5/1995 Heikki Tuuri
/* @{ */ /* @{ */
#define BUF_GET 10 /*!< get always */ #define BUF_GET 10 /*!< get always */
#define BUF_GET_IF_IN_POOL 11 /*!< get if in pool */ #define BUF_GET_IF_IN_POOL 11 /*!< get if in pool */
#define BUF_PEEK_IF_IN_POOL 12 /*!< get if in pool, do not make
the block young in the LRU list */
#define BUF_GET_NO_LATCH 14 /*!< get and bufferfix, but #define BUF_GET_NO_LATCH 14 /*!< get and bufferfix, but
set no latch; we have set no latch; we have
separated this case, because separated this case, because
...@@ -396,7 +398,7 @@ buf_page_get_gen( ...@@ -396,7 +398,7 @@ buf_page_get_gen(
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
buf_block_t* guess, /*!< in: guessed block or NULL */ buf_block_t* guess, /*!< in: guessed block or NULL */
ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL, ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
BUF_GET_NO_LATCH or BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH or
BUF_GET_IF_IN_POOL_OR_WATCH */ BUF_GET_IF_IN_POOL_OR_WATCH */
const char* file, /*!< in: file name */ const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */ ulint line, /*!< in: line where called */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment