List:Commits« Previous MessageNext Message »
From:Sergey Vojtovich Date:April 1 2010 11:37am
Subject:bzr commit into mysql-5.1-bugteam branch (svoj:3478) Bug#35077
View as plain text  
#At file:///home/svoj/devel/innodb-snapshots/mysql-5.1-bugteam/ based on revid:svoj@stripped

 3478 Sergey Vojtovich	2010-04-01
      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

    modified:
      storage/innodb_plugin/ChangeLog
      storage/innodb_plugin/buf/buf0lru.c
=== modified file 'storage/innodb_plugin/ChangeLog'
--- a/storage/innodb_plugin/ChangeLog	2010-04-01 11:36:27 +0000
+++ b/storage/innodb_plugin/ChangeLog	2010-04-01 11:36:54 +0000
@@ -1,5 +1,11 @@
 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
+
 	* handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c:
 	Clean up CHECK TABLE error handling.
 

=== modified file 'storage/innodb_plugin/buf/buf0lru.c'
--- a/storage/innodb_plugin/buf/buf0lru.c	2010-04-01 11:27:18 +0000
+++ b/storage/innodb_plugin/buf/buf0lru.c	2010-04-01 11:36:54 +0000
@@ -347,11 +347,11 @@ scan_again:
 
 	all_freed = TRUE;
 
-rescan:
 	bpage = UT_LIST_GET_LAST(buf_pool->LRU);
 
 	while (bpage != NULL) {
 		buf_page_t*	prev_bpage;
+		ibool		prev_bpage_buf_fix = FALSE;
 
 		ut_a(buf_page_in_file(bpage));
 
@@ -394,8 +394,40 @@ rescan:
 					(ulong) buf_page_get_page_no(bpage));
 			}
 #endif
-			if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE
-			    && ((buf_block_t*) bpage)->is_hashed) {
+			if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
+				/* 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	zip_size;
 
@@ -419,7 +451,8 @@ rescan:
 				buf_flush_remove(bpage);
 			}
 
-			/* Remove from the LRU list */
+			/* Remove from the LRU list. */
+
 			if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
 			    != BUF_BLOCK_ZIP_FREE) {
 				buf_LRU_block_free_hashed_page((buf_block_t*)
@@ -431,18 +464,27 @@ rescan:
 				ut_ad(block_mutex == &buf_pool_zip_mutex);
 				ut_ad(!mutex_own(block_mutex));
 
-				/* The compressed block descriptor
-				(bpage) has been deallocated and
-				block_mutex released.  Also,
-				buf_buddy_free() may have relocated
-				prev_bpage.  Rescan the LRU list. */
+				if (prev_bpage_buf_fix) {
+					/* We temporarily buffer-fixed
+					prev_bpage, so that
+					buf_buddy_free() could not
+					relocate it, in case it was a
+					compressed-only block
+					descriptor. */
+
+					mutex_enter(block_mutex);
+					ut_ad(prev_bpage->buf_fix_count > 0);
+					prev_bpage->buf_fix_count--;
+					mutex_exit(block_mutex);
+				}
 
-				goto rescan;
+				goto next_page_no_mutex;
 			}
 next_page:
 			mutex_exit(block_mutex);
 		}
 
+next_page_no_mutex:
 		bpage = prev_bpage;
 	}
 


Attachment: [text/bzr-bundle] bzr/svoj@sun.com-20100401113654-grersf4w0gbyzl5l.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (svoj:3478) Bug#35077Sergey Vojtovich1 Apr