[packages/percona-server/v5.0.x: 125/202] - update percona patches, automate that process

glen glen at pld-linux.org
Wed Oct 21 16:19:32 CEST 2015


commit 89b96684163deacc27b2a228767108d067e65a4c
Author: Elan Ruusamäe <glen at pld-linux.org>
Date:   Wed Aug 26 10:17:02 2009 +0000

    - update percona patches, automate that process
    
    Changed files:
        mysql-innodb_dict_size_limit.patch -> 1.1.2.1
        mysql-innodb_extra_rseg.patch -> 1.1.2.1
        mysql-innodb_fsync_source.patch -> 1.1.2.2
        mysql-innodb_io_patches.patch -> 1.1.2.5
        mysql-innodb_io_pattern.patch -> 1.1.2.4
        mysql-innodb_locks_held.patch -> 1.1.2.5
        mysql-innodb_recovery_patches.patch -> 1.1.2.1
        mysql-innodb_rw_lock.patch -> 1.1.2.4
        mysql-innodb_show_bp.patch -> 1.1.2.2
        mysql-innodb_split_buf_pool_mutex.patch -> 1.1.2.1
        mysql-innodb_thread_concurrency_timer_based.patch -> 1.1.2.1
        mysql-innodb_use_sys_malloc.patch -> 1.1.2.1
        mysql-microslow_innodb.patch -> 1.1.2.11
        mysql-profiling_slow.patch -> 1.1.2.1
        mysql-userstatv2.patch -> 1.1.2.11
        mysql.spec -> 1.353.2.76

 mysql-innodb_dict_size_limit.patch                |  270 +--
 mysql-innodb_extra_rseg.patch                     |  116 +-
 mysql-innodb_fsync_source.patch                   |   92 +-
 mysql-innodb_io_patches.patch                     |  854 +++++++++-
 mysql-innodb_io_pattern.patch                     |  197 +--
 mysql-innodb_locks_held.patch                     |    8 +-
 mysql-innodb_recovery_patches.patch               |  217 +++
 mysql-innodb_rw_lock.patch                        |    2 +-
 mysql-innodb_show_bp.patch                        |    8 +-
 mysql-innodb_split_buf_pool_mutex.patch           | 1870 +++++++++++++++++++++
 mysql-innodb_thread_concurrency_timer_based.patch |   93 +-
 mysql-innodb_use_sys_malloc.patch                 |  265 +++
 mysql-microslow_innodb.patch                      |  249 ++-
 mysql-profiling_slow.patch                        |   44 +-
 mysql-userstatv2.patch                            |  828 ++++-----
 mysql.spec                                        |   80 +-
 16 files changed, 4080 insertions(+), 1113 deletions(-)
---
diff --git a/mysql.spec b/mysql.spec
index a19fb37..2581941 100644
--- a/mysql.spec
+++ b/mysql.spec
@@ -65,24 +65,26 @@ Patch13:	%{name}-bug-34192.patch
 Patch14:	%{name}-bug-16470.patch
 Patch15:	%{name}-system-users.patch
 # <percona patches, http://www.percona.com/percona-lab.html>
-Patch16:	%{name}-show_patches.patch
-Patch17:	%{name}-microslow_innodb.patch
-Patch18:	%{name}-profiling_slow.patch
-Patch19:	%{name}-userstatv2.patch
-Patch20:	%{name}-microsec_process.patch
-Patch21:	%{name}-innodb_io_patches.patch
-Patch22:	%{name}-innodb_locks_held.patch
-Patch23:	%{name}-innodb_show_bp.patch
-Patch24:	%{name}-innodb_check_fragmentation.patch
-Patch25:	%{name}-innodb_io_pattern.patch
-Patch26:	%{name}-innodb_fsync_source.patch
-Patch27:	%{name}-innodb_show_hashed_memory.patch
-Patch28:	%{name}-innodb_dict_size_limit.patch
-Patch29:	%{name}-innodb_extra_rseg.patch
-Patch30:	%{name}-innodb_thread_concurrency_timer_based.patch
-Patch31:	%{name}-split_buf_pool_mutex_fixed_optimistic_safe.patch
-Patch32:	%{name}-innodb_rw_lock.patch
-Patch33:	%{name}-mysql-test.patch
+Patch100:	%{name}-show_patches.patch
+Patch101:	%{name}-microslow_innodb.patch
+Patch102:	%{name}-profiling_slow.patch
+Patch103:	%{name}-userstatv2.patch
+Patch104:	%{name}-microsec_process.patch
+Patch105:	%{name}-innodb_io_patches.patch
+Patch106:	%{name}-innodb_locks_held.patch
+Patch107:	%{name}-innodb_show_bp.patch
+Patch108:	%{name}-innodb_check_fragmentation.patch
+Patch109:	%{name}-innodb_io_pattern.patch
+Patch110:	%{name}-innodb_fsync_source.patch
+Patch111:	%{name}-innodb_show_hashed_memory.patch
+Patch112:	%{name}-innodb_dict_size_limit.patch
+Patch113:	%{name}-innodb_extra_rseg.patch
+Patch114:	%{name}-innodb_thread_concurrency_timer_based.patch
+Patch115:	%{name}-innodb_use_sys_malloc.patch
+Patch116:	%{name}-innodb_recovery_patches.patch
+Patch117:	%{name}-innodb_split_buf_pool_mutex.patch
+Patch118:	%{name}-innodb_rw_lock.patch
+Patch119:	%{name}-mysql-test.patch
 # </percona>
 Patch34:	%{name}-errorlog-no-rename.patch
 Patch35:	%{name}-alpha-stack.patch
@@ -515,24 +517,30 @@ mv sphinx-*/mysqlse sql/sphinx
 %patch13 -p1
 %patch14 -p1
 %patch15 -p1
-%patch16 -p1
-%patch17 -p1
-%patch18 -p1
-%patch19 -p1
-%patch20 -p1
-%patch21 -p1
-%patch22 -p1
-%patch23 -p1
-%patch24 -p1
-%patch25 -p1
-%patch26 -p1
-%patch27 -p1
-%patch28 -p1
-%patch29 -p1
-%patch30 -p1
-%patch31 -p1
-%patch32 -p1
-%patch33 -p1
+
+# <percona %patches
+%patch100 -p1
+%patch101 -p1
+%patch102 -p1
+%patch103 -p1
+%patch104 -p1
+%patch105 -p1
+%patch106 -p1
+%patch107 -p1
+%patch108 -p1
+%patch109 -p1
+%patch110 -p1
+%patch111 -p1
+%patch112 -p1
+%patch113 -p1
+%patch114 -p1
+%patch115 -p1
+%patch116 -p1
+%patch117 -p1
+%patch118 -p1
+%patch119 -p1
+# </percona>
+
 %patch34 -p1
 %ifarch alpha
 %patch35 -p1
diff --git a/mysql-innodb_dict_size_limit.patch b/mysql-innodb_dict_size_limit.patch
index 8ef4e36..843d043 100644
--- a/mysql-innodb_dict_size_limit.patch
+++ b/mysql-innodb_dict_size_limit.patch
@@ -1,6 +1,6 @@
-diff -ru mysql-5.0.75_base/innobase/dict/dict0boot.c mysql-5.0.75/innobase/dict/dict0boot.c
---- mysql-5.0.75_base/innobase/dict/dict0boot.c	2008-12-19 02:19:35.000000000 +0900
-+++ mysql-5.0.75/innobase/dict/dict0boot.c	2009-01-23 19:28:25.000000000 +0900
+diff -r 6eeee157fd40 innobase/dict/dict0boot.c
+--- a/innobase/dict/dict0boot.c	Fri Jul 03 15:41:34 2009 -0700
++++ b/innobase/dict/dict0boot.c	Fri Jul 03 15:41:41 2009 -0700
 @@ -247,6 +247,7 @@
  	system tables */
  	/*-------------------------*/
@@ -33,9 +33,9 @@ diff -ru mysql-5.0.75_base/innobase/dict/dict0boot.c mysql-5.0.75/innobase/dict/
  
  	dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0);
  	dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
-diff -ru mysql-5.0.75_base/innobase/dict/dict0crea.c mysql-5.0.75/innobase/dict/dict0crea.c
---- mysql-5.0.75_base/innobase/dict/dict0crea.c	2008-12-19 02:19:35.000000000 +0900
-+++ mysql-5.0.75/innobase/dict/dict0crea.c	2009-01-23 19:41:38.000000000 +0900
+diff -r 6eeee157fd40 innobase/dict/dict0crea.c
+--- a/innobase/dict/dict0crea.c	Fri Jul 03 15:41:34 2009 -0700
++++ b/innobase/dict/dict0crea.c	Fri Jul 03 15:41:41 2009 -0700
 @@ -1178,6 +1178,9 @@
              	/* Foreign constraint system tables have already been
              	created, and they are ok */
@@ -47,20 +47,20 @@ diff -ru mysql-5.0.75_base/innobase/dict/dict0crea.c mysql-5.0.75/innobase/dict/
  
              	return(DB_SUCCESS);
 @@ -1266,6 +1269,11 @@
+ 	que_graph_free(graph);
  	
  	trx->op_info = "";
- 
++
 +	table1 = dict_table_get_low("SYS_FOREIGN");
 +	table2 = dict_table_get_low("SYS_FOREIGN_COLS");
 +	table1->n_mysql_handles_opened = 1; /* for pin */
 +	table2->n_mysql_handles_opened = 1; /* for pin */
-+
+ 
  	row_mysql_unlock_data_dictionary(trx);
  
-   	trx_free_for_mysql(trx);
-diff -ru mysql-5.0.75_base/innobase/dict/dict0dict.c mysql-5.0.75/innobase/dict/dict0dict.c
---- mysql-5.0.75_base/innobase/dict/dict0dict.c	2008-12-19 02:19:35.000000000 +0900
-+++ mysql-5.0.75/innobase/dict/dict0dict.c	2009-01-26 16:03:29.000000000 +0900
+diff -r 6eeee157fd40 innobase/dict/dict0dict.c
+--- a/innobase/dict/dict0dict.c	Fri Jul 03 15:41:34 2009 -0700
++++ b/innobase/dict/dict0dict.c	Fri Jul 03 15:41:41 2009 -0700
 @@ -638,6 +638,8 @@
  	mutex_enter(&(dict_sys->mutex));
  
@@ -79,15 +79,15 @@ diff -ru mysql-5.0.75_base/innobase/dict/dict0dict.c mysql-5.0.75/innobase/dict/
  	mutex_exit(&(dict_sys->mutex));
  
  	if (table != NULL) {
-@@ -787,6 +791,8 @@
+@@ -786,6 +790,8 @@
+ 
  	        table->n_mysql_handles_opened++;
  	}
- 
-+	dict_table_LRU_trim(table);
 +
++	dict_table_LRU_trim(table);
+ 
  	mutex_exit(&(dict_sys->mutex));
  
- 	if (table != NULL) {
 @@ -1267,20 +1273,64 @@
  too much space. Currently not used! */
  
@@ -100,18 +100,24 @@ diff -ru mysql-5.0.75_base/innobase/dict/dict0dict.c mysql-5.0.75/innobase/dict/
  {
  	dict_table_t*	table;
  	dict_table_t*	prev_table;
+-
+-	ut_error;
+-
+-#ifdef UNIV_SYNC_DEBUG
+-	ut_ad(mutex_own(&(dict_sys->mutex)));
+-#endif /* UNIV_SYNC_DEBUG */
+-
 +	dict_foreign_t*	foreign;
 +	ulint		n_removed;
 +	ulint		n_have_parent;
 +	ulint		cached_foreign_tables;
- 
--	ut_error;
++
 +	//ut_error;
- 
- #ifdef UNIV_SYNC_DEBUG
- 	ut_ad(mutex_own(&(dict_sys->mutex)));
- #endif /* UNIV_SYNC_DEBUG */
- 
++
++#ifdef UNIV_SYNC_DEBUG
++	ut_ad(mutex_own(&(dict_sys->mutex)));
++#endif /* UNIV_SYNC_DEBUG */
++
 +retry:
 +	n_removed = n_have_parent = 0;
  	table = UT_LIST_GET_LAST(dict_sys->table_LRU);
@@ -156,7 +162,7 @@ diff -ru mysql-5.0.75_base/innobase/dict/dict0dict.c mysql-5.0.75/innobase/dict/
  	while (table && (dict_sys->size >
  			 buf_pool_get_max_size() / DICT_POOL_PER_VARYING)) {
  
-@@ -1292,6 +1341,7 @@
+@@ -1292,6 +1342,7 @@
  
  		table = prev_table;
  	}
@@ -164,9 +170,9 @@ diff -ru mysql-5.0.75_base/innobase/dict/dict0dict.c mysql-5.0.75/innobase/dict/
  }
  
  /**************************************************************************
-diff -ru mysql-5.0.75_base/innobase/ibuf/ibuf0ibuf.c mysql-5.0.75/innobase/ibuf/ibuf0ibuf.c
---- mysql-5.0.75_base/innobase/ibuf/ibuf0ibuf.c	2009-01-23 11:44:18.000000000 +0900
-+++ mysql-5.0.75/innobase/ibuf/ibuf0ibuf.c	2009-01-23 19:22:54.000000000 +0900
+diff -r 6eeee157fd40 innobase/ibuf/ibuf0ibuf.c
+--- a/innobase/ibuf/ibuf0ibuf.c	Fri Jul 03 15:41:34 2009 -0700
++++ b/innobase/ibuf/ibuf0ibuf.c	Fri Jul 03 15:41:41 2009 -0700
 @@ -535,6 +535,7 @@
  	sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space);
  	/* use old-style record format for the insert buffer */
@@ -175,9 +181,9 @@ diff -ru mysql-5.0.75_base/innobase/ibuf/ibuf0ibuf.c mysql-5.0.75/innobase/ibuf/
  
  	dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0);
  	dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0);
-diff -ru mysql-5.0.75_base/innobase/include/dict0dict.h mysql-5.0.75/innobase/include/dict0dict.h
---- mysql-5.0.75_base/innobase/include/dict0dict.h	2008-12-19 02:19:35.000000000 +0900
-+++ mysql-5.0.75/innobase/include/dict0dict.h	2009-01-23 21:46:22.000000000 +0900
+diff -r 6eeee157fd40 innobase/include/dict0dict.h
+--- a/innobase/include/dict0dict.h	Fri Jul 03 15:41:34 2009 -0700
++++ b/innobase/include/dict0dict.h	Fri Jul 03 15:41:41 2009 -0700
 @@ -938,6 +938,11 @@
  	const char*	ptr,	/* in: scan from */
  	const char*	string);/* in: look for this */
@@ -190,9 +196,9 @@ diff -ru mysql-5.0.75_base/innobase/include/dict0dict.h mysql-5.0.75/innobase/in
  /* Buffers for storing detailed information about the latest foreign key
  and unique key errors */
  extern FILE*	dict_foreign_err_file;
-diff -ru mysql-5.0.75_base/innobase/include/dict0dict.ic mysql-5.0.75/innobase/include/dict0dict.ic
---- mysql-5.0.75_base/innobase/include/dict0dict.ic	2008-12-19 02:19:35.000000000 +0900
-+++ mysql-5.0.75/innobase/include/dict0dict.ic	2009-01-23 18:35:55.000000000 +0900
+diff -r 6eeee157fd40 innobase/include/dict0dict.ic
+--- a/innobase/include/dict0dict.ic	Fri Jul 03 15:41:34 2009 -0700
++++ b/innobase/include/dict0dict.ic	Fri Jul 03 15:41:41 2009 -0700
 @@ -533,6 +533,13 @@
  
  	HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold, table,
@@ -218,19 +224,19 @@ diff -ru mysql-5.0.75_base/innobase/include/dict0dict.ic mysql-5.0.75/innobase/i
  		/* lock_push(trx, table, LOCK_DICT_MEM_FIX) */
  	}
  	
-diff -ru mysql-5.0.75_base/innobase/include/srv0srv.h mysql-5.0.75/innobase/include/srv0srv.h
---- mysql-5.0.75_base/innobase/include/srv0srv.h	2009-01-23 11:44:19.000000000 +0900
-+++ mysql-5.0.75/innobase/include/srv0srv.h	2009-01-27 10:47:26.000000000 +0900
+diff -r 6eeee157fd40 innobase/include/srv0srv.h
+--- a/innobase/include/srv0srv.h	Fri Jul 03 15:41:34 2009 -0700
++++ b/innobase/include/srv0srv.h	Fri Jul 03 15:41:41 2009 -0700
 @@ -146,6 +146,8 @@
+ extern ulint	srv_enable_unsafe_group_commit;
  extern uint	srv_read_ahead;
- extern ulint	srv_adaptive_checkpoint;
- 
-+extern ulint	srv_dict_size_limit;
+ extern uint	srv_adaptive_checkpoint;
 +
++extern ulint	srv_dict_size_limit;
+ 
  extern volatile ibool srv_io_pattern;
  extern ulong	srv_io_pattern_trace;
- extern ulong	srv_io_pattern_trace_running;
-@@ -545,6 +547,7 @@
+@@ -552,6 +554,7 @@
          ulint innodb_data_writes;
          ulint innodb_data_written;
          ulint innodb_data_reads;
@@ -238,19 +244,19 @@ diff -ru mysql-5.0.75_base/innobase/include/srv0srv.h mysql-5.0.75/innobase/incl
          ulint innodb_buffer_pool_pages_total;
          ulint innodb_buffer_pool_pages_data;
          ulint innodb_buffer_pool_pages_dirty;
-diff -ru mysql-5.0.75_base/innobase/srv/srv0srv.c mysql-5.0.75/innobase/srv/srv0srv.c
---- mysql-5.0.75_base/innobase/srv/srv0srv.c	2009-01-23 11:44:19.000000000 +0900
-+++ mysql-5.0.75/innobase/srv/srv0srv.c	2009-01-27 10:52:19.000000000 +0900
-@@ -345,6 +345,8 @@
- uint	srv_read_ahead = 3; /* 1: random  2: linear  3: Both */
- ulint	srv_adaptive_checkpoint = 0; /* 0:disable 1:enable */
+diff -r 6eeee157fd40 innobase/srv/srv0srv.c
+--- a/innobase/srv/srv0srv.c	Fri Jul 03 15:41:34 2009 -0700
++++ b/innobase/srv/srv0srv.c	Fri Jul 03 15:41:41 2009 -0700
+@@ -352,6 +352,8 @@
  
-+ulint	srv_dict_size_limit = 0;
+ uint	srv_read_ahead = 3; /* 1: random  2: linear  3: Both */
+ uint	srv_adaptive_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
 +
++ulint	srv_dict_size_limit = 0;
+ 
  volatile ibool srv_io_pattern = FALSE;
  ulint   srv_io_pattern_trace = 0;
- ulint   srv_io_pattern_trace_running = 0;
-@@ -1936,6 +1938,7 @@
+@@ -1953,6 +1955,7 @@
          export_vars.innodb_data_reads= os_n_file_reads;
          export_vars.innodb_data_writes= os_n_file_writes;
          export_vars.innodb_data_written= srv_data_written;
@@ -258,82 +264,9 @@ diff -ru mysql-5.0.75_base/innobase/srv/srv0srv.c mysql-5.0.75/innobase/srv/srv0
          export_vars.innodb_buffer_pool_read_requests= buf_pool->n_page_gets;
          export_vars.innodb_buffer_pool_write_requests= srv_buf_pool_write_requests;
          export_vars.innodb_buffer_pool_wait_free= srv_buf_pool_wait_free;
-diff -ru mysql-5.0.75_base/sql/ha_innodb.cc mysql-5.0.75/sql/ha_innodb.cc
---- mysql-5.0.75_base/sql/ha_innodb.cc	2009-01-23 11:44:19.000000000 +0900
-+++ mysql-5.0.75/sql/ha_innodb.cc	2009-01-27 10:54:08.000000000 +0900
-@@ -288,6 +288,8 @@
-   (char*) &export_vars.innodb_dblwr_pages_written,        SHOW_LONG},
-   {"dblwr_writes",
-   (char*) &export_vars.innodb_dblwr_writes,               SHOW_LONG},
-+  {"dict_tables",
-+  (char*) &export_vars.innodb_dict_tables,                SHOW_LONG},
-   {"log_waits",
-   (char*) &export_vars.innodb_log_waits,                  SHOW_LONG},
-   {"log_write_requests",
-diff -ru mysql-5.0.75_base/sql/ha_innodb.h mysql-5.0.75/sql/ha_innodb.h
---- mysql-5.0.75_base/sql/ha_innodb.h	2009-01-23 11:44:19.000000000 +0900
-+++ mysql-5.0.75/sql/ha_innodb.h	2009-01-26 15:49:37.000000000 +0900
-@@ -242,6 +242,7 @@
- extern ulong srv_flush_neighbor_pages;
- extern uint srv_read_ahead;
- extern ulong srv_adaptive_checkpoint;
-+extern ulong srv_dict_size_limit;
- extern ulong srv_show_locks_held;
- extern ulong srv_show_verbose_locks;
- extern ulong srv_io_pattern_trace;
-diff -ru mysql-5.0.75_base/sql/mysqld.cc mysql-5.0.75/sql/mysqld.cc
---- mysql-5.0.75_base/sql/mysqld.cc	2009-01-23 11:44:19.000000000 +0900
-+++ mysql-5.0.75/sql/mysqld.cc	2009-01-26 15:29:45.000000000 +0900
-@@ -5053,6 +5053,7 @@
-   OPT_INNODB_ADAPTIVE_CHECKPOINT,
-   OPT_INNODB_READ_IO_THREADS,
-   OPT_INNODB_WRITE_IO_THREADS,
-+  OPT_INNODB_DICT_SIZE_LIMIT,
-   OPT_INNODB_ADAPTIVE_HASH_INDEX,
-   OPT_RPL_MIRROR_BINLOG,
-   OPT_SYNC_MIRROR_BINLOG,
-@@ -5406,6 +5407,10 @@
-    "Number of background write I/O threads in InnoDB.",
-    (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads,
-    0, GET_LONG, REQUIRED_ARG, 1, 1, 64, 0, 0, 0},
-+  {"innodb_dict_size_limit", OPT_INNODB_DICT_SIZE_LIMIT,
-+   "Limit the allocated memory for dictionary cache. (0: unlimited)",
-+   (gptr*) &srv_dict_size_limit, (gptr*) &srv_dict_size_limit, 0,
-+   GET_ULONG, REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 0 ,0},
-   {"innodb_io_pattern_trace", OPT_INNODB_IO_PATTERN_TRACE,
-    "Create/Drop the internal hash table for IO pattern tracing.",
-    (gptr*) &srv_io_pattern_trace, (gptr*) &srv_io_pattern_trace,
-diff -ru mysql-5.0.75_base/sql/set_var.cc mysql-5.0.75/sql/set_var.cc
---- mysql-5.0.75_base/sql/set_var.cc	2009-01-23 11:44:19.000000000 +0900
-+++ mysql-5.0.75/sql/set_var.cc	2009-01-26 15:46:45.000000000 +0900
-@@ -522,6 +522,8 @@
-                                       &innodb_read_ahead_typelib, fix_innodb_read_ahead);
- sys_var_long_ptr	sys_innodb_adaptive_checkpoint("innodb_adaptive_checkpoint",
-                                                       &srv_adaptive_checkpoint);
-+sys_var_long_ptr	sys_innodb_dict_size_limit("innodb_dict_size_limit",
-+                                                   &srv_dict_size_limit);
- sys_var_long_ptr  sys_innodb_show_locks_held(
-                                         "innodb_show_locks_held",
-                                         &srv_show_locks_held);
-@@ -905,6 +907,7 @@
-   &sys_innodb_flush_neighbor_pages,
-   &sys_innodb_read_ahead,
-   &sys_innodb_adaptive_checkpoint,
-+  &sys_innodb_dict_size_limit,
-   &sys_innodb_show_locks_held,
-   &sys_innodb_show_verbose_locks,
-   &sys_innodb_io_pattern_trace,
-@@ -1056,6 +1059,7 @@
-   {sys_innodb_adaptive_checkpoint.name, (char*) &sys_innodb_adaptive_checkpoint, SHOW_SYS},
-   {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG},
-   {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG},
-+  {sys_innodb_dict_size_limit.name, (char*) &sys_innodb_dict_size_limit, SHOW_SYS},
-   {sys_innodb_io_pattern_trace.name, (char*) &sys_innodb_io_pattern_trace, SHOW_SYS},
-   {sys_innodb_io_pattern_trace_running.name, (char*) &sys_innodb_io_pattern_trace_running, SHOW_SYS},
-   {sys_innodb_io_pattern_size_limit.name, (char*) &sys_innodb_io_pattern_size_limit, SHOW_SYS},
-diff -ruN mysql-5.0.75_base/mysql-test/r/innodb_dict_size_limit.result mysql-5.0.75/mysql-test/r/innodb_dict_size_limit.result
---- /dev/null	1970-01-01 09:00:00.000000000 +0900
-+++ mysql-5.0.75/mysql-test/r/innodb_dict_size_limit.result	2009-01-27 11:43:46.000000000 +0900
+diff -r 6eeee157fd40 mysql-test/r/innodb_dict_size_limit.result
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/mysql-test/r/innodb_dict_size_limit.result	Fri Jul 03 15:41:41 2009 -0700
 @@ -0,0 +1,60 @@
 +DROP TABLE IF EXISTS `test_5`;
 +DROP TABLE IF EXISTS `test_4`;
@@ -395,9 +328,9 @@ diff -ruN mysql-5.0.75_base/mysql-test/r/innodb_dict_size_limit.result mysql-5.0
 +DROP TABLE `test_3`;
 +DROP TABLE `test_2`;
 +DROP TABLE `test_1`;
-diff -ruN mysql-5.0.75_base/mysql-test/t/innodb_dict_size_limit.test mysql-5.0.75/mysql-test/t/innodb_dict_size_limit.test
---- /dev/null	1970-01-01 09:00:00.000000000 +0900
-+++ mysql-5.0.75/mysql-test/t/innodb_dict_size_limit.test	2009-01-27 11:43:36.000000000 +0900
+diff -r 6eeee157fd40 mysql-test/t/innodb_dict_size_limit.test
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/mysql-test/t/innodb_dict_size_limit.test	Fri Jul 03 15:41:41 2009 -0700
 @@ -0,0 +1,63 @@
 +#
 +# Test for new variable innodb_dict_size_limit;
@@ -462,9 +395,9 @@ diff -ruN mysql-5.0.75_base/mysql-test/t/innodb_dict_size_limit.test mysql-5.0.7
 +DROP TABLE `test_2`;
 +DROP TABLE `test_1`;
 +
-diff -ruN mysql-5.0.75_base/patch_info/innodb_dict_size_limit.info mysql-5.0.75/patch_info/innodb_dict_size_limit.info
---- /dev/null	1970-01-01 09:00:00.000000000 +0900
-+++ mysql-5.0.75/patch_info/innodb_dict_size_limit.info	2009-01-26 15:46:45.000000000 +0900
+diff -r 6eeee157fd40 patch_info/innodb_dict_size_limit.info
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/patch_info/innodb_dict_size_limit.info	Fri Jul 03 15:41:41 2009 -0700
 @@ -0,0 +1,9 @@
 +File=innodb_dict_size_limit.patch
 +Name=Limit dictionary cache size
@@ -475,3 +408,76 @@ diff -ruN mysql-5.0.75_base/patch_info/innodb_dict_size_limit.info mysql-5.0.75/
 +ChangeLog=
 +2009-01-26
 +YK: Initial release
+diff -r 6eeee157fd40 sql/ha_innodb.cc
+--- a/sql/ha_innodb.cc	Fri Jul 03 15:41:34 2009 -0700
++++ b/sql/ha_innodb.cc	Fri Jul 03 15:41:41 2009 -0700
+@@ -288,6 +288,8 @@
+   (char*) &export_vars.innodb_dblwr_pages_written,        SHOW_LONG},
+   {"dblwr_writes",
+   (char*) &export_vars.innodb_dblwr_writes,               SHOW_LONG},
++  {"dict_tables",
++  (char*) &export_vars.innodb_dict_tables,                SHOW_LONG},
+   {"log_waits",
+   (char*) &export_vars.innodb_log_waits,                  SHOW_LONG},
+   {"log_write_requests",
+diff -r 6eeee157fd40 sql/ha_innodb.h
+--- a/sql/ha_innodb.h	Fri Jul 03 15:41:34 2009 -0700
++++ b/sql/ha_innodb.h	Fri Jul 03 15:41:41 2009 -0700
+@@ -243,6 +243,7 @@
+ extern ulong srv_enable_unsafe_group_commit;
+ extern uint srv_read_ahead;
+ extern uint srv_adaptive_checkpoint;
++extern ulong srv_dict_size_limit;
+ extern ulong srv_show_locks_held;
+ extern ulong srv_show_verbose_locks;
+ extern ulong srv_io_pattern_trace;
+diff -r 6eeee157fd40 sql/mysqld.cc
+--- a/sql/mysqld.cc	Fri Jul 03 15:41:34 2009 -0700
++++ b/sql/mysqld.cc	Fri Jul 03 15:41:41 2009 -0700
+@@ -5101,6 +5101,7 @@
+   OPT_INNODB_ADAPTIVE_CHECKPOINT,
+   OPT_INNODB_READ_IO_THREADS,
+   OPT_INNODB_WRITE_IO_THREADS,
++  OPT_INNODB_DICT_SIZE_LIMIT,
+   OPT_INNODB_ADAPTIVE_HASH_INDEX,
+   OPT_FEDERATED,
+   OPT_INNODB_USE_LEGACY_CARDINALITY_ALGORITHM
+@@ -5464,6 +5465,10 @@
+    "Number of background write I/O threads in InnoDB.",
+    (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads,
+    0, GET_LONG, REQUIRED_ARG, 8, 1, 64, 0, 0, 0},
++  {"innodb_dict_size_limit", OPT_INNODB_DICT_SIZE_LIMIT,
++   "Limit the allocated memory for dictionary cache. (0: unlimited)",
++   (gptr*) &srv_dict_size_limit, (gptr*) &srv_dict_size_limit, 0,
++   GET_ULONG, REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 0 ,0},
+   {"innodb_io_pattern_trace", OPT_INNODB_IO_PATTERN_TRACE,
+    "Create/Drop the internal hash table for IO pattern tracing.",
+    (gptr*) &srv_io_pattern_trace, (gptr*) &srv_io_pattern_trace,
+diff -r 6eeee157fd40 sql/set_var.cc
+--- a/sql/set_var.cc	Fri Jul 03 15:41:34 2009 -0700
++++ b/sql/set_var.cc	Fri Jul 03 15:41:41 2009 -0700
+@@ -540,6 +540,8 @@
+ sys_var_enum	sys_innodb_adaptive_checkpoint("innodb_adaptive_checkpoint",
+                            &srv_adaptive_checkpoint,
+                            &innodb_adaptive_checkpoint_typelib, fix_innodb_adaptive_checkpoint);
++sys_var_long_ptr	sys_innodb_dict_size_limit("innodb_dict_size_limit",
++                                                   &srv_dict_size_limit);
+ sys_var_long_ptr  sys_innodb_show_locks_held(
+                                         "innodb_show_locks_held",
+                                         &srv_show_locks_held);
+@@ -930,6 +932,7 @@
+   &sys_innodb_read_ahead,
+   &sys_innodb_enable_unsafe_group_commit,
+   &sys_innodb_adaptive_checkpoint,
++  &sys_innodb_dict_size_limit,
+   &sys_innodb_show_locks_held,
+   &sys_innodb_show_verbose_locks,
+   &sys_innodb_io_pattern_trace,
+@@ -1084,6 +1087,7 @@
+   {sys_innodb_adaptive_checkpoint.name, (char*) &sys_innodb_adaptive_checkpoint, SHOW_SYS},
+   {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG},
+   {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG},
++  {sys_innodb_dict_size_limit.name, (char*) &sys_innodb_dict_size_limit, SHOW_SYS},
+   {sys_innodb_io_pattern_trace.name, (char*) &sys_innodb_io_pattern_trace, SHOW_SYS},
+   {sys_innodb_io_pattern_trace_running.name, (char*) &sys_innodb_io_pattern_trace_running, SHOW_SYS},
+   {sys_innodb_io_pattern_size_limit.name, (char*) &sys_innodb_io_pattern_size_limit, SHOW_SYS},
diff --git a/mysql-innodb_extra_rseg.patch b/mysql-innodb_extra_rseg.patch
index 1c8f429..cab3b26 100644
--- a/mysql-innodb_extra_rseg.patch
+++ b/mysql-innodb_extra_rseg.patch
@@ -1,18 +1,18 @@
-diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
---- a/innobase/include/srv0srv.h	2009-05-06 15:35:46.000000000 +0900
-+++ b/innobase/include/srv0srv.h	2009-05-06 13:37:45.000000000 +0900
-@@ -147,6 +147,8 @@
+diff -r 85e7025cf2d1 innobase/include/srv0srv.h
+--- a/innobase/include/srv0srv.h	Fri Jul 03 15:41:41 2009 -0700
++++ b/innobase/include/srv0srv.h	Fri Jul 03 15:41:47 2009 -0700
+@@ -146,6 +146,8 @@
+ extern ulint	srv_enable_unsafe_group_commit;
  extern uint	srv_read_ahead;
- extern ulint	srv_adaptive_checkpoint;
- 
-+extern ulint	srv_extra_rsegments;
+ extern uint	srv_adaptive_checkpoint;
 +
++extern ulint	srv_extra_rsegments;
+ 
  extern ulint	srv_dict_size_limit;
  
- extern volatile ibool srv_io_pattern;
-diff -ruN a/innobase/include/trx0sys.h b/innobase/include/trx0sys.h
---- a/innobase/include/trx0sys.h	2009-05-06 15:35:46.000000000 +0900
-+++ b/innobase/include/trx0sys.h	2009-05-06 14:52:00.000000000 +0900
+diff -r 85e7025cf2d1 innobase/include/trx0sys.h
+--- a/innobase/include/trx0sys.h	Fri Jul 03 15:41:41 2009 -0700
++++ b/innobase/include/trx0sys.h	Fri Jul 03 15:41:47 2009 -0700
 @@ -105,6 +105,13 @@
  void
  trx_sys_create(void);
@@ -27,21 +27,21 @@ diff -ruN a/innobase/include/trx0sys.h b/innobase/include/trx0sys.h
  /********************************************************************
  Looks for a free slot for a rollback segment in the trx system file copy. */
  
-diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
---- a/innobase/srv/srv0srv.c	2009-05-06 15:35:46.000000000 +0900
-+++ b/innobase/srv/srv0srv.c	2009-05-06 13:38:23.000000000 +0900
-@@ -347,6 +347,8 @@
- uint	srv_read_ahead = 3; /* 1: random  2: linear  3: Both */
- ulint	srv_adaptive_checkpoint = 0; /* 0:disable 1:enable */
+diff -r 85e7025cf2d1 innobase/srv/srv0srv.c
+--- a/innobase/srv/srv0srv.c	Fri Jul 03 15:41:41 2009 -0700
++++ b/innobase/srv/srv0srv.c	Fri Jul 03 15:41:47 2009 -0700
+@@ -352,6 +352,8 @@
  
-+ulint	srv_extra_rsegments = 0; /* extra rseg for users */
+ uint	srv_read_ahead = 3; /* 1: random  2: linear  3: Both */
+ uint	srv_adaptive_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
 +
++ulint	srv_extra_rsegments = 0; /* extra rseg for users */
+ 
  ulint	srv_dict_size_limit = 0;
  
- volatile ibool srv_io_pattern = FALSE;
-diff -ruN a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
---- a/innobase/srv/srv0start.c	2009-05-06 15:35:46.000000000 +0900
-+++ b/innobase/srv/srv0start.c	2009-05-06 14:54:43.000000000 +0900
+diff -r 85e7025cf2d1 innobase/srv/srv0start.c
+--- a/innobase/srv/srv0start.c	Fri Jul 03 15:41:41 2009 -0700
++++ b/innobase/srv/srv0start.c	Fri Jul 03 15:41:47 2009 -0700
 @@ -1418,6 +1418,8 @@
  		dict_create();
                  srv_startup_is_before_trx_rollback_phase = FALSE;
@@ -51,9 +51,9 @@ diff -ruN a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
  #ifdef UNIV_LOG_ARCHIVE
  	} else if (srv_archive_recovery) {
  		fprintf(stderr,
-diff -ruN a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c
---- a/innobase/trx/trx0sys.c	2009-05-06 15:35:46.000000000 +0900
-+++ b/innobase/trx/trx0sys.c	2009-05-06 14:54:02.000000000 +0900
+diff -r 85e7025cf2d1 innobase/trx/trx0sys.c
+--- a/innobase/trx/trx0sys.c	Fri Jul 03 15:41:41 2009 -0700
++++ b/innobase/trx/trx0sys.c	Fri Jul 03 15:41:47 2009 -0700
 @@ -944,3 +944,28 @@
  
  	trx_sys_init_at_db_start();
@@ -83,9 +83,9 @@ diff -ruN a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c
 +	}
 +	mtr_commit(&mtr);
 +}
-diff -ruN a/patch_info/innodb_extra_rseg.info b/patch_info/innodb_extra_rseg.info
---- /dev/null	1970-01-01 09:00:00.000000000 +0900
-+++ b/patch_info/innodb_extra_rseg.info	2009-05-06 14:49:48.000000000 +0900
+diff -r 85e7025cf2d1 patch_info/innodb_extra_rseg.info
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/patch_info/innodb_extra_rseg.info	Fri Jul 03 15:41:47 2009 -0700
 @@ -0,0 +1,6 @@
 +File=innodb_extra_rseg.patch
 +Name=allow to create extra rollback segments
@@ -93,9 +93,9 @@ diff -ruN a/patch_info/innodb_extra_rseg.info b/patch_info/innodb_extra_rseg.inf
 +Author=Percona <info at percona.com>
 +License=GPL
 +Comment
-diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc
---- a/sql/ha_innodb.cc	2009-05-06 15:35:46.000000000 +0900
-+++ b/sql/ha_innodb.cc	2009-05-06 15:27:49.000000000 +0900
+diff -r 85e7025cf2d1 sql/ha_innodb.cc
+--- a/sql/ha_innodb.cc	Fri Jul 03 15:41:41 2009 -0700
++++ b/sql/ha_innodb.cc	Fri Jul 03 15:41:47 2009 -0700
 @@ -152,6 +152,7 @@
       innobase_open_files;
  
@@ -104,7 +104,7 @@ diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc
  longlong innobase_buffer_pool_size, innobase_log_file_size;
  
  /* The default values for the following char* start-up parameters
-@@ -1507,6 +1508,8 @@
+@@ -1521,6 +1522,8 @@
  	srv_n_read_io_threads = (ulint) innobase_read_io_threads;
  	srv_n_write_io_threads = (ulint) innobase_write_io_threads;
  
@@ -113,9 +113,9 @@ diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc
  	srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
  	srv_force_recovery = (ulint) innobase_force_recovery;
  
-diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h
---- a/sql/ha_innodb.h	2009-05-06 15:35:46.000000000 +0900
-+++ b/sql/ha_innodb.h	2009-05-06 13:51:35.000000000 +0900
+diff -r 85e7025cf2d1 sql/ha_innodb.h
+--- a/sql/ha_innodb.h	Fri Jul 03 15:41:41 2009 -0700
++++ b/sql/ha_innodb.h	Fri Jul 03 15:41:47 2009 -0700
 @@ -205,6 +205,7 @@
  extern long innobase_buffer_pool_awe_mem_mb;
  extern long innobase_file_io_threads, innobase_lock_wait_timeout;
@@ -124,21 +124,21 @@ diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h
  extern long innobase_force_recovery;
  extern long innobase_open_files;
  extern char *innobase_data_home_dir, *innobase_data_file_path;
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc	2009-05-06 15:35:46.000000000 +0900
-+++ b/sql/mysqld.cc	2009-05-06 14:12:05.000000000 +0900
-@@ -5096,6 +5096,7 @@
+diff -r 85e7025cf2d1 sql/mysqld.cc
+--- a/sql/mysqld.cc	Fri Jul 03 15:41:41 2009 -0700
++++ b/sql/mysqld.cc	Fri Jul 03 15:41:47 2009 -0700
+@@ -5101,6 +5101,7 @@
    OPT_INNODB_ADAPTIVE_CHECKPOINT,
    OPT_INNODB_READ_IO_THREADS,
    OPT_INNODB_WRITE_IO_THREADS,
 +  OPT_INNODB_EXTRA_RSEGMENTS,
    OPT_INNODB_DICT_SIZE_LIMIT,
    OPT_INNODB_ADAPTIVE_HASH_INDEX,
-   OPT_RPL_MIRROR_BINLOG,
-@@ -5454,6 +5455,10 @@
+   OPT_FEDERATED,
+@@ -5465,6 +5466,10 @@
     "Number of background write I/O threads in InnoDB.",
     (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads,
-    0, GET_LONG, REQUIRED_ARG, 1, 1, 64, 0, 0, 0},
+    0, GET_LONG, REQUIRED_ARG, 8, 1, 64, 0, 0, 0},
 +  {"innodb_extra_rsegments", OPT_INNODB_EXTRA_RSEGMENTS,
 +   "Number of extra user rollback segments when create new database.",
 +   (gptr*) &innobase_extra_rsegments, (gptr*) &innobase_extra_rsegments,
@@ -146,10 +146,10 @@ diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
    {"innodb_dict_size_limit", OPT_INNODB_DICT_SIZE_LIMIT,
     "Limit the allocated memory for dictionary cache. (0: unlimited)",
     (gptr*) &srv_dict_size_limit, (gptr*) &srv_dict_size_limit, 0,
-diff -ruN a/sql/set_var.cc b/sql/set_var.cc
---- a/sql/set_var.cc	2009-05-06 15:35:46.000000000 +0900
-+++ b/sql/set_var.cc	2009-05-06 14:13:24.000000000 +0900
-@@ -1063,6 +1063,7 @@
+diff -r 85e7025cf2d1 sql/set_var.cc
+--- a/sql/set_var.cc	Fri Jul 03 15:41:41 2009 -0700
++++ b/sql/set_var.cc	Fri Jul 03 15:41:47 2009 -0700
+@@ -1087,6 +1087,7 @@
    {sys_innodb_adaptive_checkpoint.name, (char*) &sys_innodb_adaptive_checkpoint, SHOW_SYS},
    {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG},
    {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG},
@@ -157,9 +157,9 @@ diff -ruN a/sql/set_var.cc b/sql/set_var.cc
    {sys_innodb_dict_size_limit.name, (char*) &sys_innodb_dict_size_limit, SHOW_SYS},
    {sys_innodb_io_pattern_trace.name, (char*) &sys_innodb_io_pattern_trace, SHOW_SYS},
    {sys_innodb_io_pattern_trace_running.name, (char*) &sys_innodb_io_pattern_trace_running, SHOW_SYS},
-diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
---- a/sql/sql_show.cc	2009-05-06 15:35:46.000000000 +0900
-+++ b/sql/sql_show.cc	2009-05-06 15:29:47.000000000 +0900
+diff -r 85e7025cf2d1 sql/sql_show.cc
+--- a/sql/sql_show.cc	Fri Jul 03 15:41:41 2009 -0700
++++ b/sql/sql_show.cc	Fri Jul 03 15:41:47 2009 -0700
 @@ -39,6 +39,8 @@
  #include "srv0srv.h"
  #include "buf0buf.h"
@@ -169,7 +169,7 @@ diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
  }
  /* We need to undef it in InnoDB */
  #undef byte
-@@ -4160,6 +4162,45 @@
+@@ -4180,6 +4182,45 @@
    DBUG_RETURN(returnable);
  }
  
@@ -215,10 +215,12 @@ diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
  /*
    Find schema_tables elment by name
  
-@@ -4978,6 +5019,16 @@
+@@ -4996,6 +5037,16 @@
+   {"INDEX_NAME", 32, MYSQL_TYPE_STRING, 0, 0, "index name"},
+   {"N_READ", 11, MYSQL_TYPE_LONG, 0, 0, "read ios"},
    {"N_WRITE", 11, MYSQL_TYPE_LONG, 0, 0, "write ios"},
-   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
- };
++  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
++};
 +
 +ST_FIELD_INFO innodb_rseg_fields_info[]=
 +{
@@ -227,12 +229,10 @@ diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
 +  {"PAGE_NO", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, ""},
 +  {"MAX_SIZE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, ""},
 +  {"CURR_SIZE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, ""},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
-+};
+   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+ };
  #endif
- 
- ST_FIELD_INFO variables_fields_info[]=
-@@ -5157,6 +5208,8 @@
+@@ -5177,6 +5228,8 @@
  #ifdef HAVE_INNOBASE_DB
    {"INNODB_IO_PATTERN", innodb_io_pattern_field_info, create_schema_table,
      innodb_io_pattern_fill_table, 0, 0, -1, -1, 0},
diff --git a/mysql-innodb_fsync_source.patch b/mysql-innodb_fsync_source.patch
index 637a7d6..2961b78 100644
--- a/mysql-innodb_fsync_source.patch
+++ b/mysql-innodb_fsync_source.patch
@@ -1,6 +1,6 @@
-diff -r 61031ebb48ce innobase/buf/buf0flu.c
---- a/innobase/buf/buf0flu.c	Mon Nov 03 05:07:46 2008 -0800
-+++ b/innobase/buf/buf0flu.c	Mon Nov 03 05:07:56 2008 -0800
+diff -r ef44d8017b6b innobase/buf/buf0flu.c
+--- a/innobase/buf/buf0flu.c	Fri Jul 03 15:41:25 2009 -0700
++++ b/innobase/buf/buf0flu.c	Fri Jul 03 15:41:32 2009 -0700
 @@ -341,7 +341,7 @@
  
  	/* Now flush the doublewrite buffer data to disk */
@@ -29,9 +29,9 @@ diff -r 61031ebb48ce innobase/buf/buf0flu.c
  #endif	
  	buf_flush_init_for_writing(block->frame, block->newest_modification,
  						block->space, block->offset);
-diff -r 61031ebb48ce innobase/fil/fil0fil.c
---- a/innobase/fil/fil0fil.c	Mon Nov 03 05:07:46 2008 -0800
-+++ b/innobase/fil/fil0fil.c	Mon Nov 03 05:07:56 2008 -0800
+diff -r ef44d8017b6b innobase/fil/fil0fil.c
+--- a/innobase/fil/fil0fil.c	Fri Jul 03 15:41:25 2009 -0700
++++ b/innobase/fil/fil0fil.c	Fri Jul 03 15:41:32 2009 -0700
 @@ -245,6 +245,7 @@
  					request */
  	UT_LIST_BASE_NODE_T(fil_space_t) space_list;
@@ -103,7 +103,7 @@ diff -r 61031ebb48ce innobase/fil/fil0fil.c
  
  	return(success);
  }
-@@ -4166,8 +4187,9 @@
+@@ -4167,8 +4188,9 @@
  void
  fil_flush(
  /*======*/
@@ -114,7 +114,7 @@ diff -r 61031ebb48ce innobase/fil/fil0fil.c
  {
  	fil_system_t*	system	= fil_system;
  	fil_space_t*	space;
-@@ -4176,7 +4198,7 @@
+@@ -4177,7 +4199,7 @@
  	ib_longlong	old_mod_counter;
  
  	mutex_enter(&(system->mutex));
@@ -123,7 +123,7 @@ diff -r 61031ebb48ce innobase/fil/fil0fil.c
  	HASH_SEARCH(hash, system->spaces, space_id, space,
  							space->id == space_id);
  	if (!space || space->is_being_deleted) {
-@@ -4281,7 +4303,8 @@
+@@ -4282,7 +4304,8 @@
  void
  fil_flush_file_spaces(
  /*==================*/
@@ -133,7 +133,7 @@ diff -r 61031ebb48ce innobase/fil/fil0fil.c
  {
  	fil_system_t*	system	= fil_system;
  	fil_space_t*	space;
-@@ -4322,7 +4345,7 @@
+@@ -4323,7 +4346,7 @@
  	a non-existing space id. */
  	for (i = 0; i < n_space_ids; i++) {
  
@@ -142,9 +142,9 @@ diff -r 61031ebb48ce innobase/fil/fil0fil.c
  	}
  
  	mem_free(space_ids);
-diff -r 61031ebb48ce innobase/include/fil0fil.h
---- a/innobase/include/fil0fil.h	Mon Nov 03 05:07:46 2008 -0800
-+++ b/innobase/include/fil0fil.h	Mon Nov 03 05:07:56 2008 -0800
+diff -r ef44d8017b6b innobase/include/fil0fil.h
+--- a/innobase/include/fil0fil.h	Fri Jul 03 15:41:25 2009 -0700
++++ b/innobase/include/fil0fil.h	Fri Jul 03 15:41:32 2009 -0700
 @@ -197,6 +197,13 @@
  fil_init(
  /*=====*/
@@ -159,7 +159,7 @@ diff -r 61031ebb48ce innobase/include/fil0fil.h
  /***********************************************************************
  Opens all log files and system tablespace data files. They stay open until the
  database server shutdown. This should be called at a server startup after the
-@@ -621,14 +628,26 @@
+@@ -625,14 +632,26 @@
  	ulint	segment);	/* in: the number of the segment in the aio
  				array to wait for */ 
  /**************************************************************************
@@ -187,7 +187,7 @@ diff -r 61031ebb48ce innobase/include/fil0fil.h
  /**************************************************************************
  Flushes to disk writes in file spaces of the given type possibly cached by
  the OS. */
-@@ -636,7 +655,8 @@
+@@ -640,7 +659,8 @@
  void
  fil_flush_file_spaces(
  /*==================*/
@@ -197,9 +197,9 @@ diff -r 61031ebb48ce innobase/include/fil0fil.h
  /**********************************************************************
  Checks the consistency of the tablespace cache. */
  
-diff -r 61031ebb48ce innobase/include/log0log.h
---- a/innobase/include/log0log.h	Mon Nov 03 05:07:46 2008 -0800
-+++ b/innobase/include/log0log.h	Mon Nov 03 05:07:56 2008 -0800
+diff -r ef44d8017b6b innobase/include/log0log.h
+--- a/innobase/include/log0log.h	Fri Jul 03 15:41:25 2009 -0700
++++ b/innobase/include/log0log.h	Fri Jul 03 15:41:32 2009 -0700
 @@ -146,6 +146,22 @@
  log_io_complete(
  /*============*/
@@ -247,8 +247,8 @@ diff -r 61031ebb48ce innobase/include/log0log.h
 +log_buffer_flush_maybe_sync(void);
  /*==========================*/
  /********************************************************************
- Advances the smallest lsn for which there are unflushed dirty blocks in the
-@@ -744,6 +767,12 @@
+ Flushes the log buffer. Forces it to disk depending on the value of
+@@ -751,6 +774,12 @@
  					AND flushed to disk */
  	ulint		n_pending_writes;/* number of currently pending flushes
  					or writes */
@@ -261,9 +261,9 @@ diff -r 61031ebb48ce innobase/include/log0log.h
  	/* NOTE on the 'flush' in names of the fields below: starting from
  	4.0.14, we separate the write of the log file and the actual fsync()
  	or other method to flush it to disk. The names below shhould really
-diff -r 61031ebb48ce innobase/log/log0log.c
---- a/innobase/log/log0log.c	Mon Nov 03 05:07:46 2008 -0800
-+++ b/innobase/log/log0log.c	Mon Nov 03 05:07:56 2008 -0800
+diff -r ef44d8017b6b innobase/log/log0log.c
+--- a/innobase/log/log0log.c	Fri Jul 03 15:41:25 2009 -0700
++++ b/innobase/log/log0log.c	Fri Jul 03 15:41:32 2009 -0700
 @@ -782,6 +782,15 @@
  	log_sys->written_to_all_lsn = log_sys->lsn;
  	
@@ -347,7 +347,7 @@ diff -r 61031ebb48ce innobase/log/log0log.c
  }
  
  /********************************************************************
-@@ -1551,7 +1567,7 @@
+@@ -1574,7 +1590,7 @@
  	mutex_exit(&(log->mutex));
  
  	if (do_flush) {
@@ -356,7 +356,7 @@ diff -r 61031ebb48ce innobase/log/log0log.c
  	}
  }
  
-@@ -1921,11 +1937,11 @@
+@@ -1944,11 +1960,11 @@
  	}
  
  	if (srv_unix_file_flush_method != SRV_UNIX_NOSYNC) {
@@ -370,7 +370,7 @@ diff -r 61031ebb48ce innobase/log/log0log.c
  	oldest_lsn = log_buf_pool_get_oldest_modification();
  
  	mutex_exit(&(log_sys->mutex));
-@@ -1938,7 +1954,8 @@
+@@ -1961,7 +1977,8 @@
  	write-ahead-logging algorithm ensures that the log has been flushed
  	up to oldest_lsn. */
  
@@ -380,7 +380,7 @@ diff -r 61031ebb48ce innobase/log/log0log.c
  
  	mutex_enter(&(log_sys->mutex));
  
-@@ -2566,7 +2583,7 @@
+@@ -2589,7 +2606,7 @@
  
  	mutex_exit(&(log_sys->mutex));
  
@@ -389,7 +389,7 @@ diff -r 61031ebb48ce innobase/log/log0log.c
  	
  	mutex_enter(&(log_sys->mutex));
  	
-@@ -2647,7 +2664,8 @@
+@@ -2670,7 +2687,8 @@
  
  		mutex_exit(&(log_sys->mutex));
  	
@@ -399,7 +399,7 @@ diff -r 61031ebb48ce innobase/log/log0log.c
  
  		calc_new_limit = FALSE;
  
-@@ -3184,8 +3202,8 @@
+@@ -3207,8 +3225,8 @@
  	}
  	mutex_exit(&kernel_mutex);
  
@@ -410,7 +410,7 @@ diff -r 61031ebb48ce innobase/log/log0log.c
  
  	/* The call fil_write_flushed_lsn_to_data_files() will pass the buffer
  	pool: therefore it is essential that the buffer pool has been
-@@ -3218,7 +3236,7 @@
+@@ -3241,7 +3259,7 @@
  
  		fil_write_flushed_lsn_to_data_files(lsn, arch_log_no);
  
@@ -419,7 +419,7 @@ diff -r 61031ebb48ce innobase/log/log0log.c
  
  	fil_close_all_files();
  
-@@ -3331,15 +3349,45 @@
+@@ -3363,15 +3381,45 @@
  	time_elapsed = 0.001 + difftime(current_time,
  					log_sys->last_printout_time);
  	fprintf(file,
@@ -471,10 +471,10 @@ diff -r 61031ebb48ce innobase/log/log0log.c
  
  	mutex_exit(&(log_sys->mutex));
  }
-diff -r 61031ebb48ce innobase/srv/srv0srv.c
---- a/innobase/srv/srv0srv.c	Mon Nov 03 05:07:46 2008 -0800
-+++ b/innobase/srv/srv0srv.c	Mon Nov 03 05:07:56 2008 -0800
-@@ -1638,6 +1638,12 @@
+diff -r ef44d8017b6b innobase/srv/srv0srv.c
+--- a/innobase/srv/srv0srv.c	Fri Jul 03 15:41:25 2009 -0700
++++ b/innobase/srv/srv0srv.c	Fri Jul 03 15:41:32 2009 -0700
+@@ -1698,6 +1698,12 @@
  		(ulong)time_elapsed);
  
  	fputs("----------\n"
@@ -487,9 +487,9 @@ diff -r 61031ebb48ce innobase/srv/srv0srv.c
  		"SEMAPHORES\n"
  		"----------\n", file);
  	sync_print(file);
-diff -r 61031ebb48ce innobase/trx/trx0sys.c
---- a/innobase/trx/trx0sys.c	Mon Nov 03 05:07:46 2008 -0800
-+++ b/innobase/trx/trx0sys.c	Mon Nov 03 05:07:56 2008 -0800
+diff -r ef44d8017b6b innobase/trx/trx0sys.c
+--- a/innobase/trx/trx0sys.c	Fri Jul 03 15:41:25 2009 -0700
++++ b/innobase/trx/trx0sys.c	Fri Jul 03 15:41:32 2009 -0700
 @@ -511,7 +511,7 @@
  		page += UNIV_PAGE_SIZE;
  	}
@@ -499,10 +499,10 @@ diff -r 61031ebb48ce innobase/trx/trx0sys.c
  	
  leave_func:
  	ut_free(unaligned_read_buf);
-diff -r 61031ebb48ce innobase/trx/trx0trx.c
---- a/innobase/trx/trx0trx.c	Mon Nov 03 05:07:46 2008 -0800
-+++ b/innobase/trx/trx0trx.c	Mon Nov 03 05:07:56 2008 -0800
-@@ -916,19 +916,21 @@
+diff -r ef44d8017b6b innobase/trx/trx0trx.c
+--- a/innobase/trx/trx0trx.c	Fri Jul 03 15:41:25 2009 -0700
++++ b/innobase/trx/trx0trx.c	Fri Jul 03 15:41:32 2009 -0700
+@@ -942,19 +942,21 @@
                          if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
                               	/* Write the log but do not flush it to disk */
  
@@ -528,7 +528,7 @@ diff -r 61031ebb48ce innobase/trx/trx0trx.c
                  } else {
                          ut_error;
                  }
-@@ -1659,18 +1661,21 @@
+@@ -1701,18 +1703,21 @@
                  if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
                          /* Write the log but do not flush it to disk */
  
@@ -553,7 +553,7 @@ diff -r 61031ebb48ce innobase/trx/trx0trx.c
          } else {
                  ut_error;
          }
-@@ -1906,19 +1911,21 @@
+@@ -1948,19 +1953,21 @@
                     	if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
                          	/* Write the log but do not flush it to disk */
  
@@ -579,9 +579,9 @@ diff -r 61031ebb48ce innobase/trx/trx0trx.c
                  } else {
                          ut_error;
                  }
-diff -r 61031ebb48ce patch_info/innodb_fsync_source.info
+diff -r ef44d8017b6b patch_info/innodb_fsync_source.info
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/patch_info/innodb_fsync_source.info	Mon Nov 03 05:07:56 2008 -0800
++++ b/patch_info/innodb_fsync_source.info	Fri Jul 03 15:41:32 2009 -0700
 @@ -0,0 +1,9 @@
 +File=innodb_fsync_source.patch
 +Name=Information of fsync callers in InnoDB
diff --git a/mysql-innodb_io_patches.patch b/mysql-innodb_io_patches.patch
index 8247a32..aaef29a 100644
--- a/mysql-innodb_io_patches.patch
+++ b/mysql-innodb_io_patches.patch
@@ -1,6 +1,6 @@
-diff -r ed298a6e5e10 innobase/buf/buf0flu.c
---- a/innobase/buf/buf0flu.c	Mon Jun 01 00:36:10 2009 -0700
-+++ b/innobase/buf/buf0flu.c	Mon Jun 01 00:36:16 2009 -0700
+diff -ruN a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c
+--- a/innobase/buf/buf0flu.c	2009-05-08 06:12:03.000000000 +0900
++++ b/innobase/buf/buf0flu.c	2009-07-02 16:44:49.000000000 +0900
 @@ -898,10 +898,17 @@
  
  				old_page_count = page_count;
@@ -19,9 +19,9 @@ diff -r ed298a6e5e10 innobase/buf/buf0flu.c
  				/* fprintf(stderr,
  				"Flush type %lu, page no %lu, neighb %lu\n",
  				flush_type, offset,
-diff -r ed298a6e5e10 innobase/buf/buf0rea.c
---- a/innobase/buf/buf0rea.c	Mon Jun 01 00:36:10 2009 -0700
-+++ b/innobase/buf/buf0rea.c	Mon Jun 01 00:36:16 2009 -0700
+diff -ruN a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c
+--- a/innobase/buf/buf0rea.c	2009-07-02 16:43:23.000000000 +0900
++++ b/innobase/buf/buf0rea.c	2009-07-02 16:44:49.000000000 +0900
 @@ -20,6 +20,7 @@
  #include "os0file.h"
  #include "srv0start.h"
@@ -52,9 +52,9 @@ diff -r ed298a6e5e10 innobase/buf/buf0rea.c
  	if (srv_startup_is_before_trx_rollback_phase) {
  	        /* No read-ahead to avoid thread deadlocks */
  	        return(0);
-diff -r ed298a6e5e10 innobase/ibuf/ibuf0ibuf.c
---- a/innobase/ibuf/ibuf0ibuf.c	Mon Jun 01 00:36:10 2009 -0700
-+++ b/innobase/ibuf/ibuf0ibuf.c	Mon Jun 01 00:36:16 2009 -0700
+diff -ruN a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c
+--- a/innobase/ibuf/ibuf0ibuf.c	2009-05-08 06:12:04.000000000 +0900
++++ b/innobase/ibuf/ibuf0ibuf.c	2009-07-02 16:44:49.000000000 +0900
 @@ -370,8 +370,9 @@
  	grow in size, as the references on the upper levels of the tree can
  	change */
@@ -81,9 +81,26 @@ diff -r ed298a6e5e10 innobase/ibuf/ibuf0ibuf.c
  
  	sync = FALSE;
  	
-diff -r ed298a6e5e10 innobase/include/os0file.h
---- a/innobase/include/os0file.h	Mon Jun 01 00:36:10 2009 -0700
-+++ b/innobase/include/os0file.h	Mon Jun 01 00:36:16 2009 -0700
+diff -ruN a/innobase/include/log0log.h b/innobase/include/log0log.h
+--- a/innobase/include/log0log.h	2009-05-08 06:12:06.000000000 +0900
++++ b/innobase/include/log0log.h	2009-07-02 16:44:49.000000000 +0900
+@@ -169,6 +169,13 @@
+ log_buffer_flush_to_disk(void);
+ /*==========================*/
+ /********************************************************************
++Flushes the log buffer. Forces it to disk depending on the value of
++the configuration parameter innodb_flush_log_at_trx_commit. */
++
++void
++log_buffer_flush_maybe_sync(void);
++/*=============================*/
++/********************************************************************
+ Advances the smallest lsn for which there are unflushed dirty blocks in the
+ buffer pool and also may make a new checkpoint. NOTE: this function may only
+ be called if the calling thread owns no synchronization objects! */
+diff -ruN a/innobase/include/os0file.h b/innobase/include/os0file.h
+--- a/innobase/include/os0file.h	2009-07-02 16:43:23.000000000 +0900
++++ b/innobase/include/os0file.h	2009-07-02 16:44:49.000000000 +0900
 @@ -551,8 +551,10 @@
  /*========*/
  	ulint	n,		/* in: maximum number of pending aio operations
@@ -97,9 +114,9 @@ diff -r ed298a6e5e10 innobase/include/os0file.h
  	ulint	n_slots_sync);	/* in: number of slots in the sync aio array */
  /***********************************************************************
  Requests an asynchronous i/o operation. */
-diff -r ed298a6e5e10 innobase/include/srv0srv.h
---- a/innobase/include/srv0srv.h	Mon Jun 01 00:36:10 2009 -0700
-+++ b/innobase/include/srv0srv.h	Mon Jun 01 00:36:16 2009 -0700
+diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
+--- a/innobase/include/srv0srv.h	2009-07-02 16:43:23.000000000 +0900
++++ b/innobase/include/srv0srv.h	2009-07-02 18:02:38.000000000 +0900
 @@ -89,6 +89,8 @@
  extern ulint	srv_lock_table_size;
  
@@ -121,14 +138,44 @@ diff -r ed298a6e5e10 innobase/include/srv0srv.h
 +extern ulint	srv_flush_neighbor_pages;
 +extern ulint	srv_enable_unsafe_group_commit;
 +extern uint	srv_read_ahead;
-+extern ulint	srv_adaptive_checkpoint;
++extern uint	srv_adaptive_checkpoint;
  /*-------------------------------------------*/
  
  extern ulint	srv_n_rows_inserted;
-diff -r ed298a6e5e10 innobase/log/log0log.c
---- a/innobase/log/log0log.c	Mon Jun 01 00:36:10 2009 -0700
-+++ b/innobase/log/log0log.c	Mon Jun 01 00:36:16 2009 -0700
-@@ -3326,6 +3326,15 @@
+diff -ruN a/innobase/log/log0log.c b/innobase/log/log0log.c
+--- a/innobase/log/log0log.c	2009-05-08 06:12:10.000000000 +0900
++++ b/innobase/log/log0log.c	2009-07-02 16:44:49.000000000 +0900
+@@ -1524,6 +1524,29 @@
+ }
+ 
+ /********************************************************************
++Flush the log buffer. Force it to disk depending on the value of
++innodb_flush_log_at_trx_commit. */
++
++void
++log_buffer_flush_maybe_sync(void)
++/*=============================*/
++{
++	dulint	lsn;
++
++	mutex_enter(&(log_sys->mutex));
++
++	lsn = log_sys->lsn;
++
++	mutex_exit(&(log_sys->mutex));
++
++	/* Force log buffer to disk when innodb_flush_log_at_trx_commit = 1. */
++	log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS,
++			srv_flush_log_at_trx_commit == 1 ? TRUE : FALSE,
++			srv_flush_log_at_trx_commit == 1 ?
++				LOG_WRITE_FROM_BACKGROUND_SYNC :
++				LOG_WRITE_FROM_BACKGROUND_ASYNC);
++}
++/********************************************************************
+ Tries to establish a big enough margin of free space in the log buffer, such
+ that a new log entry can be catenated without an immediate need for a flush. */
+ static
+@@ -3326,6 +3349,15 @@
  			(ulong) ut_dulint_get_high(log_sys->last_checkpoint_lsn),
  			(ulong) ut_dulint_get_low(log_sys->last_checkpoint_lsn));
  
@@ -144,10 +191,98 @@ diff -r ed298a6e5e10 innobase/log/log0log.c
  	current_time = time(NULL);
  			
  	time_elapsed = 0.001 + difftime(current_time,
-diff -r ed298a6e5e10 innobase/os/os0file.c
---- a/innobase/os/os0file.c	Mon Jun 01 00:36:10 2009 -0700
-+++ b/innobase/os/os0file.c	Mon Jun 01 00:36:16 2009 -0700
-@@ -2878,8 +2878,10 @@
+diff -ruN a/innobase/os/os0file.c b/innobase/os/os0file.c
+--- a/innobase/os/os0file.c	2009-07-02 16:43:23.000000000 +0900
++++ b/innobase/os/os0file.c	2009-07-02 16:44:49.000000000 +0900
+@@ -66,6 +66,28 @@
+ 
+ ibool	os_aio_print_debug	= FALSE;
+ 
++/* State for the state of an IO request in simulated AIO.
++   Protocol for simulated aio:
++     client requests IO: find slot with reserved = FALSE. Add entry with
++                         status = OS_AIO_NOT_ISSUED.
++     IO thread wakes: find adjacent slots with reserved = TRUE and status =
++                      OS_AIO_NOT_ISSUED. Change status for slots to
++                      OS_AIO_ISSUED.
++     IO operation completes: set status for slots to OS_AIO_DONE. set status
++                             for the first slot to OS_AIO_CLAIMED and return
++                             result for that slot.
++   When there are multiple read and write threads, they all compete to execute
++   the requests in the array (os_aio_array_t). This avoids the need to load
++   balance requests at the time the request is made at the cost of waking all
++   threads when a request is available.
++*/
++typedef enum {
++	OS_AIO_NOT_ISSUED, /* Available to be processed by an IO thread. */
++	OS_AIO_ISSUED,     /* Being processed by an IO thread. */
++	OS_AIO_DONE,       /* Request processed. */
++	OS_AIO_CLAIMED     /* Result being returned to client. */
++} os_aio_status;
++
+ /* The aio array slot structure */
+ typedef struct os_aio_slot_struct	os_aio_slot_t;
+ 
+@@ -74,6 +96,8 @@
+ 	ulint		pos;		/* index of the slot in the aio
+ 					array */
+ 	ibool		reserved;	/* TRUE if this slot is reserved */
++	os_aio_status   status;		/* Status for current request. Valid when reserved
++					is TRUE. Used only in simulated aio. */
+ 	time_t		reservation_time;/* time when reserved */
+ 	ulint		len;		/* length of the block to read or
+ 					write */
+@@ -84,11 +108,11 @@
+ 	ulint		offset_high;	/* 32 high bits of file offset */
+ 	os_file_t	file;		/* file where to read or write */
+ 	const char*	name;		/* file name or path */
+-	ibool		io_already_done;/* used only in simulated aio:
+-					TRUE if the physical i/o already
+-					made and only the slot message
+-					needs to be passed to the caller
+-					of os_aio_simulated_handle */
++//	ibool		io_already_done;/* used only in simulated aio:
++//					TRUE if the physical i/o already
++//					made and only the slot message
++//					needs to be passed to the caller
++//					of os_aio_simulated_handle */
+ 	fil_node_t*	message1;	/* message which is given by the */
+ 	void*		message2;	/* the requester of an aio operation
+ 					and which can be used to identify
+@@ -137,6 +161,13 @@
+ /* Array of events used in simulated aio */
+ os_event_t*	os_aio_segment_wait_events	= NULL;
+ 
++/* Number for the first global segment for reading. */
++const ulint os_aio_first_read_segment = 2;
++
++/* Number for the first global segment for writing. Set to
++2 + os_aio_read_write_threads. */
++ulint os_aio_first_write_segment = 0;
++
+ /* The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
+ are NULL when the module has not yet been initialized. */
+ static os_aio_array_t*	os_aio_read_array	= NULL;
+@@ -145,11 +176,17 @@
+ static os_aio_array_t*	os_aio_log_array	= NULL;
+ static os_aio_array_t*	os_aio_sync_array	= NULL;
+ 
++/* Per thread buffer used for merged IO requests. Used by
++os_aio_simulated_handle so that a buffer doesn't have to be allocated
++for each request. */
++static char* os_aio_thread_buffer[SRV_MAX_N_IO_THREADS];
++static ulint os_aio_thread_buffer_size[SRV_MAX_N_IO_THREADS];
++
+ static ulint	os_aio_n_segments	= ULINT_UNDEFINED;
+ 
+ /* If the following is TRUE, read i/o handler threads try to
+ wait until a batch of new read requests have been posted */
+-static ibool	os_aio_recommend_sleep_for_read_threads	= FALSE;
++static volatile ibool	os_aio_recommend_sleep_for_read_threads	= FALSE;
+ 
+ ulint	os_n_file_reads		= 0;
+ ulint	os_bytes_read_since_printout = 0;
+@@ -2878,8 +2915,10 @@
  /*========*/
  	ulint	n,		/* in: maximum number of pending aio operations
  				allowed; n must be divisible by n_segments */
@@ -160,7 +295,7 @@ diff -r ed298a6e5e10 innobase/os/os0file.c
  	ulint	n_slots_sync)	/* in: number of slots in the sync aio array */
  {
  	ulint	n_read_segs;
-@@ -2889,6 +2891,8 @@
+@@ -2889,6 +2928,8 @@
  #ifdef POSIX_ASYNC_IO
  	sigset_t   sigset;
  #endif
@@ -169,7 +304,12 @@ diff -r ed298a6e5e10 innobase/os/os0file.c
  	ut_ad(n % n_segments == 0);
  	ut_ad(n_segments >= 4);
  
-@@ -2899,8 +2903,8 @@
+@@ -2896,14 +2937,17 @@
+ 
+ 	for (i = 0; i < n_segments; i++) {
+ 	        srv_set_io_thread_op_info(i, "not started yet");
++		os_aio_thread_buffer[i] = 0;
++		os_aio_thread_buffer_size[i] = 0;
  	}
  
  	n_per_seg = n / n_segments;
@@ -180,7 +320,28 @@ diff -r ed298a6e5e10 innobase/os/os0file.c
  	
  	/* fprintf(stderr, "Array n per seg %lu\n", n_per_seg); */
  
-@@ -3181,6 +3185,13 @@
++	os_aio_first_write_segment = os_aio_first_read_segment + n_read_threads;
+ 	os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
+ 
+ 	srv_io_thread_function[0] = "insert buffer thread";
+@@ -2912,14 +2956,14 @@
+ 
+ 	srv_io_thread_function[1] = "log thread";
+ 
+-	os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg,
++	os_aio_read_array = os_aio_array_create(n_per_seg,
+ 							n_read_segs);
+ 	for (i = 2; i < 2 + n_read_segs; i++) {
+ 		ut_a(i < SRV_MAX_N_IO_THREADS);
+ 	        srv_io_thread_function[i] = "read thread";
+ 	}
+ 
+-	os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg,
++	os_aio_write_array = os_aio_array_create(n_per_seg,
+ 							n_write_segs);
+ 	for (i = 2 + n_read_segs; i < n_segments; i++) {
+ 		ut_a(i < SRV_MAX_N_IO_THREADS);
+@@ -3181,6 +3225,13 @@
  	struct aiocb*	control;
  #endif
  	ulint		i;
@@ -194,7 +355,7 @@ diff -r ed298a6e5e10 innobase/os/os0file.c
  loop:
  	os_mutex_enter(array->mutex);
  
-@@ -3199,6 +3210,16 @@
+@@ -3199,6 +3250,16 @@
  		goto loop;
  	}
  
@@ -211,7 +372,7 @@ diff -r ed298a6e5e10 innobase/os/os0file.c
  	for (i = 0;; i++) {
  		slot = os_aio_array_get_nth_slot(array, i);
  
-@@ -3206,6 +3227,7 @@
+@@ -3206,6 +3267,7 @@
  			break;
  		}
  	}
@@ -219,9 +380,330 @@ diff -r ed298a6e5e10 innobase/os/os0file.c
  
  	array->n_reserved++;
  
-diff -r ed298a6e5e10 innobase/srv/srv0srv.c
---- a/innobase/srv/srv0srv.c	Mon Jun 01 00:36:10 2009 -0700
-+++ b/innobase/srv/srv0srv.c	Mon Jun 01 00:36:16 2009 -0700
+@@ -3228,7 +3290,8 @@
+ 	slot->buf      = buf;
+ 	slot->offset   = offset;
+ 	slot->offset_high = offset_high;
+-	slot->io_already_done = FALSE;
++//	slot->io_already_done = FALSE;
++	slot->status = OS_AIO_NOT_ISSUED;
+ 	
+ #ifdef WIN_ASYNC_IO		
+ 	control = &(slot->control);
+@@ -3281,6 +3344,7 @@
+ 	ut_ad(slot->reserved);
+ 	
+ 	slot->reserved = FALSE;
++	slot->status = OS_AIO_NOT_ISSUED;
+ 
+ 	array->n_reserved--;
+ 
+@@ -3317,16 +3381,18 @@
+ 
+ 	segment = os_aio_get_array_and_local_segment(&array, global_segment);
+ 
+-	n = array->n_slots / array->n_segments;
++	n = array->n_slots;
+ 
+ 	/* Look through n slots after the segment * n'th slot */
+ 
+ 	os_mutex_enter(array->mutex);
+ 
+ 	for (i = 0; i < n; i++) {
+-		slot = os_aio_array_get_nth_slot(array, i + segment * n);
++		slot = os_aio_array_get_nth_slot(array, i);
+ 
+-		if (slot->reserved) {
++		if (slot->reserved &&
++		    (slot->status == OS_AIO_NOT_ISSUED ||
++		     slot->status == OS_AIO_DONE)) {
+ 			/* Found an i/o request */
+ 			
+ 			break;
+@@ -3336,7 +3402,25 @@
+ 	os_mutex_exit(array->mutex);
+ 
+ 	if (i < n) {
+-		os_event_set(os_aio_segment_wait_events[global_segment]);
++		if (array == os_aio_ibuf_array) {
++			os_event_set(os_aio_segment_wait_events[0]);
++
++		} else if (array == os_aio_log_array) {
++			os_event_set(os_aio_segment_wait_events[1]);
++
++		} else if (array == os_aio_read_array) {
++			ulint	x;
++			for (x = os_aio_first_read_segment; x < os_aio_first_write_segment; x++)
++				os_event_set(os_aio_segment_wait_events[x]);
++
++		} else if (array == os_aio_write_array) {
++			ulint	x;
++			for (x = os_aio_first_write_segment; x < os_aio_n_segments; x++)
++				os_event_set(os_aio_segment_wait_events[x]);
++
++		} else {
++			ut_a(0);
++		}
+ 	}
+ }
+ 
+@@ -3347,8 +3431,6 @@
+ os_aio_simulated_wake_handler_threads(void)
+ /*=======================================*/
+ {
+-	ulint	i;
+-
+ 	if (os_aio_use_native_aio) {
+ 		/* We do not use simulated aio: do nothing */
+ 
+@@ -3357,9 +3439,10 @@
+ 
+ 	os_aio_recommend_sleep_for_read_threads	= FALSE;
+ 
+-	for (i = 0; i < os_aio_n_segments; i++) {
+-		os_aio_simulated_wake_handler_thread(i);
+-	}
++	os_aio_simulated_wake_handler_thread(0);
++	os_aio_simulated_wake_handler_thread(1);
++	os_aio_simulated_wake_handler_thread(os_aio_first_read_segment);
++	os_aio_simulated_wake_handler_thread(os_aio_first_write_segment);
+ }
+ 
+ /**************************************************************************
+@@ -3640,7 +3723,7 @@
+ 	ut_ad(os_aio_validate());
+ 	ut_ad(segment < array->n_segments);
+ 
+-	n = array->n_slots / array->n_segments;
++	n = array->n_slots;
+ 
+ 	if (array == os_aio_sync_array) {
+ 		os_event_wait(os_aio_array_get_nth_slot(array, pos)->event);
+@@ -3648,12 +3731,12 @@
+ 	} else {
+ 		srv_set_io_thread_op_info(orig_seg, "wait Windows aio");
+ 		i = os_event_wait_multiple(n,
+-				(array->native_events) + segment * n);
++				(array->native_events));
+ 	}
+ 
+ 	os_mutex_enter(array->mutex);
+ 
+-	slot = os_aio_array_get_nth_slot(array, i + segment * n);
++	slot = os_aio_array_get_nth_slot(array, i);
+ 
+ 	ut_a(slot->reserved);
+ 
+@@ -3830,10 +3913,13 @@
+ 	os_aio_slot_t*	slot;
+ 	os_aio_slot_t*	slot2;
+ 	os_aio_slot_t*	consecutive_ios[OS_AIO_MERGE_N_CONSECUTIVE];
++	os_aio_slot_t*	lowest_request;
++	os_aio_slot_t*	oldest_request;
+ 	ulint		n_consecutive;
+ 	ulint		total_len;
+ 	ulint		offs;
+ 	ulint		lowest_offset;
++	ulint		oldest_offset;
+ 	ulint		biggest_age;
+ 	ulint		age;
+ 	byte*		combined_buf;
+@@ -3841,6 +3927,7 @@
+ 	ibool		ret;
+ 	ulint		n;
+ 	ulint		i;
++	time_t		now;
+ 	
+ 	segment = os_aio_get_array_and_local_segment(&array, global_segment);
+ 	
+@@ -3853,7 +3940,7 @@
+ 	ut_ad(os_aio_validate());
+ 	ut_ad(segment < array->n_segments);
+ 
+-	n = array->n_slots / array->n_segments;
++	n = array->n_slots;
+ 
+ 	/* Look through n slots after the segment * n'th slot */
+ 
+@@ -3875,9 +3962,9 @@
+ 	done */
+ 	
+ 	for (i = 0; i < n; i++) {
+-		slot = os_aio_array_get_nth_slot(array, i + segment * n);
++		slot = os_aio_array_get_nth_slot(array, i);
+ 
+-		if (slot->reserved && slot->io_already_done) {
++		if (slot->reserved && slot->status == OS_AIO_DONE) {
+ 
+ 			if (os_aio_print_debug) {
+ 				fprintf(stderr,
+@@ -3897,67 +3984,57 @@
+ 	then pick the one at the lowest offset. */
+ 
+ 	biggest_age = 0;
+-	lowest_offset = ULINT_MAX;
++	now = time(NULL);
++	oldest_request = lowest_request = NULL;
++	oldest_offset = lowest_offset = ULINT_MAX;
+ 
++	/* Find the oldest request and the request with the smallest offset */
+ 	for (i = 0; i < n; i++) {
+-		slot = os_aio_array_get_nth_slot(array, i + segment * n);
++		slot = os_aio_array_get_nth_slot(array, i);
+ 
+-		if (slot->reserved) {
+-		        age = (ulint)difftime(time(NULL),
+-						slot->reservation_time);
++		if (slot->reserved && slot->status == OS_AIO_NOT_ISSUED) {
++			age = (ulint)difftime(now, slot->reservation_time);
+ 
+ 			if ((age >= 2 && age > biggest_age)
+ 			    || (age >= 2 && age == biggest_age
+-			        && slot->offset < lowest_offset)) {
++				&& slot->offset < oldest_offset)) {
+ 
+ 			        /* Found an i/o request */
+-				consecutive_ios[0] = slot;
+-
+-				n_consecutive = 1;
+-
+ 				biggest_age = age;
+-				lowest_offset = slot->offset;
++				oldest_request = slot;
++				oldest_offset = slot->offset;
+ 			}
+-		}
+-	}
+-
+-	if (n_consecutive == 0) {
+-	        /* There were no old requests. Look for an i/o request at the
+-		lowest offset in the array (we ignore the high 32 bits of the
+-		offset in these heuristics) */
+-
+-		lowest_offset = ULINT_MAX;
+-	
+-		for (i = 0; i < n; i++) {
+-		        slot = os_aio_array_get_nth_slot(array,
+-							i + segment * n);
+-
+-			if (slot->reserved && slot->offset < lowest_offset) {
+ 
++			/* Look for an i/o request at the lowest offset in the array
++			 * (we ignore the high 32 bits of the offset) */
++			if (slot->offset < lowest_offset) {
+ 			        /* Found an i/o request */
+-				consecutive_ios[0] = slot;
+-
+-				n_consecutive = 1;
+-
++				lowest_request = slot;
+ 				lowest_offset = slot->offset;
+ 			}
+ 		}
+ 	}
+ 
+-	if (n_consecutive == 0) {
++	if (!lowest_request && !oldest_request) {
+ 
+ 		/* No i/o requested at the moment */
+ 
+ 		goto wait_for_io;
+ 	}
+ 
+-	slot = consecutive_ios[0];
++	if (oldest_request) {
++		slot = oldest_request;
++	} else {
++		slot = lowest_request;
++	}
++	consecutive_ios[0] = slot;
++	n_consecutive = 1;
+ 
+ 	/* Check if there are several consecutive blocks to read or write */
+ 
+ consecutive_loop:	
+ 	for (i = 0; i < n; i++) {
+-		slot2 = os_aio_array_get_nth_slot(array, i + segment * n);
++		slot2 = os_aio_array_get_nth_slot(array, i);
+ 
+ 		if (slot2->reserved && slot2 != slot
+ 		    && slot2->offset == slot->offset + slot->len
+@@ -3965,7 +4042,8 @@
+ 						sum does not wrap over */
+ 		    && slot2->offset_high == slot->offset_high
+ 		    && slot2->type == slot->type
+-		    && slot2->file == slot->file) {
++		    && slot2->file == slot->file
++		    && slot2->status == OS_AIO_NOT_ISSUED) {
+ 
+ 			/* Found a consecutive i/o request */
+ 
+@@ -3994,6 +4072,8 @@
+ 	
+ 	for (i = 0; i < n_consecutive; i++) {
+ 		total_len += consecutive_ios[i]->len;
++		ut_a(consecutive_ios[i]->status == OS_AIO_NOT_ISSUED);
++		consecutive_ios[i]->status = OS_AIO_ISSUED;
+ 	}
+ 
+ 	if (n_consecutive == 1) {
+@@ -4001,7 +4081,14 @@
+ 		combined_buf = slot->buf;
+ 		combined_buf2 = NULL;
+ 	} else {
+-		combined_buf2 = ut_malloc(total_len + UNIV_PAGE_SIZE);
++		if ((total_len + UNIV_PAGE_SIZE) > os_aio_thread_buffer_size[global_segment]) {
++			if (os_aio_thread_buffer[global_segment])
++				ut_free(os_aio_thread_buffer[global_segment]);
++
++			os_aio_thread_buffer[global_segment] = ut_malloc(total_len + UNIV_PAGE_SIZE);
++			os_aio_thread_buffer_size[global_segment] = total_len + UNIV_PAGE_SIZE;
++		}
++		combined_buf2 = os_aio_thread_buffer[global_segment];
+ 
+ 		ut_a(combined_buf2);
+ 
+@@ -4012,6 +4099,9 @@
+ 	this assumes that there is just one i/o-handler thread serving
+ 	a single segment of slots! */
+ 
++	ut_a(slot->reserved);
++	ut_a(slot->status == OS_AIO_ISSUED);
++
+ 	os_mutex_exit(array->mutex);
+ 
+ 	if (slot->type == OS_FILE_WRITE && n_consecutive > 1) {
+@@ -4081,16 +4171,13 @@
+ 		}
+ 	}
+ 
+-	if (combined_buf2) {
+-		ut_free(combined_buf2);
+-	}
+-
+ 	os_mutex_enter(array->mutex);
+ 
+ 	/* Mark the i/os done in slots */
+ 
+ 	for (i = 0; i < n_consecutive; i++) {
+-		consecutive_ios[i]->io_already_done = TRUE;
++		ut_a(consecutive_ios[i]->status == OS_AIO_ISSUED);
++		consecutive_ios[i]->status = OS_AIO_DONE;
+ 	}
+ 
+ 	/* We return the messages for the first slot now, and if there were
+@@ -4100,6 +4187,8 @@
+ slot_io_done:
+ 
+ 	ut_a(slot->reserved);
++	ut_a(slot->status == OS_AIO_DONE);
++	slot->status = OS_AIO_CLAIMED;
+ 
+ 	*message1 = slot->message1;
+ 	*message2 = slot->message2;
+diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
+--- a/innobase/srv/srv0srv.c	2009-07-02 16:43:23.000000000 +0900
++++ b/innobase/srv/srv0srv.c	2009-07-02 18:36:54.000000000 +0900
 @@ -167,6 +167,8 @@
  ulint	srv_lock_table_size	= ULINT_MAX;
  
@@ -252,32 +734,69 @@ diff -r ed298a6e5e10 innobase/srv/srv0srv.c
 +ulint	srv_enable_unsafe_group_commit = 0; /* 0:disable 1:enable */
 +
 +uint	srv_read_ahead = 3; /* 1: random  2: linear  3: Both */
-+ulint	srv_adaptive_checkpoint = 0; /* 0:disable 1:enable */
++uint	srv_adaptive_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
  /*-------------------------------------------*/
  ulong	srv_n_spin_wait_rounds	= 20;
  ulong	srv_n_free_tickets_to_enter = 500;
-@@ -2229,6 +2249,8 @@
+@@ -2228,6 +2248,10 @@
+ 	ulint		n_pend_ios;
  	ibool		skip_sleep	= FALSE;
  	ulint		i;
- 	
-+	dulint		oldest_lsn;
++
++	dulint		lsn_old;
 +	
++	dulint		oldest_lsn;
+ 	
  #ifdef UNIV_DEBUG_THREAD_CREATION
  	fprintf(stderr, "Master thread starts, id %lu\n",
- 			      os_thread_pf(os_thread_get_curr_id()));
-@@ -2317,9 +2339,9 @@
+@@ -2244,6 +2268,9 @@
+ 
+ 	mutex_exit(&kernel_mutex);
+ 
++	mutex_enter(&(log_sys->mutex));
++	lsn_old = log_sys->lsn;
++	mutex_exit(&(log_sys->mutex));
+ 	os_event_set(srv_sys->operational);
+ loop:
+ 	/*****************************************************************/
+@@ -2279,6 +2306,18 @@
+ 		if (!skip_sleep) {
+ 
+ 		        os_thread_sleep(1000000);
++			/*
++			mutex_enter(&(log_sys->mutex));
++			oldest_lsn = buf_pool_get_oldest_modification();
++			dulint	lsn = log_sys->lsn;
++			mutex_exit(&(log_sys->mutex));
++
++			if (!ut_dulint_is_zero(oldest_lsn))
++			fprintf(stderr,
++				"InnoDB flush: age pct: %lu, lsn progress: %lu\n",
++				ut_dulint_minus(lsn, oldest_lsn) * 100 / log_sys->max_checkpoint_age,
++				ut_dulint_minus(lsn, lsn_old));
++			*/
+ 		}
+ 
+ 		skip_sleep = FALSE;
+@@ -2317,13 +2356,14 @@
  						+ log_sys->n_pending_writes;
  		n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
  						+ buf_pool->n_pages_written;
 -		if (n_pend_ios < 3 && (n_ios - n_ios_old < 5)) {
-+		if (n_pend_ios < 3 && (n_ios - n_ios_old < PCT_IO(5))) {
++		if (n_pend_ios < PCT_IO(3) && (n_ios - n_ios_old < PCT_IO(5))) {
  			srv_main_thread_op_info = "doing insert buffer merge";
 -			ibuf_contract_for_n_pages(TRUE, 5);
 +			ibuf_contract_for_n_pages(TRUE, PCT_IBUF_IO(5));
  
  			srv_main_thread_op_info = "flushing log";
  
-@@ -2332,7 +2354,7 @@
+-			log_buffer_flush_to_disk();
++			/* No fsync when srv_flush_log_at_trx_commit != 1 */
++			log_buffer_flush_maybe_sync();
+ 		}
+ 
+ 		if (buf_get_modified_ratio_pct() >
+@@ -2332,7 +2372,7 @@
  			/* Try to keep the number of modified pages in the
  			buffer pool under the limit wished by the user */
  			
@@ -286,17 +805,20 @@ diff -r ed298a6e5e10 innobase/srv/srv0srv.c
  							  ut_dulint_max);
  
  		        /* If we had to do the flush, it may have taken
-@@ -2341,6 +2363,49 @@
+@@ -2341,6 +2381,140 @@
  			iteration of this loop. */
  			     
  			skip_sleep = TRUE;
-+		} else if (srv_adaptive_checkpoint) {
++			mutex_enter(&(log_sys->mutex));
++			lsn_old = log_sys->lsn;
++			mutex_exit(&(log_sys->mutex));
++		} else if (srv_adaptive_checkpoint == 1) {
 +
 +			/* Try to keep modified age not to exceed
 +			max_checkpoint_age * 7/8 line */
 +
 +			mutex_enter(&(log_sys->mutex));
-+
++			lsn_old = log_sys->lsn;
 +			oldest_lsn = buf_pool_get_oldest_modification();
 +			if (ut_dulint_is_zero(oldest_lsn)) {
 +
@@ -332,11 +854,99 @@ diff -r ed298a6e5e10 innobase/srv/srv0srv.c
 +					mutex_exit(&(log_sys->mutex));
 +				}
 +			}
++		} else if (srv_adaptive_checkpoint == 2) {
++
++			/* Try to keep modified age not to exceed
++			max_checkpoint_age * 7/8 line */
++
++			mutex_enter(&(log_sys->mutex));
++
++			oldest_lsn = buf_pool_get_oldest_modification();
++			if (ut_dulint_is_zero(oldest_lsn)) {
++				lsn_old = log_sys->lsn;
++				mutex_exit(&(log_sys->mutex));
++
++			} else {
++				if (ut_dulint_minus(log_sys->lsn, oldest_lsn)
++				    > (log_sys->max_checkpoint_age) - ((log_sys->max_checkpoint_age) / 8)) {
++					/* LOG_POOL_PREFLUSH_RATIO_ASYNC is exceeded. */
++					/* We should not flush from here. */
++					lsn_old = log_sys->lsn;
++					mutex_exit(&(log_sys->mutex));
++				} else if (ut_dulint_minus(log_sys->lsn, oldest_lsn)
++					   > (log_sys->max_checkpoint_age)/2 ) {
++
++					/* defence line (max_checkpoint_age * 1/2) */
++					dulint	lsn = log_sys->lsn;
 +
++					mutex_exit(&(log_sys->mutex));
++
++					ib_longlong level, bpl;
++					buf_block_t* bpage;
++
++					mutex_enter(&buf_pool->mutex);
++
++					level = 0;
++					bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
++
++					while (bpage != NULL) {
++						dulint	oldest_modification = bpage->oldest_modification;
++						if (!ut_dulint_is_zero(oldest_modification)) {
++							level += log_sys->max_checkpoint_age
++								 - ut_dulint_minus(lsn, oldest_modification);
++						}
++						bpage = UT_LIST_GET_NEXT(flush_list, bpage);
++					}
++
++					if (level) {
++						bpl = ((ib_longlong) UT_LIST_GET_LEN(buf_pool->flush_list)
++							* UT_LIST_GET_LEN(buf_pool->flush_list)
++							* ut_dulint_minus(lsn, lsn_old)) / level;
++					} else {
++						bpl = 0;
++					}
++
++					mutex_exit(&buf_pool->mutex);
++
++					if (!srv_use_doublewrite_buf) {
++						/* flush is faster than when doublewrite */
++						bpl = (bpl * 3) / 4;
++					}
++
++					if(bpl) {
++retry_flush_batch:
++						n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
++									bpl,
++									ut_dulint_add(oldest_lsn,
++										ut_dulint_minus(lsn,
++											lsn_old)));
++						if (n_pages_flushed == ULINT_UNDEFINED) {
++							os_thread_sleep(5000);
++							goto retry_flush_batch;
++						}
++					}
++
++					lsn_old = lsn;
++					/*
++					fprintf(stderr,
++						"InnoDB flush: age pct: %lu, lsn progress: %lu, blocks to flush:%llu\n",
++						ut_dulint_minus(lsn, oldest_lsn) * 100 / log_sys->max_checkpoint_age,
++						ut_dulint_minus(lsn, lsn_old), bpl);
++					*/
++				} else {
++					lsn_old = log_sys->lsn;
++					mutex_exit(&(log_sys->mutex));
++				}
++			}
++
++		} else {
++			mutex_enter(&(log_sys->mutex));
++			lsn_old = log_sys->lsn;
++			mutex_exit(&(log_sys->mutex));
  		}
  
  		if (srv_activity_count == old_activity_count) {
-@@ -2367,10 +2432,10 @@
+@@ -2367,23 +2541,25 @@
  	n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
  	n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
  						+ buf_pool->n_pages_written;
@@ -348,8 +958,12 @@ diff -r ed298a6e5e10 innobase/srv/srv0srv.c
 +		buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100), ut_dulint_max);
  
  		srv_main_thread_op_info = "flushing log";
- 		log_buffer_flush_to_disk();
-@@ -2380,7 +2445,7 @@
+-		log_buffer_flush_to_disk();
++		/* No fsync when srv_flush_log_at_trx_commit != 1 */
++		log_buffer_flush_maybe_sync();
+ 	}
+ 
+ 	/* We run a batch of insert buffer merge every 10 seconds,
  	even if the server were active */
  
  	srv_main_thread_op_info = "doing insert buffer merge";
@@ -357,8 +971,13 @@ diff -r ed298a6e5e10 innobase/srv/srv0srv.c
 +	ibuf_contract_for_n_pages(TRUE, PCT_IBUF_IO(5));
  
  	srv_main_thread_op_info = "flushing log";
- 	log_buffer_flush_to_disk();
-@@ -2422,14 +2487,14 @@
+-	log_buffer_flush_to_disk();
++	/* No fsync when srv_flush_log_at_trx_commit != 1 */
++	log_buffer_flush_maybe_sync();
+ 
+ 	/* We run a full purge every 10 seconds, even if the server
+ 	were active */
+@@ -2422,14 +2598,14 @@
  		(> 70 %), we assume we can afford reserving the disk(s) for
  		the time it requires to flush 100 pages */
  
@@ -375,7 +994,7 @@ diff -r ed298a6e5e10 innobase/srv/srv0srv.c
  							ut_dulint_max);
  	}
  
-@@ -2518,7 +2583,7 @@
+@@ -2518,7 +2694,7 @@
  	if (srv_fast_shutdown && srv_shutdown_state > 0) {
  	        n_bytes_merged = 0;
  	} else {
@@ -384,7 +1003,7 @@ diff -r ed298a6e5e10 innobase/srv/srv0srv.c
  	}
  
  	srv_main_thread_op_info = "reserving kernel mutex";
-@@ -2535,7 +2600,7 @@
+@@ -2535,7 +2711,7 @@
  
  	if (srv_fast_shutdown < 2) {
  		n_pages_flushed =
@@ -393,9 +1012,25 @@ diff -r ed298a6e5e10 innobase/srv/srv0srv.c
  	} else {
  		/* In the fastest shutdown we do not flush the buffer pool
  		to data files: we set n_pages_flushed to 0 artificially. */
-diff -r ed298a6e5e10 innobase/srv/srv0start.c
---- a/innobase/srv/srv0start.c	Mon Jun 01 00:36:10 2009 -0700
-+++ b/innobase/srv/srv0start.c	Mon Jun 01 00:36:16 2009 -0700
+@@ -2557,7 +2733,14 @@
+ 
+ 	srv_main_thread_op_info = "flushing log";
+ 
+-	log_buffer_flush_to_disk();
++	current_time = time(NULL);
++	if (difftime(current_time, last_flush_time) > 1) {
++		log_buffer_flush_to_disk();
++		last_flush_time = current_time;
++	} else {
++		/* No fsync when srv_flush_log_at_trx_commit != 1 */
++		log_buffer_flush_maybe_sync();
++	}
+ 
+ 	srv_main_thread_op_info = "making checkpoint";
+ 
+diff -ruN a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
+--- a/innobase/srv/srv0start.c	2009-05-08 06:12:12.000000000 +0900
++++ b/innobase/srv/srv0start.c	2009-07-02 16:44:49.000000000 +0900
 @@ -1205,24 +1205,28 @@
  		return(DB_ERROR);
  	}
@@ -418,9 +1053,8 @@ diff -r ed298a6e5e10 innobase/srv/srv0start.c
  		os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD
  						* srv_n_file_io_threads,
 -					srv_n_file_io_threads,
--					SRV_MAX_N_PENDING_SYNC_IOS);
 +					srv_n_read_io_threads, srv_n_write_io_threads,
-+					SRV_MAX_N_PENDING_SYNC_IOS * 8);
+ 					SRV_MAX_N_PENDING_SYNC_IOS);
  	} else {
  		os_aio_init(SRV_N_PENDING_IOS_PER_THREAD
  						* srv_n_file_io_threads,
@@ -429,9 +1063,9 @@ diff -r ed298a6e5e10 innobase/srv/srv0start.c
  					SRV_MAX_N_PENDING_SYNC_IOS);
  	}
  	
-diff -r ed298a6e5e10 patch_info/innodb_io_patches.info
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/patch_info/innodb_io_patches.info	Mon Jun 01 00:36:16 2009 -0700
+diff -ruN a/patch_info/innodb_io_patches.info b/patch_info/innodb_io_patches.info
+--- /dev/null	1970-01-01 09:00:00.000000000 +0900
++++ b/patch_info/innodb_io_patches.info	2009-07-02 16:44:49.000000000 +0900
 @@ -0,0 +1,11 @@
 +File=innodb_io_patches.patch
 +Name=Cluster of past InnoDB IO patches
@@ -444,9 +1078,9 @@ diff -r ed298a6e5e10 patch_info/innodb_io_patches.info
 +YK: Initial release
 +2009-01-09
 +YK: Some parameters are added
-diff -r ed298a6e5e10 sql/ha_innodb.cc
---- a/sql/ha_innodb.cc	Mon Jun 01 00:36:10 2009 -0700
-+++ b/sql/ha_innodb.cc	Mon Jun 01 00:36:16 2009 -0700
+diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc
+--- a/sql/ha_innodb.cc	2009-07-02 16:43:23.000000000 +0900
++++ b/sql/ha_innodb.cc	2009-07-02 16:44:49.000000000 +0900
 @@ -149,6 +149,7 @@
       innobase_lock_wait_timeout, innobase_force_recovery,
       innobase_open_files;
@@ -475,9 +1109,9 @@ diff -r ed298a6e5e10 sql/ha_innodb.cc
  
                  /* For ibbackup to work the order of transactions in binlog
                  and InnoDB must be the same. Consider the situation
-diff -r ed298a6e5e10 sql/ha_innodb.h
---- a/sql/ha_innodb.h	Mon Jun 01 00:36:10 2009 -0700
-+++ b/sql/ha_innodb.h	Mon Jun 01 00:36:16 2009 -0700
+diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h
+--- a/sql/ha_innodb.h	2009-07-02 16:43:23.000000000 +0900
++++ b/sql/ha_innodb.h	2009-07-02 18:10:51.000000000 +0900
 @@ -204,6 +204,7 @@
  extern long innobase_additional_mem_pool_size;
  extern long innobase_buffer_pool_awe_mem_mb;
@@ -497,14 +1131,14 @@ diff -r ed298a6e5e10 sql/ha_innodb.h
 +extern ulong srv_flush_neighbor_pages;
 +extern ulong srv_enable_unsafe_group_commit;
 +extern uint srv_read_ahead;
-+extern ulong srv_adaptive_checkpoint;
++extern uint srv_adaptive_checkpoint;
 +
  /* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does
  NOT update cardinality for indexes of InnoDB table". By default we are
  running with the fix disabled because MySQL 5.1 is frozen for such
-diff -r ed298a6e5e10 sql/mysqld.cc
---- a/sql/mysqld.cc	Mon Jun 01 00:36:10 2009 -0700
-+++ b/sql/mysqld.cc	Mon Jun 01 00:36:16 2009 -0700
+diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
+--- a/sql/mysqld.cc	2009-07-02 16:43:23.000000000 +0900
++++ b/sql/mysqld.cc	2009-07-02 18:00:04.000000000 +0900
 @@ -5086,6 +5086,16 @@
    OPT_INNODB_ROLLBACK_ON_TIMEOUT,
    OPT_SECURE_FILE_PRIV,
@@ -522,14 +1156,14 @@ diff -r ed298a6e5e10 sql/mysqld.cc
    OPT_INNODB_ADAPTIVE_HASH_INDEX,
    OPT_FEDERATED,
    OPT_INNODB_USE_LEGACY_CARDINALITY_ALGORITHM
-@@ -5403,6 +5413,45 @@
+@@ -5403,6 +5413,44 @@
     (gptr*) &srv_use_legacy_cardinality_algorithm,
     (gptr*) &srv_use_legacy_cardinality_algorithm,
     0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
 +  {"innodb_io_capacity", OPT_INNODB_IO_CAPACITY,
 +   "Number of IO operations per second the server can do. Tunes background IO rate.",
 +   (gptr*) &srv_io_capacity, (gptr*) &srv_io_capacity,
-+   0, GET_ULONG, REQUIRED_ARG, 100, 100, 999999999, 0, 0, 0},
++   0, GET_ULONG, REQUIRED_ARG, 200, 100, 999999999, 0, 0, 0},
 +  {"innodb_ibuf_max_size", OPT_INNODB_IBUF_MAX_SIZE,
 +   "The maximum size of the insert buffer. (in bytes)",
 +   (gptr*) &srv_ibuf_max_size, (gptr*) &srv_ibuf_max_size, 0,
@@ -550,9 +1184,8 @@ diff -r ed298a6e5e10 sql/mysqld.cc
 +   "Control read ahead activity. (none, random, linear, [both])",
 +   0, 0, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 +  {"innodb_adaptive_checkpoint", OPT_INNODB_ADAPTIVE_CHECKPOINT,
-+   "Enable/Diasable flushing along modified age. 0:disable 1:enable",
-+   (gptr*) &srv_adaptive_checkpoint, (gptr*) &srv_adaptive_checkpoint,
-+   0, GET_ULONG, REQUIRED_ARG, 0, 0, 1, 0, 0, 0},
++   "Enable/Diasable flushing along modified age. ([none], reflex, estimate)",
++   0, 0, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 +  {"innodb_enable_unsafe_group_commit", OPT_INNODB_ENABLE_UNSAFE_GROUP_COMMIT,
 +   "Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.",
 +   (gptr*) &srv_enable_unsafe_group_commit, (gptr*) &srv_enable_unsafe_group_commit,
@@ -560,15 +1193,15 @@ diff -r ed298a6e5e10 sql/mysqld.cc
 +  {"innodb_read_io_threads", OPT_INNODB_READ_IO_THREADS,
 +   "Number of background read I/O threads in InnoDB.",
 +   (gptr*) &innobase_read_io_threads, (gptr*) &innobase_read_io_threads,
-+   0, GET_LONG, REQUIRED_ARG, 1, 1, 64, 0, 0, 0},
++   0, GET_LONG, REQUIRED_ARG, 8, 1, 64, 0, 0, 0},
 +  {"innodb_write_io_threads", OPT_INNODB_WRITE_IO_THREADS,
 +   "Number of background write I/O threads in InnoDB.",
 +   (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads,
-+   0, GET_LONG, REQUIRED_ARG, 1, 1, 64, 0, 0, 0},
++   0, GET_LONG, REQUIRED_ARG, 8, 1, 64, 0, 0, 0},
  #endif /* End HAVE_INNOBASE_DB */
    {"isam", OPT_ISAM, "Obsolete. ISAM storage engine is no longer supported.",
     (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 0, 0, 0,
-@@ -7644,6 +7693,22 @@
+@@ -7644,6 +7692,38 @@
    case OPT_INNODB_LOG_ARCHIVE:
      innobase_log_archive= argument ? test(atoi(argument)) : 1;
      break;
@@ -588,13 +1221,29 @@ diff -r ed298a6e5e10 sql/mysqld.cc
 +      srv_read_ahead = (uint) ((type - 1) & 3);
 +    }
 +    break;
++  case OPT_INNODB_ADAPTIVE_CHECKPOINT:
++    if (argument == disabled_my_option)
++      srv_adaptive_checkpoint = 0;
++    else if (! argument)
++      srv_adaptive_checkpoint = 0;
++    else
++    {
++      int type;
++      if ((type=find_type(argument, &innodb_adaptive_checkpoint_typelib, 2)) <= 0)
++      {
++        fprintf(stderr,"Unknown innodb_adaptive_checkpoint type: %s\n",argument);
++        exit(1);
++      }
++      srv_adaptive_checkpoint = (uint) ((type - 1) % 3);
++    }
++    break;
  #endif /* HAVE_INNOBASE_DB */
    case OPT_MYISAM_RECOVER:
    {
-diff -r ed298a6e5e10 sql/set_var.cc
---- a/sql/set_var.cc	Mon Jun 01 00:36:10 2009 -0700
-+++ b/sql/set_var.cc	Mon Jun 01 00:36:16 2009 -0700
-@@ -489,6 +489,39 @@
+diff -ruN a/sql/set_var.cc b/sql/set_var.cc
+--- a/sql/set_var.cc	2009-07-02 16:43:23.000000000 +0900
++++ b/sql/set_var.cc	2009-07-02 17:45:29.000000000 +0900
+@@ -489,6 +489,57 @@
  sys_var_long_ptr  sys_innodb_flush_log_at_trx_commit(
                                          "innodb_flush_log_at_trx_commit",
                                          &srv_flush_log_at_trx_commit);
@@ -629,12 +1278,30 @@ diff -r ed298a6e5e10 sql/set_var.cc
 +                                      &innodb_read_ahead_typelib, fix_innodb_read_ahead);
 +sys_var_long_ptr	sys_innodb_enable_unsafe_group_commit("innodb_enable_unsafe_group_commit",
 +                                                             &srv_enable_unsafe_group_commit);
-+sys_var_long_ptr	sys_innodb_adaptive_checkpoint("innodb_adaptive_checkpoint",
-+                                                      &srv_adaptive_checkpoint);
++
++const char *innodb_adaptive_checkpoint_names[]=
++{
++  "none", /* 0 */
++  "reflex", /* 1 */
++  "estimate", /* 2 */
++  /* For compatibility of the older patch */
++  "0", /* 3 ("none" + 3) */
++  "1", /* 4 ("reflex" + 3) */
++  "2", /* 5 ("estimate" + 3) */
++  NullS
++};
++TYPELIB innodb_adaptive_checkpoint_typelib=
++{
++  array_elements(innodb_adaptive_checkpoint_names) - 1, "innodb_adaptive_checkpoint_typelib",
++  innodb_adaptive_checkpoint_names, NULL
++};
++sys_var_enum	sys_innodb_adaptive_checkpoint("innodb_adaptive_checkpoint",
++                           &srv_adaptive_checkpoint,
++                           &innodb_adaptive_checkpoint_typelib, fix_innodb_adaptive_checkpoint);
  sys_var_const_os_str_ptr sys_innodb_data_file_path("innodb_data_file_path", 
                                                 &innobase_data_file_path);
  sys_var_const_os_str_ptr sys_innodb_data_home_dir("innodb_data_home_dir", 
-@@ -860,6 +893,13 @@
+@@ -860,6 +911,13 @@
    &sys_innodb_thread_concurrency,
    &sys_innodb_commit_concurrency,
    &sys_innodb_flush_log_at_trx_commit,
@@ -648,7 +1315,7 @@ diff -r ed298a6e5e10 sql/set_var.cc
  #endif
    &sys_trust_routine_creators,
    &sys_trust_function_creators,
-@@ -997,6 +1037,16 @@
+@@ -997,6 +1055,16 @@
    {sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS},
    {sys_innodb_thread_concurrency.name, (char*) &sys_innodb_thread_concurrency, SHOW_SYS},
    {sys_innodb_thread_sleep_delay.name, (char*) &sys_innodb_thread_sleep_delay, SHOW_SYS},
@@ -665,7 +1332,7 @@ diff -r ed298a6e5e10 sql/set_var.cc
    {sys_innodb_use_legacy_cardinality_algorithm.name,
     (char*) &sys_innodb_use_legacy_cardinality_algorithm, SHOW_SYS},
  #endif
-@@ -1459,6 +1509,13 @@
+@@ -1459,6 +1527,18 @@
    }
  }
  
@@ -674,31 +1341,38 @@ diff -r ed298a6e5e10 sql/set_var.cc
 +{
 +  srv_read_ahead &= 3;
 +}
++
++extern void fix_innodb_adaptive_checkpoint(THD *thd, enum_var_type type)
++{
++  srv_adaptive_checkpoint %= 3;
++}
 +#endif /* HAVE_INNOBASE_DB */
 +
  static void fix_max_binlog_size(THD *thd, enum_var_type type)
  {
    DBUG_ENTER("fix_max_binlog_size");
-diff -r ed298a6e5e10 sql/set_var.h
---- a/sql/set_var.h	Mon Jun 01 00:36:10 2009 -0700
-+++ b/sql/set_var.h	Mon Jun 01 00:36:16 2009 -0700
-@@ -31,6 +31,10 @@
+diff -ruN a/sql/set_var.h b/sql/set_var.h
+--- a/sql/set_var.h	2009-07-02 16:43:23.000000000 +0900
++++ b/sql/set_var.h	2009-07-02 17:35:17.000000000 +0900
+@@ -31,6 +31,11 @@
  
  extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
  
 +#ifdef HAVE_INNOBASE_DB
 +extern TYPELIB innodb_read_ahead_typelib;
++extern TYPELIB innodb_adaptive_checkpoint_typelib;
 +#endif /* HAVE_INNOBASE_DB */
 +
  typedef int (*sys_check_func)(THD *,  set_var *);
  typedef bool (*sys_update_func)(THD *, set_var *);
  typedef void (*sys_after_update_func)(THD *,enum_var_type);
-@@ -1148,6 +1152,9 @@
+@@ -1148,6 +1153,10 @@
  int sql_set_variables(THD *thd, List<set_var_base> *var_list);
  bool not_all_support_one_shot(List<set_var_base> *var_list);
  void fix_delay_key_write(THD *thd, enum_var_type type);
 +#ifdef HAVE_INNOBASE_DB
 +void fix_innodb_read_ahead(THD *thd, enum_var_type type);
++void fix_innodb_adaptive_checkpoint(THD *thd, enum_var_type type);
 +#endif /* HAVE_INNOBASE_DB */
  ulong fix_sql_mode(ulong sql_mode);
  extern sys_var_const_str sys_charset_system;
diff --git a/mysql-innodb_io_pattern.patch b/mysql-innodb_io_pattern.patch
index 305f63d..d9e60e9 100644
--- a/mysql-innodb_io_pattern.patch
+++ b/mysql-innodb_io_pattern.patch
@@ -1,20 +1,20 @@
-diff -r 5060df9888d7 include/mysql_com.h
---- a/include/mysql_com.h	Tue Feb 17 22:33:54 2009 -0800
-+++ b/include/mysql_com.h	Tue Feb 17 22:33:58 2009 -0800
-@@ -121,6 +121,9 @@
- #define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */
+diff -r d4826c0a98c2 include/mysql_com.h
+--- a/include/mysql_com.h	Wed Jul 29 09:58:58 2009 -0700
++++ b/include/mysql_com.h	Wed Jul 29 10:00:12 2009 -0700
+@@ -122,6 +122,9 @@
  #define REFRESH_DES_KEY_FILE	0x40000L
  #define REFRESH_USER_RESOURCES	0x80000L
-+
+ 
 +/* TRUNCATE INFORMATION_SCHEMA.INNODB_IO_PATTERN */
 +#define REFRESH_INNODB_IO_PATTERN	0x1000000L
- 
++
  #define CLIENT_LONG_PASSWORD	1	/* new more secure passwords */
  #define CLIENT_FOUND_ROWS	2	/* Found instead of affected rows */
-diff -r 5060df9888d7 innobase/buf/buf0buf.c
---- a/innobase/buf/buf0buf.c	Tue Feb 17 22:33:54 2009 -0800
-+++ b/innobase/buf/buf0buf.c	Tue Feb 17 22:33:58 2009 -0800
-@@ -653,6 +653,9 @@
+ #define CLIENT_LONG_FLAG	4	/* Get all column flags */
+diff -r d4826c0a98c2 innobase/buf/buf0buf.c
+--- a/innobase/buf/buf0buf.c	Wed Jul 29 09:58:58 2009 -0700
++++ b/innobase/buf/buf0buf.c	Wed Jul 29 10:00:12 2009 -0700
+@@ -654,6 +654,9 @@
  	}
  
  	buf_pool->page_hash = hash_create(2 * max_size);
@@ -24,7 +24,7 @@ diff -r 5060df9888d7 innobase/buf/buf0buf.c
  
  	buf_pool->n_pend_reads = 0;
  
-@@ -1966,6 +1969,9 @@
+@@ -1967,6 +1970,9 @@
  	ulint		io_type;
  	ulint		read_page_no;
  	
@@ -34,7 +34,7 @@ diff -r 5060df9888d7 innobase/buf/buf0buf.c
  	ut_ad(block);
  
  	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
-@@ -2067,6 +2073,26 @@
+@@ -2068,6 +2074,26 @@
  		buf_pool->n_pages_read++;
  
  		rw_lock_x_unlock_gen(&(block->lock), BUF_IO_READ);
@@ -61,7 +61,7 @@ diff -r 5060df9888d7 innobase/buf/buf0buf.c
  
  #ifdef UNIV_DEBUG
  		if (buf_debug_prints) {
-@@ -2082,6 +2108,26 @@
+@@ -2083,6 +2109,26 @@
  		buf_flush_write_complete(block);
  
  		rw_lock_s_unlock_gen(&(block->lock), BUF_IO_WRITE);
@@ -88,7 +88,7 @@ diff -r 5060df9888d7 innobase/buf/buf0buf.c
  
  		buf_pool->n_pages_written++;
  
-@@ -2656,3 +2702,58 @@
+@@ -2657,3 +2703,58 @@
  return buf_pool_get_nth_block(buf_pool, i);
  
  }
@@ -147,9 +147,9 @@ diff -r 5060df9888d7 innobase/buf/buf0buf.c
 +       }
 +       mutex_exit(&(buf_pool->mutex));
 +}
-diff -r 5060df9888d7 innobase/include/buf0buf.h
---- a/innobase/include/buf0buf.h	Tue Feb 17 22:33:54 2009 -0800
-+++ b/innobase/include/buf0buf.h	Tue Feb 17 22:33:58 2009 -0800
+diff -r d4826c0a98c2 innobase/include/buf0buf.h
+--- a/innobase/include/buf0buf.h	Wed Jul 29 09:58:58 2009 -0700
++++ b/innobase/include/buf0buf.h	Wed Jul 29 10:00:12 2009 -0700
 @@ -709,6 +709,18 @@
  void buf_pool_dump(void);
  buf_block_t* buf_pool_get_nth_block_no_inline(buf_pool_t* pool, ulint i);  
@@ -195,9 +195,9 @@ diff -r 5060df9888d7 innobase/include/buf0buf.h
  /* States of a control block */
  #define	BUF_BLOCK_NOT_USED	211	/* is in the free list */
  #define BUF_BLOCK_READY_FOR_USE	212	/* when buf_get_free_block returns
-diff -r 5060df9888d7 innobase/include/buf0types.h
---- a/innobase/include/buf0types.h	Tue Feb 17 22:33:54 2009 -0800
-+++ b/innobase/include/buf0types.h	Tue Feb 17 22:33:58 2009 -0800
+diff -r d4826c0a98c2 innobase/include/buf0types.h
+--- a/innobase/include/buf0types.h	Wed Jul 29 09:58:58 2009 -0700
++++ b/innobase/include/buf0types.h	Wed Jul 29 10:00:12 2009 -0700
 @@ -12,6 +12,8 @@
  typedef	struct buf_block_struct		buf_block_t;
  typedef	struct buf_pool_struct		buf_pool_t;
@@ -207,13 +207,13 @@ diff -r 5060df9888d7 innobase/include/buf0types.h
  /* The 'type' used of a buffer frame */
  typedef	byte	buf_frame_t;
  
-diff -r 5060df9888d7 innobase/include/srv0srv.h
---- a/innobase/include/srv0srv.h	Tue Feb 17 22:33:54 2009 -0800
-+++ b/innobase/include/srv0srv.h	Tue Feb 17 22:33:58 2009 -0800
-@@ -145,6 +145,11 @@
- extern ulint	srv_flush_neighbor_pages;
+diff -r d4826c0a98c2 innobase/include/srv0srv.h
+--- a/innobase/include/srv0srv.h	Wed Jul 29 09:58:58 2009 -0700
++++ b/innobase/include/srv0srv.h	Wed Jul 29 10:00:12 2009 -0700
+@@ -146,6 +146,11 @@
+ extern ulint	srv_enable_unsafe_group_commit;
  extern uint	srv_read_ahead;
- extern ulint	srv_adaptive_checkpoint;
+ extern uint	srv_adaptive_checkpoint;
 +
 +extern volatile ibool srv_io_pattern;
 +extern ulong	srv_io_pattern_trace;
@@ -222,13 +222,13 @@ diff -r 5060df9888d7 innobase/include/srv0srv.h
  /*-------------------------------------------*/
  
  extern ulint	srv_n_rows_inserted;
-diff -r 5060df9888d7 innobase/srv/srv0srv.c
---- a/innobase/srv/srv0srv.c	Tue Feb 17 22:33:54 2009 -0800
-+++ b/innobase/srv/srv0srv.c	Tue Feb 17 22:33:58 2009 -0800
-@@ -344,6 +344,11 @@
+diff -r d4826c0a98c2 innobase/srv/srv0srv.c
+--- a/innobase/srv/srv0srv.c	Wed Jul 29 09:58:58 2009 -0700
++++ b/innobase/srv/srv0srv.c	Wed Jul 29 10:00:12 2009 -0700
+@@ -352,6 +352,11 @@
  
  uint	srv_read_ahead = 3; /* 1: random  2: linear  3: Both */
- ulint	srv_adaptive_checkpoint = 0; /* 0:disable 1:enable */
+ uint	srv_adaptive_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
 +
 +volatile ibool srv_io_pattern = FALSE;
 +ulint   srv_io_pattern_trace = 0;
@@ -237,9 +237,9 @@ diff -r 5060df9888d7 innobase/srv/srv0srv.c
  /*-------------------------------------------*/
  ulong	srv_n_spin_wait_rounds	= 20;
  ulong	srv_n_free_tickets_to_enter = 500;
-diff -r 5060df9888d7 mysql-test/r/information_schema.result
---- a/mysql-test/r/information_schema.result	Tue Feb 17 22:33:54 2009 -0800
-+++ b/mysql-test/r/information_schema.result	Tue Feb 17 22:33:58 2009 -0800
+diff -r d4826c0a98c2 mysql-test/r/information_schema.result
+--- a/mysql-test/r/information_schema.result	Wed Jul 29 09:58:58 2009 -0700
++++ b/mysql-test/r/information_schema.result	Wed Jul 29 10:00:12 2009 -0700
 @@ -59,6 +59,7 @@
  USER_PRIVILEGES
  USER_STATISTICS
@@ -296,9 +296,9 @@ diff -r 5060df9888d7 mysql-test/r/information_schema.result
  KEY_COLUMN_USAGE	information_schema.KEY_COLUMN_USAGE	1
  PROCESSLIST	information_schema.PROCESSLIST	1
  PROFILING	information_schema.PROFILING	1
-diff -r 5060df9888d7 mysql-test/r/information_schema_db.result
---- a/mysql-test/r/information_schema_db.result	Tue Feb 17 22:33:54 2009 -0800
-+++ b/mysql-test/r/information_schema_db.result	Tue Feb 17 22:33:58 2009 -0800
+diff -r d4826c0a98c2 mysql-test/r/information_schema_db.result
+--- a/mysql-test/r/information_schema_db.result	Wed Jul 29 09:58:58 2009 -0700
++++ b/mysql-test/r/information_schema_db.result	Wed Jul 29 10:00:12 2009 -0700
 @@ -28,6 +28,7 @@
  USER_PRIVILEGES
  USER_STATISTICS
@@ -307,9 +307,9 @@ diff -r 5060df9888d7 mysql-test/r/information_schema_db.result
  show tables from INFORMATION_SCHEMA like 'T%';
  Tables_in_information_schema (T%)
  TABLES
-diff -r 5060df9888d7 mysql-test/r/mysqlshow.result
---- a/mysql-test/r/mysqlshow.result	Tue Feb 17 22:33:54 2009 -0800
-+++ b/mysql-test/r/mysqlshow.result	Tue Feb 17 22:33:58 2009 -0800
+diff -r d4826c0a98c2 mysql-test/r/mysqlshow.result
+--- a/mysql-test/r/mysqlshow.result	Wed Jul 29 09:58:58 2009 -0700
++++ b/mysql-test/r/mysqlshow.result	Wed Jul 29 10:00:12 2009 -0700
 @@ -102,6 +102,7 @@
  | USER_PRIVILEGES                       |
  | USER_STATISTICS                       |
@@ -326,9 +326,9 @@ diff -r 5060df9888d7 mysql-test/r/mysqlshow.result
  +---------------------------------------+
  Wildcard: inf_rmation_schema
  +--------------------+
-diff -r 5060df9888d7 patch_info/innodb_io_pattern.info
+diff -r d4826c0a98c2 patch_info/innodb_io_pattern.info
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/patch_info/innodb_io_pattern.info	Tue Feb 17 22:33:58 2009 -0800
++++ b/patch_info/innodb_io_pattern.info	Wed Jul 29 10:00:12 2009 -0700
 @@ -0,0 +1,8 @@
 +File=innodb_io_pattern.patch
 +Name=Information schema table of InnoDB IO counts for each datafile pages
@@ -338,10 +338,10 @@ diff -r 5060df9888d7 patch_info/innodb_io_pattern.info
 +Comment=INFORMATION_SCHEMA.INNODB_IO_PATTERN
 +2008-12-01
 +YK: fix for mysql-test
-diff -r 5060df9888d7 sql/ha_innodb.cc
---- a/sql/ha_innodb.cc	Tue Feb 17 22:33:54 2009 -0800
-+++ b/sql/ha_innodb.cc	Tue Feb 17 22:33:58 2009 -0800
-@@ -1569,6 +1569,8 @@
+diff -r d4826c0a98c2 sql/ha_innodb.cc
+--- a/sql/ha_innodb.cc	Wed Jul 29 09:58:58 2009 -0700
++++ b/sql/ha_innodb.cc	Wed Jul 29 10:00:12 2009 -0700
+@@ -1583,6 +1583,8 @@
          pthread_cond_init(&commit_cond, NULL);
  	innodb_inited= 1;
  
@@ -350,7 +350,7 @@ diff -r 5060df9888d7 sql/ha_innodb.cc
  	/* If this is a replication slave and we needed to do a crash recovery,
  	set the master binlog position to what InnoDB internally knew about
  	how far we got transactions durable inside InnoDB. There is a
-@@ -6535,6 +6537,28 @@
+@@ -6551,6 +6553,28 @@
  }
  
  /****************************************************************************
@@ -379,32 +379,32 @@ diff -r 5060df9888d7 sql/ha_innodb.cc
  Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
  Monitor to the client. */
  
-diff -r 5060df9888d7 sql/ha_innodb.h
---- a/sql/ha_innodb.h	Tue Feb 17 22:33:54 2009 -0800
-+++ b/sql/ha_innodb.h	Tue Feb 17 22:33:58 2009 -0800
+diff -r d4826c0a98c2 sql/ha_innodb.h
+--- a/sql/ha_innodb.h	Wed Jul 29 09:58:58 2009 -0700
++++ b/sql/ha_innodb.h	Wed Jul 29 10:00:12 2009 -0700
 @@ -245,6 +245,9 @@
- extern ulong srv_adaptive_checkpoint;
+ extern uint srv_adaptive_checkpoint;
  extern ulong srv_show_locks_held;
  extern ulong srv_show_verbose_locks;
 +extern ulong srv_io_pattern_trace;
 +extern ulong srv_io_pattern_trace_running;
 +extern ulong srv_io_pattern_size_limit;
-
+ 
  /* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does
  NOT update cardinality for indexes of InnoDB table". By default we are
-@@ -270,6 +273,9 @@
- bool innodb_I_S_buffer_pool_content(THD* thd, TABLE_LIST *tables);
+@@ -278,6 +281,9 @@
  bool innodb_mutex_show_status(THD* thd);
  void innodb_export_status(void);
-+
+ 
 +void innodb_io_pattern_control(void);
 +void innodb_io_pattern_clear(void);
- 
++
  void innobase_release_temporary_latches(THD *thd);
  
-diff -r 5060df9888d7 sql/lex.h
---- a/sql/lex.h	Tue Feb 17 22:33:54 2009 -0800
-+++ b/sql/lex.h	Tue Feb 17 22:33:58 2009 -0800
+ void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
+diff -r d4826c0a98c2 sql/lex.h
+--- a/sql/lex.h	Wed Jul 29 09:58:58 2009 -0700
++++ b/sql/lex.h	Wed Jul 29 10:00:12 2009 -0700
 @@ -244,6 +244,7 @@
    { "INNER",		SYM(INNER_SYM)},
    { "INNOBASE",		SYM(INNOBASE_SYM)},
@@ -413,10 +413,10 @@ diff -r 5060df9888d7 sql/lex.h
    { "INOUT",            SYM(INOUT_SYM)},
    { "INSENSITIVE",      SYM(INSENSITIVE_SYM)},
    { "INSERT",		SYM(INSERT)},
-diff -r 5060df9888d7 sql/mysqld.cc
---- a/sql/mysqld.cc	Tue Feb 17 22:33:54 2009 -0800
-+++ b/sql/mysqld.cc	Tue Feb 17 22:33:58 2009 -0800
-@@ -5026,6 +5026,9 @@
+diff -r d4826c0a98c2 sql/mysqld.cc
+--- a/sql/mysqld.cc	Wed Jul 29 09:58:58 2009 -0700
++++ b/sql/mysqld.cc	Wed Jul 29 10:00:12 2009 -0700
+@@ -5029,6 +5029,9 @@
    OPT_INNODB_SYNC_SPIN_LOOPS,
    OPT_INNODB_CONCURRENCY_TICKETS,
    OPT_INNODB_THREAD_SLEEP_DELAY,
@@ -426,10 +426,10 @@ diff -r 5060df9888d7 sql/mysqld.cc
    OPT_BDB_CACHE_SIZE,
    OPT_BDB_LOG_BUFFER_SIZE,
    OPT_BDB_MAX_LOCK,
-@@ -5445,6 +5448,18 @@
+@@ -5461,6 +5464,18 @@
     "Number of background write I/O threads in InnoDB.",
     (gptr*) &innobase_write_io_threads, (gptr*) &innobase_write_io_threads,
-    0, GET_LONG, REQUIRED_ARG, 1, 1, 64, 0, 0, 0},
+    0, GET_LONG, REQUIRED_ARG, 8, 1, 64, 0, 0, 0},
 +  {"innodb_io_pattern_trace", OPT_INNODB_IO_PATTERN_TRACE,
 +   "Create/Drop the internal hash table for IO pattern tracing.",
 +   (gptr*) &srv_io_pattern_trace, (gptr*) &srv_io_pattern_trace,
@@ -445,10 +445,10 @@ diff -r 5060df9888d7 sql/mysqld.cc
  #endif /* End HAVE_INNOBASE_DB */
    {"isam", OPT_ISAM, "Obsolete. ISAM storage engine is no longer supported.",
     (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 0, 0, 0,
-diff -r 5060df9888d7 sql/set_var.cc
---- a/sql/set_var.cc	Tue Feb 17 22:33:54 2009 -0800
-+++ b/sql/set_var.cc	Tue Feb 17 22:33:58 2009 -0800
-@@ -528,6 +528,12 @@
+diff -r d4826c0a98c2 sql/set_var.cc
+--- a/sql/set_var.cc	Wed Jul 29 09:58:58 2009 -0700
++++ b/sql/set_var.cc	Wed Jul 29 10:00:12 2009 -0700
+@@ -546,6 +546,12 @@
  sys_var_long_ptr  sys_innodb_show_verbose_locks(
                                          "innodb_show_verbose_locks",
                                          &srv_show_verbose_locks);
@@ -461,7 +461,7 @@ diff -r 5060df9888d7 sql/set_var.cc
  sys_var_const_os_str_ptr sys_innodb_data_file_path("innodb_data_file_path", 
                                                 &innobase_data_file_path);
  sys_var_const_os_str_ptr sys_innodb_data_home_dir("innodb_data_home_dir", 
-@@ -901,6 +907,9 @@
+@@ -926,6 +932,9 @@
    &sys_innodb_adaptive_checkpoint,
    &sys_innodb_show_locks_held,
    &sys_innodb_show_verbose_locks,
@@ -471,7 +471,7 @@ diff -r 5060df9888d7 sql/set_var.cc
  #endif
    &sys_trust_routine_creators,
    &sys_trust_function_creators,
-@@ -1072,6 +1072,9 @@
+@@ -1075,6 +1084,9 @@
    {sys_innodb_adaptive_checkpoint.name, (char*) &sys_innodb_adaptive_checkpoint, SHOW_SYS},
    {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG},
    {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG},
@@ -481,7 +481,7 @@ diff -r 5060df9888d7 sql/set_var.cc
    {sys_innodb_use_legacy_cardinality_algorithm.name,
     (char*) &sys_innodb_use_legacy_cardinality_algorithm, SHOW_SYS},
  #endif
-@@ -3160,6 +3172,19 @@
+@@ -3210,6 +3222,19 @@
      thd->variables.lc_time_names= global_system_variables.lc_time_names;
  }
  
@@ -501,10 +501,10 @@ diff -r 5060df9888d7 sql/set_var.cc
  /*
    Functions to update thd->options bits
  */
-diff -r 5060df9888d7 sql/set_var.h
---- a/sql/set_var.h	Tue Feb 17 22:33:54 2009 -0800
-+++ b/sql/set_var.h	Tue Feb 17 22:33:58 2009 -0800
-@@ -989,6 +989,17 @@
+diff -r d4826c0a98c2 sql/set_var.h
+--- a/sql/set_var.h	Wed Jul 29 09:58:58 2009 -0700
++++ b/sql/set_var.h	Wed Jul 29 10:00:12 2009 -0700
+@@ -1012,6 +1012,17 @@
    virtual void set_default(THD *thd, enum_var_type type);
  };
  
@@ -522,10 +522,10 @@ diff -r 5060df9888d7 sql/set_var.h
  /****************************************************************************
    Classes for parsing of the SET command
  ****************************************************************************/
-diff -r 5060df9888d7 sql/sql_parse.cc
---- a/sql/sql_parse.cc	Tue Feb 17 22:33:54 2009 -0800
-+++ b/sql/sql_parse.cc	Tue Feb 17 22:33:58 2009 -0800
-@@ -8009,6 +8009,13 @@
+diff -r d4826c0a98c2 sql/sql_parse.cc
+--- a/sql/sql_parse.cc	Wed Jul 29 09:58:58 2009 -0700
++++ b/sql/sql_parse.cc	Wed Jul 29 10:00:12 2009 -0700
+@@ -8104,6 +8104,13 @@
      }
      pthread_mutex_unlock(&LOCK_global_user_client_stats);
    }
@@ -539,14 +539,13 @@ diff -r 5060df9888d7 sql/sql_parse.cc
   *write_to_binlog= tmp_write_to_binlog;
   return result;
  }
-diff -r 5060df9888d7 sql/sql_show.cc
---- a/sql/sql_show.cc	Tue Feb 17 22:33:54 2009 -0800
-+++ b/sql/sql_show.cc	Tue Feb 17 22:33:58 2009 -0800
-@@ -32,6 +32,17 @@
- #ifdef HAVE_INNOBASE_DB
+diff -r d4826c0a98c2 sql/sql_show.cc
+--- a/sql/sql_show.cc	Wed Jul 29 09:58:58 2009 -0700
++++ b/sql/sql_show.cc	Wed Jul 29 10:00:12 2009 -0700
+@@ -33,6 +33,17 @@
  #include "ha_innodb.h"
  #endif
-+
+ 
 +#ifdef HAVE_INNOBASE_DB
 +#define INSIDE_HA_INNOBASE_CC
 +extern "C" {
@@ -557,10 +556,11 @@ diff -r 5060df9888d7 sql/sql_show.cc
 +/* We need to undef it in InnoDB */
 +#undef byte
 +#endif /* HAVE_INNOBASE_DB */
- 
++
  #ifndef NO_EMBEDDED_ACCESS_CHECKS
  static const char *grant_names[]={
-@@ -4088,6 +4099,67 @@
+   "select","insert","update","delete","create","drop","reload","shutdown",
+@@ -4108,6 +4119,72 @@
    DBUG_RETURN(res);
  }
  
@@ -574,6 +574,11 @@ diff -r 5060df9888d7 sql/sql_show.cc
 +  DBUG_ENTER("innodb_io_pattern_fill_table");
 +  int returnable= 0;
 +
++  /* deny access to non-superusers */
++  if (check_global_access(thd, PROCESS_ACL)) {
++    DBUG_RETURN(0);
++  }
++
 +  /* We cannot use inline functions of InnoDB here */
 +
 +  /* !!!!!ATTENTION!!!!!: This function is not protected by mutex for performance.     */
@@ -628,7 +633,7 @@ diff -r 5060df9888d7 sql/sql_show.cc
  /*
    Find schema_tables elment by name
  
-@@ -4894,6 +4966,19 @@
+@@ -4914,6 +4986,19 @@
    {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  };
  
@@ -648,7 +653,7 @@ diff -r 5060df9888d7 sql/sql_show.cc
  
  ST_FIELD_INFO variables_fields_info[]=
  {
-@@ -5069,6 +5154,10 @@
+@@ -5089,6 +5174,10 @@
     make_old_format, 0, -1, -1, 1},
    {"VIEWS", view_fields_info, create_schema_table, 
      get_all_tables, 0, get_schema_views_record, 1, 2, 0},
@@ -659,9 +664,9 @@ diff -r 5060df9888d7 sql/sql_show.cc
    {0, 0, 0, 0, 0, 0, 0, 0, 0}
  };
  
-diff -r 5060df9888d7 sql/sql_yacc.yy
---- a/sql/sql_yacc.yy	Tue Feb 17 22:33:54 2009 -0800
-+++ b/sql/sql_yacc.yy	Tue Feb 17 22:33:58 2009 -0800
+diff -r d4826c0a98c2 sql/sql_yacc.yy
+--- a/sql/sql_yacc.yy	Wed Jul 29 09:58:58 2009 -0700
++++ b/sql/sql_yacc.yy	Wed Jul 29 10:00:12 2009 -0700
 @@ -685,6 +685,7 @@
  %token  INFILE
  %token  INNER_SYM
@@ -670,7 +675,7 @@ diff -r 5060df9888d7 sql/sql_yacc.yy
  %token  INOUT_SYM
  %token  INSENSITIVE_SYM
  %token  INSERT
-@@ -8541,6 +8542,7 @@
+@@ -8500,6 +8501,7 @@
          | MASTER_SYM    { Lex->type|= REFRESH_MASTER; }
  	| DES_KEY_FILE	{ Lex->type|= REFRESH_DES_KEY_FILE; }
   	| RESOURCES     { Lex->type|= REFRESH_USER_RESOURCES; }
@@ -678,7 +683,7 @@ diff -r 5060df9888d7 sql/sql_yacc.yy
   	| CLIENT_STATS_SYM { Lex->type|= REFRESH_CLIENT_STATS; }
   	| USER_STATS_SYM { Lex->type|= REFRESH_USER_STATS; }
   	| TABLE_STATS_SYM { Lex->type|= REFRESH_TABLE_STATS; }
-@@ -9594,6 +9596,7 @@
+@@ -9552,6 +9554,7 @@
  	| ISOLATION		{}
  	| ISSUER_SYM		{}
  	| INNOBASE_SYM		{}
diff --git a/mysql-innodb_locks_held.patch b/mysql-innodb_locks_held.patch
index 65ac766..062fa47 100644
--- a/mysql-innodb_locks_held.patch
+++ b/mysql-innodb_locks_held.patch
@@ -150,7 +150,7 @@ diff -r e9fb5b8bcf78 sql/ha_innodb.h
 @@ -243,6 +243,8 @@
  extern ulong srv_enable_unsafe_group_commit;
  extern uint srv_read_ahead;
- extern ulong srv_adaptive_checkpoint;
+ extern uint srv_adaptive_checkpoint;
 +extern ulong srv_show_locks_held;
 +extern ulong srv_show_verbose_locks;
  
@@ -187,9 +187,9 @@ diff -r e9fb5b8bcf78 sql/set_var.cc
 --- a/sql/set_var.cc	Mon Jun 01 00:36:33 2009 -0700
 +++ b/sql/set_var.cc	Mon Jun 01 00:36:41 2009 -0700
 @@ -527,6 +527,12 @@
-                                                              &srv_enable_unsafe_group_commit);
- sys_var_long_ptr	sys_innodb_adaptive_checkpoint("innodb_adaptive_checkpoint",
-                                                       &srv_adaptive_checkpoint);
+ sys_var_enum	sys_innodb_adaptive_checkpoint("innodb_adaptive_checkpoint",
+                            &srv_adaptive_checkpoint,
+                            &innodb_adaptive_checkpoint_typelib, fix_innodb_adaptive_checkpoint);
 +sys_var_long_ptr  sys_innodb_show_locks_held(
 +                                        "innodb_show_locks_held",
 +                                        &srv_show_locks_held);
diff --git a/mysql-innodb_recovery_patches.patch b/mysql-innodb_recovery_patches.patch
new file mode 100644
index 0000000..3d3e567
--- /dev/null
+++ b/mysql-innodb_recovery_patches.patch
@@ -0,0 +1,217 @@
+diff -ruN a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c
+--- a/innobase/buf/buf0flu.c	2009-08-04 16:53:42.000000000 +0900
++++ b/innobase/buf/buf0flu.c	2009-08-04 17:02:36.000000000 +0900
+@@ -85,6 +85,22 @@
+ 	prev_b = NULL;
+ 	b = UT_LIST_GET_FIRST(buf_pool->flush_list);
+ 
++	if (srv_fast_recovery) {
++	/* speed hack */
++	if (b == NULL || (ut_dulint_cmp(b->oldest_modification,
++					block->oldest_modification) < 0)) {
++		UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, block);
++	} else {
++		b = UT_LIST_GET_LAST(buf_pool->flush_list);
++		if (ut_dulint_cmp(b->oldest_modification,
++					block->oldest_modification) < 0) {
++			/* align oldest_modification not to sort */
++			block->oldest_modification = b->oldest_modification;
++		}
++		UT_LIST_ADD_LAST(flush_list, buf_pool->flush_list, block);
++	}
++	} else {
++	/* normal */
+ 	while (b && (ut_dulint_cmp(b->oldest_modification,
+ 					block->oldest_modification) > 0)) {
+ 		prev_b = b;
+@@ -97,6 +113,7 @@
+ 		UT_LIST_INSERT_AFTER(flush_list, buf_pool->flush_list, prev_b,
+ 								block);
+ 	}
++	}
+ 
+ 	ut_ad(buf_flush_validate_low());
+ }
+diff -ruN a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c
+--- a/innobase/buf/buf0rea.c	2009-08-04 16:53:42.000000000 +0900
++++ b/innobase/buf/buf0rea.c	2009-08-04 17:11:41.000000000 +0900
+@@ -127,6 +127,46 @@
+ 	block = buf_page_init_for_read(err, mode, space, tablespace_version,
+ 								offset);
+ 	if (block == NULL) {
++		/* bugfix: http://bugs.mysql.com/bug.php?id=43948 */
++		if (recv_recovery_is_on() && *err == DB_TABLESPACE_DELETED) {
++			/* hashed log recs must be treated here */
++			recv_addr_t*    recv_addr;
++
++			mutex_enter(&(recv_sys->mutex));
++
++			if (recv_sys->apply_log_recs == FALSE) {
++				mutex_exit(&(recv_sys->mutex));
++				goto not_to_recover;
++			}
++
++			/* recv_get_fil_addr_struct() */
++			recv_addr = HASH_GET_FIRST(recv_sys->addr_hash,
++					hash_calc_hash(ut_fold_ulint_pair(space, offset),
++						recv_sys->addr_hash));
++			while (recv_addr) {
++				if ((recv_addr->space == space)
++					&& (recv_addr->page_no == offset)) {
++					break;
++				}
++				recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
++			}
++
++			if ((recv_addr == NULL)
++			    || (recv_addr->state == RECV_BEING_PROCESSED)
++			    || (recv_addr->state == RECV_PROCESSED)) {
++				mutex_exit(&(recv_sys->mutex));
++				goto not_to_recover;
++			}
++
++			fprintf(stderr, " (space:%lu is deleted)", space);
++			recv_addr->state = RECV_PROCESSED;
++
++			ut_a(recv_sys->n_addrs);
++			recv_sys->n_addrs--;
++
++			mutex_exit(&(recv_sys->mutex));
++		}
++not_to_recover:
+ 		
+ 		return(0);
+ 	}
+@@ -697,11 +737,11 @@
+ 		while (buf_pool->n_pend_reads >= recv_n_pool_free_frames / 2) {
+ 
+ 			os_aio_simulated_wake_handler_threads();
+-			os_thread_sleep(500000);
++			os_thread_sleep(10000);
+ 
+ 			count++;
+ 
+-			if (count > 100) {
++			if (count > 5000) {
+ 				fprintf(stderr,
+ "InnoDB: Error: InnoDB has waited for 50 seconds for pending\n"
+ "InnoDB: reads to the buffer pool to be finished.\n"
+diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
+--- a/innobase/include/srv0srv.h	2009-08-04 16:53:42.000000000 +0900
++++ b/innobase/include/srv0srv.h	2009-08-04 17:39:51.000000000 +0900
+@@ -59,6 +59,8 @@
+ extern ibool	srv_file_per_table;
+ extern ibool    srv_locks_unsafe_for_binlog;
+ 
++extern ibool	srv_fast_recovery;
++
+ extern ulint	srv_n_data_files;
+ extern char**	srv_data_file_names;
+ extern ulint*	srv_data_file_sizes;
+diff -ruN a/innobase/log/log0recv.c b/innobase/log/log0recv.c
+--- a/innobase/log/log0recv.c	2009-07-07 21:54:08.000000000 +0900
++++ b/innobase/log/log0recv.c	2009-08-04 17:15:15.000000000 +0900
+@@ -101,7 +101,7 @@
+ use these free frames to read in pages when we start applying the
+ log records to the database. */
+ 
+-ulint  recv_n_pool_free_frames         = 256;
++ulint  recv_n_pool_free_frames         = 1024;
+ 
+ /* The maximum lsn we see for a page during the recovery process. If this
+ is bigger than the lsn we are able to scan up to, that is an indication that
+@@ -1135,6 +1135,8 @@
+ 	recv_addr = recv_get_fil_addr_struct(space, page_no);
+ 
+ 	if ((recv_addr == NULL)
++		/* bugfix: http://bugs.mysql.com/bug.php?id=44140 */
++	    || (recv_addr->state == RECV_BEING_READ && !just_read_in)
+ 	    || (recv_addr->state == RECV_BEING_PROCESSED)
+ 	    || (recv_addr->state == RECV_PROCESSED)) {
+ 
+diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
+--- a/innobase/srv/srv0srv.c	2009-08-04 16:53:42.000000000 +0900
++++ b/innobase/srv/srv0srv.c	2009-08-04 17:41:05.000000000 +0900
+@@ -88,6 +88,8 @@
+                                                 i.e. do not use next-key locking
+                                                 except on duplicate key checking and
+                                                 foreign key checking */
++ibool	srv_fast_recovery = FALSE;
++
+ ulint	srv_n_data_files = 0;
+ char**	srv_data_file_names = NULL;
+ ulint*	srv_data_file_sizes = NULL;	/* size in database pages */ 
+diff -ruN a/patch_info/innodb_recovery_patches.info b/patch_info/innodb_recovery_patches.info
+--- /dev/null	1970-01-01 09:00:00.000000000 +0900
++++ b/patch_info/innodb_recovery_patches.info	2009-08-04 16:58:07.000000000 +0900
+@@ -0,0 +1,6 @@
++File=innodb_recovery_patches.patch
++Name=Bugfixes and adjustments about recovery process
++Version=1.0
++Author=Percona <info at percona.com>
++License=GPL
++Comment=
+diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc
+--- a/sql/ha_innodb.cc	2009-08-04 16:53:42.000000000 +0900
++++ b/sql/ha_innodb.cc	2009-08-04 17:35:44.000000000 +0900
+@@ -182,6 +182,7 @@
+ my_bool innobase_rollback_on_timeout		= FALSE;
+ my_bool innobase_create_status_file		= FALSE;
+ my_bool innobase_adaptive_hash_index		= TRUE;
++my_bool innobase_fast_recovery			= FALSE;
+ 
+ static char *internal_innobase_data_file_path	= NULL;
+ 
+@@ -1534,6 +1535,8 @@
+ 	srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
+ 	srv_force_recovery = (ulint) innobase_force_recovery;
+ 
++	srv_fast_recovery = (ibool) innobase_fast_recovery;
++
+ 	srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
+ 	srv_use_checksums = (ibool) innobase_use_checksums;
+ 
+diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h
+--- a/sql/ha_innodb.h	2009-08-04 16:53:42.000000000 +0900
++++ b/sql/ha_innodb.h	2009-08-04 17:37:18.000000000 +0900
+@@ -220,6 +220,7 @@
+                innobase_use_large_pages,
+                innobase_use_native_aio,
+ 	       innobase_file_per_table, innobase_locks_unsafe_for_binlog,
++	       innobase_fast_recovery,
+ 	       innobase_rollback_on_timeout,
+                innobase_create_status_file,
+                innobase_adaptive_hash_index;
+diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
+--- a/sql/mysqld.cc	2009-08-04 16:53:42.000000000 +0900
++++ b/sql/mysqld.cc	2009-08-04 17:48:25.000000000 +0900
+@@ -5102,6 +5102,7 @@
+   OPT_INNODB_READ_IO_THREADS,
+   OPT_INNODB_WRITE_IO_THREADS,
+   OPT_INNODB_USE_SYS_MALLOC,
++  OPT_INNODB_FAST_RECOVERY,
+   OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED,
+   OPT_INNODB_EXTRA_RSEGMENTS,
+   OPT_INNODB_DICT_SIZE_LIMIT,
+@@ -5347,6 +5348,10 @@
+   {"innodb_doublewrite", OPT_INNODB_DOUBLEWRITE, "Enable InnoDB doublewrite buffer (enabled by default). \
+ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
+    (gptr*) &innobase_use_doublewrite, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
++  {"innodb_fast_recovery", OPT_INNODB_FAST_RECOVERY,
++   "Enable to use speed hack of recovery avoiding flush list sorting.",
++   (gptr*) &innobase_fast_recovery, (gptr*) &innobase_fast_recovery,
++   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+   {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN,
+    "Speeds up the shutdown process of the InnoDB storage engine. Possible "
+    "values are 0, 1 (faster)"
+diff -ruN a/sql/set_var.cc b/sql/set_var.cc
+--- a/sql/set_var.cc	2009-08-04 16:53:42.000000000 +0900
++++ b/sql/set_var.cc	2009-08-04 17:51:49.000000000 +0900
+@@ -1088,6 +1088,7 @@
+   {"innodb_read_io_threads", (char*) &innobase_read_io_threads, SHOW_LONG},
+   {"innodb_write_io_threads", (char*) &innobase_write_io_threads, SHOW_LONG},
+   {"innodb_use_sys_malloc", (char*) &innobase_use_sys_malloc, SHOW_MY_BOOL},
++  {"innodb_fast_recovery", (char*) &innobase_fast_recovery, SHOW_MY_BOOL},
+   {"innodb_thread_concurrency_timer_based", (char*) &innobase_thread_concurrency_timer_based, SHOW_MY_BOOL},
+   {"innodb_extra_rsegments", (char*) &innobase_extra_rsegments, SHOW_LONG},
+   {sys_innodb_dict_size_limit.name, (char*) &sys_innodb_dict_size_limit, SHOW_SYS},
diff --git a/mysql-innodb_rw_lock.patch b/mysql-innodb_rw_lock.patch
index e45fccd..b4a1a79 100644
--- a/mysql-innodb_rw_lock.patch
+++ b/mysql-innodb_rw_lock.patch
@@ -6,7 +6,7 @@ diff -ruN a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
  	}
  
 -	ut_ad(btr_search_latch.writer != RW_LOCK_EX);
-+	ut_ad(rw_lock_get_writer(&btr_search_latch) != RW_LOCK_EX);
++	ut_ad(btr_search_latch.writer_count == 0);
  	ut_ad(btr_search_latch.reader_count > 0);
  
  	rec = ha_search_and_get_data(btr_search_sys->hash_index, fold);
diff --git a/mysql-innodb_show_bp.patch b/mysql-innodb_show_bp.patch
index a56ae9a..766a3b7 100644
--- a/mysql-innodb_show_bp.patch
+++ b/mysql-innodb_show_bp.patch
@@ -386,7 +386,7 @@ diff -r fe944d2c6e1f sql/sql_show.cc
  #endif
  
  #ifndef NO_EMBEDDED_ACCESS_CHECKS
-@@ -4042,6 +4046,13 @@
+@@ -4042,6 +4046,19 @@
    DBUG_RETURN(res);
  }
  
@@ -394,6 +394,12 @@ diff -r fe944d2c6e1f sql/sql_show.cc
 +{
 +  DBUG_ENTER("fill_innodb_bp_content");
 +  int res= 0;
++
++  /* deny access to non-superusers */
++  if (check_global_access(thd, PROCESS_ACL)) {
++    DBUG_RETURN(0);
++  }
++
 +  innodb_I_S_buffer_pool_content(thd, tables);
 +  DBUG_RETURN(res);
 +}
diff --git a/mysql-innodb_split_buf_pool_mutex.patch b/mysql-innodb_split_buf_pool_mutex.patch
new file mode 100644
index 0000000..7fa7ac0
--- /dev/null
+++ b/mysql-innodb_split_buf_pool_mutex.patch
@@ -0,0 +1,1870 @@
+diff -r 7ac364cc9b41 innobase/buf/buf0buf.c
+--- a/innobase/buf/buf0buf.c	Fri Jul 03 15:41:50 2009 -0700
++++ b/innobase/buf/buf0buf.c	Fri Jul 03 15:41:57 2009 -0700
+@@ -549,6 +549,17 @@
+ 	mutex_create(&(buf_pool->mutex));
+ 	mutex_set_level(&(buf_pool->mutex), SYNC_BUF_POOL);
+ 
++	mutex_create(&(buf_pool->LRU_mutex));
++	mutex_set_level(&(buf_pool->LRU_mutex), SYNC_BUF_LRU_LIST);
++	rw_lock_create(&(buf_pool->hash_latch));
++	rw_lock_set_level(&(buf_pool->hash_latch), SYNC_BUF_PAGE_HASH);
++	mutex_create(&(buf_pool->free_mutex));
++	mutex_set_level(&(buf_pool->free_mutex), SYNC_BUF_FREE_LIST);
++	mutex_create(&(buf_pool->flush_list_mutex));
++	mutex_set_level(&(buf_pool->flush_list_mutex), SYNC_BUF_FLUSH_LIST);
++
++	mutex_enter(&(buf_pool->LRU_mutex));
++	rw_lock_x_lock(&(buf_pool->hash_latch));
+ 	mutex_enter(&(buf_pool->mutex));
+ 
+ 	if (srv_use_awe) {
+@@ -724,6 +735,8 @@
+ 		block->in_free_list = TRUE;
+ 	}
+ 
++	mutex_exit(&(buf_pool->LRU_mutex));
++	rw_lock_x_unlock(&(buf_pool->hash_latch));
+ 	mutex_exit(&(buf_pool->mutex));
+ 
+ 	if (srv_use_adaptive_hash_indexes) {
+@@ -753,6 +766,7 @@
+ {
+ 	buf_block_t*	bck;
+ 
++	ut_error; /* don't support AWE */
+ #ifdef UNIV_SYNC_DEBUG
+ 	ut_ad(mutex_own(&(buf_pool->mutex)));
+ #endif /* UNIV_SYNC_DEBUG */
+@@ -851,7 +865,7 @@
+ 	buf_block_t*	block)	/* in: block to make younger */
+ {
+ #ifdef UNIV_SYNC_DEBUG
+-	ut_ad(!mutex_own(&(buf_pool->mutex)));
++	ut_ad(!mutex_own(&(buf_pool->LRU_mutex)));
+ #endif /* UNIV_SYNC_DEBUG */
+ 
+ 	/* Note that we read freed_page_clock's without holding any mutex:
+@@ -860,12 +874,12 @@
+ 	if (buf_pool->freed_page_clock >= block->freed_page_clock 
+ 				+ 1 + (buf_pool->curr_size / 4)) {
+ 
+-		mutex_enter(&buf_pool->mutex);
++		mutex_enter(&buf_pool->LRU_mutex);
+ 		/* There has been freeing activity in the LRU list:
+ 		best to move to the head of the LRU list */
+ 
+ 		buf_LRU_make_block_young(block);
+-		mutex_exit(&buf_pool->mutex);
++		mutex_exit(&buf_pool->LRU_mutex);
+ 	}
+ }
+ 
+@@ -881,7 +895,7 @@
+ {
+ 	buf_block_t*	block;
+ 	
+-	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->LRU_mutex));
+ 
+ 	block = buf_block_align(frame);
+ 
+@@ -889,7 +903,7 @@
+ 
+ 	buf_LRU_make_block_young(block);
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->LRU_mutex));
+ }
+ 
+ /************************************************************************
+@@ -900,7 +914,7 @@
+ /*===========*/
+ 	buf_block_t*	block)	/* in, own: block to be freed */
+ {
+-	mutex_enter(&(buf_pool->mutex));
++	//mutex_enter(&(buf_pool->mutex));
+ 
+ 	mutex_enter(&block->mutex);
+ 
+@@ -910,7 +924,7 @@
+ 
+ 	mutex_exit(&block->mutex);
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	//mutex_exit(&(buf_pool->mutex));
+ }
+ 
+ /*************************************************************************
+@@ -951,11 +965,11 @@
+ {
+ 	buf_block_t*	block;
+ 
+-	mutex_enter_fast(&(buf_pool->mutex));
++	rw_lock_s_lock(&(buf_pool->hash_latch));
+ 
+ 	block = buf_page_hash_get(space, offset);
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	rw_lock_s_unlock(&(buf_pool->hash_latch));
+ 
+ 	return(block);
+ }
+@@ -972,7 +986,7 @@
+ {
+ 	buf_block_t*	block;
+ 
+-	mutex_enter_fast(&(buf_pool->mutex));
++	rw_lock_s_lock(&(buf_pool->hash_latch));
+ 
+ 	block = buf_page_hash_get(space, offset);
+ 
+@@ -980,7 +994,7 @@
+ 		block->check_index_page_at_flush = FALSE;
+ 	}
+ 	
+-	mutex_exit(&(buf_pool->mutex));
++	rw_lock_s_unlock(&(buf_pool->hash_latch));
+ }
+ 
+ /************************************************************************
+@@ -999,7 +1013,7 @@
+ 	buf_block_t*	block;
+ 	ibool		is_hashed;
+ 
+-	mutex_enter_fast(&(buf_pool->mutex));
++	rw_lock_s_lock(&(buf_pool->hash_latch));
+ 
+ 	block = buf_page_hash_get(space, offset);
+ 
+@@ -1009,7 +1023,7 @@
+ 		is_hashed = block->is_hashed;
+ 	}
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	rw_lock_s_unlock(&(buf_pool->hash_latch));
+ 
+ 	return(is_hashed);
+ }
+@@ -1051,7 +1065,7 @@
+ {
+ 	buf_block_t*	block;
+ 
+-	mutex_enter_fast(&(buf_pool->mutex));
++	rw_lock_s_lock(&(buf_pool->hash_latch));
+ 
+ 	block = buf_page_hash_get(space, offset);
+ 
+@@ -1059,7 +1073,7 @@
+ 		block->file_page_was_freed = TRUE;
+ 	}
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	rw_lock_s_unlock(&(buf_pool->hash_latch));
+ 
+ 	return(block);
+ }
+@@ -1080,7 +1094,7 @@
+ {
+ 	buf_block_t*	block;
+ 
+-	mutex_enter_fast(&(buf_pool->mutex));
++	rw_lock_s_lock(&(buf_pool->hash_latch));
+ 
+ 	block = buf_page_hash_get(space, offset);
+ 
+@@ -1088,7 +1102,7 @@
+ 		block->file_page_was_freed = FALSE;
+ 	}
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	rw_lock_s_unlock(&(buf_pool->hash_latch));
+ 
+ 	return(block);
+ }
+@@ -1167,26 +1181,33 @@
+ 	buf_pool->n_page_gets++;
+ loop:
+ 	block = NULL;
+-	mutex_enter_fast(&(buf_pool->mutex));
++	//mutex_enter_fast(&(buf_pool->mutex));
+ 	
+ 	if (guess) {
+ 		block = buf_block_align(guess);
+ 
++		mutex_enter(&block->mutex);
+ 		if ((offset != block->offset) || (space != block->space)
+ 				|| (block->state != BUF_BLOCK_FILE_PAGE)) {
+ 
++			mutex_exit(&block->mutex);
+ 			block = NULL;
+ 		}
+ 	}
+ 
+ 	if (block == NULL) {
++		rw_lock_s_lock(&(buf_pool->hash_latch));
+ 		block = buf_page_hash_get(space, offset);
++		if(block) {
++			mutex_enter(&block->mutex);
++		}
++		rw_lock_s_unlock(&(buf_pool->hash_latch));
+ 	}
+ 
+ 	if (block == NULL) {
+ 		/* Page not in buf_pool: needs to be read from file */
+ 
+-		mutex_exit(&(buf_pool->mutex));
++		//mutex_exit(&(buf_pool->mutex));
+ 
+ 		if (mode == BUF_GET_IF_IN_POOL) {
+ 
+@@ -1205,7 +1226,7 @@
+ 		goto loop;
+ 	}
+ 
+-	mutex_enter(&block->mutex);
++	//mutex_enter(&block->mutex);
+ 
+ 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
+ 
+@@ -1217,7 +1238,7 @@
+ 
+ 		if (mode == BUF_GET_IF_IN_POOL) {
+ 			/* The page is only being read to buffer */
+-			mutex_exit(&buf_pool->mutex);
++			//mutex_exit(&buf_pool->mutex);
+ 			mutex_exit(&block->mutex);
+ 
+ 			return(NULL);
+@@ -1242,7 +1263,7 @@
+ #else
+ 	buf_block_buf_fix_inc(block);
+ #endif
+-	mutex_exit(&buf_pool->mutex);
++	//mutex_exit(&buf_pool->mutex);
+ 
+ 	/* Check if this is the first access to the page */
+ 
+@@ -1685,7 +1706,7 @@
+ 	buf_block_t*	block)	/* in: block to init */
+ {
+ #ifdef UNIV_SYNC_DEBUG
+-	ut_ad(mutex_own(&(buf_pool->mutex)));
++	ut_ad(mutex_own(&(buf_pool->LRU_mutex)));
+ 	ut_ad(mutex_own(&(block->mutex)));
+ #endif /* UNIV_SYNC_DEBUG */
+ 	ut_a(block->state != BUF_BLOCK_FILE_PAGE);
+@@ -1792,7 +1813,8 @@
+ 
+ 	ut_a(block);
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->LRU_mutex));
++	rw_lock_x_lock(&(buf_pool->hash_latch));
+ 	mutex_enter(&block->mutex);
+ 
+ 	if (fil_tablespace_deleted_or_being_deleted_in_mem(space,
+@@ -1807,7 +1829,8 @@
+ 		being deleted, or the page is already in buf_pool, return */
+ 
+ 		mutex_exit(&block->mutex);
+-		mutex_exit(&(buf_pool->mutex));
++		mutex_exit(&(buf_pool->LRU_mutex));
++		rw_lock_x_unlock(&(buf_pool->hash_latch));
+ 
+ 		buf_block_free(block);
+ 
+@@ -1822,10 +1845,14 @@
+ 	ut_ad(block);
+ 	
+ 	buf_page_init(space, offset, block);
++	rw_lock_x_unlock(&(buf_pool->hash_latch));
+ 
+ 	/* The block must be put to the LRU list, to the old blocks */
+ 
+ 	buf_LRU_add_block(block, TRUE); 	/* TRUE == to old blocks */
++	mutex_exit(&(buf_pool->LRU_mutex));
++
++	mutex_enter(&(buf_pool->mutex)); /* for consistency about aio */
+ 	
+ 	block->io_fix = BUF_IO_READ;
+ 
+@@ -1874,7 +1901,8 @@
+ 
+ 	free_block = buf_LRU_get_free_block();
+ 	
+-	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->LRU_mutex));
++	rw_lock_x_lock(&(buf_pool->hash_latch));
+ 
+ 	block = buf_page_hash_get(space, offset);
+ 
+@@ -1885,7 +1913,8 @@
+ 		block->file_page_was_freed = FALSE;
+ 
+ 		/* Page can be found in buf_pool */
+-		mutex_exit(&(buf_pool->mutex));
++		mutex_exit(&(buf_pool->LRU_mutex));
++		rw_lock_x_unlock(&(buf_pool->hash_latch));
+ 
+ 		buf_block_free(free_block);
+ 
+@@ -1908,6 +1937,7 @@
+ 	mutex_enter(&block->mutex);
+ 
+ 	buf_page_init(space, offset, block);
++	rw_lock_x_unlock(&(buf_pool->hash_latch));
+ 
+ 	/* The block must be put to the LRU list */
+ 	buf_LRU_add_block(block, FALSE);
+@@ -1919,7 +1949,7 @@
+ #endif
+ 	buf_pool->n_pages_created++;
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->LRU_mutex));
+ 
+ 	mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
+ 
+@@ -1933,7 +1963,7 @@
+ 	ibuf_merge_or_delete_for_page(NULL, space, offset, TRUE);
+ 
+ 	/* Flush pages from the end of the LRU list if necessary */
+-	buf_flush_free_margin();
++	buf_flush_free_margin(FALSE);
+ 
+ 	frame = block->frame;
+ 
+@@ -1969,6 +1999,7 @@
+ {
+ 	ulint		io_type;
+ 	ulint		read_page_no;
++	ulint		flush_type;
+ 	
+ 	buf_io_counter_t*	io_counter;
+ 	ulint		fold;
+@@ -2051,9 +2082,6 @@
+ 		}
+ 	}
+ 	
+-	mutex_enter(&(buf_pool->mutex));
+-	mutex_enter(&block->mutex);
+-
+ #ifdef UNIV_IBUF_DEBUG
+ 	ut_a(ibuf_count_get(block->space, block->offset) == 0);
+ #endif
+@@ -2062,9 +2090,12 @@
+ 	removes the newest lock debug record, without checking the thread
+ 	id. */
+ 
+-	block->io_fix = 0;
+-	
+ 	if (io_type == BUF_IO_READ) {
++		mutex_enter(&block->mutex);
++		mutex_enter(&(buf_pool->mutex));
++
++		block->io_fix = 0;
++
+ 		/* NOTE that the call to ibuf may have moved the ownership of
+ 		the x-latch to this OS thread: do not let this confuse you in
+ 		debugging! */		
+@@ -2095,6 +2126,8 @@
+ 		}
+ 		}
+ 
++		mutex_exit(&(buf_pool->mutex));
++		mutex_exit(&block->mutex);
+ #ifdef UNIV_DEBUG
+ 		if (buf_debug_prints) {
+ 			fputs("Has read ", stderr);
+@@ -2103,10 +2136,23 @@
+ 	} else {
+ 		ut_ad(io_type == BUF_IO_WRITE);
+ 
++		flush_type = block->flush_type;
++		if (flush_type == BUF_FLUSH_LRU) {
++			mutex_enter(&(buf_pool->LRU_mutex));
++		}
++		mutex_enter(&block->mutex);
++		mutex_enter(&(buf_pool->mutex));
++
++		block->io_fix = 0;
++
+ 		/* Write means a flush operation: call the completion
+ 		routine in the flush system */
+ 
+ 		buf_flush_write_complete(block);
++
++		if (flush_type == BUF_FLUSH_LRU) {
++			mutex_exit(&(buf_pool->LRU_mutex));
++		}
+ 
+ 		rw_lock_s_unlock_gen(&(block->lock), BUF_IO_WRITE);
+ 		/* io_counter here */
+@@ -2132,6 +2178,9 @@
+ 
+ 		buf_pool->n_pages_written++;
+ 
++		mutex_exit(&(buf_pool->mutex));
++		mutex_exit(&block->mutex);
++
+ #ifdef UNIV_DEBUG
+ 		if (buf_debug_prints) {
+ 			fputs("Has written ", stderr);
+@@ -2139,9 +2188,6 @@
+ #endif /* UNIV_DEBUG */
+ 	}
+ 	
+-	mutex_exit(&block->mutex);
+-	mutex_exit(&(buf_pool->mutex));
+-
+ #ifdef UNIV_DEBUG
+ 	if (buf_debug_prints) {
+ 		fprintf(stderr, "page space %lu page no %lu\n",
+@@ -2169,11 +2215,11 @@
+ 		freed = buf_LRU_search_and_free_block(100);
+ 	}
+ 	
+-	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->LRU_mutex));
+ 
+ 	ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->LRU_mutex));
+ }
+ 
+ /*************************************************************************
+@@ -2195,7 +2241,10 @@
+ 	
+ 	ut_ad(buf_pool);
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	//mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->LRU_mutex));
++	rw_lock_x_lock(&(buf_pool->hash_latch));
++	/* for keep the new latch order, it cannot validate correctly... */
+ 
+ 	for (i = 0; i < buf_pool->curr_size; i++) {
+ 
+@@ -2256,18 +2305,26 @@
+ 	}
+ 
+ 	ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);
++	/* because of latching order with block->mutex, we cannot get free_mutex before that */
++/*
+ 	if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {
+ 		fprintf(stderr, "Free list len %lu, free blocks %lu\n",
+ 			(ulong) UT_LIST_GET_LEN(buf_pool->free), (ulong) n_free);
+ 		ut_error;
+ 	}
++*/
++	/* because of latching order with block->mutex, we cannot get flush_list_mutex before that */
++/*
+ 	ut_a(UT_LIST_GET_LEN(buf_pool->flush_list) == n_flush);
+ 
+ 	ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush);
+ 	ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush);
+ 	ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush);
++*/
+ 	
+-	mutex_exit(&(buf_pool->mutex));
++	//mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->LRU_mutex));
++	rw_lock_x_unlock(&(buf_pool->hash_latch));
+ 
+ 	ut_a(buf_LRU_validate());
+ 	ut_a(buf_flush_validate());
+@@ -2299,7 +2356,9 @@
+ 	index_ids = mem_alloc(sizeof(dulint) * size);
+ 	counts = mem_alloc(sizeof(ulint) * size);
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->LRU_mutex));
++	mutex_enter(&(buf_pool->free_mutex));
++	mutex_enter(&(buf_pool->flush_list_mutex));
+ 	
+ 	fprintf(stderr,
+ 		"buf_pool size %lu\n"
+@@ -2352,7 +2411,9 @@
+ 		}
+ 	}
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->LRU_mutex));
++	mutex_exit(&(buf_pool->free_mutex));
++	mutex_exit(&(buf_pool->flush_list_mutex));
+ 
+ 	for (i = 0; i < n_found; i++) {
+ 		index = dict_index_get_if_in_cache(index_ids[i]);
+@@ -2387,7 +2448,7 @@
+         ulint i;
+         ulint fixed_pages_number = 0;
+ 
+-        mutex_enter(&(buf_pool->mutex));
++        //mutex_enter(&(buf_pool->mutex));
+ 
+         for (i = 0; i < buf_pool->curr_size; i++) {
+ 
+@@ -2404,7 +2465,7 @@
+ 		}
+         }
+ 
+-        mutex_exit(&(buf_pool->mutex));
++        //mutex_exit(&(buf_pool->mutex));
+         return fixed_pages_number;
+ }
+ #endif /* UNIV_DEBUG */
+@@ -2432,7 +2493,7 @@
+ {
+ 	ulint	ratio;
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	//mutex_enter(&(buf_pool->mutex)); /* optimistic */
+ 
+ 	ratio = (100 * UT_LIST_GET_LEN(buf_pool->flush_list))
+ 		     / (1 + UT_LIST_GET_LEN(buf_pool->LRU)
+@@ -2440,7 +2501,7 @@
+ 
+ 		       /* 1 + is there to avoid division by zero */   
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	//mutex_exit(&(buf_pool->mutex)); /* optimistic */
+ 
+ 	return(ratio);
+ }
+@@ -2460,7 +2521,10 @@
+ 	ut_ad(buf_pool);
+ 	size = buf_pool->curr_size;
+ 
++	mutex_enter(&(buf_pool->LRU_mutex));
++	mutex_enter(&(buf_pool->free_mutex));
+ 	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->flush_list_mutex));
+ 	
+ 	if (srv_use_awe) {
+ 		fprintf(stderr,
+@@ -2533,7 +2597,10 @@
+ 	buf_pool->n_pages_written_old = buf_pool->n_pages_written;
+ 	buf_pool->n_pages_awe_remapped_old = buf_pool->n_pages_awe_remapped;
+ 
++	mutex_exit(&(buf_pool->LRU_mutex));
++	mutex_exit(&(buf_pool->free_mutex));
+ 	mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->flush_list_mutex));
+ }
+ 
+ /**************************************************************************
+@@ -2563,7 +2630,7 @@
+ 	
+ 	ut_ad(buf_pool);
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	//mutex_enter(&(buf_pool->mutex)); /* optimistic */
+ 
+ 	for (i = 0; i < buf_pool->curr_size; i++) {
+ 
+@@ -2586,7 +2653,7 @@
+ 		mutex_exit(&block->mutex);
+  	}
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	//mutex_exit(&(buf_pool->mutex)); /* optimistic */
+ 
+ 	return(TRUE);
+ }	
+@@ -2626,11 +2693,11 @@
+ {
+ 	ulint	len;
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->free_mutex));
+ 
+ 	len = UT_LIST_GET_LEN(buf_pool->free);
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->free_mutex));
+ 
+ 	return(len);
+ }
+diff -r 7ac364cc9b41 innobase/buf/buf0flu.c
+--- a/innobase/buf/buf0flu.c	Fri Jul 03 15:41:50 2009 -0700
++++ b/innobase/buf/buf0flu.c	Fri Jul 03 15:41:57 2009 -0700
+@@ -49,7 +49,9 @@
+ 	buf_block_t*	block)	/* in: block which is modified */
+ {
+ #ifdef UNIV_SYNC_DEBUG
+-	ut_ad(mutex_own(&(buf_pool->mutex)));
++	//ut_ad(mutex_own(&(buf_pool->mutex)));
++	ut_ad(mutex_own(&block->mutex));
++	ut_ad(mutex_own(&(buf_pool->flush_list_mutex)));
+ #endif /* UNIV_SYNC_DEBUG */
+ 
+ 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
+@@ -79,7 +81,9 @@
+ 	buf_block_t*	b;
+ 	
+ #ifdef UNIV_SYNC_DEBUG
+-	ut_ad(mutex_own(&(buf_pool->mutex)));
++	//ut_ad(mutex_own(&(buf_pool->mutex)));
++	ut_ad(mutex_own(&block->mutex));
++	ut_ad(mutex_own(&(buf_pool->flush_list_mutex)));
+ #endif /* UNIV_SYNC_DEBUG */
+ 
+ 	prev_b = NULL;
+@@ -113,16 +117,18 @@
+ 				BUF_BLOCK_FILE_PAGE and in the LRU list */
+ {
+ #ifdef UNIV_SYNC_DEBUG
+-	ut_ad(mutex_own(&(buf_pool->mutex)));
++	//ut_ad(mutex_own(&(buf_pool->mutex)));
+ 	ut_ad(mutex_own(&block->mutex));
+ #endif /* UNIV_SYNC_DEBUG */
+-	if (block->state != BUF_BLOCK_FILE_PAGE) {
++	if (!block->in_LRU_list || block->state != BUF_BLOCK_FILE_PAGE) {
++		/* permited not to own LRU_mutex..  */
++/*
+ 		ut_print_timestamp(stderr);
+ 		fprintf(stderr,
+ "  InnoDB: Error: buffer block state %lu in the LRU list!\n",
+ 			(ulong)block->state);
+ 		ut_print_buf(stderr, (byte*)block, sizeof(buf_block_t));
+-
++*/
+ 		return(FALSE);
+ 	}
+ 
+@@ -148,12 +154,13 @@
+ 	ulint		flush_type)/* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
+ {
+ #ifdef UNIV_SYNC_DEBUG
+-	ut_ad(mutex_own(&(buf_pool->mutex)));
++	//ut_ad(mutex_own(&(buf_pool->mutex)));
+ 	ut_ad(mutex_own(&(block->mutex)));
+ #endif /* UNIV_SYNC_DEBUG */
+-	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
++	//ut_a(block->state == BUF_BLOCK_FILE_PAGE);
+ 
+-	if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0)
++	if (block->state == BUF_BLOCK_FILE_PAGE
++	    && (ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0)
+ 	    					&& (block->io_fix == 0)) {
+ 	    	if (flush_type != BUF_FLUSH_LRU) {
+ 
+@@ -182,15 +189,17 @@
+ {
+ 	ut_ad(block);
+ #ifdef UNIV_SYNC_DEBUG
+-	ut_ad(mutex_own(&(buf_pool->mutex)));
++	//ut_ad(mutex_own(&(buf_pool->mutex)));
+ #endif /* UNIV_SYNC_DEBUG */
+ 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
+ 
++	mutex_enter(&(buf_pool->flush_list_mutex));
+ 	block->oldest_modification = ut_dulint_zero;
+ 
+ 	UT_LIST_REMOVE(flush_list, buf_pool->flush_list, block);
+ 
+ 	ut_d(UT_LIST_VALIDATE(flush_list, buf_block_t, buf_pool->flush_list));
++	mutex_exit(&(buf_pool->flush_list_mutex));
+ 
+ 	(buf_pool->n_flush[block->flush_type])--;
+ 
+@@ -536,18 +545,20 @@
+ 	ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST
+ 				|| flush_type == BUF_FLUSH_SINGLE_PAGE);
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	rw_lock_s_lock(&(buf_pool->hash_latch));
+ 
+ 	block = buf_page_hash_get(space, offset);
+ 
+ 	ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE);
+ 
+ 	if (!block) {
+-		mutex_exit(&(buf_pool->mutex));
++		rw_lock_s_unlock(&(buf_pool->hash_latch));
+ 		return(0);
+ 	}
+ 
+ 	mutex_enter(&block->mutex);
++	mutex_enter(&(buf_pool->mutex));
++	rw_lock_s_unlock(&(buf_pool->hash_latch));
+ 
+ 	if (flush_type == BUF_FLUSH_LIST
+ 	    && buf_flush_ready_for_flush(block, flush_type)) {
+@@ -744,7 +755,7 @@
+ 		high = fil_space_get_size(space);
+ 	}
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	rw_lock_s_lock(&(buf_pool->hash_latch));
+ 
+ 	for (i = low; i < high; i++) {
+ 
+@@ -778,7 +789,7 @@
+ 
+ 				mutex_exit(&block->mutex);
+ 
+-				mutex_exit(&(buf_pool->mutex));
++				rw_lock_s_unlock(&(buf_pool->hash_latch));
+ 
+ 				/* Note: as we release the buf_pool mutex
+ 				above, in buf_flush_try_page we cannot be sure
+@@ -789,14 +800,14 @@
+ 				count += buf_flush_try_page(space, i,
+ 							    flush_type);
+ 
+-				mutex_enter(&(buf_pool->mutex));
++				rw_lock_s_lock(&(buf_pool->hash_latch));
+ 			} else {
+ 				mutex_exit(&block->mutex);
+ 			}
+ 		}
+ 	}
+ 				
+-	mutex_exit(&(buf_pool->mutex));
++	rw_lock_s_unlock(&(buf_pool->hash_latch));
+ 
+ 	return(count);
+ }
+@@ -831,6 +842,7 @@
+ 	ulint		space;
+ 	ulint		offset;
+ 	ibool		found;
++	ulint		remaining	= 0;
+ 	
+ 	ut_ad((flush_type == BUF_FLUSH_LRU)
+ 					|| (flush_type == BUF_FLUSH_LIST)); 
+@@ -849,6 +861,12 @@
+ 	}
+ 
+ 	(buf_pool->init_flush)[flush_type] = TRUE;
++
++	mutex_exit(&(buf_pool->mutex));
++
++	if (flush_type == BUF_FLUSH_LRU) {
++		mutex_enter(&(buf_pool->LRU_mutex));
++	}
+ 	
+ 	for (;;) {
+ 		/* If we have flushed enough, leave the loop */
+@@ -865,7 +883,10 @@
+ 	    	} else {
+ 			ut_ad(flush_type == BUF_FLUSH_LIST);
+ 
++			mutex_enter(&(buf_pool->flush_list_mutex));
++			remaining = UT_LIST_GET_LEN(buf_pool->flush_list);
+ 			block = UT_LIST_GET_LAST(buf_pool->flush_list);
++			mutex_exit(&(buf_pool->flush_list_mutex));
+ 			if (!block
+ 			    || (ut_dulint_cmp(block->oldest_modification,
+ 			    				lsn_limit) >= 0)) {
+@@ -895,7 +916,9 @@
+ 				offset = block->offset;
+ 	    
+ 				mutex_exit(&block->mutex);
+-				mutex_exit(&(buf_pool->mutex));
++				if (flush_type == BUF_FLUSH_LRU) {
++					mutex_exit(&(buf_pool->LRU_mutex));
++				}
+ 
+ 				old_page_count = page_count;
+ 				
+@@ -915,7 +938,9 @@
+ 				flush_type, offset,
+ 				page_count - old_page_count); */
+ 
+-				mutex_enter(&(buf_pool->mutex));
++				if (flush_type == BUF_FLUSH_LRU) {
++					mutex_enter(&(buf_pool->LRU_mutex));
++				}
+ 
+ 			} else if (flush_type == BUF_FLUSH_LRU) {
+ 
+@@ -927,16 +952,25 @@
+ 
+ 				mutex_exit(&block->mutex);
+ 
++				mutex_enter(&(buf_pool->flush_list_mutex));
+ 				block = UT_LIST_GET_PREV(flush_list, block);
++				mutex_exit(&(buf_pool->flush_list_mutex));
++				remaining--;
+ 			}
+ 	    	}
+ 
+ 	    	/* If we could not find anything to flush, leave the loop */
+ 
+-	    	if (!found) {
++	    	if (!found && !remaining) {
+ 	    		break;
+ 	    	}
+ 	}
++
++	if (flush_type == BUF_FLUSH_LRU) {
++		mutex_exit(&(buf_pool->LRU_mutex));
++	}
++
++	mutex_enter(&(buf_pool->mutex));
+ 
+ 	(buf_pool->init_flush)[flush_type] = FALSE;
+ 
+@@ -997,7 +1031,7 @@
+ 	ulint		n_replaceable;
+ 	ulint		distance	= 0;
+ 	
+-	mutex_enter(&(buf_pool->mutex));
++	//mutex_enter(&(buf_pool->mutex)); /* optimistic */
+ 
+ 	n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
+ 
+@@ -1007,6 +1041,12 @@
+ 	       && (n_replaceable < BUF_FLUSH_FREE_BLOCK_MARGIN
+ 	       				+ BUF_FLUSH_EXTRA_MARGIN)
+ 	       && (distance < BUF_LRU_FREE_SEARCH_LEN)) {
++
++		if (!block->in_LRU_list) {
++			/* reatart. but it is very optimistic */
++			block = UT_LIST_GET_LAST(buf_pool->LRU);
++			continue;
++		}
+ 
+ 		mutex_enter(&block->mutex);
+ 
+@@ -1021,7 +1061,7 @@
+ 		block = UT_LIST_GET_PREV(LRU, block);
+ 	}
+ 	
+-	mutex_exit(&(buf_pool->mutex));
++	//mutex_exit(&(buf_pool->mutex)); /* optimistic */
+ 
+ 	if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN) {
+ 
+@@ -1040,8 +1080,9 @@
+ immediately, without waiting. */ 
+ 
+ void
+-buf_flush_free_margin(void)
++buf_flush_free_margin(
+ /*=======================*/
++	ibool	wait)
+ {
+ 	ulint	n_to_flush;
+ 	ulint	n_flushed;
+@@ -1051,7 +1092,7 @@
+ 	if (n_to_flush > 0) {
+ 		n_flushed = buf_flush_batch(BUF_FLUSH_LRU, n_to_flush,
+ 							ut_dulint_zero);
+-		if (n_flushed == ULINT_UNDEFINED) {
++		if (wait && n_flushed == ULINT_UNDEFINED) {
+ 			/* There was an LRU type flush batch already running;
+ 			let us wait for it to end */
+ 		   
+@@ -1101,11 +1142,11 @@
+ {
+ 	ibool	ret;
+ 	
+-	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->flush_list_mutex));
+ 
+ 	ret = buf_flush_validate_low();
+ 	
+-	mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->flush_list_mutex));
+ 
+ 	return(ret);
+ }
+diff -r 7ac364cc9b41 innobase/buf/buf0lru.c
+--- a/innobase/buf/buf0lru.c	Fri Jul 03 15:41:50 2009 -0700
++++ b/innobase/buf/buf0lru.c	Fri Jul 03 15:41:57 2009 -0700
+@@ -108,7 +108,7 @@
+ 
+ 	page_arr = ut_malloc(sizeof(ulint)
+ 			     * BUF_LRU_DROP_SEARCH_HASH_SIZE);
+-	mutex_enter(&buf_pool->mutex);
++	mutex_enter(&buf_pool->LRU_mutex);
+ 
+ scan_again:
+ 	num_entries = 0;
+@@ -147,12 +147,12 @@
+ 			}
+ 			/* Array full. We release the buf_pool->mutex to
+ 			obey the latching order. */
+-			mutex_exit(&buf_pool->mutex);
++			mutex_exit(&buf_pool->LRU_mutex);
+ 
+ 			buf_LRU_drop_page_hash_batch(id, page_arr,
+ 						     num_entries);
+ 			num_entries = 0;
+-			mutex_enter(&buf_pool->mutex);
++			mutex_enter(&buf_pool->LRU_mutex);
+ 		} else {
+ 			mutex_exit(&block->mutex);
+ 		}
+@@ -177,7 +177,7 @@
+ 		}
+ 	}
+ 
+-	mutex_exit(&buf_pool->mutex);
++	mutex_exit(&buf_pool->LRU_mutex);
+ 
+ 	/* Drop any remaining batch of search hashed pages. */
+ 	buf_LRU_drop_page_hash_batch(id, page_arr, num_entries);
+@@ -206,7 +206,8 @@
+ 	buf_LRU_drop_page_hash_for_tablespace(id);
+ 
+ scan_again:
+-	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->LRU_mutex));
++	rw_lock_x_lock(&(buf_pool->hash_latch));
+ 	
+ 	all_freed = TRUE;
+ 	
+@@ -244,7 +245,8 @@
+ 			
+ 				mutex_exit(&block->mutex);
+ 
+-				mutex_exit(&(buf_pool->mutex));
++				mutex_exit(&(buf_pool->LRU_mutex));
++				rw_lock_x_unlock(&(buf_pool->hash_latch));
+ 
+ 				/* Note that the following call will acquire
+ 				an S-latch on the page */
+@@ -274,7 +276,8 @@
+ 		block = UT_LIST_GET_PREV(LRU, block);
+ 	}
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->LRU_mutex));
++	rw_lock_x_unlock(&(buf_pool->hash_latch));
+ 	
+ 	if (!all_freed) {
+ 		os_thread_sleep(20000);
+@@ -297,14 +300,14 @@
+ 	ulint		len;
+ 	ulint		limit;
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	mutex_enter(&(buf_pool->LRU_mutex));
+ 
+ 	len = UT_LIST_GET_LEN(buf_pool->LRU);
+ 
+ 	if (len < BUF_LRU_OLD_MIN_LEN) {
+ 		/* The LRU list is too short to do read-ahead */
+ 
+-		mutex_exit(&(buf_pool->mutex));
++		mutex_exit(&(buf_pool->LRU_mutex));
+ 
+ 		return(0);
+ 	}
+@@ -313,7 +316,7 @@
+ 
+ 	limit = block->LRU_position - len / BUF_LRU_INITIAL_RATIO;
+ 
+-	mutex_exit(&(buf_pool->mutex));
++	mutex_exit(&(buf_pool->LRU_mutex));
+ 
+ 	return(limit);
+ }
+@@ -337,13 +340,15 @@
+ 	ulint		distance = 0;
+ 	ibool		freed;
+ 
+-	mutex_enter(&(buf_pool->mutex));
++	/* optimistic search... */
++	//mutex_enter(&(buf_pool->mutex));
+ 	
++retry:
+ 	freed = FALSE;
+ 	block = UT_LIST_GET_LAST(buf_pool->LRU);
+ 
+ 	while (block != NULL) {
+-	        ut_a(block->in_LRU_list);
++	        //ut_a(block->in_LRU_list); /* optimistic */
+ 
+ 		mutex_enter(&block->mutex);
+ 
+@@ -358,9 +363,17 @@
+ 			}
+ #endif /* UNIV_DEBUG */
+ 
++			mutex_exit(&block->mutex);
++
++			mutex_enter(&(buf_pool->LRU_mutex));/* optimistic */
++
++			rw_lock_x_lock(&(buf_pool->hash_latch));
++			mutex_enter(&block->mutex);
++			if(block->in_LRU_list && buf_flush_ready_for_replace(block)) {
+ 			buf_LRU_block_remove_hashed_page(block);
++			rw_lock_x_unlock(&(buf_pool->hash_latch));
+ 
+-			mutex_exit(&(buf_pool->mutex));
++			mutex_exit(&(buf_pool->LRU_mutex));
+ 			mutex_exit(&block->mutex);
+ 
+ 			/* Remove possible adaptive hash index built on the
+@@ -373,7 +386,6 @@
+ 
+ 			ut_a(block->buf_fix_count == 0);
+ 
+-			mutex_enter(&(buf_pool->mutex));
+ 			mutex_enter(&block->mutex);
+ 
+ 			buf_LRU_block_free_hashed_page(block);
+@@ -381,6 +393,16 @@
+ 			mutex_exit(&block->mutex);
+ 
+ 			break;
++			} else { /* someone may interrupt...??? */
++			mutex_exit(&(buf_pool->LRU_mutex));/* optimistic */
++
++			rw_lock_x_unlock(&(buf_pool->hash_latch));
++
++			if (!(block->in_LRU_list)) {
++				mutex_exit(&block->mutex);
++				goto retry;
++			}
++			}
+ 		}
+ 
<Skipped 3879 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/percona-server.git/commitdiff/431f68fe79a66d5dfdd53f2655709e6c925fbc22




More information about the pld-cvs-commit mailing list