mirror of
https://github.com/MariaDB/server.git
synced 2025-02-01 03:21:53 +01:00
Applying InnoDB snapshot, fixes BUG#35077.
Detailed revision comments: r6548 | marko | 2010-02-03 15:01:39 +0200 (Wed, 03 Feb 2010) | 11 lines branches/zip: buf_LRU_invalidate_tablespace(): Ensure that prev_bpage is not relocated when freeing a compressed block. This avoids the costly rescan of the LRU list. (Bug #35077, Issue #449) At most one buffer-fix will be active at a time, affecting two blocks: the buf_page_t and the compressed page frame. This should not block the memory defragmentation in buf0buddy.c too much. In fact, it may avoid unnecessary copying if also prev_bpage belongs to the tablespace that is being invalidated. rb://240
This commit is contained in:
parent
101d6a09cb
commit
409e884391
2 changed files with 58 additions and 10 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2010-02-03 The InnoDB Team
|
||||||
|
|
||||||
|
* buf/buf0lru.c:
|
||||||
|
Fix Bug#35077 Very slow DROP TABLE (ALTER TABLE, OPTIMIZE TABLE)
|
||||||
|
on compressed tables
|
||||||
|
|
||||||
2010-02-03 The InnoDB Team
|
2010-02-03 The InnoDB Team
|
||||||
|
|
||||||
* handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c:
|
* handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c:
|
||||||
|
|
|
@ -347,11 +347,11 @@ scan_again:
|
||||||
|
|
||||||
all_freed = TRUE;
|
all_freed = TRUE;
|
||||||
|
|
||||||
rescan:
|
|
||||||
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||||
|
|
||||||
while (bpage != NULL) {
|
while (bpage != NULL) {
|
||||||
buf_page_t* prev_bpage;
|
buf_page_t* prev_bpage;
|
||||||
|
ibool prev_bpage_buf_fix = FALSE;
|
||||||
|
|
||||||
ut_a(buf_page_in_file(bpage));
|
ut_a(buf_page_in_file(bpage));
|
||||||
|
|
||||||
|
@ -394,8 +394,40 @@ rescan:
|
||||||
(ulong) buf_page_get_page_no(bpage));
|
(ulong) buf_page_get_page_no(bpage));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE
|
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
|
||||||
&& ((buf_block_t*) bpage)->is_hashed) {
|
/* This is a compressed-only block
|
||||||
|
descriptor. Ensure that prev_bpage
|
||||||
|
cannot be relocated when bpage is freed. */
|
||||||
|
if (UNIV_LIKELY(prev_bpage != NULL)) {
|
||||||
|
switch (buf_page_get_state(
|
||||||
|
prev_bpage)) {
|
||||||
|
case BUF_BLOCK_FILE_PAGE:
|
||||||
|
/* Descriptors of uncompressed
|
||||||
|
blocks will not be relocated,
|
||||||
|
because we are holding the
|
||||||
|
buf_pool_mutex. */
|
||||||
|
break;
|
||||||
|
case BUF_BLOCK_ZIP_PAGE:
|
||||||
|
case BUF_BLOCK_ZIP_DIRTY:
|
||||||
|
/* Descriptors of compressed-
|
||||||
|
only blocks can be relocated,
|
||||||
|
unless they are buffer-fixed.
|
||||||
|
Because both bpage and
|
||||||
|
prev_bpage are protected by
|
||||||
|
buf_pool_zip_mutex, it is
|
||||||
|
not necessary to acquire
|
||||||
|
further mutexes. */
|
||||||
|
ut_ad(&buf_pool_zip_mutex
|
||||||
|
== block_mutex);
|
||||||
|
ut_ad(mutex_own(block_mutex));
|
||||||
|
prev_bpage_buf_fix = TRUE;
|
||||||
|
prev_bpage->buf_fix_count++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ut_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (((buf_block_t*) bpage)->is_hashed) {
|
||||||
ulint page_no;
|
ulint page_no;
|
||||||
ulint zip_size;
|
ulint zip_size;
|
||||||
|
|
||||||
|
@ -419,7 +451,8 @@ rescan:
|
||||||
buf_flush_remove(bpage);
|
buf_flush_remove(bpage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove from the LRU list */
|
/* Remove from the LRU list. */
|
||||||
|
|
||||||
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
|
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
|
||||||
!= BUF_BLOCK_ZIP_FREE) {
|
!= BUF_BLOCK_ZIP_FREE) {
|
||||||
buf_LRU_block_free_hashed_page((buf_block_t*)
|
buf_LRU_block_free_hashed_page((buf_block_t*)
|
||||||
|
@ -431,18 +464,27 @@ rescan:
|
||||||
ut_ad(block_mutex == &buf_pool_zip_mutex);
|
ut_ad(block_mutex == &buf_pool_zip_mutex);
|
||||||
ut_ad(!mutex_own(block_mutex));
|
ut_ad(!mutex_own(block_mutex));
|
||||||
|
|
||||||
/* The compressed block descriptor
|
if (prev_bpage_buf_fix) {
|
||||||
(bpage) has been deallocated and
|
/* We temporarily buffer-fixed
|
||||||
block_mutex released. Also,
|
prev_bpage, so that
|
||||||
buf_buddy_free() may have relocated
|
buf_buddy_free() could not
|
||||||
prev_bpage. Rescan the LRU list. */
|
relocate it, in case it was a
|
||||||
|
compressed-only block
|
||||||
|
descriptor. */
|
||||||
|
|
||||||
goto rescan;
|
mutex_enter(block_mutex);
|
||||||
|
ut_ad(prev_bpage->buf_fix_count > 0);
|
||||||
|
prev_bpage->buf_fix_count--;
|
||||||
|
mutex_exit(block_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
goto next_page_no_mutex;
|
||||||
}
|
}
|
||||||
next_page:
|
next_page:
|
||||||
mutex_exit(block_mutex);
|
mutex_exit(block_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next_page_no_mutex:
|
||||||
bpage = prev_bpage;
|
bpage = prev_bpage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue