diff options
Diffstat (limited to 'storage/xtradb/buf/buf0buddy.cc')
-rw-r--r-- | storage/xtradb/buf/buf0buddy.cc | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/storage/xtradb/buf/buf0buddy.cc b/storage/xtradb/buf/buf0buddy.cc index 3f8f339a81a..8f6be0cf2af 100644 --- a/storage/xtradb/buf/buf0buddy.cc +++ b/storage/xtradb/buf/buf0buddy.cc @@ -131,7 +131,7 @@ buf_buddy_stamp_free( buf_buddy_free_t* buf, /*!< in/out: block to stamp */ ulint i) /*!< in: block size */ { - ut_d(memset(buf, i, BUF_BUDDY_LOW << i)); + ut_d(memset(buf, static_cast<int>(i), BUF_BUDDY_LOW << i)); buf_buddy_mem_invalid(buf, i); mach_write_to_4(buf->stamp.bytes + BUF_BUDDY_STAMP_OFFSET, BUF_BUDDY_STAMP_FREE); @@ -545,10 +545,8 @@ buf_buddy_relocate( { buf_page_t* bpage; const ulint size = BUF_BUDDY_LOW << i; - ib_mutex_t* mutex; ulint space; ulint offset; - prio_rw_lock_t* hash_lock; ut_ad(mutex_own(&buf_pool->zip_free_mutex)); ut_ad(!mutex_own(&buf_pool->zip_mutex)); @@ -570,8 +568,13 @@ buf_buddy_relocate( ut_ad(space != BUF_BUDDY_STAMP_FREE); mutex_exit(&buf_pool->zip_free_mutex); - /* Lock page hash to prevent a relocation for the target page */ - bpage = buf_page_hash_get_s_locked(buf_pool, space, offset, &hash_lock); + + ulint fold = buf_page_address_fold(space, offset); + prio_rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, fold); + + rw_lock_x_lock(hash_lock); + + bpage = buf_page_hash_get_low(buf_pool, space, offset, fold); if (!bpage || bpage->zip.data != src) { /* The block has probably been freshly @@ -579,9 +582,8 @@ buf_buddy_relocate( added to buf_pool->page_hash yet. Obviously, it cannot be relocated. */ - if (bpage) { - rw_lock_s_unlock(hash_lock); - } + rw_lock_x_unlock(hash_lock); + mutex_enter(&buf_pool->zip_free_mutex); return(false); } @@ -592,7 +594,8 @@ buf_buddy_relocate( For the sake of simplicity, give up. */ ut_ad(page_zip_get_size(&bpage->zip) < size); - rw_lock_s_unlock(hash_lock); + rw_lock_x_unlock(hash_lock); + mutex_enter(&buf_pool->zip_free_mutex); return(false); } @@ -601,31 +604,44 @@ buf_buddy_relocate( contain uninitialized data. */ UNIV_MEM_ASSERT_W(src, size); - mutex = buf_page_get_mutex(bpage); - - mutex_enter(mutex); + ib_mutex_t* block_mutex = buf_page_get_mutex(bpage); - rw_lock_s_unlock(hash_lock); + mutex_enter(block_mutex); mutex_enter(&buf_pool->zip_free_mutex); if (buf_page_can_relocate(bpage)) { /* Relocate the compressed page. */ - ullint usec = ut_time_us(NULL); + ullint usec = ut_time_us(NULL); + ut_a(bpage->zip.data == src); - memcpy(dst, src, size); - bpage->zip.data = (page_zip_t*) dst; - mutex_exit(mutex); + + /* Note: This is potentially expensive, we need a better + solution here. We go with correctness for now. */ + ::memcpy(dst, src, size); + + bpage->zip.data = reinterpret_cast<page_zip_t*>(dst); + + rw_lock_x_unlock(hash_lock); + + mutex_exit(block_mutex); + buf_buddy_mem_invalid( reinterpret_cast<buf_buddy_free_t*>(src), i); buf_buddy_stat_t* buddy_stat = &buf_pool->buddy_stat[i]; - buddy_stat->relocated++; + + ++buddy_stat->relocated; + buddy_stat->relocated_usec += ut_time_us(NULL) - usec; + return(true); } - mutex_exit(mutex); + rw_lock_x_unlock(hash_lock); + + mutex_exit(block_mutex); + return(false); } |