]> git.pld-linux.org Git - packages/percona-server.git/commitdiff
- drop old patches
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Wed, 15 Dec 2010 22:23:47 +0000 (22:23 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    mysql-acc-pslist.patch -> 1.8
    mysql-innodb_dict_size_limit.patch -> 1.2
    mysql-innodb_extra_rseg.patch -> 1.2
    mysql-innodb_rw_lock.patch -> 1.3
    mysql-innodb_thread_concurrency_timer_based.patch -> 1.2
    mysql-microslow.patch -> 1.8
    mysql-mysql-test.patch -> 1.2
    mysql-profiling_slow.patch -> 1.2
    mysql-split_buf_pool_mutex_fixed_optimistic_safe.patch -> 1.3
    mysql-userstats.patch -> 1.9

mysql-acc-pslist.patch [deleted file]
mysql-innodb_dict_size_limit.patch [deleted file]
mysql-innodb_extra_rseg.patch [deleted file]
mysql-innodb_rw_lock.patch [deleted file]
mysql-innodb_thread_concurrency_timer_based.patch [deleted file]
mysql-microslow.patch [deleted file]
mysql-mysql-test.patch [deleted file]
mysql-profiling_slow.patch [deleted file]
mysql-split_buf_pool_mutex_fixed_optimistic_safe.patch [deleted file]
mysql-userstats.patch [deleted file]

diff --git a/mysql-acc-pslist.patch b/mysql-acc-pslist.patch
deleted file mode 100644 (file)
index f447f4f..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-diff -r 1a59073d658d mysql-test/r/create.result
---- a/mysql-test/r/create.result       Sat Sep 13 17:31:30 2008 -0700
-+++ b/mysql-test/r/create.result       Sat Sep 13 17:31:40 2008 -0700
-@@ -1720,7 +1720,8 @@
-   `COMMAND` varchar(16) NOT NULL DEFAULT '',
-   `TIME` bigint(7) NOT NULL DEFAULT '0',
-   `STATE` varchar(64) DEFAULT NULL,
--  `INFO` longtext
-+  `INFO` longtext,
-+  `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8
- drop table t1;
- create temporary table t1 like information_schema.processlist;
-@@ -1734,7 +1735,8 @@
-   `COMMAND` varchar(16) NOT NULL DEFAULT '',
-   `TIME` bigint(7) NOT NULL DEFAULT '0',
-   `STATE` varchar(64) DEFAULT NULL,
--  `INFO` longtext
-+  `INFO` longtext,
-+  `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8
- drop table t1;
- create table t1 like information_schema.character_sets;
-diff -r 1a59073d658d sql/sql_show.cc
---- a/sql/sql_show.cc  Sat Sep 13 17:31:30 2008 -0700
-+++ b/sql/sql_show.cc  Sat Sep 13 17:31:40 2008 -0700
-@@ -1803,7 +1803,7 @@
-   TABLE *table= tables->table;
-   CHARSET_INFO *cs= system_charset_info;
-   char *user;
--  time_t now= my_time(0);
-+  ulonglong unow= my_micro_time();
-   DBUG_ENTER("fill_process_list");
-   user= thd->security_ctx->master_access & PROCESS_ACL ?
-@@ -1873,8 +1873,8 @@
-         table->field[4]->store(command_name[tmp->command].str,
-                                command_name[tmp->command].length, cs);
-       /* MYSQL_TIME */
--      table->field[5]->store((longlong)(tmp->start_time ?
--                                      now - tmp->start_time : 0), FALSE);
-+      const ulonglong utime= tmp->start_utime ? unow - tmp->start_utime : 0;
-+      table->field[5]->store(utime / 1000000, TRUE);
-       /* STATE */
- #ifndef EMBEDDED_LIBRARY
-       val= (char*) (tmp->locked ? "Locked" :
-@@ -1896,11 +1896,15 @@
-         table->field[7]->set_notnull();
-       }
-+      /* TIME_MS */
-+      table->field[8]->store((double)(utime / 1000.0));
-+
-       if (schema_table_store_record(thd, table))
-       {
-         VOID(pthread_mutex_unlock(&LOCK_thread_count));
-         DBUG_RETURN(1);
-       }
-+
-     }
-   }
-@@ -5531,7 +5535,7 @@
-     into it two numbers, based on modulus of base-10 numbers.  In the ones
-     position is the number of decimals.  Tens position is unused.  In the
-     hundreds and thousands position is a two-digit decimal number representing
--    length.  Encode this value with  (decimals*100)+length  , where
-+    length.  Encode this value with  (length*100)+decimals  , where
-     0<decimals<10 and 0<=length<100 .
-   @param
-@@ -6539,6 +6543,8 @@
-   {"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
-   {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
-    SKIP_OPEN_TABLE},
-+  {"TIME_MS", 100 * (MY_INT64_NUM_DECIMAL_DIGITS + 1) + 3, MYSQL_TYPE_DECIMAL,
-+    0, 0, "Time_ms", SKIP_OPEN_TABLE},
-   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
- };
diff --git a/mysql-innodb_dict_size_limit.patch b/mysql-innodb_dict_size_limit.patch
deleted file mode 100644 (file)
index 8ef4e36..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-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
-@@ -247,6 +247,7 @@
-       system tables */
-       /*-------------------------*/
-       table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, FALSE);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
-       dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
-@@ -283,6 +284,7 @@
-       ut_a(success);
-       /*-------------------------*/
-       table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, FALSE);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0);
-       dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
-@@ -309,6 +311,7 @@
-       ut_a(success);
-       /*-------------------------*/
-       table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, FALSE);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0);
-       dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
-@@ -345,6 +348,7 @@
-       ut_a(success);
-       /*-------------------------*/
-       table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, FALSE);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       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
-@@ -1178,6 +1178,9 @@
-               /* Foreign constraint system tables have already been
-               created, and they are ok */
-+              table1->n_mysql_handles_opened = 1; /* for pin */
-+              table2->n_mysql_handles_opened = 1; /* for pin */
-+
-               mutex_exit(&(dict_sys->mutex));
-               return(DB_SUCCESS);
-@@ -1266,6 +1269,11 @@
-       
-       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
-@@ -638,6 +638,8 @@
-       mutex_enter(&(dict_sys->mutex));
-       table = dict_table_get_on_id_low(table_id, trx);
-+
-+      dict_table_LRU_trim(table);
-       
-       mutex_exit(&(dict_sys->mutex));
-@@ -752,6 +754,8 @@
-       
-       table = dict_table_get_low(table_name);
-+      dict_table_LRU_trim(table);
-+
-       mutex_exit(&(dict_sys->mutex));
-       if (table != NULL) {
-@@ -787,6 +791,8 @@
-               table->n_mysql_handles_opened++;
-       }
-+      dict_table_LRU_trim(table);
-+
-       mutex_exit(&(dict_sys->mutex));
-       if (table != NULL) {
-@@ -1267,20 +1273,64 @@
- too much space. Currently not used! */
- void
--dict_table_LRU_trim(void)
--/*=====================*/
-+dict_table_LRU_trim(
-+/*================*/
-+      dict_table_t*   self)
- {
-       dict_table_t*   table;
-       dict_table_t*   prev_table;
-+      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 */
-+retry:
-+      n_removed = n_have_parent = 0;
-       table = UT_LIST_GET_LAST(dict_sys->table_LRU);
-+      while ( srv_dict_size_limit && table
-+              && ((dict_sys->table_hash->n_cells
-+                   + dict_sys->table_id_hash->n_cells
-+                   + dict_sys->col_hash->n_cells) * sizeof(hash_cell_t)
-+                  + dict_sys->size) > srv_dict_size_limit ) {
-+              prev_table = UT_LIST_GET_PREV(table_LRU, table);
-+
-+              if (table == self || table->n_mysql_handles_opened)
-+                      goto next_loop;
-+
-+              cached_foreign_tables = 0;
-+              foreign = UT_LIST_GET_FIRST(table->foreign_list);
-+              while (foreign != NULL) {
-+                      if (foreign->referenced_table)
-+                              cached_foreign_tables++;
-+                      foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
-+              }
-+
-+              /* TODO: use table->mem_fix also, if it becomes exact. */
-+
-+              if (cached_foreign_tables == 0) {
-+                      dict_table_remove_from_cache(table);
-+                      n_removed++;
-+              } else {
-+                      n_have_parent++;
-+              }
-+next_loop:
-+              table = prev_table;
-+      }
-+
-+      if ( srv_dict_size_limit && n_have_parent && n_removed
-+              && ((dict_sys->table_hash->n_cells
-+                   + dict_sys->table_id_hash->n_cells
-+                   + dict_sys->col_hash->n_cells) * sizeof(hash_cell_t)
-+                  + dict_sys->size) > srv_dict_size_limit )
-+              goto retry;
-+/*
-       while (table && (dict_sys->size >
-                        buf_pool_get_max_size() / DICT_POOL_PER_VARYING)) {
-@@ -1292,6 +1341,7 @@
-               table = prev_table;
-       }
-+*/
- }
- /**************************************************************************
-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
-@@ -535,6 +535,7 @@
-       sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space);
-       /* use old-style record format for the insert buffer */
-       table = dict_mem_table_create(buf, space, 2, FALSE);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       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
-@@ -938,6 +938,11 @@
-       const char*     ptr,    /* in: scan from */
-       const char*     string);/* in: look for this */
-+void
-+dict_table_LRU_trim(
-+/*================*/
-+      dict_table_t*   self);
-+
- /* 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
-@@ -533,6 +533,13 @@
-       HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold, table,
-                               ut_strcmp(table->name, table_name) == 0);
-+
-+      /* make young in table_LRU */
-+      if (table) {
-+              UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
-+              UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
-+      }
-+
-       return(table);
- }
-@@ -592,6 +599,10 @@
-       if (table != NULL) {
-               table->mem_fix++;
-+              /* make young in table_LRU */
-+              UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
-+              UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
-+
-               /* 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
-@@ -146,6 +146,8 @@
- extern uint   srv_read_ahead;
- extern ulint  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 @@
-         ulint innodb_data_writes;
-         ulint innodb_data_written;
-         ulint innodb_data_reads;
-+        ulint innodb_dict_tables;
-         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 */
-+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 @@
-         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;
-+        export_vars.innodb_dict_tables= (dict_sys ? UT_LIST_GET_LEN(dict_sys->table_LRU) : 0);
-         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
-@@ -0,0 +1,60 @@
-+DROP TABLE IF EXISTS `test_5`;
-+DROP TABLE IF EXISTS `test_4`;
-+DROP TABLE IF EXISTS `test_3`;
-+DROP TABLE IF EXISTS `test_2`;
-+DROP TABLE IF EXISTS `test_1`;
-+SET storage_engine=InnoDB;
-+SET GLOBAL innodb_dict_size_limit=1;
-+FLUSH TABLES;
-+CREATE TABLE `test_1` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+CREATE TABLE `test_2` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+CREATE TABLE `test_3` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+CREATE TABLE `test_4` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+CREATE TABLE `test_5` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+ALTER TABLE `test_5` ADD CONSTRAINT FOREIGN KEY(`b`) REFERENCES `test_4`(`a`);
-+ALTER TABLE `test_4` ADD CONSTRAINT FOREIGN KEY(`b`) REFERENCES `test_3`(`a`);
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+Variable_name Value
-+Innodb_dict_tables    9
-+FLUSH TABLES;
-+SELECT * FROM `test_1`;
-+a     b
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+Variable_name Value
-+Innodb_dict_tables    8
-+SELECT * FROM `test_3`;
-+a     b
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+Variable_name Value
-+Innodb_dict_tables    11
-+FLUSH TABLES;
-+SELECT * FROM `test_2`;
-+a     b
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+Variable_name Value
-+Innodb_dict_tables    8
-+SELECT * FROM `test_1`;
-+a     b
-+FLUSH TABLES;
-+SELECT * FROM `test_4`;
-+a     b
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+Variable_name Value
-+Innodb_dict_tables    9
-+SELECT * FROM `test_3`;
-+a     b
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+Variable_name Value
-+Innodb_dict_tables    10
-+SET GLOBAL innodb_dict_size_limit=0;
-+FLUSH TABLES;
-+SELECT * FROM `test_2`;
-+a     b
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+Variable_name Value
-+Innodb_dict_tables    11
-+DROP TABLE `test_5`;
-+DROP TABLE `test_4`;
-+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
-@@ -0,0 +1,63 @@
-+#
-+# Test for new variable innodb_dict_size_limit;
-+#
-+-- source include/have_innodb.inc
-+
-+--disable_warnings
-+DROP TABLE IF EXISTS `test_5`;
-+DROP TABLE IF EXISTS `test_4`;
-+DROP TABLE IF EXISTS `test_3`;
-+DROP TABLE IF EXISTS `test_2`;
-+DROP TABLE IF EXISTS `test_1`;
-+--enable_warnings
-+
-+SET storage_engine=InnoDB;
-+SET GLOBAL innodb_dict_size_limit=1;
-+
-+FLUSH TABLES;
-+
-+CREATE TABLE `test_1` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+CREATE TABLE `test_2` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+CREATE TABLE `test_3` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+CREATE TABLE `test_4` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+CREATE TABLE `test_5` (`a` int, `b` int, PRIMARY KEY  (`a`));
-+
-+ALTER TABLE `test_5` ADD CONSTRAINT FOREIGN KEY(`b`) REFERENCES `test_4`(`a`);
-+ALTER TABLE `test_4` ADD CONSTRAINT FOREIGN KEY(`b`) REFERENCES `test_3`(`a`);
-+
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+
-+FLUSH TABLES;
-+SELECT * FROM `test_1`;
-+
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+
-+SELECT * FROM `test_3`;
-+
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+
-+FLUSH TABLES;
-+SELECT * FROM `test_2`;
-+
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+
-+SELECT * FROM `test_1`;
-+FLUSH TABLES;
-+SELECT * FROM `test_4`;
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+
-+SELECT * FROM `test_3`;
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+
-+SET GLOBAL innodb_dict_size_limit=0;
-+FLUSH TABLES;
-+SELECT * FROM `test_2`;
-+
-+SHOW GLOBAL STATUS LIKE 'Innodb_dict_tables';
-+
-+DROP TABLE `test_5`;
-+DROP TABLE `test_4`;
-+DROP TABLE `test_3`;
-+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
-@@ -0,0 +1,9 @@
-+File=innodb_dict_size_limit.patch
-+Name=Limit dictionary cache size
-+Version=1.0
-+Author=Percona
-+License=GPL
-+Comment=Variable innodb_dict_size_limit in bytes
-+ChangeLog=
-+2009-01-26
-+YK: Initial release
diff --git a/mysql-innodb_extra_rseg.patch b/mysql-innodb_extra_rseg.patch
deleted file mode 100644 (file)
index 1c8f429..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-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 @@
- extern uint   srv_read_ahead;
- extern ulint  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
-@@ -105,6 +105,13 @@
- void
- trx_sys_create(void);
- /*================*/
-+/*********************************************************************
-+Create extra rollback segments when create_new_db */
-+
-+void
-+trx_sys_create_extra_rseg(
-+/*======================*/
-+      ulint   num);   /* in: number of extra user rollback segments */
- /********************************************************************
- 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 */
-+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
-@@ -1418,6 +1418,8 @@
-               dict_create();
-                 srv_startup_is_before_trx_rollback_phase = FALSE;
-+              if (srv_extra_rsegments)
-+                      trx_sys_create_extra_rseg(srv_extra_rsegments);
- #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
-@@ -944,3 +944,28 @@
-       trx_sys_init_at_db_start();
- }
-+
-+/*********************************************************************
-+Create extra rollback segments when create_new_db */
-+
-+void
-+trx_sys_create_extra_rseg(
-+/*======================*/
-+      ulint   num)    /* in: number of extra user rollback segments */
-+{
-+      mtr_t   mtr;
-+      ulint   slot_no;
-+      ulint   i;
-+
-+      /* Craete extra rollback segments */
-+      mtr_start(&mtr);
-+      for (i = 1; i < num + 1; i++) {
-+              if(!trx_rseg_create(TRX_SYS_SPACE, ULINT_MAX, &slot_no, &mtr)) {
-+                      fprintf(stderr,
-+"InnoDB: Warning: Failed to create extra rollback segments.\n");
-+                      break;
-+              }
-+              ut_a(slot_no == i);
-+      }
-+      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
-@@ -0,0 +1,6 @@
-+File=innodb_extra_rseg.patch
-+Name=allow to create extra rollback segments
-+Version=1.0
-+Author=Percona <info@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
-@@ -152,6 +152,7 @@
-      innobase_open_files;
- long innobase_read_io_threads, innobase_write_io_threads;
-+long innobase_extra_rsegments;
- longlong innobase_buffer_pool_size, innobase_log_file_size;
- /* The default values for the following char* start-up parameters
-@@ -1507,6 +1508,8 @@
-       srv_n_read_io_threads = (ulint) innobase_read_io_threads;
-       srv_n_write_io_threads = (ulint) innobase_write_io_threads;
-+      srv_extra_rsegments = (ulint) innobase_extra_rsegments;
-+
-       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
-@@ -205,6 +205,7 @@
- extern long innobase_buffer_pool_awe_mem_mb;
- extern long innobase_file_io_threads, innobase_lock_wait_timeout;
- extern long innobase_read_io_threads, innobase_write_io_threads;
-+extern long innobase_extra_rsegments;
- 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 @@
-   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 @@
-    "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_extra_rsegments", OPT_INNODB_EXTRA_RSEGMENTS,
-+   "Number of extra user rollback segments when create new database.",
-+   (gptr*) &innobase_extra_rsegments, (gptr*) &innobase_extra_rsegments,
-+   0, GET_LONG, REQUIRED_ARG, 0, 0, 127, 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,
-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 @@
-   {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},
-+  {"innodb_extra_rsegments", (char*) &innobase_extra_rsegments, 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},
-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
-@@ -39,6 +39,8 @@
- #include "srv0srv.h"
- #include "buf0buf.h"
- #include "dict0dict.h"
-+#include "trx0rseg.h" /* for trx_rseg_struct */
-+#include "trx0sys.h" /* for trx_sys */
- }
- /* We need to undef it in InnoDB */
- #undef byte
-@@ -4160,6 +4162,45 @@
-   DBUG_RETURN(returnable);
- }
-+int
-+innodb_rseg_fill(
-+/*=================*/
-+      THD*            thd,    /* in: thread */
-+      TABLE_LIST*     tables, /* in/out: tables to fill */
-+      COND*           cond)   /* in: condition (ignored) */
-+{
-+      TABLE*  table   = (TABLE *) tables->table;
-+      int     status  = 0;
-+      trx_rseg_t*     rseg;
-+
-+      DBUG_ENTER("innodb_rseg_fill");
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+
-+              DBUG_RETURN(0);
-+      }
-+
-+      rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
-+
-+      while (rseg) {
-+              table->field[0]->store(rseg->id);
-+              table->field[1]->store(rseg->space);
-+              table->field[2]->store(rseg->page_no);
-+              table->field[3]->store(rseg->max_size);
-+              table->field[4]->store(rseg->curr_size);
-+
-+              if (schema_table_store_record(thd, table)) {
-+                      status = 1;
-+                      break;
-+              }
-+
-+              rseg = UT_LIST_GET_NEXT(rseg_list, rseg);
-+      }
-+
-+      DBUG_RETURN(status);
-+}
-+
- /*
-   Find schema_tables elment by name
-@@ -4978,6 +5019,16 @@
-   {"N_WRITE", 11, MYSQL_TYPE_LONG, 0, 0, "write ios"},
-   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
- };
-+
-+ST_FIELD_INFO innodb_rseg_fields_info[]=
-+{
-+  {"RSEG_ID", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, ""},
-+  {"SPACE_ID", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, ""},
-+  {"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}
-+};
- #endif
- ST_FIELD_INFO variables_fields_info[]=
-@@ -5157,6 +5208,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},
-+  {"INNODB_RSEG", innodb_rseg_fields_info, create_schema_table,
-+    innodb_rseg_fill, 0, 0, -1, -1, 0},
- #endif
-   {0, 0, 0, 0, 0, 0, 0, 0, 0}
- };
diff --git a/mysql-innodb_rw_lock.patch b/mysql-innodb_rw_lock.patch
deleted file mode 100644 (file)
index f4a33fb..0000000
+++ /dev/null
@@ -1,1309 +0,0 @@
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.h mysql-5.1.29-rc/storage/innobase/include/sync0rw.h
---- mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.h    2008-10-12 06:54:14.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/sync0rw.h 2008-11-17 15:34:00.000000000 +0900
-@@ -328,7 +328,17 @@
- Accessor functions for rw lock. */
- UNIV_INLINE
- ulint
--rw_lock_get_waiters(
-+rw_lock_get_s_waiters(
-+/*==================*/
-+      rw_lock_t*      lock);
-+UNIV_INLINE
-+ulint
-+rw_lock_get_x_waiters(
-+/*==================*/
-+      rw_lock_t*      lock);
-+UNIV_INLINE
-+ulint
-+rw_lock_get_wx_waiters(
- /*================*/
-       rw_lock_t*      lock);
- UNIV_INLINE
-@@ -412,6 +422,11 @@
-       rw_lock_debug_t*        info);  /* in: debug struct */
- #endif /* UNIV_SYNC_DEBUG */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+/* This value means NOT_LOCKED */
-+#define RW_LOCK_BIAS          0x00100000
-+#endif
-+
- /* NOTE! The structure appears here only for the compiler to know its size.
- Do not use its fields directly! The structure used in the spin lock
- implementation of a read-write lock. Several threads may have a shared lock
-@@ -421,9 +436,9 @@
- field. Then no new readers are allowed in. */
- struct rw_lock_struct {
--      os_event_t      event;  /* Used by sync0arr.c for thread queueing */
--
--#ifdef __WIN__
-+                      /* Used by sync0arr.c for thread queueing */
-+      os_event_t      s_event;        /* Used for s_lock */
-+      os_event_t      x_event;        /* Used for x_lock */
-       os_event_t      wait_ex_event;  /* This windows specific event is
-                               used by the thread which has set the
-                               lock state to RW_LOCK_WAIT_EX. The
-@@ -431,30 +446,34 @@
-                               thread will be the next one to proceed
-                               once the current the event gets
-                               signalled. See LEMMA 2 in sync0sync.c */
-+
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      volatile lint   lock_word;      /* Used by using atomic builtin */
- #endif
--      ulint   reader_count;   /* Number of readers who have locked this
-+      volatile ulint  reader_count;   /* Number of readers who have locked this
-                               lock in the shared mode */
--      ulint   writer;         /* This field is set to RW_LOCK_EX if there
-+      volatile ulint  writer;         /* This field is set to RW_LOCK_EX if there
-                               is a writer owning the lock (in exclusive
-                               mode), RW_LOCK_WAIT_EX if a writer is
-                               queueing for the lock, and
-                               RW_LOCK_NOT_LOCKED, otherwise. */
--      os_thread_id_t  writer_thread;
-+      volatile os_thread_id_t writer_thread;
-                               /* Thread id of a possible writer thread */
--      ulint   writer_count;   /* Number of times the same thread has
-+      volatile ulint  writer_count;   /* Number of times the same thread has
-                               recursively locked the lock in the exclusive
-                               mode */
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_t mutex;          /* The mutex protecting rw_lock_struct */
-+#endif
-       ulint   pass;           /* Default value 0. This is set to some
-                               value != 0 given by the caller of an x-lock
-                               operation, if the x-lock is to be passed to
-                               another thread to unlock (which happens in
-                               asynchronous i/o). */
--      ulint   waiters;        /* This ulint is set to 1 if there are
--                              waiters (readers or writers) in the global
--                              wait array, waiting for this rw_lock.
--                              Otherwise, == 0. */
-+      volatile ulint  s_waiters;      /* 1: there are waiters (s_lock) */
-+      volatile ulint  x_waiters;      /* 1: there are waiters (x_lock) */
-+      volatile ulint  wait_ex_waiters;        /* 1: there are waiters (wait_ex) */
-       UT_LIST_NODE_T(rw_lock_t) list;
-                               /* All allocated rw locks are put into a
-                               list */
-@@ -467,7 +486,7 @@
-       const char*     cfile_name;/* File name where lock created */
-       const char*     last_s_file_name;/* File name where last s-locked */
-       const char*     last_x_file_name;/* File name where last x-locked */
--      ibool           writer_is_wait_ex;
-+      volatile ibool          writer_is_wait_ex;
-                               /* This is TRUE if the writer field is
-                               RW_LOCK_WAIT_EX; this field is located far
-                               from the memory update hotspot fields which
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.ic mysql-5.1.29-rc/storage/innobase/include/sync0rw.ic
---- mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.ic   2008-10-12 06:54:14.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/sync0rw.ic        2008-11-17 16:07:32.000000000 +0900
-@@ -47,20 +47,52 @@
- Accessor functions for rw lock. */
- UNIV_INLINE
- ulint
--rw_lock_get_waiters(
-+rw_lock_get_s_waiters(
- /*================*/
-       rw_lock_t*      lock)
- {
--      return(lock->waiters);
-+      return(lock->s_waiters);
- }
- UNIV_INLINE
--void
--rw_lock_set_waiters(
-+ulint
-+rw_lock_get_x_waiters(
-+/*================*/
-+      rw_lock_t*      lock)
-+{
-+      return(lock->x_waiters);
-+}
-+UNIV_INLINE
-+ulint
-+rw_lock_get_wx_waiters(
- /*================*/
-+      rw_lock_t*      lock)
-+{
-+      return(lock->wait_ex_waiters);
-+}
-+UNIV_INLINE
-+void
-+rw_lock_set_s_waiters(
-+      rw_lock_t*      lock,
-+      ulint           flag)
-+{
-+      lock->s_waiters = flag;
-+}
-+UNIV_INLINE
-+void
-+rw_lock_set_x_waiters(
-       rw_lock_t*      lock,
-       ulint           flag)
- {
--      lock->waiters = flag;
-+      lock->x_waiters = flag;
-+}
-+UNIV_INLINE
-+void
-+rw_lock_set_wx_waiters(
-+/*================*/
-+      rw_lock_t*      lock,
-+      ulint           flag)
-+{
-+      lock->wait_ex_waiters = flag;
- }
- UNIV_INLINE
- ulint
-@@ -68,7 +100,19 @@
- /*===============*/
-       rw_lock_t*      lock)
- {
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (lock->writer == RW_LOCK_NOT_LOCKED) {
-+              return(RW_LOCK_NOT_LOCKED);
-+      }
-+
-+      if (lock->writer_is_wait_ex) {
-+              return(RW_LOCK_WAIT_EX);
-+      } else {
-+              return(RW_LOCK_EX);
-+      }
-+#else
-       return(lock->writer);
-+#endif
- }
- UNIV_INLINE
- void
-@@ -96,6 +140,7 @@
- {
-       lock->reader_count = count;
- }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
- UNIV_INLINE
- mutex_t*
- rw_lock_get_mutex(
-@@ -104,6 +149,7 @@
- {
-       return(&(lock->mutex));
- }
-+#endif
- /**********************************************************************
- Returns the value of writer_count for the lock. Does not reserve the lock
-@@ -133,13 +179,27 @@
-       const char*     file_name, /* in: file name where lock requested */
-       ulint           line)   /* in: line where requested */
- {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       ut_ad(mutex_own(rw_lock_get_mutex(lock)));
-+#endif
-       /* Check if the writer field is free */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (UNIV_LIKELY(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED)) {
-+              /* try s-lock */
-+              if(__sync_sub_and_fetch(&(lock->lock_word),1) <= 0) {
-+                      /* fail */
-+                      __sync_fetch_and_add(&(lock->lock_word),1);
-+                      return(FALSE);  /* locking did not succeed */
-+              }
-+              /* success */
-+              __sync_fetch_and_add(&(lock->reader_count),1);
-+#else
-       if (UNIV_LIKELY(lock->writer == RW_LOCK_NOT_LOCKED)) {
-               /* Set the shared lock by incrementing the reader count */
-               lock->reader_count++;
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-               rw_lock_add_debug_info(lock, pass, RW_LOCK_SHARED, file_name,
-@@ -166,11 +226,15 @@
-       const char*     file_name,      /* in: file name where requested */
-       ulint           line)           /* in: line where lock requested */
- {
--      ut_ad(lock->writer == RW_LOCK_NOT_LOCKED);
-+      ut_ad(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
-       ut_ad(rw_lock_get_reader_count(lock) == 0);
-       /* Set the shared lock by incrementing the reader count */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      __sync_fetch_and_add(&(lock->reader_count),1);
-+#else
-       lock->reader_count++;
-+#endif
-       lock->last_s_file_name = file_name;
-       lock->last_s_line = line;
-@@ -198,7 +262,11 @@
-       rw_lock_set_writer(lock, RW_LOCK_EX);
-       lock->writer_thread = os_thread_get_curr_id();
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      __sync_fetch_and_add(&(lock->writer_count),1);
-+#else
-       lock->writer_count++;
-+#endif
-       lock->pass = 0;
-       lock->last_x_file_name = file_name;
-@@ -240,15 +308,21 @@
-       ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */
- #endif /* UNIV_SYNC_DEBUG */
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-       if (UNIV_LIKELY(rw_lock_s_lock_low(lock, pass, file_name, line))) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               return; /* Success */
-       } else {
-               /* Did not succeed, try spin wait */
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               rw_lock_s_lock_spin(lock, pass, file_name, line);
-@@ -271,11 +345,23 @@
- {
-       ibool   success = FALSE;
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
-+              /* try s-lock */
-+              if(__sync_sub_and_fetch(&(lock->lock_word),1) <= 0) {
-+                      /* fail */
-+                      __sync_fetch_and_add(&(lock->lock_word),1);
-+                      return(FALSE);  /* locking did not succeed */
-+              }
-+              /* success */
-+              __sync_fetch_and_add(&(lock->reader_count),1);
-+#else
-       mutex_enter(rw_lock_get_mutex(lock));
-       if (lock->writer == RW_LOCK_NOT_LOCKED) {
-               /* Set the shared lock by incrementing the reader count */
-               lock->reader_count++;
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-               rw_lock_add_debug_info(lock, 0, RW_LOCK_SHARED, file_name,
-@@ -288,7 +374,9 @@
-               success = TRUE;
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-       return(success);
- }
-@@ -308,6 +396,55 @@
- {
-       ibool           success         = FALSE;
-       os_thread_id_t  curr_thread     = os_thread_get_curr_id();
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if ((lock->lock_word == RW_LOCK_BIAS)
-+                      && rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
-+              /* try x-lock */
-+              if(__sync_sub_and_fetch(&(lock->lock_word),
-+                              RW_LOCK_BIAS) == 0) {
-+                      /* success */
-+                      /* try to lock writer */
-+                      if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
-+                                      == RW_LOCK_NOT_LOCKED) {
-+                              /* success */
-+                              lock->writer_thread = curr_thread;
-+                              lock->pass = 0;
-+                              lock->writer_is_wait_ex = FALSE;
-+                              /* next function may work as memory barrier */
-+                      relock:
-+                              __sync_fetch_and_add(&(lock->writer_count),1);
-+
-+#ifdef UNIV_SYNC_DEBUG
-+                              rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line);
-+#endif
-+
-+                              lock->last_x_file_name = file_name;
-+                              lock->last_x_line = line;
-+
-+                              ut_ad(rw_lock_validate(lock));
-+
-+                              return(TRUE);
-+                      } else {
-+                              /* x-unlock */
-+                              __sync_fetch_and_add(&(lock->lock_word),
-+                                      RW_LOCK_BIAS);
-+                      }
-+              } else {
-+                      /* fail (x-lock) */
-+                      __sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS);
-+              }
-+      }
-+
-+      if (lock->pass == 0
-+                      && os_thread_eq(lock->writer_thread, curr_thread)
-+                      && rw_lock_get_writer(lock) == RW_LOCK_EX) {
-+              goto relock;
-+      }
-+
-+      ut_ad(rw_lock_validate(lock));
-+
-+      return(FALSE);
-+#else
-       mutex_enter(rw_lock_get_mutex(lock));
-       if (UNIV_UNLIKELY(rw_lock_get_reader_count(lock) != 0)) {
-@@ -338,6 +475,7 @@
-       ut_ad(rw_lock_validate(lock));
-       return(success);
-+#endif
- }
- /**********************************************************************
-@@ -353,16 +491,33 @@
- #endif
-       )
- {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_t*        mutex   = &(lock->mutex);
--      ibool           sg      = FALSE;
-+#endif
-+      ibool           x_sg    = FALSE;
-+      ibool           wx_sg   = FALSE;
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      ibool           last    = FALSE;
-+#endif
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       /* Acquire the mutex protecting the rw-lock fields */
-       mutex_enter(mutex);
-+#endif
-       /* Reset the shared lock by decrementing the reader count */
-       ut_a(lock->reader_count > 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      /* unlock lock_word */
-+      __sync_fetch_and_add(&(lock->lock_word),1);
-+
-+      if(__sync_sub_and_fetch(&(lock->reader_count),1) == 0) {
-+              last = TRUE;
-+      }
-+#else
-       lock->reader_count--;
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-       rw_lock_remove_debug_info(lock, pass, RW_LOCK_SHARED);
-@@ -371,20 +526,36 @@
-       /* If there may be waiters and this was the last s-lock,
-       signal the object */
--      if (UNIV_UNLIKELY(lock->waiters)
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (UNIV_UNLIKELY(last && lock->wait_ex_waiters)) {
-+#else
-+      if (UNIV_UNLIKELY(lock->wait_ex_waiters)
-           && lock->reader_count == 0) {
--              sg = TRUE;
-+#endif
-+              wx_sg = TRUE;
--              rw_lock_set_waiters(lock, 0);
-+              rw_lock_set_wx_waiters(lock, 0);
-       }
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      else if (UNIV_UNLIKELY(last && lock->x_waiters)) {
-+#else
-+      else if (UNIV_UNLIKELY(lock->x_waiters)
-+               && lock->reader_count == 0) {
-+#endif
-+              x_sg = TRUE;
-+              rw_lock_set_x_waiters(lock, 0);
-+      }
-+
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(mutex);
-+#endif
--      if (UNIV_UNLIKELY(sg)) {
--#ifdef __WIN__
-+      if (UNIV_UNLIKELY(wx_sg)) {
-               os_event_set(lock->wait_ex_event);
--#endif
--              os_event_set(lock->event);
-+              sync_array_object_signalled(sync_primary_wait_array);
-+      } else if (UNIV_UNLIKELY(x_sg)) {
-+              os_event_set(lock->x_event);
-               sync_array_object_signalled(sync_primary_wait_array);
-       }
-@@ -408,13 +579,19 @@
-       ut_ad(lock->reader_count > 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      __sync_sub_and_fetch(&(lock->reader_count),1);
-+#else
-       lock->reader_count--;
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-       rw_lock_remove_debug_info(lock, 0, RW_LOCK_SHARED);
- #endif
--      ut_ad(!lock->waiters);
-+      ut_ad(!lock->s_waiters);
-+      ut_ad(!lock->x_waiters);
-+      ut_ad(!lock->wait_ex_waiters);
-       ut_ad(rw_lock_validate(lock));
- #ifdef UNIV_SYNC_PERF_STAT
-       rw_s_exit_count++;
-@@ -434,41 +611,81 @@
- #endif
-       )
- {
--      ibool   sg      = FALSE;
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      ibool   last    = FALSE;
-+#endif
-+      ibool   s_sg    = FALSE;
-+      ibool   x_sg    = FALSE;
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       /* Acquire the mutex protecting the rw-lock fields */
-       mutex_enter(&(lock->mutex));
-+#endif
-       /* Reset the exclusive lock if this thread no longer has an x-mode
-       lock */
-       ut_ad(lock->writer_count > 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if(__sync_sub_and_fetch(&(lock->writer_count),1) == 0) {
-+              last = TRUE;
-+      }
-+
-+      if (last) {
-+              /* unlock lock_word */
-+              __sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS);
-+
-+              /* FIXME: It is a value of bad manners for pthread.
-+                        But we shouldn't keep an ID of not-owner. */
-+              lock->writer_thread = -1;
-+
-+              /* atomic operation may be safer about memory order. */
-+              rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
-+              __sync_synchronize();
-+      }
-+#else
-       lock->writer_count--;
-       if (lock->writer_count == 0) {
-               rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
-       }
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-       rw_lock_remove_debug_info(lock, pass, RW_LOCK_EX);
- #endif
-       /* If there may be waiters, signal the lock */
--      if (UNIV_UNLIKELY(lock->waiters)
--          && lock->writer_count == 0) {
--
--              sg = TRUE;
--              rw_lock_set_waiters(lock, 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (last) {
-+#else
-+      if (lock->writer_count == 0) {
-+#endif
-+              if(lock->s_waiters){
-+                      s_sg = TRUE;
-+                      rw_lock_set_s_waiters(lock, 0);
-+              }
-+              if(lock->x_waiters){
-+                      x_sg = TRUE;
-+                      rw_lock_set_x_waiters(lock, 0);
-+              }
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(&(lock->mutex));
-+#endif
--      if (UNIV_UNLIKELY(sg)) {
-+      if (UNIV_UNLIKELY(s_sg)) {
-+              os_event_set(lock->s_event);
-+              sync_array_object_signalled(sync_primary_wait_array);
-+      }
-+      if (UNIV_UNLIKELY(x_sg)) {
- #ifdef __WIN__
-+              /* I doubt the necessity of it. */
-               os_event_set(lock->wait_ex_event);
- #endif
--              os_event_set(lock->event);
-+              os_event_set(lock->x_event);
-               sync_array_object_signalled(sync_primary_wait_array);
-       }
-@@ -493,9 +710,13 @@
-       ut_ad(lock->writer_count > 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if(__sync_sub_and_fetch(&(lock->writer_count),1) == 0) {
-+#else
-       lock->writer_count--;
-       if (lock->writer_count == 0) {
-+#endif
-               rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
-       }
-@@ -503,7 +724,9 @@
-       rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX);
- #endif
--      ut_ad(!lock->waiters);
-+      ut_ad(!lock->s_waiters);
-+      ut_ad(!lock->x_waiters);
-+      ut_ad(!lock->wait_ex_waiters);
-       ut_ad(rw_lock_validate(lock));
- #ifdef UNIV_SYNC_PERF_STAT
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/sync/sync0arr.c mysql-5.1.29-rc/storage/innobase/sync/sync0arr.c
---- mysql-5.1.29-rc_orig/storage/innobase/sync/sync0arr.c      2008-10-12 06:54:15.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/sync/sync0arr.c   2008-11-17 16:17:39.000000000 +0900
-@@ -307,13 +307,13 @@
- {
-       if (type == SYNC_MUTEX) {
-               return(os_event_reset(((mutex_t *) object)->event));
--#ifdef __WIN__
-       } else if (type == RW_LOCK_WAIT_EX) {
-               return(os_event_reset(
-                      ((rw_lock_t *) object)->wait_ex_event));
--#endif
--      } else {
--              return(os_event_reset(((rw_lock_t *) object)->event));
-+      } else if (type == RW_LOCK_SHARED) {
-+              return(os_event_reset(((rw_lock_t *) object)->s_event));
-+      } else { /* RW_LOCK_EX */
-+              return(os_event_reset(((rw_lock_t *) object)->x_event));
-       }
- }
-@@ -413,15 +413,12 @@
-       if (cell->request_type == SYNC_MUTEX) {
-               event = ((mutex_t*) cell->wait_object)->event;
--#ifdef __WIN__
--      /* On windows if the thread about to wait is the one which
--      has set the state of the rw_lock to RW_LOCK_WAIT_EX, then
--      it waits on a special event i.e.: wait_ex_event. */
-       } else if (cell->request_type == RW_LOCK_WAIT_EX) {
-               event = ((rw_lock_t*) cell->wait_object)->wait_ex_event;
--#endif
-+      } else if (cell->request_type == RW_LOCK_SHARED) {
-+              event = ((rw_lock_t*) cell->wait_object)->s_event;
-       } else {
--              event = ((rw_lock_t*) cell->wait_object)->event;
-+              event = ((rw_lock_t*) cell->wait_object)->x_event;
-       }
-               cell->waiting = TRUE;
-@@ -462,6 +459,7 @@
-       mutex_t*        mutex;
-       rw_lock_t*      rwlock;
-       ulint           type;
-+      ulint           writer;
-       type = cell->request_type;
-@@ -491,12 +489,10 @@
-                       (ulong) mutex->waiters);
-       } else if (type == RW_LOCK_EX
--#ifdef __WIN__
-                  || type == RW_LOCK_WAIT_EX
--#endif
-                  || type == RW_LOCK_SHARED) {
--              fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
-+              fputs(type == RW_LOCK_SHARED ? "S-lock on" : "X-lock on", file);
-               rwlock = cell->old_wait_rw_lock;
-@@ -504,22 +500,24 @@
-                       " RW-latch at %p created in file %s line %lu\n",
-                       (void*) rwlock, rwlock->cfile_name,
-                       (ulong) rwlock->cline);
--              if (rwlock->writer != RW_LOCK_NOT_LOCKED) {
-+              writer = rw_lock_get_writer(rwlock);
-+              if (writer != RW_LOCK_NOT_LOCKED) {
-                       fprintf(file,
-                               "a writer (thread id %lu) has"
-                               " reserved it in mode %s",
-                               (ulong) os_thread_pf(rwlock->writer_thread),
--                              rwlock->writer == RW_LOCK_EX
-+                              writer == RW_LOCK_EX
-                               ? " exclusive\n"
-                               : " wait exclusive\n");
-               }
-               fprintf(file,
--                      "number of readers %lu, waiters flag %lu\n"
-+                      "number of readers %lu, s_waiters flag %lu, x_waiters flag %lu\n"
-                       "Last time read locked in file %s line %lu\n"
-                       "Last time write locked in file %s line %lu\n",
-                       (ulong) rwlock->reader_count,
--                      (ulong) rwlock->waiters,
-+                      (ulong) rwlock->s_waiters,
-+                      (ulong) (rwlock->x_waiters || rwlock->wait_ex_waiters),
-                       rwlock->last_s_file_name,
-                       (ulong) rwlock->last_s_line,
-                       rwlock->last_x_file_name,
-@@ -844,11 +842,15 @@
- /*========================*/
-       sync_array_t*   arr)    /* in: wait array */
- {
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      __sync_fetch_and_add(&(arr->sg_count),1);
-+#else
-       sync_array_enter(arr);
-       arr->sg_count++;
-       sync_array_exit(arr);
-+#endif
- }
- /**************************************************************************
-@@ -889,19 +891,23 @@
-                                       mutex = cell->wait_object;
-                                       os_event_set(mutex->event);
--#ifdef __WIN__
-                               } else if (cell->request_type
-                                          == RW_LOCK_WAIT_EX) {
-                                       rw_lock_t*      lock;
-                                       lock = cell->wait_object;
-                                       os_event_set(lock->wait_ex_event);
--#endif
--                              } else {
-+                              } else if (cell->request_type
-+                                         == RW_LOCK_SHARED) {
-                                       rw_lock_t*      lock;
-                                       lock = cell->wait_object;
--                                      os_event_set(lock->event);
-+                                      os_event_set(lock->s_event);
-+                              } else {
-+                                      rw_lock_t*      lock;
-+
-+                                      lock = cell->wait_object;
-+                                      os_event_set(lock->x_event);
-                               }
-                       }
-               }
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/sync/sync0rw.c mysql-5.1.29-rc/storage/innobase/sync/sync0rw.c
---- mysql-5.1.29-rc_orig/storage/innobase/sync/sync0rw.c       2008-10-12 06:54:15.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/sync/sync0rw.c    2008-11-17 17:43:45.000000000 +0900
-@@ -119,6 +119,7 @@
-       /* If this is the very first time a synchronization object is
-       created, then the following call initializes the sync system. */
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
-       lock->mutex.cfile_name = cfile_name;
-@@ -128,8 +129,14 @@
-       lock->mutex.cmutex_name = cmutex_name;
-       lock->mutex.mutex_type = 1;
- #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-+#endif /* !HAVE_GCC_ATOMIC_BUILTINS */
--      rw_lock_set_waiters(lock, 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      lock->lock_word = RW_LOCK_BIAS;
-+#endif
-+      rw_lock_set_s_waiters(lock, 0);
-+      rw_lock_set_x_waiters(lock, 0);
-+      rw_lock_set_wx_waiters(lock, 0);
-       rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
-       lock->writer_count = 0;
-       rw_lock_set_reader_count(lock, 0);
-@@ -151,11 +158,9 @@
-       lock->last_x_file_name = "not yet reserved";
-       lock->last_s_line = 0;
-       lock->last_x_line = 0;
--      lock->event = os_event_create(NULL);
--
--#ifdef __WIN__
-+      lock->s_event = os_event_create(NULL);
-+      lock->x_event = os_event_create(NULL);
-       lock->wait_ex_event = os_event_create(NULL);
--#endif
-       mutex_enter(&rw_lock_list_mutex);
-@@ -181,19 +186,21 @@
- {
-       ut_ad(rw_lock_validate(lock));
-       ut_a(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
--      ut_a(rw_lock_get_waiters(lock) == 0);
-+      ut_a(rw_lock_get_s_waiters(lock) == 0);
-+      ut_a(rw_lock_get_x_waiters(lock) == 0);
-+      ut_a(rw_lock_get_wx_waiters(lock) == 0);
-       ut_a(rw_lock_get_reader_count(lock) == 0);
-       lock->magic_n = 0;
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_free(rw_lock_get_mutex(lock));
-+#endif
-       mutex_enter(&rw_lock_list_mutex);
--      os_event_free(lock->event);
--
--#ifdef __WIN__
-+      os_event_free(lock->s_event);
-+      os_event_free(lock->x_event);
-       os_event_free(lock->wait_ex_event);
--#endif
-       if (UT_LIST_GET_PREV(list, lock)) {
-               ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
-@@ -212,6 +219,8 @@
- Checks that the rw-lock has been initialized and that there are no
- simultaneous shared and exclusive locks. */
-+/* MEMO: If HAVE_GCC_ATOMIC_BUILTINS, we should use this function statically. */
-+
- ibool
- rw_lock_validate(
- /*=============*/
-@@ -219,7 +228,9 @@
- {
-       ut_a(lock);
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-       ut_a(lock->magic_n == RW_LOCK_MAGIC_N);
-       ut_a((rw_lock_get_reader_count(lock) == 0)
-@@ -227,11 +238,17 @@
-       ut_a((rw_lock_get_writer(lock) == RW_LOCK_EX)
-            || (rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX)
-            || (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED));
--      ut_a((rw_lock_get_waiters(lock) == 0)
--           || (rw_lock_get_waiters(lock) == 1));
-+      ut_a((rw_lock_get_s_waiters(lock) == 0)
-+           || (rw_lock_get_s_waiters(lock) == 1));
-+      ut_a((rw_lock_get_x_waiters(lock) == 0)
-+           || (rw_lock_get_x_waiters(lock) == 1));
-+      ut_a((rw_lock_get_wx_waiters(lock) == 0)
-+           || (rw_lock_get_wx_waiters(lock) == 1));
-       ut_a((lock->writer != RW_LOCK_EX) || (lock->writer_count > 0));
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-       return(TRUE);
- }
-@@ -258,13 +275,14 @@
-       ut_ad(rw_lock_validate(lock));
- lock_loop:
-+      i = 0;
-+spin_loop:
-       rw_s_spin_wait_count++;
-       /* Spin waiting for the writer field to become free */
--      i = 0;
--      while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
--             && i < SYNC_SPIN_ROUNDS) {
-+      while (i < SYNC_SPIN_ROUNDS
-+             && rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) {
-               if (srv_spin_wait_delay) {
-                       ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
-               }
-@@ -285,15 +303,27 @@
-                       lock->cfile_name, (ulong) lock->cline, (ulong) i);
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-       /* We try once again to obtain the lock */
-       if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               return; /* Success */
-       } else {
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+              /* like sync0sync.c doing */
-+              i++;
-+
-+              if (i < SYNC_SPIN_ROUNDS) {
-+                      goto spin_loop;
-+              }
-+#endif
-               /* If we get here, locking did not succeed, we may
-               suspend the thread to wait in the wait array */
-@@ -304,9 +334,19 @@
-                                       file_name, line,
-                                       &index);
--              rw_lock_set_waiters(lock, 1);
-+              rw_lock_set_s_waiters(lock, 1);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+              /* like sync0sync.c doing */
-+              for (i = 0; i < 4; i++) {
-+                      if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
-+                              sync_array_free_cell(sync_primary_wait_array, index);
-+                              return; /* Success */
-+                      }
-+              }
-+#else
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               if (srv_print_latch_waits) {
-                       fprintf(stderr,
-@@ -343,13 +383,19 @@
- {
-       ut_ad(rw_lock_is_locked(lock, RW_LOCK_EX));
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(&(lock->mutex));
-+#endif
-       lock->writer_thread = os_thread_get_curr_id();
-       lock->pass = 0;
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(&(lock->mutex));
-+#else
-+      __sync_synchronize();
-+#endif
- }
- /**********************************************************************
-@@ -367,6 +413,89 @@
-       const char*     file_name,/* in: file name where lock requested */
-       ulint           line)   /* in: line where requested */
- {
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      os_thread_id_t  curr_thread     = os_thread_get_curr_id();
-+
-+      /* try to lock writer */
-+      if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
-+                      == RW_LOCK_NOT_LOCKED) {
-+              /* success */
-+              /* obtain RW_LOCK_WAIT_EX right */
-+              lock->writer_thread = curr_thread;
-+              lock->pass = pass;
-+              lock->writer_is_wait_ex = TRUE;
-+              /* atomic operation may be safer about memory order. */
-+              __sync_synchronize();
-+#ifdef UNIV_SYNC_DEBUG
-+              rw_lock_add_debug_info(lock, pass, RW_LOCK_WAIT_EX,
-+                                      file_name, line);
-+#endif
-+      }
-+
-+      if (!os_thread_eq(lock->writer_thread, curr_thread)) {
-+              return(RW_LOCK_NOT_LOCKED);
-+      }
-+
-+      switch(rw_lock_get_writer(lock)) {
-+          case RW_LOCK_WAIT_EX:
-+              /* have right to try x-lock */
-+              if (lock->lock_word == RW_LOCK_BIAS) {
-+                      /* try x-lock */
-+                      if(__sync_sub_and_fetch(&(lock->lock_word),
-+                                      RW_LOCK_BIAS) == 0) {
-+                              /* success */
-+                              lock->pass = pass;
-+                              lock->writer_is_wait_ex = FALSE;
-+                              __sync_fetch_and_add(&(lock->writer_count),1);
-+
-+#ifdef UNIV_SYNC_DEBUG
-+                              rw_lock_remove_debug_info(lock, pass, RW_LOCK_WAIT_EX);
-+                              rw_lock_add_debug_info(lock, pass, RW_LOCK_EX,
-+                                                      file_name, line);
-+#endif
-+
-+                              lock->last_x_file_name = file_name;
-+                              lock->last_x_line = line;
-+
-+                              /* Locking succeeded, we may return */
-+                              return(RW_LOCK_EX);
-+                      } else {
-+                              /* fail */
-+                              __sync_fetch_and_add(&(lock->lock_word),
-+                                      RW_LOCK_BIAS);
-+                      }
-+              }
-+              /* There are readers, we have to wait */
-+              return(RW_LOCK_WAIT_EX);
-+
-+              break;
-+
-+          case RW_LOCK_EX:
-+              /* already have x-lock */
-+              if ((lock->pass == 0)&&(pass == 0)) {
-+                      __sync_fetch_and_add(&(lock->writer_count),1);
-+
-+#ifdef UNIV_SYNC_DEBUG
-+                      rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name,
-+                                              line);
-+#endif
-+
-+                      lock->last_x_file_name = file_name;
-+                      lock->last_x_line = line;
-+
-+                      /* Locking succeeded, we may return */
-+                      return(RW_LOCK_EX);
-+              }
-+
-+              return(RW_LOCK_NOT_LOCKED);
-+
-+              break;
-+
-+          default: /* ??? */
-+              return(RW_LOCK_NOT_LOCKED);
-+      }
-+#else /* HAVE_GCC_ATOMIC_BUILTINS */
-+
-       ut_ad(mutex_own(rw_lock_get_mutex(lock)));
-       if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
-@@ -447,6 +576,7 @@
-               /* Locking succeeded, we may return */
-               return(RW_LOCK_EX);
-       }
-+#endif /* HAVE_GCC_ATOMIC_BUILTINS */
-       /* Locking did not succeed */
-       return(RW_LOCK_NOT_LOCKED);
-@@ -472,19 +602,33 @@
-       ulint           line)   /* in: line where requested */
- {
-       ulint   index;  /* index of the reserved wait cell */
--      ulint   state;  /* lock state acquired */
-+      ulint   state = RW_LOCK_NOT_LOCKED;     /* lock state acquired */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      ulint   prev_state = RW_LOCK_NOT_LOCKED;
-+#endif
-       ulint   i;      /* spin round count */
-       ut_ad(rw_lock_validate(lock));
- lock_loop:
-+      i = 0;
-+
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      prev_state = state;
-+#else
-       /* Acquire the mutex protecting the rw-lock fields */
-       mutex_enter_fast(&(lock->mutex));
-+#endif
-       state = rw_lock_x_lock_low(lock, pass, file_name, line);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (state != prev_state) i=0; /* if progress, reset counter. */
-+#else
-       mutex_exit(&(lock->mutex));
-+#endif
-+spin_loop:
-       if (state == RW_LOCK_EX) {
-               return; /* Locking succeeded */
-@@ -492,10 +636,9 @@
-       } else if (state == RW_LOCK_NOT_LOCKED) {
-               /* Spin waiting for the writer field to become free */
--              i = 0;
--              while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
--                     && i < SYNC_SPIN_ROUNDS) {
-+              while (i < SYNC_SPIN_ROUNDS
-+                     && rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) {
-                       if (srv_spin_wait_delay) {
-                               ut_delay(ut_rnd_interval(0,
-                                                        srv_spin_wait_delay));
-@@ -509,9 +652,12 @@
-       } else if (state == RW_LOCK_WAIT_EX) {
-               /* Spin waiting for the reader count field to become zero */
--              i = 0;
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+              while (lock->lock_word != RW_LOCK_BIAS
-+#else
-               while (rw_lock_get_reader_count(lock) != 0
-+#endif
-                      && i < SYNC_SPIN_ROUNDS) {
-                       if (srv_spin_wait_delay) {
-                               ut_delay(ut_rnd_interval(0,
-@@ -524,7 +670,6 @@
-                       os_thread_yield();
-               }
-       } else {
--              i = 0; /* Eliminate a compiler warning */
-               ut_error;
-       }
-@@ -541,34 +686,69 @@
-       /* We try once again to obtain the lock. Acquire the mutex protecting
-       the rw-lock fields */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      prev_state = state;
-+#else
-       mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-       state = rw_lock_x_lock_low(lock, pass, file_name, line);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (state != prev_state) i=0; /* if progress, reset counter. */
-+#endif
-+
-       if (state == RW_LOCK_EX) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               return; /* Locking succeeded */
-       }
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      /* like sync0sync.c doing */
-+      i++;
-+
-+      if (i < SYNC_SPIN_ROUNDS) {
-+              goto spin_loop;
-+      }
-+#endif
-+
-       rw_x_system_call_count++;
-       sync_array_reserve_cell(sync_primary_wait_array,
-                               lock,
--#ifdef __WIN__
--                              /* On windows RW_LOCK_WAIT_EX signifies
--                              that this thread should wait on the
--                              special wait_ex_event. */
-                               (state == RW_LOCK_WAIT_EX)
-                                ? RW_LOCK_WAIT_EX :
--#endif
-                               RW_LOCK_EX,
-                               file_name, line,
-                               &index);
--      rw_lock_set_waiters(lock, 1);
-+      if (state == RW_LOCK_WAIT_EX) {
-+              rw_lock_set_wx_waiters(lock, 1);
-+      } else {
-+              rw_lock_set_x_waiters(lock, 1);
-+      }
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      /* like sync0sync.c doing */
-+      for (i = 0; i < 4; i++) {
-+              prev_state = state;
-+              state = rw_lock_x_lock_low(lock, pass, file_name, line);
-+              if (state == RW_LOCK_EX) {
-+                      sync_array_free_cell(sync_primary_wait_array, index);
-+                      return; /* Locking succeeded */
-+              }
-+              if (state != prev_state) {
-+                      /* retry! */
-+                      sync_array_free_cell(sync_primary_wait_array, index);
-+                      goto lock_loop;
-+              }
-+      }
-+#else
-       mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-       if (srv_print_latch_waits) {
-               fprintf(stderr,
-@@ -730,7 +910,9 @@
-       ut_ad(lock);
-       ut_ad(rw_lock_validate(lock));
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(&(lock->mutex));
-+#endif
-       info = UT_LIST_GET_FIRST(lock->debug_list);
-@@ -740,7 +922,9 @@
-                   && (info->pass == 0)
-                   && (info->lock_type == lock_type)) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-                       mutex_exit(&(lock->mutex));
-+#endif
-                       /* Found! */
-                       return(TRUE);
-@@ -748,7 +932,9 @@
-               info = UT_LIST_GET_NEXT(list, info);
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(&(lock->mutex));
-+#endif
-       return(FALSE);
- }
-@@ -770,21 +956,25 @@
-       ut_ad(lock);
-       ut_ad(rw_lock_validate(lock));
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(&(lock->mutex));
-+#endif
-       if (lock_type == RW_LOCK_SHARED) {
-               if (lock->reader_count > 0) {
-                       ret = TRUE;
-               }
-       } else if (lock_type == RW_LOCK_EX) {
--              if (lock->writer == RW_LOCK_EX) {
-+              if (rw_lock_get_writer(lock) == RW_LOCK_EX) {
-                       ret = TRUE;
-               }
-       } else {
-               ut_error;
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(&(lock->mutex));
-+#endif
-       return(ret);
- }
-@@ -814,16 +1004,26 @@
-               count++;
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_enter(&(lock->mutex));
-+#endif
-               if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
-                   || (rw_lock_get_reader_count(lock) != 0)
--                  || (rw_lock_get_waiters(lock) != 0)) {
-+                  || (rw_lock_get_s_waiters(lock) != 0)
-+                  || (rw_lock_get_x_waiters(lock) != 0)
-+                  || (rw_lock_get_wx_waiters(lock) != 0)) {
-                       fprintf(file, "RW-LOCK: %p ", (void*) lock);
--                      if (rw_lock_get_waiters(lock)) {
--                              fputs(" Waiters for the lock exist\n", file);
-+                      if (rw_lock_get_s_waiters(lock)) {
-+                              fputs(" s_waiters for the lock exist,", file);
-+                      }
-+                      if (rw_lock_get_x_waiters(lock)) {
-+                              fputs(" x_waiters for the lock exist\n", file);
-+                      }
-+                      if (rw_lock_get_wx_waiters(lock)) {
-+                              fputs(" wait_ex_waiters for the lock exist\n", file);
-                       } else {
-                               putc('\n', file);
-                       }
-@@ -835,7 +1035,9 @@
-                       }
-               }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(&(lock->mutex));
-+#endif
-               lock = UT_LIST_GET_NEXT(list, lock);
-       }
-@@ -860,10 +1062,18 @@
-       if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
-           || (rw_lock_get_reader_count(lock) != 0)
--          || (rw_lock_get_waiters(lock) != 0)) {
-+          || (rw_lock_get_s_waiters(lock) != 0)
-+          || (rw_lock_get_x_waiters(lock) != 0)
-+          || (rw_lock_get_wx_waiters(lock) != 0)) {
--              if (rw_lock_get_waiters(lock)) {
--                      fputs(" Waiters for the lock exist\n", stderr);
-+              if (rw_lock_get_s_waiters(lock)) {
-+                      fputs(" s_waiters for the lock exist,", stderr);
-+              }
-+              if (rw_lock_get_x_waiters(lock)) {
-+                      fputs(" x_waiters for the lock exist\n", stderr);
-+              }
-+              if (rw_lock_get_wx_waiters(lock)) {
-+                      fputs(" wait_ex_waiters for the lock exist\n", stderr);
-               } else {
-                       putc('\n', stderr);
-               }
-@@ -922,14 +1132,18 @@
-       lock = UT_LIST_GET_FIRST(rw_lock_list);
-       while (lock != NULL) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-               if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
-                   || (rw_lock_get_reader_count(lock) != 0)) {
-                       count++;
-               }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               lock = UT_LIST_GET_NEXT(list, lock);
-       }
-diff -ruN mysql-5.1.29-rc_orig/patch_info/innodb_rw_lock.info mysql-5.1.29-rc/patch_info/innodb_rw_lock.info
---- /dev/null  1970-01-01 09:00:00.000000000 +0900
-+++ mysql-5.1.29-rc/patch_info/innodb_rw_lock.info     2008-11-17 15:23:46.000000000 +0900
-@@ -0,0 +1,6 @@
-+File=innodb_rw_lock.patch
-+Name=Fix of InnoDB rw_locks
-+Version=1.0
-+Author=Yasufumi Kinoshita
-+License=BSD
-+Comment=
diff --git a/mysql-innodb_thread_concurrency_timer_based.patch b/mysql-innodb_thread_concurrency_timer_based.patch
deleted file mode 100644 (file)
index 5e26818..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-diff -ruN a/innobase/configure b/innobase/configure
---- a/innobase/configure       2009-01-30 06:56:31.000000000 +0900
-+++ b/innobase/configure       2009-05-06 15:40:47.000000000 +0900
-@@ -21306,6 +21306,88 @@
- fi
- done
-+
-+# as http://lists.mysql.com/commits/40686 does
-+{ echo "$as_me:$LINENO: checking whether the compiler provides atomic builtins" >&5
-+echo $ECHO_N "checking whether the compiler provides atomic builtins... $ECHO_C" >&6; }
-+if test "${mysql_cv_atomic_builtins+set}" = set; then
-+  echo $ECHO_N "(cached) $ECHO_C" >&6
-+else
-+  if test "$cross_compiling" = yes; then
-+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-+See \`config.log' for more details." >&5
-+echo "$as_me: error: cannot run test program while cross compiling
-+See \`config.log' for more details." >&2;}
-+   { (exit 1); exit 1; }; }
-+else
-+  cat >conftest.$ac_ext <<_ACEOF
-+/* confdefs.h.  */
-+_ACEOF
-+cat confdefs.h >>conftest.$ac_ext
-+cat >>conftest.$ac_ext <<_ACEOF
-+/* end confdefs.h.  */
-+
-+  int main()
-+  {
-+    int foo= -10; int bar= 10;
-+    __sync_fetch_and_add(&foo, bar);
-+    if (foo)
-+      return -1;
-+    bar= __sync_lock_test_and_set(&foo, bar);
-+    if (bar || foo != 10)
-+      return -1;
-+    bar= __sync_val_compare_and_swap(&bar, foo, 15);
-+    if (bar)
-+      return -1;
-+    return 0;
-+  }
-+
-+_ACEOF
-+rm -f conftest$ac_exeext
-+if { (ac_try="$ac_link"
-+case "(($ac_try" in
-+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-+  *) ac_try_echo=$ac_try;;
-+esac
-+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-+  (eval "$ac_link") 2>&5
-+  ac_status=$?
-+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-+  { (case "(($ac_try" in
-+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-+  *) ac_try_echo=$ac_try;;
-+esac
-+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-+  (eval "$ac_try") 2>&5
-+  ac_status=$?
-+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+  (exit $ac_status); }; }; then
-+  mysql_cv_atomic_builtins=yes
-+else
-+  echo "$as_me: program exited with status $ac_status" >&5
-+echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+( exit $ac_status )
-+mysql_cv_atomic_builtins=no
-+fi
-+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-+fi
-+
-+
-+fi
-+{ echo "$as_me:$LINENO: result: $mysql_cv_atomic_builtins" >&5
-+echo "${ECHO_T}$mysql_cv_atomic_builtins" >&6; }
-+
-+if test "x$mysql_cv_atomic_builtins" = xyes; then
-+
-+cat >>confdefs.h <<\_ACEOF
-+#define HAVE_ATOMIC_BUILTINS 1
-+_ACEOF
-+
-+fi
-+
- #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args.
- # Some versions of Unix only take 2 arguments.
- #AC_C_INLINE  Already checked in MySQL
-diff -ruN a/innobase/configure.in b/innobase/configure.in
---- a/innobase/configure.in    2009-01-30 06:42:15.000000000 +0900
-+++ b/innobase/configure.in    2009-05-06 15:40:47.000000000 +0900
-@@ -42,6 +42,31 @@
- AC_CHECK_FUNCS(sched_yield)
- AC_CHECK_FUNCS(fdatasync)
- AC_CHECK_FUNCS(localtime_r)
-+
-+# as http://lists.mysql.com/commits/40686 does
-+AC_CACHE_CHECK([whether the compiler provides atomic builtins],
-+               [mysql_cv_atomic_builtins], [AC_TRY_RUN([
-+  int main()
-+  {
-+    int foo= -10; int bar= 10;
-+    __sync_fetch_and_add(&foo, bar);
-+    if (foo)
-+      return -1;
-+    bar= __sync_lock_test_and_set(&foo, bar);
-+    if (bar || foo != 10)
-+      return -1;
-+    bar= __sync_val_compare_and_swap(&bar, foo, 15);
-+    if (bar)
-+      return -1;
-+    return 0;
-+  }
-+], [mysql_cv_atomic_builtins=yes], [mysql_cv_atomic_builtins=no])])
-+
-+if test "x$mysql_cv_atomic_builtins" = xyes; then
-+  AC_DEFINE(HAVE_ATOMIC_BUILTINS, 1,
-+            [Define to 1 if compiler provides atomic builtins.])
-+fi
-+
- #AC_CHECK_FUNCS(readdir_r) MySQL checks that it has also the right args.
- # Some versions of Unix only take 2 arguments.
- #AC_C_INLINE  Already checked in MySQL
-diff -ruN a/innobase/ib_config.h b/innobase/ib_config.h
---- a/innobase/ib_config.h     2009-01-30 07:05:03.000000000 +0900
-+++ b/innobase/ib_config.h     2009-05-06 15:40:47.000000000 +0900
-@@ -7,6 +7,9 @@
- /* Define to 1 if you have the <aio.h> header file. */
- #define HAVE_AIO_H 1
-+/* Define to 1 if compiler provides atomic builtins. */
-+#define HAVE_ATOMIC_BUILTINS 1
-+
- /* Define to 1 if you have the <dlfcn.h> header file. */
- #define HAVE_DLFCN_H 1
-diff -ruN a/innobase/ib_config.h.in b/innobase/ib_config.h.in
---- a/innobase/ib_config.h.in  2009-01-30 06:56:11.000000000 +0900
-+++ b/innobase/ib_config.h.in  2009-05-06 15:40:47.000000000 +0900
-@@ -6,6 +6,9 @@
- /* Define to 1 if you have the <aio.h> header file. */
- #undef HAVE_AIO_H
-+/* Define to 1 if compiler provides atomic builtins. */
-+#undef HAVE_ATOMIC_BUILTINS
-+
- /* Define to 1 if you have the <dlfcn.h> header file. */
- #undef HAVE_DLFCN_H
-diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
---- a/innobase/include/srv0srv.h       2009-05-06 15:38:01.000000000 +0900
-+++ b/innobase/include/srv0srv.h       2009-05-06 16:04:36.000000000 +0900
-@@ -90,6 +90,8 @@
- extern ulint  srv_mem_pool_size;
- extern ulint  srv_lock_table_size;
-+extern ibool  srv_thread_concurrency_timer_based;
-+
- extern ulint  srv_n_file_io_threads;
- extern ulint  srv_n_read_io_threads;
- extern ulint  srv_n_write_io_threads;
-diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
---- a/innobase/srv/srv0srv.c   2009-05-06 15:38:01.000000000 +0900
-+++ b/innobase/srv/srv0srv.c   2009-05-06 17:12:54.000000000 +0900
-@@ -267,6 +267,7 @@
- computer. Bigger computers need bigger values. Value 0 will disable the
- concurrency check. */
-+ibool srv_thread_concurrency_timer_based = TRUE;
- ulong srv_thread_concurrency  = 0;
- ulong   srv_commit_concurrency  = 0;
-@@ -1020,6 +1021,74 @@
- Puts an OS thread to wait if there are too many concurrent threads
- (>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
-+#ifdef HAVE_ATOMIC_BUILTINS
-+static void
-+enter_innodb_with_tickets(trx_t* trx)
-+{
-+      trx->declared_to_be_inside_innodb = TRUE;
-+      trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
-+      return;
-+}
-+
-+static void
-+srv_conc_enter_innodb_timer_based(trx_t* trx)
-+{
-+      lint    conc_n_threads;
-+      ibool   has_yielded = FALSE;
-+      ulint   has_slept = 0;
-+
-+      if (trx->declared_to_be_inside_innodb) {
-+              ut_print_timestamp(stderr);
-+              fputs(
-+"  InnoDB: Error: trying to declare trx to enter InnoDB, but\n"
-+"InnoDB: it already is declared.\n", stderr);
-+              trx_print(stderr, trx, 0);
-+              putc('\n', stderr);
-+      }
-+retry:
-+      if (srv_conc_n_threads < (lint) srv_thread_concurrency) {
-+              conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
-+              if (conc_n_threads <= (lint) srv_thread_concurrency) {
-+                      enter_innodb_with_tickets(trx);
-+                      return;
-+              }
-+              __sync_add_and_fetch(&srv_conc_n_threads, -1);
-+      }
-+      if (!has_yielded)
-+      {
-+              has_yielded = TRUE;
-+              os_thread_yield();
-+              goto retry;
-+      }
-+      if (trx->has_search_latch
-+          || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {
-+
-+              conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
-+              enter_innodb_with_tickets(trx);
-+              return;
-+      }
-+      if (has_slept < 2)
-+      {
-+              trx->op_info = "sleeping before entering InnoDB";
-+              os_thread_sleep(10000);
-+              trx->op_info = "";
-+              has_slept++;
-+      }
-+      conc_n_threads = __sync_add_and_fetch(&srv_conc_n_threads, 1);
-+      enter_innodb_with_tickets(trx);
-+      return;
-+}
-+
-+static void
-+srv_conc_exit_innodb_timer_based(trx_t* trx)
-+{
-+      __sync_add_and_fetch(&srv_conc_n_threads, -1);
-+      trx->declared_to_be_inside_innodb = FALSE;
-+      trx->n_tickets_to_enter_innodb = 0;
-+      return;
-+}
-+#endif
-+
- void
- srv_conc_enter_innodb(
- /*==================*/
-@@ -1043,6 +1112,13 @@
-               return;
-       }
-+#ifdef HAVE_ATOMIC_BUILTINS
-+      if (srv_thread_concurrency_timer_based) {
-+              srv_conc_enter_innodb_timer_based(trx);
-+              return;
-+      }
-+#endif
-+
-       os_fast_mutex_lock(&srv_conc_mutex);
- retry:
-       if (trx->declared_to_be_inside_innodb) {
-@@ -1196,6 +1272,15 @@
-               return;
-       }
-+      ut_ad(srv_conc_n_threads >= 0);
-+#ifdef HAVE_ATOMIC_BUILTINS
-+      if (srv_thread_concurrency_timer_based) {
-+              __sync_add_and_fetch(&srv_conc_n_threads, 1);
-+              trx->declared_to_be_inside_innodb = TRUE;
-+              trx->n_tickets_to_enter_innodb = 1;
-+              return;
-+      }
-+#endif
-       os_fast_mutex_lock(&srv_conc_mutex);
-       srv_conc_n_threads++;
-@@ -1227,8 +1312,16 @@
-               return;
-       }
-+#ifdef HAVE_ATOMIC_BUILTINS
-+      if (srv_thread_concurrency_timer_based) {
-+              srv_conc_exit_innodb_timer_based(trx);
-+              return;
-+      }
-+#endif
-+
-       os_fast_mutex_lock(&srv_conc_mutex);
-+      ut_ad(srv_conc_n_threads > 0);
-       srv_conc_n_threads--;
-       trx->declared_to_be_inside_innodb = FALSE;
-       trx->n_tickets_to_enter_innodb = 0;
-diff -ruN a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
---- a/innobase/srv/srv0start.c 2009-05-06 15:38:01.000000000 +0900
-+++ b/innobase/srv/srv0start.c 2009-05-06 17:22:26.000000000 +0900
-@@ -1040,6 +1040,11 @@
-               return(DB_ERROR);
-       }
-+#ifdef HAVE_ATOMIC_BUILTINS
-+      fprintf(stderr,
-+              "InnoDB: use atomic builtins.\n");
-+#endif
-+
-       /* Since InnoDB does not currently clean up all its internal data
-          structures in MySQL Embedded Server Library server_end(), we
-          print an error message if someone tries to start up InnoDB a
-diff -ruN a/patch_info/innodb_thread_concurrency_timer_based.info b/patch_info/innodb_thread_concurrency_timer_based.info
---- /dev/null  1970-01-01 09:00:00.000000000 +0900
-+++ b/patch_info/innodb_thread_concurrency_timer_based.info    2009-05-06 17:17:12.000000000 +0900
-@@ -0,0 +1,6 @@
-+File=thread_concurrency_timer_based.patch
-+Name=Use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)
-+Version=1.0
-+Author=Percona <info@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:38:01.000000000 +0900
-+++ b/sql/ha_innodb.cc 2009-05-06 15:54:08.000000000 +0900
-@@ -152,6 +152,7 @@
-      innobase_open_files;
- long innobase_read_io_threads, innobase_write_io_threads;
-+my_bool innobase_thread_concurrency_timer_based;
- long innobase_extra_rsegments;
- longlong innobase_buffer_pool_size, innobase_log_file_size;
-@@ -1477,6 +1478,9 @@
-       srv_n_log_files = (ulint) innobase_log_files_in_group;
-       srv_log_file_size = (ulint) innobase_log_file_size;
-+      srv_thread_concurrency_timer_based =
-+              (ibool) innobase_thread_concurrency_timer_based;
-+
- #ifdef UNIV_LOG_ARCHIVE
-       srv_log_archive_on = (ulint) innobase_log_archive;
- #endif /* UNIV_LOG_ARCHIVE */
-diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h
---- a/sql/ha_innodb.h  2009-05-06 15:38:01.000000000 +0900
-+++ b/sql/ha_innodb.h  2009-05-06 15:55:50.000000000 +0900
-@@ -205,6 +205,7 @@
- extern long innobase_buffer_pool_awe_mem_mb;
- extern long innobase_file_io_threads, innobase_lock_wait_timeout;
- extern long innobase_read_io_threads, innobase_write_io_threads;
-+extern my_bool innobase_thread_concurrency_timer_based;
- extern long innobase_extra_rsegments;
- extern long innobase_force_recovery;
- extern long innobase_open_files;
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc    2009-05-06 15:38:01.000000000 +0900
-+++ b/sql/mysqld.cc    2009-05-06 16:22:06.000000000 +0900
-@@ -5096,6 +5096,7 @@
-   OPT_INNODB_ADAPTIVE_CHECKPOINT,
-   OPT_INNODB_READ_IO_THREADS,
-   OPT_INNODB_WRITE_IO_THREADS,
-+  OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED,
-   OPT_INNODB_EXTRA_RSEGMENTS,
-   OPT_INNODB_DICT_SIZE_LIMIT,
-   OPT_INNODB_ADAPTIVE_HASH_INDEX,
-@@ -5455,6 +5456,11 @@
-    "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_thread_concurrency_timer_based", OPT_INNODB_THREAD_CONCURRENCY_TIMER_BASED,
-+   "Use InnoDB timer based concurrency throttling. ",
-+   (gptr*) &innobase_thread_concurrency_timer_based,
-+   (gptr*) &innobase_thread_concurrency_timer_based,
-+   0, GET_BOOL, NO_ARG, 0, 0, 0, 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,
-diff -ruN a/sql/set_var.cc b/sql/set_var.cc
---- a/sql/set_var.cc   2009-05-06 15:38:01.000000000 +0900
-+++ b/sql/set_var.cc   2009-05-06 16:02:27.000000000 +0900
-@@ -1063,6 +1063,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},
-+  {"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},
-   {sys_innodb_io_pattern_trace.name, (char*) &sys_innodb_io_pattern_trace, SHOW_SYS},
diff --git a/mysql-microslow.patch b/mysql-microslow.patch
deleted file mode 100644 (file)
index c02227d..0000000
+++ /dev/null
@@ -1,699 +0,0 @@
-diff -r 0b1f42e1aacf sql/event_scheduler.cc
---- a/sql/event_scheduler.cc   Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/event_scheduler.cc   Thu Dec 04 08:55:29 2008 -0800
-@@ -192,6 +192,7 @@
-   thd->client_capabilities|= CLIENT_MULTI_RESULTS;
-   pthread_mutex_lock(&LOCK_thread_count);
-   thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
-+  thd->write_to_slow_log = TRUE;
-   pthread_mutex_unlock(&LOCK_thread_count);
-   /*
-diff -r 0b1f42e1aacf sql/filesort.cc
---- a/sql/filesort.cc  Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/filesort.cc  Thu Dec 04 08:55:29 2008 -0800
-@@ -188,6 +188,7 @@
-   {
-     status_var_increment(thd->status_var.filesort_scan_count);
-   }
-+  thd->query_plan_flags|= QPLAN_FILESORT;
- #ifdef CAN_TRUST_RANGE
-   if (select && select->quick && select->quick->records > 0L)
-   {
-@@ -253,6 +254,7 @@
-   }
-   else
-   {
-+    thd->query_plan_flags|= QPLAN_FILESORT_DISK;
-     if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
-     {
-       x_free(table_sort.buffpek);
-@@ -1202,6 +1204,7 @@
-   DBUG_ENTER("merge_buffers");
-   status_var_increment(current_thd->status_var.filesort_merge_passes);
-+  current_thd->query_plan_fsort_passes++;
-   if (param->not_killable)
-   {
-     killed= &not_killable;
-diff -r 0b1f42e1aacf sql/log.cc
---- a/sql/log.cc       Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/log.cc       Thu Dec 04 08:55:29 2008 -0800
-@@ -963,7 +963,7 @@
-     /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
-     user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
-                              sctx->priv_user ? sctx->priv_user : "", "[",
--                             sctx->user ? sctx->user : "", "] @ ",
-+                             sctx->user ? sctx->user : (thd->slave_thread ? "SQL_SLAVE" : ""), "] @ ",
-                              sctx->host ? sctx->host : "", " [",
-                              sctx->ip ? sctx->ip : "", "]", NullS) -
-                     user_host_buff);
-@@ -985,6 +985,13 @@
-       query= command_name[thd->command].str;
-       query_length= command_name[thd->command].length;
-     }
-+
-+    if (!query_length) 
-+    { 
-+      thd->sent_row_count= thd->examined_row_count= 0; 
-+      thd->query_plan_flags= QPLAN_NONE; 
-+      thd->query_plan_fsort_passes= 0; 
-+    } 
-     for (current_handler= slow_log_handler_list; *current_handler ;)
-       error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
-@@ -2242,16 +2249,31 @@
-       if (my_b_write(&log_file, (uchar*) "\n", 1))
-         tmp_errno= errno;
-     }
-+    
-     /* For slow query log */
-     sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
-     sprintf(lock_time_buff,  "%.6f", ulonglong2double(lock_utime)/1000000.0);
-     if (my_b_printf(&log_file,
--                    "# Query_time: %s  Lock_time: %s"
--                    " Rows_sent: %lu  Rows_examined: %lu\n",
-+                    "# Thread_id: %lu  Schema: %s\n" \
-+                    "# Query_time: %s  Lock_time: %s  Rows_sent: %lu  Rows_examined: %lu\n",
-+                    (ulong) thd->thread_id, (thd->db ? thd->db : ""),
-                     query_time_buff, lock_time_buff,
-                     (ulong) thd->sent_row_count,
-                     (ulong) thd->examined_row_count) == (uint) -1)
-       tmp_errno= errno;
-+     if ((thd->variables.log_slow_verbosity & SLOG_V_QUERY_PLAN) && 
-+         my_b_printf(&log_file, 
-+                     "# QC_Hit: %s  Full_scan: %s  Full_join: %s  Tmp_table: %s  Tmp_table_on_disk: %s\n" \
-+                     "# Filesort: %s  Filesort_on_disk: %s  Merge_passes: %lu\n", 
-+                     ((thd->query_plan_flags & QPLAN_QC) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_FULL_SCAN) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_FULL_JOIN) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_TMP_TABLE) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_TMP_DISK) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_FILESORT) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_FILESORT_DISK) ? "Yes" : "No"), 
-+                     thd->query_plan_fsort_passes) == (uint) -1) 
-+       tmp_errno=errno; 
-     if (thd->db && strcmp(thd->db, db))
-     {                                         // Database changed
-       if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
-diff -r 0b1f42e1aacf sql/mysql_priv.h
---- a/sql/mysql_priv.h Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/mysql_priv.h Thu Dec 04 08:55:29 2008 -0800
-@@ -597,6 +597,73 @@
- #define WEEK_FIRST_WEEKDAY   4
- #define STRING_BUFFER_USUAL_SIZE 80
-+
-+/* Slow log */
-+
-+struct msl_opts
-+{
-+  ulong val;
-+  const char *name;
-+};
-+
-+#define SLOG_V_QUERY_PLAN     1 << 1
-+/* ... */
-+#define SLOG_V_INVALID        1 << 31
-+#define SLOG_V_NONE           1 << 0
-+
-+static const struct msl_opts slog_verb[]= 
-+{
-+  /* Basic flags */
-+
-+  { SLOG_V_QUERY_PLAN, "query_plan" },
-+
-+  /* End of baisc flags */
-+
-+  { 0, "" },
-+
-+  /* Complex flags */
-+
-+  { SLOG_V_QUERY_PLAN, "standard" },
-+  { SLOG_V_INVALID, "full" },
-+
-+  /* End of complex flags */
-+
-+  { SLOG_V_INVALID, (char *)0 }
-+};
-+
-+#define QPLAN_NONE            0
-+#define QPLAN_QC              1 << 0
-+#define QPLAN_QC_NO           1 << 1
-+#define QPLAN_FULL_SCAN       1 << 2
-+#define QPLAN_FULL_JOIN       1 << 3
-+#define QPLAN_TMP_TABLE       1 << 4
-+#define QPLAN_TMP_DISK        1 << 5
-+#define QPLAN_FILESORT        1 << 6
-+#define QPLAN_FILESORT_DISK   1 << 7
-+/* ... */
-+#define QPLAN_MAX             1 << 31
-+
-+#define SLOG_F_QC_NO          QPLAN_QC_NO
-+#define SLOG_F_FULL_SCAN      QPLAN_FULL_SCAN
-+#define SLOG_F_FULL_JOIN      QPLAN_FULL_JOIN
-+#define SLOG_F_TMP_TABLE      QPLAN_TMP_TABLE
-+#define SLOG_F_TMP_DISK       QPLAN_TMP_DISK
-+#define SLOG_F_FILESORT       QPLAN_FILESORT
-+#define SLOG_F_FILESORT_DISK  QPLAN_FILESORT_DISK
-+#define SLOG_F_INVALID        1 << 31
-+#define SLOG_F_NONE           0
-+
-+static const struct msl_opts slog_filter[]= 
-+{
-+  { SLOG_F_QC_NO,         "qc_miss" },
-+  { SLOG_F_FULL_SCAN,     "full_scan" },
-+  { SLOG_F_FULL_JOIN,     "full_join" },
-+  { SLOG_F_TMP_TABLE,     "tmp_table" },
-+  { SLOG_F_TMP_DISK,      "tmp_table_on_disk" },
-+  { SLOG_F_FILESORT,      "filesort" },
-+  { SLOG_F_FILESORT_DISK, "filesort_on_disk" },
-+  { SLOG_F_INVALID,       (char *)0 }
-+};
- /*
-   Some defines for exit codes for ::is_equal class functions.
---- mysql-5.1.49/sql/mysqld.cc~        2010-07-24 15:19:16.000000000 +0300
-+++ mysql-5.1.49/sql/mysqld.cc 2010-07-24 15:22:23.181784212 +0300
-@@ -5553,6 +5553,9 @@
-   OPT_SECURE_FILE_PRIV,
-   OPT_MIN_EXAMINED_ROW_LIMIT,
-   OPT_LOG_SLOW_SLAVE_STATEMENTS,
-+  OPT_LOG_SLOW_RATE_LIMIT, 
-+  OPT_LOG_SLOW_VERBOSITY, 
-+  OPT_LOG_SLOW_FILTER, 
- #if defined(ENABLED_DEBUG_SYNC)
-   OPT_DEBUG_SYNC_TIMEOUT,
- #endif /* defined(ENABLED_DEBUG_SYNC) */
-@@ -6819,6 +6819,17 @@
-    "The minimum percentage of warm blocks in key cache.",
-    &dflt_key_cache_var.param_division_limit, NULL, NULL,
-    (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0},
-+  {"log_slow_filter", OPT_LOG_SLOW_FILTER,
-+   "Log only the queries that followed certain execution plan. Multiple flags allowed in a comma-separated string. [qc_miss, full_scan, full_join, tmp_table, tmp_table_on_disk, filesort, filesort_on_disk]",
-+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_F_NONE, 0, 0},
-+  {"log_slow_rate_limit", OPT_LOG_SLOW_RATE_LIMIT,
-+   "Rate limit statement writes to slow log to only those from every (1/log_slow_rate_limit) session.",
-+   (uchar**) &global_system_variables.log_slow_rate_limit,
-+   (uchar**) &max_system_variables.log_slow_rate_limit, 0, GET_ULONG,
-+   REQUIRED_ARG, 1, 1, ~0L, 0, 1L, 0},
-+  {"log_slow_verbosity", OPT_LOG_SLOW_VERBOSITY,
-+   "Choose how verbose the messages to your slow log will be. Multiple flags allowed in a comma-separated string. [microtime, query_plan, innodb]",
-+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_V_NONE, 0, 0},
-   {"long_query_time", OPT_LONG_QUERY_TIME,
-    "Log all queries that have taken more than long_query_time seconds to "
-    "execute. The argument will be treated as a decimal value with "
-@@ -7556,6 +7570,10 @@
-   global_system_variables.old_passwords= 0;
-   global_system_variables.old_alter_table= 0;
-   global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
-+  
-+  global_system_variables.log_slow_verbosity= SLOG_V_NONE; 
-+  global_system_variables.log_slow_filter= SLOG_F_NONE; 
-+  
-   /*
-     Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
-     when collecting index statistics for MyISAM tables.
-@@ -8007,6 +8025,24 @@
-   case OPT_BOOTSTRAP:
-     opt_noacl=opt_bootstrap=1;
-     break;
-+  case OPT_LOG_SLOW_FILTER: 
-+    if ((global_system_variables.log_slow_filter=  
-+          msl_flag_resolve_by_name(slog_filter, argument, 
-+                                   SLOG_F_NONE, SLOG_F_INVALID)) == SLOG_F_INVALID) 
-+    { 
-+      fprintf(stderr,"Invalid argument to log_slow_filter\n"); 
-+      exit(1); 
-+    } 
-+    break; 
-+  case OPT_LOG_SLOW_VERBOSITY: 
-+    if ((global_system_variables.log_slow_verbosity=  
-+         msl_flag_resolve_by_name(slog_verb, argument, 
-+                                  SLOG_V_NONE, SLOG_V_INVALID)) == SLOG_V_INVALID) 
-+    { 
-+      fprintf(stderr,"Invalid argument to log_slow_verbosity\n"); 
-+      exit(1); 
-+    } 
-+    break; 
-   case OPT_SERVER_ID:
-     server_id_supplied = 1;
-     break;
-diff -r 0b1f42e1aacf sql/set_var.cc
---- a/sql/set_var.cc   Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/set_var.cc   Thu Dec 04 08:55:29 2008 -0800
-@@ -336,6 +336,20 @@
-                                             &SV::max_join_size,
-                                             fix_max_join_size);
- #endif
-+static sys_var_thd_ulong  sys_log_slow_rate_limit(&vars, "log_slow_rate_limit", 
-+              &SV::log_slow_rate_limit); 
-+static sys_var_thd_msl_flag sys_log_slow_filter(&vars, "log_slow_filter", 
-+              &SV::log_slow_filter, 
-+                                       SLOG_F_NONE, 
-+                                       SLOG_F_NONE, 
-+                                       SLOG_F_INVALID, 
-+                                       slog_filter); 
-+static sys_var_thd_msl_flag sys_log_slow_verbosity(&vars, "log_slow_verbosity", 
-+              &SV::log_slow_verbosity, 
-+                                       SLOG_V_NONE, 
-+                                       SLOG_V_NONE, 
-+                                       SLOG_V_INVALID, 
-+                                       slog_verb); 
- static sys_var_long_ptr_global
- sys_max_prepared_stmt_count(&vars, "max_prepared_stmt_count",
-                             &max_prepared_stmt_count,
-@@ -3631,6 +3645,192 @@
- #endif
- }
-+/* Slow log stuff */
-+
-+ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len)
-+{
-+  ulong i;
-+  
-+  for (i=0; opts[i].name; i++)
-+  {
-+    if (!my_strnncoll(&my_charset_latin1,
-+                      (const uchar *)name, len,
-+                      (const uchar *)opts[i].name, strlen(opts[i].name)))
-+      return opts[i].val;
-+  }
-+  return opts[i].val;
-+}
-+
-+ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list, 
-+                               const ulong none_val, const ulong invalid_val)
-+{
-+  const char *p, *e;
-+  ulong val= none_val;
-+  
-+  if (!*names_list)
-+    return val;
-+  
-+  for (p= e= names_list; ; e++)
-+  {
-+    ulong i;
-+    
-+    if (*e != ',' && *e)
-+      continue;
-+    for (i=0; opts[i].name; i++)
-+    {
-+      if (!my_strnncoll(&my_charset_latin1,
-+                        (const uchar *)p, e - p,
-+                        (const uchar *)opts[i].name, strlen(opts[i].name)))
-+      {
-+        val= val | opts[i].val;
-+        break;
-+      }
-+    }
-+    if (opts[i].val == invalid_val)
-+      return invalid_val;
-+    if (!*e)
-+      break;
-+    p= e + 1;
-+  }
-+  return val;
-+}
-+
-+const char *msl_option_get_name(const struct msl_opts *opts, ulong val)
-+{
-+  for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
-+  {
-+    if (opts[i].val == val)
-+      return opts[i].name;
-+  }
-+  return "*INVALID*";
-+}
-+
-+char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val)
-+{
-+  uint offset= 0;
-+  
-+  *buf= '\0';
-+  for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
-+  {
-+    if (opts[i].val & val)
-+      offset+= snprintf(buf+offset, STRING_BUFFER_USUAL_SIZE - offset - 1,
-+                        "%s%s", (offset ? "," : ""), opts[i].name);
-+  }
-+  return buf;
-+}
-+
-+/****************************************************************************
-+ Functions to handle log_slow_verbosity
-+****************************************************************************/
-+
-+/* Based upon sys_var::check_enum() */
-+
-+bool sys_var_thd_msl_option::check(THD *thd, set_var *var)
-+{
-+  char buff[STRING_BUFFER_USUAL_SIZE];
-+  String str(buff, sizeof(buff), &my_charset_latin1), *res;
-+
-+  if (var->value->result_type() == STRING_RESULT)
-+  {
-+    ulong verb= this->invalid_val;
-+    if (!(res=var->value->val_str(&str)) ||
-+            (var->save_result.ulong_value=
-+          (ulong) (verb= msl_option_resolve_by_name(this->opts, res->ptr(), res->length()))) == this->invalid_val)
-+      goto err;
-+    return 0;
-+  }
-+
-+err:
-+  my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
-+  return 1;
-+}
-+
-+uchar *sys_var_thd_msl_option::value_ptr(THD *thd, enum_var_type type,
-+                                      LEX_STRING *base)
-+{
-+  ulong val;
-+  val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
-+        thd->variables.*offset);
-+  const char *verbosity= msl_option_get_name(this->opts, val);
-+  return (uchar *) verbosity;
-+}
-+
-+
-+void sys_var_thd_msl_option::set_default(THD *thd, enum_var_type type)
-+{
-+  if (type == OPT_GLOBAL)
-+    global_system_variables.*offset= (ulong) this->default_val;
-+  else
-+    thd->variables.*offset= (ulong) (global_system_variables.*offset);
-+}
-+
-+
-+bool sys_var_thd_msl_option::update(THD *thd, set_var *var)
-+{
-+  if (var->type == OPT_GLOBAL)
-+    global_system_variables.*offset= var->save_result.ulong_value;
-+  else
-+    thd->variables.*offset= var->save_result.ulong_value;
-+  return 0;
-+}
-+
-+/****************************************************************************
-+ Functions to handle log_slow_filter
-+****************************************************************************/
-+  
-+/* Based upon sys_var::check_enum() */
-+
-+bool sys_var_thd_msl_flag::check(THD *thd, set_var *var)
-+{
-+  char buff[2 * STRING_BUFFER_USUAL_SIZE];
-+  String str(buff, sizeof(buff), &my_charset_latin1), *res;
-+
-+  if (var->value->result_type() == STRING_RESULT)
-+  {
-+    ulong filter= this->none_val;
-+    if (!(res=var->value->val_str(&str)) ||
-+       (var->save_result.ulong_value=
-+          (ulong) (filter= msl_flag_resolve_by_name(this->flags, res->ptr(), this->none_val, 
-+                                                    this->invalid_val))) == this->invalid_val)
-+      goto err;
-+    return 0;
-+  }
-+
-+err:
-+  my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
-+  return 1;
-+}
-+
-+uchar *sys_var_thd_msl_flag::value_ptr(THD *thd, enum_var_type type,
-+                                      LEX_STRING *base)
-+{
-+  ulong val;
-+  val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
-+        thd->variables.*offset);
-+  msl_flag_get_name(this->flags, this->flags_string, val);
-+  return (uchar *) this->flags_string;
-+}
-+
-+
-+void sys_var_thd_msl_flag::set_default(THD *thd, enum_var_type type)
-+{
-+  if (type == OPT_GLOBAL)
-+    global_system_variables.*offset= (ulong) this->default_val;
-+  else
-+    thd->variables.*offset= (ulong) (global_system_variables.*offset);
-+}
-+
-+
-+bool sys_var_thd_msl_flag::update(THD *thd, set_var *var)
-+{
-+  if (var->type == OPT_GLOBAL)
-+    global_system_variables.*offset= var->save_result.ulong_value;
-+  else
-+    thd->variables.*offset= var->save_result.ulong_value;
-+  return 0;
-+}
-+
-+
- /****************************************************************************
-  Functions to handle table_type
- ****************************************************************************/
-diff -r 0b1f42e1aacf sql/set_var.h
---- a/sql/set_var.h    Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/set_var.h    Thu Dec 04 08:55:29 2008 -0800
-@@ -1057,6 +1057,68 @@
-   bool update(THD *thd, set_var *var);
- };
-+class sys_var_thd_msl_option :public sys_var_thd
-+{
-+protected:
-+  ulong SV::*offset;
-+  const ulong none_val;
-+  const ulong default_val;
-+  const ulong invalid_val;
-+  const struct msl_opts *opts;
-+public:
-+  sys_var_thd_msl_option(sys_var_chain *chain, const char *name_arg,
-+                         ulong SV::*offset_arg,
-+                         const ulong none_val_arg,
-+                         const ulong default_val_arg,
-+                         const ulong invalid_val_arg,
-+                         const struct msl_opts *opts_arg)
-+    :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
-+     default_val(default_val_arg), invalid_val(invalid_val_arg), 
-+     opts(opts_arg)
-+  { chain_sys_var(chain); }
-+  bool check(THD *thd, set_var *var);
-+  SHOW_TYPE show_type() { return SHOW_CHAR; }
-+  bool check_update_type(Item_result type)
-+  {
-+    return type != STRING_RESULT;             /* Only accept strings */
-+  }
-+  void set_default(THD *thd, enum_var_type type);
-+  bool update(THD *thd, set_var *var);
-+  uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-+};
-+
-+
-+class sys_var_thd_msl_flag :public sys_var_thd
-+{
-+protected:
-+  char flags_string[2 * STRING_BUFFER_USUAL_SIZE];
-+  ulong SV::*offset;
-+  const ulong none_val;
-+  const ulong default_val;
-+  const ulong invalid_val;
-+  const struct msl_opts *flags;
-+public:
-+  sys_var_thd_msl_flag(sys_var_chain *chain, const char *name_arg,
-+                       ulong SV::*offset_arg, 
-+                       const ulong none_val_arg, 
-+                       const ulong default_val_arg, 
-+                       const ulong invalid_val_arg,
-+                       const struct msl_opts *flags_arg)
-+    :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
-+     default_val(default_val_arg), invalid_val(invalid_val_arg), 
-+     flags(flags_arg)
-+  { chain_sys_var(chain); }
-+  bool check(THD *thd, set_var *var);
-+  SHOW_TYPE show_type() { return SHOW_CHAR; }
-+  bool check_update_type(Item_result type)
-+  {
-+    return type != STRING_RESULT;             /* Only accept strings */
-+  }
-+  void set_default(THD *thd, enum_var_type type);
-+  bool update(THD *thd, set_var *var);
-+  uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-+};
-+
- /**
-   Handler for setting the system variable --read-only.
-@@ -1323,3 +1385,10 @@
- bool process_key_caches(process_key_cache_t func);
- void delete_elements(I_List<NAMED_LIST> *list,
-                    void (*free_element)(const char*, uchar*));
-+
-+/* Slow log functions */
-+ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len);
-+ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list, 
-+                               const ulong none_val, const ulong invalid_val);
-+const char *msl_option_get_name(const struct msl_opts *opts, ulong val);
-+char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val);
-diff -r 0b1f42e1aacf sql/slave.cc
---- a/sql/slave.cc     Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/slave.cc     Thu Dec 04 08:55:29 2008 -0800
-@@ -1561,6 +1561,7 @@
-     + MAX_LOG_EVENT_HEADER;  /* note, incr over the global not session var */
-   thd->slave_thread = 1;
-   thd->enable_slow_log= opt_log_slow_slave_statements;
-+  thd->write_to_slow_log= opt_log_slow_slave_statements;
-   set_slave_thread_options(thd);
-   thd->client_capabilities = CLIENT_LOCAL_FILES;
-   pthread_mutex_lock(&LOCK_thread_count);
-diff -r 0b1f42e1aacf sql/sql_cache.cc
---- a/sql/sql_cache.cc Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_cache.cc Thu Dec 04 08:55:29 2008 -0800
-@@ -1465,6 +1465,7 @@
-   thd->limit_found_rows = query->found_rows();
-   thd->status_var.last_query_cost= 0.0;
-+  thd->query_plan_flags|= QPLAN_QC;
-   if (!thd->main_da.is_set())
-     thd->main_da.disable_status();
-@@ -1473,6 +1474,7 @@
- err_unlock:
-   STRUCT_UNLOCK(&structure_guard_mutex);
- err:
-+  thd->query_plan_flags|= QPLAN_QC_NO;
-   DBUG_RETURN(0);                             // Query was not cached
- }
-diff -r 0b1f42e1aacf sql/sql_class.h
---- a/sql/sql_class.h  Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_class.h  Thu Dec 04 08:55:29 2008 -0800
-@@ -396,6 +396,11 @@
-   DATE_TIME_FORMAT *datetime_format;
-   DATE_TIME_FORMAT *time_format;
-   my_bool sysdate_is_now;
-+
-+  ulong log_slow_rate_limit; 
-+  ulong log_slow_filter; 
-+  ulong log_slow_verbosity; 
-+            
- };
-@@ -1339,6 +1344,11 @@
-   
-   thr_lock_type update_lock_default;
-   Delayed_insert *di;
-+
-+  bool       write_to_slow_log; 
-+ 
-+  ulong      query_plan_flags; 
-+  ulong      query_plan_fsort_passes; 
-   /* <> 0 if we are inside of trigger or stored function. */
-   uint in_sub_stmt;
-diff -r 0b1f42e1aacf sql/sql_connect.cc
---- a/sql/sql_connect.cc       Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_connect.cc       Thu Dec 04 08:55:29 2008 -0800
-@@ -1124,6 +1124,15 @@
-     prepare_new_connection_state(thd);
-+    /* 
-+      If rate limiting of slow log writes is enabled, decide whether to log this 
-+      new thread's queries or not. Uses extremely simple algorithm. :) 
-+    */ 
-+    thd->write_to_slow_log= FALSE; 
-+    if (thd->variables.log_slow_rate_limit <= 1 ||  
-+        (thd->thread_id % thd->variables.log_slow_rate_limit) == 0) 
-+         thd->write_to_slow_log= TRUE; 
-+
-     while (!net->error && net->vio != 0 &&
-            !(thd->killed == THD::KILL_CONNECTION))
-     {
-diff -r 0b1f42e1aacf sql/sql_parse.cc
---- a/sql/sql_parse.cc Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_parse.cc Thu Dec 04 08:55:29 2008 -0800
-@@ -1692,6 +1692,27 @@
-   if (unlikely(thd->in_sub_stmt))
-     DBUG_VOID_RETURN;                           // Don't set time for sub stmt
-+  /* Follow the slow log filter configuration. */ 
-+  if (thd->variables.log_slow_filter != SLOG_F_NONE &&  
-+      (!(thd->variables.log_slow_filter & thd->query_plan_flags) || 
-+       ((thd->variables.log_slow_filter & SLOG_F_QC_NO) &&  
-+        (thd->query_plan_flags & QPLAN_QC)))) 
-+    DBUG_VOID_RETURN; 
-+ 
-+  /* 
-+    Low long_query_time value most likely means user is debugging stuff and even  
-+    though some thread's queries are not supposed to be logged b/c of the rate  
-+    limit, if one of them takes long enough (>= 1 second) it will be sensible  
-+    to make an exception and write to slow log anyway. 
-+  */ 
-+  if (thd->write_to_slow_log != TRUE && thd->variables.long_query_time < 1000000 && 
-+      (ulong) (thd->start_utime - thd->utime_after_lock) >= 1000000) 
-+    thd->write_to_slow_log= TRUE; 
-+ 
-+  /* Do not log this thread's queries due to rate limiting. */ 
-+  if (thd->write_to_slow_log != TRUE) 
-+    DBUG_VOID_RETURN; 
-+
-   /*
-     Do not log administrative statements unless the appropriate option is
-     set; do not log into slow log if reading from backup.
-@@ -5773,6 +5794,9 @@
-   thd->total_warn_count=0;                    // Warnings for this query
-   thd->rand_used= 0;
-   thd->sent_row_count= thd->examined_row_count= 0;
-+
-+  thd->query_plan_flags= QPLAN_NONE; 
-+  thd->query_plan_fsort_passes= 0; 
-   /*
-     Because we come here only for start of top-statements, binlog format is
-diff -r 0b1f42e1aacf sql/sql_select.cc
---- a/sql/sql_select.cc        Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_select.cc        Thu Dec 04 08:55:29 2008 -0800
-@@ -6480,7 +6480,10 @@
-         {
-           join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
-           if (statistics)
-+          {
-             status_var_increment(join->thd->status_var.select_scan_count);
-+            join->thd->query_plan_flags|= QPLAN_FULL_SCAN;
-+          }
-         }
-       }
-       else
-@@ -6494,7 +6497,10 @@
-         {
-           join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
-           if (statistics)
-+          {
-             status_var_increment(join->thd->status_var.select_full_join_count);
-+            join->thd->query_plan_flags|= QPLAN_FULL_JOIN;
-+          }
-         }
-       }
-       if (!table->no_keyread)
-@@ -9638,6 +9644,7 @@
-               (ulong) rows_limit,test(group)));
-   status_var_increment(thd->status_var.created_tmp_tables);
-+  thd->query_plan_flags|= QPLAN_TMP_TABLE;
-   if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
-     temp_pool_slot = bitmap_lock_set_next(&temp_pool);
-@@ -10508,6 +10515,7 @@
-     goto err;
-   }
-   status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
-+  table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
-   share->db_record_offset= 1;
-   DBUG_RETURN(0);
-  err:
diff --git a/mysql-mysql-test.patch b/mysql-mysql-test.patch
deleted file mode 100644 (file)
index 7fce8e0..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
---- a/mysql-test/r/information_schema.result   2009-05-07 19:31:26.000000000 +0000
-+++ b/mysql-test/r/information_schema.result   2009-05-07 19:32:59.000000000 +0000
-@@ -60,6 +60,7 @@
- USER_STATISTICS
- VIEWS
- INNODB_IO_PATTERN
-+INNODB_RSEG
- columns_priv
- db
- func
-@@ -743,7 +744,7 @@
- CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
- CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
- count(*)
--109
-+110
- drop view a2, a1;
- drop table t_crashme;
- select table_schema,table_name, column_name from
-@@ -819,7 +820,7 @@
- flush privileges;
- SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
- table_schema  count(*)
--information_schema    24
-+information_schema    25
- mysql 17
- create table t1 (i int, j int);
- create trigger trg1 before insert on t1 for each row
-@@ -1228,6 +1229,7 @@
- USER_STATISTICS       USER
- VIEWS TABLE_SCHEMA
- INNODB_IO_PATTERN     SPACE
-+INNODB_RSEG   RSEG_ID
- SELECT t.table_name, c1.column_name
- FROM information_schema.tables t
- INNER JOIN
-@@ -1267,6 +1269,7 @@
- USER_STATISTICS       USER
- VIEWS TABLE_SCHEMA
- INNODB_IO_PATTERN     SPACE
-+INNODB_RSEG   RSEG_ID
- SELECT MAX(table_name) FROM information_schema.tables;
- MAX(table_name)
- VIEWS
-@@ -1342,6 +1345,7 @@
- INDEX_STATISTICS      information_schema.INDEX_STATISTICS     1
- INNODB_BUFFER_POOL_CONTENT    information_schema.INNODB_BUFFER_POOL_CONTENT   1
- INNODB_IO_PATTERN     information_schema.INNODB_IO_PATTERN    1
-+INNODB_RSEG   information_schema.INNODB_RSEG  1
- KEY_COLUMN_USAGE      information_schema.KEY_COLUMN_USAGE     1
- PROCESSLIST   information_schema.PROCESSLIST  1
- PROFILING     information_schema.PROFILING    1
---- a/mysql-test/r/information_schema_db.result        2009-05-07 19:31:27.000000000 +0000
-+++ b/mysql-test/r/information_schema_db.result        2009-05-07 19:35:01.000000000 +0000
-@@ -29,6 +29,7 @@
- USER_STATISTICS
- VIEWS
- INNODB_IO_PATTERN
-+INNODB_RSEG
- show tables from INFORMATION_SCHEMA like 'T%';
- Tables_in_information_schema (T%)
- TABLES
---- a/mysql-test/r/mysqlshow.result    2009-05-07 19:31:26.000000000 +0000
-+++ b/mysql-test/r/mysqlshow.result    2009-05-07 19:36:32.000000000 +0000
-@@ -103,6 +103,7 @@
- | USER_STATISTICS                       |
- | VIEWS                                 |
- | INNODB_IO_PATTERN                     |
-+| INNODB_RSEG                           |
- +---------------------------------------+
- Database: INFORMATION_SCHEMA
- +---------------------------------------+
-@@ -132,6 +133,7 @@
- | USER_STATISTICS                       |
- | VIEWS                                 |
- | INNODB_IO_PATTERN                     |
-+| INNODB_RSEG                           |
- +---------------------------------------+
- Wildcard: inf_rmation_schema
- +--------------------+
---- a/mysql-test/r/profiling.result    2009-05-28 19:39:42.000000000 +0000
-+++ b/mysql-test/r/profiling.result    2009-05-28 19:40:14.000000000 +0000
-@@ -6,6 +6,8 @@
- Variable_name Value
- profiling     OFF
- profiling_history_size        15
-+profiling_server      OFF
-+profiling_use_getrusage       OFF
- select @@profiling;
- @@profiling
- 0
-@@ -16,12 +18,16 @@
- Variable_name Value
- profiling     OFF
- profiling_history_size        100
-+profiling_server      OFF
-+profiling_use_getrusage       OFF
- set session profiling = ON;
- set session profiling_history_size=30;
- show session variables like 'profil%';
- Variable_name Value
- profiling     ON
- profiling_history_size        30
-+profiling_server      OFF
-+profiling_use_getrusage       OFF
- select @@profiling;
- @@profiling
- 1
diff --git a/mysql-profiling_slow.patch b/mysql-profiling_slow.patch
deleted file mode 100644 (file)
index 703b8b7..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-diff -r 92e70e675363 patch_info/profiling_slow.info
---- /dev/null  Thu Jan 01 00:00:00 1970 +0000
-+++ b/patch_info/profiling_slow.info   Mon Jun 01 00:50:00 2009 -0700
-@@ -0,0 +1,9 @@
-+File=profiling_slow.info
-+Name=profiling from SHOW PROFILE to slow.log
-+Version=1.0
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment=
-+Changelog
-+2009-05-18
-+Initial implementation
-diff -r 92e70e675363 sql/log.cc
---- a/sql/log.cc       Mon Jun 01 00:48:56 2009 -0700
-+++ b/sql/log.cc       Mon Jun 01 00:50:00 2009 -0700
-@@ -2402,6 +2402,11 @@
-           tmp_errno=errno;
-       }
-     }
-+
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+    thd->profiling.print_current(&log_file);
-+#endif
-+
-     if (thd->db && strcmp(thd->db,db))
-     {                                         // Database changed
-       if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
-diff -r 92e70e675363 sql/mysqld.cc
---- a/sql/mysqld.cc    Mon Jun 01 00:48:56 2009 -0700
-+++ b/sql/mysqld.cc    Mon Jun 01 00:50:00 2009 -0700
-@@ -5052,6 +5052,8 @@
-   OPT_PORT_OPEN_TIMEOUT,
-   OPT_MERGE,
-   OPT_PROFILING,
-+  OPT_PROFILING_SERVER,
-+  OPT_PROFILING_USE_GETRUSAGE,
-   OPT_SLOW_LOG,
-   OPT_SLOW_QUERY_LOG_FILE,
-   OPT_USE_GLOBAL_LONG_QUERY_TIME,
-@@ -5675,6 +5677,16 @@
-    (gptr*) &global_system_variables.profiling_history_size,
-    (gptr*) &max_system_variables.profiling_history_size,
-    0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
-+  {"profiling_server", OPT_PROFILING_SERVER,
-+   "Enable profiling of all threads",
-+   (gptr*) &global_system_variables.profiling_server,
-+   (gptr*) &max_system_variables.profiling_server, 0, GET_BOOL,
-+   OPT_ARG, 0, 0, 0, 0, 0, 0 },
-+  {"profiling_use_getrusage", OPT_PROFILING_USE_GETRUSAGE,
-+   "Enable getrusage function call for profiling",
-+   (gptr*) &global_system_variables.profiling_use_getrusage,
-+   (gptr*) &max_system_variables.profiling_use_getrusage, 0, GET_BOOL,
-+   OPT_ARG, 0, 0, 0, 0, 0, 0 },
- #endif
-   {"relay-log", OPT_RELAY_LOG,
-    "The location and name to use for relay logs.",
-diff -r 92e70e675363 sql/set_var.cc
---- a/sql/set_var.cc   Mon Jun 01 00:48:56 2009 -0700
-+++ b/sql/set_var.cc   Mon Jun 01 00:50:00 2009 -0700
-@@ -592,6 +592,10 @@
-                                       ulonglong(OPTION_PROFILING));
- static sys_var_thd_ulong      sys_profiling_history_size("profiling_history_size",
-                                             &SV::profiling_history_size);
-+static sys_var_thd_bool       sys_profiling_server("profiling_server",
-+                                            &SV::profiling_server);
-+static sys_var_thd_bool       sys_profiling_use_getrusage("profiling_use_getrusage",
-+                                            &SV::profiling_use_getrusage);
- #endif
- /* Local state variables */
-@@ -764,6 +768,8 @@
- #ifdef ENABLED_PROFILING
-   &sys_profiling,
-   &sys_profiling_history_size,
-+  &sys_profiling_server,
-+  &sys_profiling_use_getrusage,
- #endif
-   &sys_pseudo_thread_id,
-   &sys_query_alloc_block_size,
-@@ -1094,6 +1100,8 @@
- #ifdef ENABLED_PROFILING
-   {sys_profiling.name,        (char*) &sys_profiling,               SHOW_SYS},
-   {sys_profiling_history_size.name, (char*) &sys_profiling_history_size, SHOW_SYS},
-+  {sys_profiling_server.name, (char*) &sys_profiling_server, SHOW_SYS},
-+  {sys_profiling_use_getrusage.name, (char*) &sys_profiling_use_getrusage, SHOW_SYS},
- #endif
-   {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
-   {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
-diff -r 92e70e675363 sql/sql_class.h
---- a/sql/sql_class.h  Mon Jun 01 00:48:56 2009 -0700
-+++ b/sql/sql_class.h  Mon Jun 01 00:50:00 2009 -0700
-@@ -550,6 +550,8 @@
-   ulong optimizer_search_depth;
-   ulong preload_buff_size;
-   ulong profiling_history_size;
-+  my_bool profiling_server;
-+  my_bool profiling_use_getrusage;
-   ulong query_cache_type;
-   ulong log_slow_rate_limit;
-   ulong read_buff_size;
-diff -r 92e70e675363 sql/sql_profile.cc
---- a/sql/sql_profile.cc       Mon Jun 01 00:48:56 2009 -0700
-+++ b/sql/sql_profile.cc       Mon Jun 01 00:50:00 2009 -0700
-@@ -221,9 +221,22 @@
- */
- void PROF_MEASUREMENT::collect()
- {
-+  struct timespec tp;
-   time_usecs= (double) my_getsystime() / 10.0;  /* 1 sec was 1e7, now is 1e6 */
- #ifdef HAVE_GETRUSAGE
--  getrusage(RUSAGE_SELF, &rusage);
-+  if ((profile->get_profiling())->enabled_getrusage())
-+    getrusage(RUSAGE_SELF, &rusage);
-+#endif
-+
-+#ifdef HAVE_CLOCK_GETTIME
-+  if (!(clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+  {
-+    cpu_time_usecs= tp.tv_sec*1000000000.0 + tp.tv_nsec;
-+  } 
-+  else
-+  {
-+    cpu_time_usecs= 0;
-+  }
- #endif
- }
-@@ -341,7 +354,7 @@
-     finish_current_query();
-   }
--  enabled= (((thd)->options & OPTION_PROFILING) != 0);
-+  enabled= (((thd)->options & OPTION_PROFILING) != 0) || ( thd->variables.profiling_server );
-   if (! enabled) DBUG_VOID_RETURN;
-@@ -379,7 +392,8 @@
-     status_change("ending", NULL, NULL, 0);
-     if ((enabled) &&                                    /* ON at start? */
--        ((thd->options & OPTION_PROFILING) != 0) &&   /* and ON at end? */
-+        (((thd->options & OPTION_PROFILING) != 0) || 
-+          (thd->variables.profiling_server)) &&   /* and ON at end? */
-         (current->query_source != NULL) &&
-         (! current->entries.is_empty()))
-     {
-@@ -480,6 +494,88 @@
-   DBUG_VOID_RETURN;
- }
-+bool PROFILING::enabled_getrusage()
-+{
-+  return thd->variables.profiling_use_getrusage;
-+}
-+
-+/**
-+  Print output for current query to file 
-+*/
-+
-+int PROFILING::print_current(IO_CACHE *log_file)
-+{
-+  DBUG_ENTER("PROFILING::print_current");
-+  ulonglong row_number= 0;
-+  char query_time_buff[22+7];
-+  char query_cpu_time_buff[22+7];
-+
-+  QUERY_PROFILE *query;
-+  /* Get current query */
-+  if (current == NULL)
-+  {
-+    DBUG_RETURN(0);
-+  }
-+
-+  query= current;
-+
-+  my_b_printf(log_file, "# PROFILE_VALUES ");
-+
-+    void *entry_iterator;
-+    PROF_MEASUREMENT *entry, *previous= NULL, *first= NULL;
-+    /* ...and for each query, go through all its state-change steps. */
-+    for (entry_iterator= query->entries.new_iterator();
-+         entry_iterator != NULL;
-+         entry_iterator= query->entries.iterator_next(entry_iterator),
-+         previous=entry, row_number++)
-+    {
-+      entry= query->entries.iterator_value(entry_iterator);
-+
-+      /* Skip the first.  We count spans of fence, not fence-posts. */
-+      if (previous == NULL) {first= entry; continue;}
-+
-+      if (thd->lex->orig_sql_command == SQLCOM_SHOW_PROFILE)
-+      {
-+        /*
-+          We got here via a SHOW command.  That means that we stored
-+          information about the query we wish to show and that isn't
-+          in a WHERE clause at a higher level to filter out rows we
-+          wish to exclude.
-+
-+          Because that functionality isn't available in the server yet,
-+          we must filter here, at the wrong level.  Once one can con-
-+          struct where and having conditions at the SQL layer, then this
-+          condition should be ripped out.
-+        */
-+        if (thd->lex->profile_query_id == 0) /* 0 == show final query */
-+        {
-+          if (query != last)
-+            continue;
-+        }
-+        else
-+        {
-+          if (thd->lex->profile_query_id != query->profiling_query_id)
-+            continue;
-+        }
-+      }
-+
-+      snprintf(query_time_buff, sizeof(query_time_buff), "%.6f", (entry->time_usecs-previous->time_usecs)/(1000.0*1000));
-+      snprintf(query_cpu_time_buff, sizeof(query_cpu_time_buff), "%.6f", (entry->cpu_time_usecs-previous->cpu_time_usecs)/(1000.0*1000*1000));
-+      my_b_printf(log_file, "%s: %s (cpu: %s), ", previous->status, query_time_buff, query_cpu_time_buff);
-+
-+    }
-+
-+    my_b_printf(log_file, "\n");
-+    if ((entry != NULL) && (first != NULL))
-+    {
-+      snprintf(query_time_buff, sizeof(query_time_buff), "%.6f", (entry->time_usecs-first->time_usecs)/(1000.0*1000));
-+      snprintf(query_cpu_time_buff, sizeof(query_cpu_time_buff), "%.6f", (entry->cpu_time_usecs-first->cpu_time_usecs)/(1000.0*1000*1000));
-+      my_b_printf(log_file, "# PROFILE_TOTALS Total: %s (cpu: %s)\n", query_time_buff, query_cpu_time_buff);
-+    }
-+
-+  DBUG_RETURN(0);
-+}
-+
- /**
-   Fill the information schema table, "query_profile", as defined in show.cc .
-   There are two ways to get to this function:  Selecting from the information
-diff -r 92e70e675363 sql/sql_profile.h
---- a/sql/sql_profile.h        Mon Jun 01 00:48:56 2009 -0700
-+++ b/sql/sql_profile.h        Mon Jun 01 00:50:00 2009 -0700
-@@ -193,6 +193,7 @@
-   unsigned int line;
-   double time_usecs;
-+  double cpu_time_usecs;
-   char *allocated_status_memory;
-   void set_label(const char *status_arg, const char *function_arg, 
-@@ -243,6 +244,11 @@
-   /* Show this profile.  This is called by PROFILING. */
-   bool show(uint options);
-+
-+public:
-+
-+  inline PROFILING * get_profiling() { return profiling; };
-+
- };
-@@ -288,9 +294,11 @@
-   /* SHOW PROFILES */
-   bool show_profiles();
-+  bool enabled_getrusage();
-   /* ... from INFORMATION_SCHEMA.PROFILING ... */
-   int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
-+  int print_current(IO_CACHE *log_file);
- };
- #  endif /* HAVE_PROFILING */
diff --git a/mysql-split_buf_pool_mutex_fixed_optimistic_safe.patch b/mysql-split_buf_pool_mutex_fixed_optimistic_safe.patch
deleted file mode 100644 (file)
index ef673d9..0000000
+++ /dev/null
@@ -1,1281 +0,0 @@
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/buf/buf0buf.c mysql-5.1.29-rc/storage/innobase/buf/buf0buf.c
---- mysql-5.1.29-rc_orig/storage/innobase/buf/buf0buf.c        2008-10-12 06:54:12.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/buf/buf0buf.c     2008-11-18 15:44:00.000000000 +0900
-@@ -596,6 +596,15 @@
-       ---------------------------- */
-       mutex_create(&buf_pool->mutex, SYNC_BUF_POOL);
-+      mutex_create(&(buf_pool->flush_list_mutex), SYNC_NO_ORDER_CHECK);
-+      mutex_create(&(buf_pool->LRU_mutex), SYNC_NO_ORDER_CHECK);
-+      mutex_create(&(buf_pool->free_mutex), SYNC_NO_ORDER_CHECK);
-+      mutex_create(&(buf_pool->hash_mutex), SYNC_NO_ORDER_CHECK);
-+
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       mutex_enter(&(buf_pool->mutex));
-       if (srv_use_awe) {
-@@ -773,6 +782,10 @@
-               block->in_free_list = TRUE;
-       }
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       mutex_exit(&(buf_pool->mutex));
-       if (srv_use_adaptive_hash_indexes) {
-@@ -905,12 +918,12 @@
-       if (buf_block_peek_if_too_old(block)) {
--              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));
-       }
- }
-@@ -926,7 +939,7 @@
- {
-       buf_block_t*    block;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-       block = buf_block_align(frame);
-@@ -934,7 +947,7 @@
-       buf_LRU_make_block_young(block);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
- }
- /************************************************************************
-@@ -945,7 +958,7 @@
- /*===========*/
-       buf_block_t*    block)  /* in, own: block to be freed */
- {
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       mutex_enter(&block->mutex);
-@@ -955,7 +968,7 @@
-       mutex_exit(&block->mutex);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
- }
- /*************************************************************************
-@@ -996,11 +1009,11 @@
- {
-       buf_block_t*    block;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(block);
- }
-@@ -1017,7 +1030,7 @@
- {
-       buf_block_t*    block;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1025,7 +1038,7 @@
-               block->check_index_page_at_flush = FALSE;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
- }
- /************************************************************************
-@@ -1044,7 +1057,7 @@
-       buf_block_t*    block;
-       ibool           is_hashed;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1054,7 +1067,7 @@
-               is_hashed = block->is_hashed;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(is_hashed);
- }
-@@ -1096,7 +1109,7 @@
- {
-       buf_block_t*    block;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1104,7 +1117,7 @@
-               block->file_page_was_freed = TRUE;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(block);
- }
-@@ -1125,7 +1138,7 @@
- {
-       buf_block_t*    block;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1133,7 +1146,7 @@
-               block->file_page_was_freed = FALSE;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(block);
- }
-@@ -1174,26 +1187,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) {
-+              mutex_enter_fast(&(buf_pool->hash_mutex));
-               block = buf_page_hash_get(space, offset);
-+              if(block) {
-+                      mutex_enter(&block->mutex);
-+              }
-+              mutex_exit(&(buf_pool->hash_mutex));
-       }
-       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) {
-@@ -1212,7 +1232,7 @@
-               goto loop;
-       }
--      mutex_enter(&block->mutex);
-+      // mutex_enter(&block->mutex);
-       ut_a(block->state == BUF_BLOCK_FILE_PAGE);
-@@ -1224,7 +1244,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);
-@@ -1241,7 +1261,9 @@
-               LRU list and we must put it to awe_LRU_free_mapped list once
-               mapped to a frame */
-+              mutex_enter_fast(&(buf_pool->mutex));
-               buf_awe_map_page_to_frame(block, TRUE);
-+              mutex_exit(&buf_pool->mutex);
-       }
- #ifdef UNIV_SYNC_DEBUG
-@@ -1249,7 +1271,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 */
-@@ -1747,7 +1769,8 @@
-       ut_a(block);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       mutex_enter(&block->mutex);
-       if (fil_tablespace_deleted_or_being_deleted_in_mem(
-@@ -1763,7 +1786,8 @@
-               already in buf_pool, return */
-               mutex_exit(&block->mutex);
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->LRU_mutex));
-+              mutex_exit(&(buf_pool->hash_mutex));
-               buf_block_free(block);
-@@ -1778,10 +1802,14 @@
-       ut_ad(block);
-       buf_page_init(space, offset, block);
-+      mutex_exit(&(buf_pool->hash_mutex));
-       /* 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;
-@@ -1830,7 +1858,8 @@
-       free_block = buf_LRU_get_free_block();
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1841,7 +1870,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));
-+              mutex_exit(&(buf_pool->hash_mutex));
-               buf_block_free(free_block);
-@@ -1864,6 +1894,7 @@
-       mutex_enter(&block->mutex);
-       buf_page_init(space, offset, block);
-+      mutex_exit(&(buf_pool->hash_mutex));
-       /* The block must be put to the LRU list */
-       buf_LRU_add_block(block, FALSE);
-@@ -1875,7 +1906,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);
-@@ -1889,7 +1920,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;
-@@ -1928,6 +1959,7 @@
-       buf_block_t*    block)  /* in: pointer to the block in question */
- {
-       ulint           io_type;
-+      ulint           flush_type;
-       ut_ad(block);
-@@ -2040,9 +2072,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
-@@ -2051,9 +2080,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! */
-@@ -2064,6 +2096,8 @@
-               rw_lock_x_unlock_gen(&(block->lock), BUF_IO_READ);
-+              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&block->mutex);
- #ifdef UNIV_DEBUG
-               if (buf_debug_prints) {
-                       fputs("Has read ", stderr);
-@@ -2072,15 +2106,33 @@
-       } else {
-               ut_ad(io_type == BUF_IO_WRITE);
-+              flush_type = block->flush_type;
-+              if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
-+                      mutex_enter(&(buf_pool->LRU_mutex));
-+              }
-+              mutex_enter(&(buf_pool->flush_list_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);
-+              mutex_exit(&(buf_pool->flush_list_mutex));
-+              if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
-+                      mutex_exit(&(buf_pool->LRU_mutex));
-+              }
-+
-               rw_lock_s_unlock_gen(&(block->lock), BUF_IO_WRITE);
-               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);
-@@ -2088,9 +2140,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",
-@@ -2118,11 +2167,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));
- }
- #ifdef UNIV_DEBUG
-@@ -2142,10 +2191,22 @@
-       ulint           n_flush         = 0;
-       ulint           n_free          = 0;
-       ulint           n_page          = 0;
-+      ulint           n_single_flush_tmp      = 0;
-+      ulint           n_lru_flush_tmp         = 0;
-+      ulint           n_list_flush_tmp        = 0;
-       ut_ad(buf_pool);
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-+
-       mutex_enter(&(buf_pool->mutex));
-+      n_single_flush_tmp = buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE];
-+      n_list_flush_tmp = buf_pool->n_flush[BUF_FLUSH_LIST];
-+      n_lru_flush_tmp = buf_pool->n_flush[BUF_FLUSH_LRU];
-+      mutex_exit(&(buf_pool->mutex));
-       for (i = 0; i < buf_pool->curr_size; i++) {
-@@ -2216,11 +2277,14 @@
-       }
-       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));
-+      ut_a(n_single_flush_tmp == n_single_flush);
-+      ut_a(n_list_flush_tmp == n_list_flush);
-+      ut_a(n_lru_flush_tmp == n_lru_flush);
-+      
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       ut_a(buf_LRU_validate());
-       ut_a(buf_flush_validate());
-@@ -2252,7 +2316,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->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       fprintf(stderr,
-               "buf_pool size %lu\n"
-@@ -2305,7 +2371,9 @@
-               }
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       for (i = 0; i < n_found; i++) {
-               index = dict_index_get_if_in_cache(index_ids[i]);
-@@ -2339,8 +2407,6 @@
-       ulint           i;
-       ulint           fixed_pages_number = 0;
--      mutex_enter(&(buf_pool->mutex));
--
-       for (i = 0; i < buf_pool->curr_size; i++) {
-               block = buf_pool_get_nth_block(buf_pool, i);
-@@ -2356,7 +2422,6 @@
-               }
-       }
--      mutex_exit(&(buf_pool->mutex));
-       return(fixed_pages_number);
- }
-@@ -2385,7 +2450,9 @@
- {
-       ulint   ratio;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       ratio = (100 * UT_LIST_GET_LEN(buf_pool->flush_list))
-               / (1 + UT_LIST_GET_LEN(buf_pool->LRU)
-@@ -2393,7 +2460,9 @@
-       /* 1 + is there to avoid division by zero */
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       return(ratio);
- }
-@@ -2413,6 +2482,9 @@
-       ut_ad(buf_pool);
-       size = buf_pool->curr_size;
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       mutex_enter(&(buf_pool->mutex));
-       if (srv_use_awe) {
-@@ -2487,6 +2559,9 @@
-       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->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       mutex_exit(&(buf_pool->mutex));
- }
-@@ -2517,8 +2592,6 @@
-       ut_ad(buf_pool);
--      mutex_enter(&(buf_pool->mutex));
--
-       for (i = 0; i < buf_pool->curr_size; i++) {
-               block = buf_pool_get_nth_block(buf_pool, i);
-@@ -2540,8 +2613,6 @@
-               mutex_exit(&block->mutex);
-       }
--      mutex_exit(&(buf_pool->mutex));
--
-       return(TRUE);
- }
-@@ -2580,11 +2651,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 -ruN mysql-5.1.29-rc_orig/storage/innobase/buf/buf0flu.c mysql-5.1.29-rc/storage/innobase/buf/buf0flu.c
---- mysql-5.1.29-rc_orig/storage/innobase/buf/buf0flu.c        2008-10-12 06:54:12.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/buf/buf0flu.c     2008-11-18 15:26:07.000000000 +0900
-@@ -109,13 +109,15 @@
-       ut_ad(mutex_own(&(buf_pool->mutex)));
-       ut_ad(mutex_own(&block->mutex));
-       if (block->state != BUF_BLOCK_FILE_PAGE) {
-+              /* It is 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, block, sizeof(buf_block_t));
--
-+*/
-               return(FALSE);
-       }
-@@ -546,18 +548,20 @@
-       ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST
-             || flush_type == BUF_FLUSH_SINGLE_PAGE);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-       ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE);
-       if (!block) {
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->hash_mutex));
-               return(0);
-       }
-       mutex_enter(&block->mutex);
-+      mutex_enter(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       if (flush_type == BUF_FLUSH_LIST
-           && buf_flush_ready_for_flush(block, flush_type)) {
-@@ -755,7 +759,7 @@
-               high = fil_space_get_size(space);
-       }
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       for (i = low; i < high; i++) {
-@@ -789,7 +793,7 @@
-                               mutex_exit(&block->mutex);
--                              mutex_exit(&(buf_pool->mutex));
-+                              mutex_exit(&(buf_pool->hash_mutex));
-                               /* Note: as we release the buf_pool mutex
-                               above, in buf_flush_try_page we cannot be sure
-@@ -800,14 +804,14 @@
-                               count += buf_flush_try_page(space, i,
-                                                           flush_type);
--                              mutex_enter(&(buf_pool->mutex));
-+                              mutex_enter(&(buf_pool->hash_mutex));
-                       } else {
-                               mutex_exit(&block->mutex);
-                       }
-               }
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(count);
- }
-@@ -863,6 +867,13 @@
-       (buf_pool->init_flush)[flush_type] = TRUE;
-+      mutex_exit(&(buf_pool->mutex));
-+
-+      if (flush_type == BUF_FLUSH_LRU) {
-+              mutex_enter(&(buf_pool->LRU_mutex));
-+      }
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+
-       for (;;) {
-               /* If we have flushed enough, leave the loop */
-               if (page_count >= min_n) {
-@@ -908,7 +919,10 @@
-                               offset = block->offset;
-                               mutex_exit(&block->mutex);
--                              mutex_exit(&(buf_pool->mutex));
-+                              if (flush_type == BUF_FLUSH_LRU) {
-+                                      mutex_exit(&(buf_pool->LRU_mutex));
-+                              }
-+                              mutex_exit(&(buf_pool->flush_list_mutex));
-                               old_page_count = page_count;
-@@ -920,7 +934,10 @@
-                               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));
-+                              }
-+                              mutex_enter(&(buf_pool->flush_list_mutex));
-                       } else if (flush_type == BUF_FLUSH_LRU) {
-@@ -943,6 +960,13 @@
-               }
-       }
-+      if (flush_type == BUF_FLUSH_LRU) {
-+              mutex_exit(&(buf_pool->LRU_mutex));
-+      }
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+
-+      mutex_enter(&(buf_pool->mutex));
-+
-       (buf_pool->init_flush)[flush_type] = FALSE;
-       if ((buf_pool->n_flush[flush_type] == 0)
-@@ -1001,10 +1025,14 @@
-       ulint           n_replaceable;
-       ulint           distance        = 0;
--      mutex_enter(&(buf_pool->mutex));
-+      /* optimistic search... */
-+      //mutex_enter(&(buf_pool->LRU_mutex));
-+      //mutex_enter(&(buf_pool->free_mutex));
-       n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
-+      //mutex_exit(&(buf_pool->free_mutex));
-+
-       block = UT_LIST_GET_LAST(buf_pool->LRU);
-       while ((block != NULL)
-@@ -1025,7 +1053,7 @@
-               block = UT_LIST_GET_PREV(LRU, block);
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      //mutex_exit(&(buf_pool->LRU_mutex));
-       if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN) {
-@@ -1044,8 +1072,9 @@
- immediately, without waiting. */
- void
--buf_flush_free_margin(void)
-+buf_flush_free_margin(
- /*=======================*/
-+      ibool   wait)
- {
-       ulint   n_to_flush;
-       ulint   n_flushed;
-@@ -1055,7 +1084,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 */
-@@ -1105,11 +1134,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 -ruN mysql-5.1.29-rc_orig/storage/innobase/buf/buf0lru.c mysql-5.1.29-rc/storage/innobase/buf/buf0lru.c
---- mysql-5.1.29-rc_orig/storage/innobase/buf/buf0lru.c        2008-10-12 06:54:12.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/buf/buf0lru.c     2008-11-18 15:09:58.000000000 +0900
-@@ -79,7 +79,10 @@
-       ibool           all_freed;
- scan_again:
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       all_freed = TRUE;
-@@ -119,7 +122,10 @@
-                               mutex_exit(&block->mutex);
--                              mutex_exit(&(buf_pool->mutex));
-+                              mutex_exit(&(buf_pool->LRU_mutex));
-+                              mutex_exit(&(buf_pool->flush_list_mutex));
-+                              mutex_exit(&(buf_pool->free_mutex));
-+                              mutex_exit(&(buf_pool->hash_mutex));
-                               /* Note that the following call will acquire
-                               an S-latch on the page */
-@@ -149,7 +155,10 @@
-               block = prev_block;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       if (!all_freed) {
-               os_thread_sleep(20000);
-@@ -172,14 +181,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);
-       }
-@@ -188,7 +197,7 @@
-       limit = block->LRU_position - len / BUF_LRU_INITIAL_RATIO;
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-       return(limit);
- }
-@@ -212,13 +221,15 @@
-       ulint           distance = 0;
-       ibool           freed;
--      mutex_enter(&(buf_pool->mutex));
-+      /* optimistic search... */
-+      //mutex_enter(&(buf_pool->LRU_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);
-@@ -234,9 +245,17 @@
-                       }
- #endif /* UNIV_DEBUG */
-+                      mutex_exit(&block->mutex);
-+
-+                      mutex_enter(&(buf_pool->LRU_mutex));/* optimistic */
-+
-+                      mutex_enter(&(buf_pool->hash_mutex));
-+                      mutex_enter(&block->mutex);
-+                      if(block->in_LRU_list && buf_flush_ready_for_replace(block)) {
-                       buf_LRU_block_remove_hashed_page(block);
-+                      mutex_exit(&(buf_pool->hash_mutex));
--                      mutex_exit(&(buf_pool->mutex));
-+                      mutex_exit(&(buf_pool->LRU_mutex));
-                       mutex_exit(&block->mutex);
-                       /* Remove possible adaptive hash index built on the
-@@ -257,14 +276,25 @@
-                       ut_a(block->buf_fix_count == 0);
--                      mutex_enter(&(buf_pool->mutex));
-+                      mutex_enter(&(buf_pool->free_mutex));
-                       mutex_enter(&block->mutex);
-                       buf_LRU_block_free_hashed_page(block);
-                       freed = TRUE;
-+                      mutex_exit(&(buf_pool->free_mutex));
-                       mutex_exit(&block->mutex);
-                       break;
-+                      } else { /* someone may interrupt...??? */
-+                      mutex_exit(&(buf_pool->LRU_mutex));/* optimistic */
-+
-+                      mutex_exit(&(buf_pool->hash_mutex));
-+
-+                      if (!(block->in_LRU_list)) {
-+                              mutex_exit(&block->mutex);
-+                              goto retry;
-+                      }
-+                      }
-               }
-               mutex_exit(&block->mutex);
-@@ -275,13 +305,21 @@
-               if (!freed && n_iterations <= 10
-                   && distance > 100 + (n_iterations * buf_pool->curr_size)
-                   / 10) {
--                      buf_pool->LRU_flush_ended = 0;
-+                      mutex_enter(&(buf_pool->mutex));
-+                      buf_pool->LRU_flush_ended = 0;
-                       mutex_exit(&(buf_pool->mutex));
-+                      //mutex_exit(&(buf_pool->LRU_mutex));
-+
-                       return(FALSE);
-               }
-       }
-+      if (!freed) {
-+              //mutex_exit(&(buf_pool->LRU_mutex));
-+      }
-+
-+      mutex_enter(&(buf_pool->mutex));
-       if (buf_pool->LRU_flush_ended > 0) {
-               buf_pool->LRU_flush_ended--;
-       }
-@@ -333,7 +371,8 @@
- {
-       ibool   ret     = FALSE;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
-           + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
-@@ -341,7 +380,8 @@
-               ret = TRUE;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       return(ret);
- }
-@@ -364,7 +404,7 @@
-       ibool           mon_value_was   = FALSE;
-       ibool           started_monitor = FALSE;
- loop:
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->free_mutex)); /* LRU info:optimistic */
-       if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
-           + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 20) {
-@@ -461,7 +501,7 @@
-               mutex_exit(&block->mutex);
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->free_mutex));
-               if (started_monitor) {
-                       srv_print_innodb_monitor = mon_value_was;
-@@ -473,7 +513,7 @@
-       /* If no block was in the free list, search from the end of the LRU
-       list and try to free a block there */
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       freed = buf_LRU_search_and_free_block(n_iterations);
-@@ -517,7 +557,7 @@
-       /* No free block was found: try to flush the LRU list */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(TRUE);
-       ++srv_buf_pool_wait_free;
-       os_aio_simulated_wake_handler_threads();
-@@ -988,7 +1028,7 @@
-       ulint           LRU_pos;
-       ut_ad(buf_pool);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-       if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
-@@ -1033,6 +1073,9 @@
-               ut_a(buf_pool->LRU_old_len == old_len);
-       }
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-+
-       UT_LIST_VALIDATE(free, buf_block_t, buf_pool->free);
-       block = UT_LIST_GET_FIRST(buf_pool->free);
-@@ -1043,7 +1086,7 @@
-               block = UT_LIST_GET_NEXT(free, block);
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       return(TRUE);
- }
-@@ -1059,7 +1102,7 @@
-       ulint           len;
-       ut_ad(buf_pool);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-       fprintf(stderr, "Pool ulint clock %lu\n",
-               (ulong) buf_pool->ulint_clock);
-@@ -1105,6 +1148,6 @@
-               }
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
- }
- #endif /* UNIV_DEBUG */
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/buf/buf0rea.c mysql-5.1.29-rc/storage/innobase/buf/buf0rea.c
---- mysql-5.1.29-rc_orig/storage/innobase/buf/buf0rea.c        2008-10-12 06:54:12.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/buf/buf0rea.c     2008-11-18 15:28:13.000000000 +0900
-@@ -219,10 +219,12 @@
-               return(0);
-       }
-+      mutex_exit(&(buf_pool->mutex));
-       /* Count how many blocks in the area have been recently accessed,
-       that is, reside near the start of the LRU list. */
-+      mutex_enter(&(buf_pool->hash_mutex));
-       for (i = low; i < high; i++) {
-               block = buf_page_hash_get(space, i);
-@@ -233,8 +235,9 @@
-                       recent_blocks++;
-               }
-       }
-+      mutex_exit(&(buf_pool->hash_mutex));
--      mutex_exit(&(buf_pool->mutex));
-+      // mutex_exit(&(buf_pool->mutex));
-       if (recent_blocks < BUF_READ_AHEAD_RANDOM_THRESHOLD) {
-               /* Do nothing */
-@@ -334,7 +337,7 @@
-       }
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
-       return(count + count2);
- }
-@@ -432,6 +435,7 @@
-               return(0);
-       }
-+      mutex_exit(&(buf_pool->mutex));
-       /* Check that almost all pages in the area have been accessed; if
-       offset == low, the accesses must be in a descending order, otherwise,
-@@ -445,6 +449,7 @@
-       fail_count = 0;
-+      mutex_enter(&(buf_pool->hash_mutex));
-       for (i = low; i < high; i++) {
-               block = buf_page_hash_get(space, i);
-@@ -462,12 +467,13 @@
-                       pred_block = block;
-               }
-       }
-+      mutex_exit(&(buf_pool->hash_mutex));
-       if (fail_count > BUF_READ_AHEAD_LINEAR_AREA
-           - BUF_READ_AHEAD_LINEAR_THRESHOLD) {
-               /* Too many failures: return */
--              mutex_exit(&(buf_pool->mutex));
-+              //mutex_exit(&(buf_pool->mutex));
-               return(0);
-       }
-@@ -475,10 +481,11 @@
-       /* If we got this far, we know that enough pages in the area have
-       been accessed in the right order: linear read-ahead can be sensible */
-+      mutex_enter(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-       if (block == NULL) {
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->hash_mutex));
-               return(0);
-       }
-@@ -494,7 +501,7 @@
-       pred_offset = fil_page_get_prev(frame);
-       succ_offset = fil_page_get_next(frame);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       if ((offset == low) && (succ_offset == offset + 1)) {
-@@ -573,7 +580,7 @@
-       os_aio_simulated_wake_handler_threads();
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints && (count > 0)) {
-@@ -639,7 +646,7 @@
-       os_aio_simulated_wake_handler_threads();
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints) {
-@@ -716,7 +723,7 @@
-       os_aio_simulated_wake_handler_threads();
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints) {
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/buf0buf.h mysql-5.1.29-rc/storage/innobase/include/buf0buf.h
---- mysql-5.1.29-rc_orig/storage/innobase/include/buf0buf.h    2008-10-12 06:54:13.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/buf0buf.h 2008-11-18 15:09:58.000000000 +0900
-@@ -926,6 +926,7 @@
-                                       currently always the same as
-                                       max_size */
-       hash_table_t*   page_hash;      /* hash table of the file pages */
-+      mutex_t         hash_mutex;
-       ulint           n_pend_reads;   /* number of pending read operations */
-@@ -958,6 +959,7 @@
-       UT_LIST_BASE_NODE_T(buf_block_t) flush_list;
-                                       /* base node of the modified block
-                                       list */
-+      mutex_t         flush_list_mutex;
-       ibool           init_flush[BUF_FLUSH_LIST + 1];
-                                       /* this is TRUE when a flush of the
-                                       given type is being initialized */
-@@ -991,8 +993,10 @@
-                                       in the case of AWE, at the start are
-                                       always free blocks for which the
-                                       physical memory is mapped to a frame */
-+      mutex_t         free_mutex;
-       UT_LIST_BASE_NODE_T(buf_block_t) LRU;
-                                       /* base node of the LRU list */
-+      mutex_t         LRU_mutex;
-       buf_block_t*    LRU_old;        /* pointer to the about 3/8 oldest
-                                       blocks in the LRU list; NULL if LRU
-                                       length less than BUF_LRU_OLD_MIN_LEN */
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/buf0buf.ic mysql-5.1.29-rc/storage/innobase/include/buf0buf.ic
---- mysql-5.1.29-rc_orig/storage/innobase/include/buf0buf.ic   2008-10-12 06:54:13.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/buf0buf.ic        2008-11-18 15:09:58.000000000 +0900
-@@ -104,7 +104,7 @@
-       buf_block_t*    block;
-       dulint          lsn;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-       block = UT_LIST_GET_LAST(buf_pool->flush_list);
-@@ -114,7 +114,7 @@
-               lsn = block->oldest_modification;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-       return(lsn);
- }
-@@ -388,18 +388,18 @@
-                               /* out: TRUE if io going on */
-       buf_block_t*    block)  /* in: buf_pool block, must be bufferfixed */
- {
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&block->mutex);
-       ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
-       ut_ad(block->buf_fix_count > 0);
-       if (block->io_fix != 0) {
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&block->mutex);
-               return(TRUE);
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&block->mutex);
-       return(FALSE);
- }
-@@ -421,7 +421,7 @@
-       block = buf_block_align(frame);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&block->mutex);
-       if (block->state == BUF_BLOCK_FILE_PAGE) {
-               lsn = block->newest_modification;
-@@ -429,7 +429,7 @@
-               lsn = ut_dulint_zero;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&block->mutex);
-       return(lsn);
- }
-@@ -624,9 +624,9 @@
-       ut_a(block->buf_fix_count > 0);
-       if (rw_latch == RW_X_LATCH && mtr->modifications) {
--              mutex_enter(&buf_pool->mutex);
-+              mutex_enter(&buf_pool->flush_list_mutex);
-               buf_flush_note_modification(block, mtr);
--              mutex_exit(&buf_pool->mutex);
-+              mutex_exit(&buf_pool->flush_list_mutex);
-       }
-       mutex_enter(&block->mutex);
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/buf0flu.h mysql-5.1.29-rc/storage/innobase/include/buf0flu.h
---- mysql-5.1.29-rc_orig/storage/innobase/include/buf0flu.h    2008-10-12 06:54:13.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/buf0flu.h 2008-11-18 15:09:58.000000000 +0900
-@@ -26,8 +26,9 @@
- a margin of replaceable pages there. */
- void
--buf_flush_free_margin(void);
-+buf_flush_free_margin(
- /*=======================*/
-+      ibool   wait);
- /************************************************************************
- Initializes a page for writing to the tablespace. */
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/buf0flu.ic mysql-5.1.29-rc/storage/innobase/include/buf0flu.ic
---- mysql-5.1.29-rc_orig/storage/innobase/include/buf0flu.ic   2008-10-12 06:54:13.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/buf0flu.ic        2008-11-18 15:09:58.000000000 +0900
-@@ -84,7 +84,7 @@
-       ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
- #endif /* UNIV_SYNC_DEBUG */
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-       ut_ad(ut_dulint_cmp(block->newest_modification, end_lsn) <= 0);
-@@ -102,5 +102,5 @@
-                                   start_lsn) <= 0);
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
- }
-diff -ruN mysql-5.1.29-rc_orig/patch_info/split_buf_pool_mutex_fixed_optimistic_safe.info mysql-5.1.29-rc/patch_info/split_buf_pool_mutex_fixed_optimistic_safe.info
---- /dev/null  1970-01-01 09:00:00.000000000 +0900
-+++ mysql-5.1.29-rc/patch_info/split_buf_pool_mutex_fixed_optimistic_safe.info 2008-11-18 15:09:58.000000000 +0900
-@@ -0,0 +1,6 @@
-+File=split_buf_pool_mutex_fixed_optimistic_safe.patch
-+Name=InnoDB patch to fix buffer pool scalability
-+Version=1.0
-+Author=Yasufumi Kinoshita
-+License=BSD
-+Comment=
diff --git a/mysql-userstats.patch b/mysql-userstats.patch
deleted file mode 100644 (file)
index 29b5727..0000000
+++ /dev/null
@@ -1,1466 +0,0 @@
-diff -r 3ed7e96969f9 include/mysql_com.h
---- a/include/mysql_com.h      Thu Dec 04 08:54:17 2008 -0800
-+++ b/include/mysql_com.h      Thu Dec 04 08:54:27 2008 -0800
-@@ -115,6 +115,8 @@
-                                          thread */
- #define REFRESH_MASTER          128     /* Remove all bin logs in the index
-                                          and truncate the index */
-+#define REFRESH_TABLE_STATS     256     /* Refresh table stats hash table */
-+#define REFRESH_INDEX_STATS     512     /* Refresh index stats hash table */
- /* The following can't be set with mysql_refresh() */
- #define REFRESH_READ_LOCK     16384   /* Lock tables for read */
-diff -r 3ed7e96969f9 sql/handler.cc
---- a/sql/handler.cc   Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/handler.cc   Thu Dec 04 08:54:27 2008 -0800
-@@ -1205,6 +1205,7 @@
-         error=1;
-       }
-       status_var_increment(thd->status_var.ha_commit_count);
-+      thd->diff_commit_trans++;
-       ha_info_next= ha_info->next();
-       ha_info->reset(); /* keep it conveniently zero-filled */
-     }
-@@ -1272,6 +1273,7 @@
-         error=1;
-       }
-       status_var_increment(thd->status_var.ha_rollback_count);
-+      thd->diff_rollback_trans++;
-       ha_info_next= ha_info->next();
-       ha_info->reset(); /* keep it conveniently zero-filled */
-     }
-@@ -1724,6 +1726,7 @@
-       error=1;
-     }
-     status_var_increment(thd->status_var.ha_rollback_count);
-+    thd->diff_rollback_trans++;
-     ha_info_next= ha_info->next();
-     ha_info->reset(); /* keep it conveniently zero-filled */
-   }
-@@ -2058,6 +2061,8 @@
-       dup_ref=ref+ALIGN_SIZE(ref_length);
-     cached_table_flags= table_flags();
-   }
-+  rows_read = rows_changed = 0;
-+  memset(index_rows_read, 0, sizeof(index_rows_read));
-   DBUG_RETURN(error);
- }
-@@ -3487,6 +3492,97 @@
-   return;
- }
-+// Updates the global table stats with the TABLE this handler represents.
-+void handler::update_global_table_stats() {
-+  if (!rows_read && !rows_changed) return;  // Nothing to update.
-+  // table_cache_key is db_name + '\0' + table_name + '\0'.
-+  if (!table->s || !table->s->table_cache_key.str || !table->s->table_name.str) return;
-+
-+  TABLE_STATS* table_stats;
-+  char key[NAME_LEN * 2 + 2];
-+  // [db] + '.' + [table]
-+  sprintf(key, "%s.%s", table->s->table_cache_key.str, table->s->table_name.str);
-+
-+  pthread_mutex_lock(&LOCK_global_table_stats);
-+  // Gets the global table stats, creating one if necessary.
-+  if (!(table_stats = (TABLE_STATS*)hash_search(&global_table_stats,
-+                                                (uchar*)key,
-+                                                strlen(key)))) {
-+    if (!(table_stats = ((TABLE_STATS*)
-+                         my_malloc(sizeof(TABLE_STATS), MYF(MY_WME))))) {
-+      // Out of memory.
-+      sql_print_error("Allocating table stats failed.");
-+      goto end;
-+    }
-+    strncpy(table_stats->table, key, sizeof(table_stats->table));
-+    table_stats->rows_read = 0;
-+    table_stats->rows_changed = 0;
-+    table_stats->rows_changed_x_indexes = 0;
-+
-+    if (my_hash_insert(&global_table_stats, (uchar*)table_stats)) {
-+      // Out of memory.
-+      sql_print_error("Inserting table stats failed.");
-+      my_free((char*)table_stats, 0);
-+      goto end;
-+    }
-+  }
-+  // Updates the global table stats.
-+  table_stats->rows_read += rows_read;
-+  table_stats->rows_changed += rows_changed;
-+  table_stats->rows_changed_x_indexes +=
-+      rows_changed * (table->s->keys ? table->s->keys : 1);
-+  rows_read = rows_changed = 0;
-+end:
-+  pthread_mutex_unlock(&LOCK_global_table_stats);
-+}
-+
-+// Updates the global index stats with this handler's accumulated index reads.
-+void handler::update_global_index_stats() {
-+  // table_cache_key is db_name + '\0' + table_name + '\0'.
-+  if (!table->s || !table->s->table_cache_key.str || !table->s->table_name.str) return;
-+
-+  for (int x = 0; x < table->s->keys; x++) {
-+    if (index_rows_read[x]) {
-+      // Rows were read using this index.
-+      KEY* key_info = &table->key_info[x];
-+
-+      if (!key_info->name) continue;
-+
-+      INDEX_STATS* index_stats;
-+      char key[NAME_LEN * 3 + 3];
-+      // [db] + '.' + [table] + '.' + [index]
-+      sprintf(key, "%s.%s.%s",  table->s->table_cache_key.str,
-+              table->s->table_name.str, key_info->name);
-+
-+      pthread_mutex_lock(&LOCK_global_index_stats);
-+      // Gets the global index stats, creating one if necessary.
-+      if (!(index_stats = (INDEX_STATS*)hash_search(&global_index_stats,
-+                                                    (uchar*)key,
-+                                                    strlen(key)))) {
-+        if (!(index_stats = ((INDEX_STATS*)
-+                             my_malloc(sizeof(INDEX_STATS), MYF(MY_WME))))) {
-+          // Out of memory.
-+          sql_print_error("Allocating index stats failed.");
-+          goto end;
-+        }
-+        strncpy(index_stats->index, key, sizeof(index_stats->index));
-+        index_stats->rows_read = 0;
-+
-+        if (my_hash_insert(&global_index_stats, (uchar*)index_stats)) {
-+          // Out of memory.
-+          sql_print_error("Inserting index stats failed.");
-+          my_free((char*)index_stats, 0);
-+          goto end;
-+        }
-+      }
-+      // Updates the global index stats.
-+      index_stats->rows_read += index_rows_read[x];
-+      index_rows_read[x] = 0;
-+end:
-+      pthread_mutex_unlock(&LOCK_global_index_stats);
-+    }
-+  }
-+}
- /****************************************************************************
- ** Some general functions that isn't in the handler class
-diff -r 3ed7e96969f9 sql/handler.h
---- a/sql/handler.h    Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/handler.h    Thu Dec 04 08:54:27 2008 -0800
-@@ -29,6 +29,10 @@
- #endif
- #define USING_TRANSACTIONS
-+
-+#if MAX_KEY > 128
-+#error MAX_KEY is too large.  Values up to 128 are supported.
-+#endif
- // the following is for checking tables
-@@ -690,6 +694,7 @@
-    */
-    enum log_status (*get_log_status)(handlerton *hton, char *log);
-+
-    /*
-      Iterators creator.
-      Presence of the pointer should be checked before using
-@@ -1137,6 +1142,10 @@
-   */
-   uint auto_inc_intervals_count;
-+   ulonglong rows_read;
-+   ulonglong rows_changed;
-+   ulonglong index_rows_read[MAX_KEY];
-+
-   handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
-     :table_share(share_arg), table(0),
-     estimation_rows_to_insert(0), ht(ht_arg),
-@@ -1145,8 +1154,10 @@
-     ft_handler(0), inited(NONE),
-     locked(FALSE), implicit_emptied(0),
-     pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
--    auto_inc_intervals_count(0)
--    {}
-+    auto_inc_intervals_count(0), rows_read(0), rows_changed(0)
-+    {
-+        memset(index_rows_read, 0, sizeof(index_rows_read));
-+    }
-   virtual ~handler(void)
-   {
-     DBUG_ASSERT(locked == FALSE);
-@@ -1267,7 +1278,13 @@
-   {
-     table= table_arg;
-     table_share= share;
-+    rows_read = rows_changed = 0;
-+    memset(index_rows_read, 0, sizeof(index_rows_read));
-   }
-+  
-+  void update_global_table_stats();
-+  void update_global_index_stats();
-+
-   virtual double scan_time()
-   { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
-   virtual double read_time(uint index, uint ranges, ha_rows rows)
-diff -r 3ed7e96969f9 sql/lex.h
---- a/sql/lex.h        Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/lex.h        Thu Dec 04 08:54:27 2008 -0800
-@@ -245,6 +245,7 @@
-   { "IN",             SYM(IN_SYM)},
-   { "INDEX",          SYM(INDEX_SYM)},
-   { "INDEXES",                SYM(INDEXES)},
-+  { "INDEX_STATISTICS",       SYM(INDEX_STATS_SYM)},
-   { "INFILE",         SYM(INFILE)},
-   { "INITIAL_SIZE",   SYM(INITIAL_SIZE_SYM)},
-   { "INNER",          SYM(INNER_SYM)},
-@@ -528,6 +529,7 @@
-   { "TABLES",         SYM(TABLES)},
-   { "TABLESPACE",             SYM(TABLESPACE)},
-   { "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)},
-+  { "TABLE_STATISTICS",       SYM(TABLE_STATS_SYM)},
-   { "TEMPORARY",      SYM(TEMPORARY)},
-   { "TEMPTABLE",      SYM(TEMPTABLE_SYM)},
-   { "TERMINATED",     SYM(TERMINATED)},
-@@ -570,6 +572,7 @@
-   { "USE",            SYM(USE_SYM)},
-   { "USER",           SYM(USER)},
-   { "USER_RESOURCES", SYM(RESOURCES)},
-+  { "USER_STATISTICS",        SYM(USER_STATS_SYM)},
-   { "USE_FRM",                SYM(USE_FRM)},
-   { "USING",          SYM(USING)},
-   { "UTC_DATE",         SYM(UTC_DATE_SYM)},
-diff -r 3ed7e96969f9 sql/mysql_priv.h
---- a/sql/mysql_priv.h Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/mysql_priv.h Thu Dec 04 08:54:27 2008 -0800
-@@ -1060,7 +1060,19 @@
- bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
- void init_max_user_conn(void);
- void init_update_queries(void);
-+void init_global_user_stats(void);
-+void init_global_table_stats(void);
-+void init_global_index_stats(void);
- void free_max_user_conn(void);
-+void free_global_user_stats(void);
-+void free_global_table_stats(void);
-+void free_global_index_stats(void);
-+// Uses the THD to update the global stats.
-+void update_global_user_stats(THD* thd);
-+// Set stats for concurrent connections displayed by mysqld_show().
-+void set_concurrent_connections_stats();
-+// Increments connection count for user.
-+int increment_connection_count(THD* thd, bool use_lock);
- pthread_handler_t handle_bootstrap(void *arg);
- int mysql_execute_command(THD *thd);
- bool do_command(THD *thd);
-@@ -2015,6 +2027,12 @@
- extern struct system_variables max_system_variables;
- extern struct system_status_var global_status_var;
- extern struct rand_struct sql_rand;
-+extern HASH global_user_stats;
-+extern pthread_mutex_t LOCK_global_user_stats;
-+extern HASH global_table_stats;
-+extern pthread_mutex_t LOCK_global_table_stats;
-+extern HASH global_index_stats;
-+extern pthread_mutex_t LOCK_global_index_stats;
- extern const char *opt_date_time_formats[];
- extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
-diff -r 3ed7e96969f9 sql/mysqld.cc
---- a/sql/mysqld.cc    Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/mysqld.cc    Thu Dec 04 08:54:27 2008 -0800
-@@ -589,6 +589,11 @@
-               LOCK_global_system_variables,
-               LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
-                 LOCK_connection_count;
-+
-+pthread_mutex_t LOCK_global_user_stats;
-+pthread_mutex_t LOCK_global_table_stats;
-+pthread_mutex_t LOCK_global_index_stats;
-+
- /**
-   The below lock protects access to two global server variables:
-   max_prepared_stmt_count and prepared_stmt_count. These variables
-@@ -1266,6 +1271,9 @@
-   x_free(opt_secure_file_priv);
-   bitmap_free(&temp_pool);
-   free_max_user_conn();
-+  free_global_user_stats();
-+  free_global_table_stats();
-+  free_global_index_stats();
- #ifdef HAVE_REPLICATION
-   end_slave_list();
- #endif
-@@ -1378,6 +1386,9 @@
-   (void) pthread_cond_destroy(&COND_thread_cache);
-   (void) pthread_cond_destroy(&COND_flush_thread_cache);
-   (void) pthread_cond_destroy(&COND_manager);
-+  (void) pthread_mutex_destroy(&LOCK_global_user_stats);
-+  (void) pthread_mutex_destroy(&LOCK_global_table_stats);
-+  (void) pthread_mutex_destroy(&LOCK_global_index_stats);
- }
- #endif /*EMBEDDED_LIBRARY*/
-@@ -3072,6 +3083,7 @@
-   {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
-   {"show_grants",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
-   {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
-+  {"show_index_stats",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_INDEX_STATS]), SHOW_LONG_STATUS},
-   {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
-   {"show_new_master",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
-   {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
-@@ -3089,9 +3101,11 @@
-   {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
-   {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
-   {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
-+  {"show_table_stats",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS},
-   {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
-   {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
-   {"show_triggers",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
-+  {"show_user_stats",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS},
-   {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
-   {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
-   {"slave_start",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
-@@ -3507,6 +3521,9 @@
- #endif
-   (void) pthread_mutex_init(&LOCK_server_started, MY_MUTEX_INIT_FAST);
-   (void) pthread_cond_init(&COND_server_started,NULL);
-+  (void) pthread_mutex_init(&LOCK_global_user_stats, MY_MUTEX_INIT_FAST);
-+  (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
-+  (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
-   sp_cache_init();
- #ifdef HAVE_EVENT_SCHEDULER
-   Events::init_mutexes();
-@@ -3872,6 +3889,9 @@
-   if (!errmesg[0][0])
-     unireg_abort(1);
-+   init_global_table_stats();
-+   init_global_index_stats();
-+
-   /* We have to initialize the storage engines before CSV logging */
-   if (ha_init())
-   {
-@@ -4018,6 +4038,7 @@
-   init_max_user_conn();
-   init_update_queries();
-+  init_global_user_stats();
-   DBUG_RETURN(0);
- }
-diff -r 3ed7e96969f9 sql/sql_base.cc
---- a/sql/sql_base.cc  Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_base.cc  Thu Dec 04 08:54:27 2008 -0800
-@@ -1343,6 +1343,12 @@
-   DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str,
-                         table->s->table_name.str, (long) table));
-+  if(table->file)
-+  {
-+    table->file->update_global_table_stats();
-+    table->file->update_global_index_stats();
-+  }
-+
-   *table_ptr=table->next;
-   /*
-     When closing a MERGE parent or child table, detach the children first.
-@@ -1882,6 +1888,9 @@
-   DBUG_ENTER("close_temporary");
-   DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
-                           table->s->db.str, table->s->table_name.str));
-+ 
-+  table->file->update_global_table_stats();
-+  table->file->update_global_index_stats();
-   free_io_cache(table);
-   closefrm(table, 0);
-diff -r 3ed7e96969f9 sql/sql_class.cc
---- a/sql/sql_class.cc Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_class.cc Thu Dec 04 08:54:27 2008 -0800
-@@ -578,6 +578,8 @@
-   bzero(ha_data, sizeof(ha_data));
-   mysys_var=0;
-   binlog_evt_union.do_union= FALSE;
-+  busy_time = 0;
-+  updated_row_count = 0;
-   enable_slow_log= 0;
- #ifndef DBUG_OFF
-   dbug_sentry=THD_SENTRY_MAGIC;
-@@ -838,6 +838,7 @@
-   reset_current_stmt_binlog_row_based();
-   bzero((char *) &status_var, sizeof(status_var));
-   sql_log_bin_toplevel= options & OPTION_BIN_LOG;
-+  reset_stats();
- #if defined(ENABLED_DEBUG_SYNC)
-   /* Initialize the Debug Sync Facility. See debug_sync.cc. */
-@@ -845,6 +846,52 @@
- #endif /* defined(ENABLED_DEBUG_SYNC) */
- }
-+// Resets stats in a THD.
-+void THD::reset_stats(void) {
-+  current_connect_time = time(NULL);
-+  last_global_update_time = current_connect_time;
-+  reset_diff_stats();
-+}
-+
-+// Resets the 'diff' stats, which are used to update global stats.
-+void THD::reset_diff_stats(void) {
-+  diff_total_busy_time = 0;
-+  diff_total_sent_rows = 0;
-+  diff_total_updated_rows = 0;
-+  diff_select_commands = 0;
-+  diff_update_commands = 0;
-+  diff_other_commands = 0;
-+  diff_commit_trans = 0;
-+  diff_rollback_trans = 0;
-+}
-+
-+// Updates 'diff' stats of a THD.
-+void THD::update_stats() {
-+  diff_total_busy_time += busy_time;
-+  diff_total_sent_rows += sent_row_count;
-+  diff_total_updated_rows += updated_row_count;
-+  // The replication thread has the COM_CONNECT command.
-+  if ((old_command == COM_QUERY || command == COM_CONNECT) &&
-+      (lex->sql_command >= 0 && lex->sql_command < SQLCOM_END)) {
-+    // A SQL query.
-+    if (lex->sql_command == SQLCOM_SELECT) {
-+      if (!(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)) {
-+        diff_select_commands++;
-+      } else {
-+        // 'SHOW ' commands become SQLCOM_SELECT.
-+        diff_other_commands++;
-+        // 'SHOW ' commands shouldn't inflate total sent row count.
-+        diff_total_sent_rows -= sent_row_count;
-+      }
-+    } else if (is_update_query(lex->sql_command)) {
-+      diff_update_commands++;
-+    } else {
-+      diff_other_commands++;
-+    }
-+  }
-+  // diff_commit_trans is updated in handler.cc.
-+  // diff_rollback_trans is updated in handler.cc.
-+}
- /*
-   Init THD for query processing.
-diff -r 3ed7e96969f9 sql/sql_class.h
---- a/sql/sql_class.h  Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_class.h  Thu Dec 04 08:54:27 2008 -0800
-@@ -1327,6 +1327,8 @@
-     first byte of the packet in do_command()
-   */
-   enum enum_server_command command;
-+  // Used to save the command, before it is set to COM_SLEEP.
-+  enum enum_server_command old_command;
-   uint32     server_id;
-   uint32     file_id;                 // for LOAD DATA INFILE
-   /* remote (peer) port */
-@@ -1616,6 +1618,7 @@
-   ulonglong  options;           /* Bitmap of states */
-   longlong   row_count_func;    /* For the ROW_COUNT() function */
-   ha_rows    cuted_fields;
-+  ha_rows    updated_row_count;
-   /*
-     number of rows we actually sent to the client, including "synthetic"
-@@ -1767,6 +1770,27 @@
-   */
-   LOG_INFO*  current_linfo;
-   NET*       slave_net;                       // network connection from slave -> m.
-+
-+  /*
-+    Used to update global user stats.  The global user stats are updated
-+    occasionally with the 'diff' variables.  After the update, the 'diff'
-+    variables are reset to 0.
-+   */
-+  // Time when the current thread connected to MySQL.
-+  time_t current_connect_time;
-+  // Last time when THD stats were updated in global_user_stats.
-+  time_t last_global_update_time;
-+  // Busy (non-idle) time for just one command.
-+  double busy_time;
-+  // Busy time not updated in global_user_stats yet.
-+  double diff_total_busy_time;
-+  // Number of rows not reflected in global_user_stats yet.
-+  ha_rows diff_total_sent_rows, diff_total_updated_rows;
-+  // Number of commands not reflected in global_user_stats yet.
-+  ulonglong diff_select_commands, diff_update_commands, diff_other_commands;
-+  // Number of transactions not reflected in global_user_stats yet.
-+  ulonglong diff_commit_trans, diff_rollback_trans;
-+
-   /* Used by the sys_var class to store temporary values */
-   union
-   {
-@@ -1827,6 +1851,9 @@
-     alloc_root. 
-   */
-   void init_for_queries();
-+  void reset_stats(void);
-+  void reset_diff_stats(void);
-+  void update_stats(void);
-   void change_user(void);
-   void cleanup(void);
-   void cleanup_after_query();
-diff -r 3ed7e96969f9 sql/sql_connect.cc
---- a/sql/sql_connect.cc       Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_connect.cc       Thu Dec 04 08:54:27 2008 -0800
-@@ -520,6 +520,14 @@
-                  0,0,
-                  (hash_get_key) get_key_conn, (hash_free_key) free_user,
-                  0);
-+  if (hash_init(&hash_user_connections,system_charset_info,max_connections,
-+                0,0,
-+                (hash_get_key) get_key_conn, (hash_free_key) free_user,
-+                0)) {
-+    sql_print_error("Initializing hash_user_connections failed.");
-+    exit(1);
-+  }
-+
- #endif
- }
-@@ -1107,6 +1115,13 @@
-     if (login_connection(thd))
-       goto end_thread;
-+    thd->reset_stats();
-+    // Updates global user connection stats.
-+    if (increment_connection_count(thd, true)) {
-+      net_send_error(thd, ER_OUTOFMEMORY);  // Out of memory
-+      goto end_thread;
-+    }
-+
-     prepare_new_connection_state(thd);
-     while (!net->error && net->vio != 0 &&
-@@ -1119,6 +1134,8 @@
-    
- end_thread:
-     close_connection(thd, 0, 1);
-+    thd->update_stats();
-+    update_global_user_stats(thd);
-     if (thread_scheduler.end_thread(thd,1))
-       return 0;                                 // Probably no-threads
-diff -r 3ed7e96969f9 sql/sql_delete.cc
---- a/sql/sql_delete.cc        Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_delete.cc        Thu Dec 04 08:54:27 2008 -0800
-@@ -402,6 +402,7 @@
-     my_ok(thd, (ha_rows) thd->row_count_func);
-     DBUG_PRINT("info",("%ld records deleted",(long) deleted));
-   }
-+  thd->updated_row_count += deleted;
-   DBUG_RETURN(error >= 0 || thd->is_error());
- }
-@@ -938,6 +939,7 @@
-     thd->row_count_func= deleted;
-     ::my_ok(thd, (ha_rows) thd->row_count_func);
-   }
-+  thd->updated_row_count += deleted;
-   return 0;
- }
-diff -r 3ed7e96969f9 sql/sql_insert.cc
---- a/sql/sql_insert.cc        Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_insert.cc        Thu Dec 04 08:54:27 2008 -0800
-@@ -969,6 +969,7 @@
-     thd->row_count_func= info.copied + info.deleted + updated;
-     ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
-   }
-+  thd->updated_row_count += thd->row_count_func;
-   thd->abort_on_warning= 0;
-   DBUG_RETURN(FALSE);
-diff -r 3ed7e96969f9 sql/sql_lex.h
---- a/sql/sql_lex.h    Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_lex.h    Thu Dec 04 08:54:27 2008 -0800
-@@ -118,7 +118,7 @@
-   SQLCOM_SHOW_CREATE_TRIGGER,
-   SQLCOM_ALTER_DB_UPGRADE,
-   SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
--
-+  SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, 
-   /*
-     When a command is added here, be sure it's also added in mysqld.cc
-     in "struct show_var_st status_vars[]= {" ...
-diff -r 3ed7e96969f9 sql/sql_parse.cc
---- a/sql/sql_parse.cc Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_parse.cc Thu Dec 04 08:54:27 2008 -0800
-@@ -45,6 +45,15 @@
- static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
- static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
-+
-+HASH global_user_stats;
-+extern pthread_mutex_t LOCK_global_user_stats;
-+
-+HASH global_table_stats;
-+extern pthread_mutex_t LOCK_global_table_stats;
-+
-+HASH global_index_stats;
-+extern pthread_mutex_t LOCK_global_index_stats;
- const char *any_db="*any*";   // Special symbol for check_access
-@@ -326,7 +335,9 @@
-   sql_command_flags[SQLCOM_SHOW_FUNC_CODE]=  CF_STATUS_COMMAND;
-   sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]=  CF_STATUS_COMMAND;
-   sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND;
--  sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND;
-+  sql_command_flags[SQLCOM_SHOW_USER_STATS]= CF_STATUS_COMMAND;
-+  sql_command_flags[SQLCOM_SHOW_TABLE_STATS]= CF_STATUS_COMMAND;
-+  sql_command_flags[SQLCOM_SHOW_INDEX_STATS]= CF_STATUS_COMMAND;
-    sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
-                                                  CF_SHOW_TABLE_COMMAND |
-@@ -544,6 +555,86 @@
-   DBUG_RETURN(0);
- }
-+extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length,
-+                                    my_bool not_used __attribute__((unused)))
-+{
-+  *length = strlen(user_stats->user);
-+  return (uchar*)user_stats->user;
-+}
-+
-+extern "C" void free_user_stats(USER_STATS* user_stats)
-+{
-+  my_free((char*)user_stats, MYF(0));
-+}
-+
-+void init_global_user_stats(void)
-+{
-+  if (hash_init(&global_user_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_user_stats,
-+                (hash_free_key)free_user_stats, 0)) {
-+    sql_print_error("Initializing global_user_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+extern "C" uchar *get_key_table_stats(TABLE_STATS *table_stats, size_t *length,
-+                                     my_bool not_used __attribute__((unused)))
-+{
-+  *length = strlen(table_stats->table);
-+  return (uchar*)table_stats->table;
-+}
-+
-+extern "C" void free_table_stats(TABLE_STATS* table_stats)
-+{
-+  my_free((char*)table_stats, MYF(0));
-+}
-+
-+void init_global_table_stats(void)
-+{
-+  if (hash_init(&global_table_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_table_stats,
-+                (hash_free_key)free_table_stats, 0)) {
-+    sql_print_error("Initializing global_table_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+extern "C" uchar *get_key_index_stats(INDEX_STATS *index_stats, size_t *length,
-+                                     my_bool not_used __attribute__((unused)))
-+{
-+  *length = strlen(index_stats->index);
-+  return (uchar*)index_stats->index;
-+}
-+
-+extern "C" void free_index_stats(INDEX_STATS* index_stats)
-+{
-+  my_free((char*)index_stats, MYF(0));
-+}
-+
-+void init_global_index_stats(void)
-+{
-+  if (hash_init(&global_index_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_index_stats,
-+                (hash_free_key)free_index_stats, 0)) {
-+    sql_print_error("Initializing global_index_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+void free_global_user_stats(void)
-+{
-+  hash_free(&global_user_stats);
-+}
-+
-+void free_global_table_stats(void)
-+{
-+  hash_free(&global_table_stats);
-+}
-+
-+void free_global_index_stats(void)
-+{
-+  hash_free(&global_index_stats);
-+}
- /**
-   @brief Check access privs for a MERGE table and fix children lock types.
-@@ -962,6 +1053,9 @@
-   DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
-   thd->command=command;
-+  // To increment the correct command counter for user stats, 'command' must
-+  // be saved because it is set to COM_SLEEP at the end of this function.
-+  thd->old_command = command;
-   /*
-     Commands which always take a long time are logged into
-     the slow log only if opt_log_slow_admin_statements is set.
-@@ -1740,6 +1834,9 @@
-   case SCH_COLUMN_PRIVILEGES:
-   case SCH_TABLE_CONSTRAINTS:
-   case SCH_KEY_COLUMN_USAGE:
-+  case SCH_USER_STATS:
-+  case SCH_TABLE_STATS:
-+  case SCH_INDEX_STATS:
-   default:
-     break;
-   }
-@@ -2129,6 +2226,9 @@
-     my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
-     break;
- #endif
-+  case SQLCOM_SHOW_USER_STATS:
-+  case SQLCOM_SHOW_TABLE_STATS:
-+  case SQLCOM_SHOW_INDEX_STATS:
-   case SQLCOM_SHOW_STATUS_PROC:
-   case SQLCOM_SHOW_STATUS_FUNC:
-     if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
-@@ -2306,6 +2406,7 @@
-   }
- #endif
-+
-   case SQLCOM_BACKUP_TABLE:
-   {
-     DBUG_ASSERT(first_table == all_tables && first_table != 0);
-@@ -5372,6 +5473,130 @@
- #endif /*NO_EMBEDDED_ACCESS_CHECKS*/
-+// 'mysql_system_user' is used for when the user is not defined for a THD.
-+static char mysql_system_user[] = "#mysql_system#";
-+
-+// Returns 'user' if it's not NULL.  Returns 'mysql_system_user' otherwise.
-+static char* get_valid_user_string(char* user) {
-+  return user ? user : mysql_system_user;
-+}
-+
-+// Increments the global user stats connection count.  If 'use_lock' is true,
-+// 'LOCK_global_user_stats' will be locked/unlocked.  Returns 0 on success,
-+// 1 on error.
-+int increment_connection_count(THD* thd, bool use_lock) {
-+  char* user_string = get_valid_user_string(thd->main_security_ctx.user);
-+
-+  USER_STATS* user_stats;
-+  int return_value = 0;
-+
-+  if (use_lock) pthread_mutex_lock(&LOCK_global_user_stats);
-+  if (!(user_stats = (USER_STATS*)hash_search(&global_user_stats,
-+                                              (uchar*)user_string,
-+                                              strlen(user_string)))) {
-+    // First connection for this user.
-+    if (!(user_stats = ((USER_STATS*)
-+                        my_malloc(sizeof(USER_STATS), MYF(MY_WME))))) {
-+      // Out of memory.
-+      return_value = 1;
-+      goto end;
-+    }
-+    strncpy(user_stats->user, user_string, sizeof(user_stats->user));
-+    user_stats->total_connections = 0;
-+    user_stats->concurrent_connections = 0;
-+    user_stats->connected_time = 0;
-+    user_stats->busy_time = 0;
-+    user_stats->rows_fetched = 0;
-+    user_stats->rows_updated = 0;
-+    user_stats->select_commands = 0;
-+    user_stats->update_commands = 0;
-+    user_stats->other_commands = 0;
-+    user_stats->commit_trans = 0;
-+    user_stats->rollback_trans = 0;
-+
-+    if (my_hash_insert(&global_user_stats, (uchar*)user_stats)) {
-+      // Out of memory.
-+      my_free((char*)user_stats, 0);
-+      return_value = 1;
-+      goto end;
-+    }
-+  }
-+  user_stats->total_connections++;
-+end:
-+  if (use_lock) pthread_mutex_unlock(&LOCK_global_user_stats);
-+  return return_value;
-+}
-+
-+// Used to update the global user stats.
-+static void update_global_user_stats_with_user(THD* thd,
-+                                               USER_STATS* user_stats) {
-+  time_t current_time = time(NULL);
-+  user_stats->connected_time += current_time - thd->last_global_update_time;
-+  thd->last_global_update_time = current_time;
-+  user_stats->busy_time += thd->diff_total_busy_time;
-+  user_stats->rows_fetched += thd->diff_total_sent_rows;
-+  user_stats->rows_updated += thd->diff_total_updated_rows;
-+  user_stats->select_commands += thd->diff_select_commands;
-+  user_stats->update_commands += thd->diff_update_commands;
-+  user_stats->other_commands += thd->diff_other_commands;
-+  user_stats->commit_trans += thd->diff_commit_trans;
-+  user_stats->rollback_trans += thd->diff_rollback_trans;
-+}
-+
-+// Updates the global stats of a thread/user.
-+void update_global_user_stats(THD* thd) {
-+  char* user_string = get_valid_user_string(thd->main_security_ctx.user);
-+
-+  USER_STATS* user_stats;
-+  pthread_mutex_lock(&LOCK_global_user_stats);
-+  if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
-+                                             (uchar*)user_string,
-+                                             strlen(user_string)))) {
-+    // Found user.
-+    update_global_user_stats_with_user(thd, user_stats);
-+    thd->reset_diff_stats();
-+  } else {
-+    // The user name should exist.
-+    increment_connection_count(thd, false);
-+  }
-+  pthread_mutex_unlock(&LOCK_global_user_stats);
-+}
-+
-+// Determines the concurrent number of connections of current threads.
-+void set_concurrent_connections_stats() {
-+  USER_STATS* user_stats;
-+
-+  pthread_mutex_lock(&LOCK_global_user_stats);
-+  pthread_mutex_lock(&LOCK_thread_count);
-+
-+  // Resets all concurrent connections to 0.
-+  for (int i = 0; i < global_user_stats.records; ++i) {
-+    user_stats = (USER_STATS*)hash_element(&global_user_stats, i);
-+    user_stats->concurrent_connections = 0;
-+  }
-+
-+  I_List_iterator<THD> it(threads);
-+  THD* thd;
-+  // Iterates through the current threads.
-+  while ((thd = it++)) {
-+    char* user_string = get_valid_user_string(thd->main_security_ctx.user);
-+    if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
-+                                               (uchar*)user_string,
-+                                               strlen(user_string)))) {
-+      // Found user.
-+      user_stats->concurrent_connections++;
-+      update_global_user_stats_with_user(thd, user_stats);
-+      thd->reset_diff_stats();
-+    } else {
-+      // The user name should exist.
-+      increment_connection_count(thd, false);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_thread_count);
-+  pthread_mutex_unlock(&LOCK_global_user_stats);
-+}
-+
-+
- /**
-   check for global access and give descriptive error message if it fails.
-@@ -5539,6 +5764,10 @@
-     reset_dynamic(&thd->user_var_events);
-     thd->user_var_events_alloc= thd->mem_root;
-   }
-+  
-+  thd->updated_row_count=0;
-+  thd->busy_time=0;
-+
-   thd->clear_error();
-   thd->main_da.reset_diagnostics_area();
-   thd->total_warn_count=0;                    // Warnings for this query
-@@ -5722,6 +5951,16 @@
-   DBUG_ENTER("mysql_parse");
-   DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
-+
-+  int start_time_error = 0;
-+  int end_time_error = 0;
-+  struct timeval start_time, end_time;
-+  double start_usecs = 0;
-+  double end_usecs = 0;
-+  // Gets the start time, in order to measure how long this command takes.
-+  if (!(start_time_error = gettimeofday(&start_time, NULL))) {
-+    start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
-+  }
-   /*
-     Warning.
-@@ -5816,6 +6055,27 @@
-     *found_semicolon= NULL;
-   }
-+  // Gets the end time.
-+  if (!(end_time_error = gettimeofday(&end_time, NULL))) {
-+    end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
-+  }
-+
-+  // Calculates the difference between the end and start times.
-+  if (end_usecs >= start_usecs && !start_time_error && !end_time_error) {
-+    thd->busy_time = (end_usecs - start_usecs) / 1000000;
-+    // In case there are bad values, 2629743 is the #seconds in a month.
-+    if (thd->busy_time > 2629743) {
-+      thd->busy_time = 0;
-+    }
-+  } else {
-+    // end time went back in time, or gettimeofday() failed.
-+    thd->busy_time = 0;
-+  }
-+
-+  // Updates THD stats and the global user stats.
-+  thd->update_stats();
-+  update_global_user_stats(thd);
-+
-   DBUG_VOID_RETURN;
- }
-@@ -6398,6 +6658,7 @@
-     tables->lock_type= lock_type;
-     tables->updating=  for_update;
-   }
-+
-   DBUG_VOID_RETURN;
- }
-@@ -6779,6 +7040,21 @@
- #endif
-  if (options & REFRESH_USER_RESOURCES)
-    reset_mqh((LEX_USER *) NULL, 0);             /* purecov: inspected */
-+ if (options & REFRESH_TABLE_STATS)
-+ {
-+   pthread_mutex_lock(&LOCK_global_table_stats);
-+   free_global_table_stats();
-+   init_global_table_stats();
-+   pthread_mutex_unlock(&LOCK_global_table_stats);
-+ }
-+ if (options & REFRESH_INDEX_STATS)
-+ {
-+   pthread_mutex_lock(&LOCK_global_index_stats);
-+   free_global_index_stats();
-+   init_global_index_stats();
-+   pthread_mutex_unlock(&LOCK_global_index_stats);
-+ }
-+   
-  *write_to_binlog= tmp_write_to_binlog;
-  return result;
- }
-diff -r 3ed7e96969f9 sql/sql_show.cc
---- a/sql/sql_show.cc  Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_show.cc  Thu Dec 04 08:54:27 2008 -0800
-@@ -2260,6 +2260,90 @@
-   DBUG_RETURN(FALSE);
- }
-+
-+int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_user_stats");
-+
-+  set_concurrent_connections_stats();
-+
-+  pthread_mutex_lock(&LOCK_global_user_stats);
-+  for (int i = 0; i < global_user_stats.records; ++i) {
-+    restore_record(table, s->default_values);
-+    USER_STATS *user_stats = (USER_STATS*)hash_element(&global_user_stats, i);
-+    table->field[0]->store(user_stats->user, strlen(user_stats->user), system_charset_info);
-+    table->field[1]->store((longlong)user_stats->total_connections, TRUE);
-+    table->field[2]->store((longlong)user_stats->concurrent_connections, TRUE);
-+    table->field[3]->store((longlong)user_stats->connected_time, TRUE);
-+    table->field[4]->store((longlong)user_stats->busy_time, TRUE);
-+    table->field[5]->store((longlong)user_stats->rows_fetched, TRUE);
-+    table->field[6]->store((longlong)user_stats->rows_updated, TRUE);
-+    table->field[7]->store((longlong)user_stats->select_commands, TRUE);
-+    table->field[8]->store((longlong)user_stats->update_commands, TRUE);
-+    table->field[9]->store((longlong)user_stats->other_commands, TRUE);
-+    table->field[10]->store((longlong)user_stats->commit_trans, TRUE);
-+    table->field[11]->store((longlong)user_stats->rollback_trans, TRUE);
-+
-+    if (schema_table_store_record(thd, table))
-+    {
-+      VOID(pthread_mutex_unlock(&LOCK_global_user_stats));
-+      DBUG_RETURN(1);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_global_user_stats);
-+  DBUG_RETURN(0);
-+}
-+
-+
-+int fill_schema_table_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_table_stats");
-+
-+  pthread_mutex_lock(&LOCK_global_table_stats);
-+  for (int i = 0; i < global_table_stats.records; ++i) {
-+    restore_record(table, s->default_values);
-+    TABLE_STATS *table_stats = 
-+      (TABLE_STATS*)hash_element(&global_table_stats, i);
-+    table->field[0]->store(table_stats->table, strlen(table_stats->table), system_charset_info);
-+    table->field[1]->store((longlong)table_stats->rows_read, TRUE);
-+    table->field[2]->store((longlong)table_stats->rows_changed, TRUE);
-+    table->field[3]->store((longlong)table_stats->rows_changed_x_indexes, TRUE);
-+
-+    if (schema_table_store_record(thd, table))
-+    {
-+      VOID(pthread_mutex_unlock(&LOCK_global_table_stats));
-+      DBUG_RETURN(1);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_global_table_stats);
-+  DBUG_RETURN(0);
-+}
-+
-+
-+int fill_schema_index_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_index_stats");
-+
-+  pthread_mutex_lock(&LOCK_global_index_stats);
-+  for (int i = 0; i < global_index_stats.records; ++i) {
-+    restore_record(table, s->default_values);
-+    INDEX_STATS *index_stats = 
-+      (INDEX_STATS*)hash_element(&global_index_stats, i);
-+    table->field[0]->store(index_stats->index, strlen(index_stats->index), system_charset_info);
-+    table->field[1]->store((longlong)index_stats->rows_read, TRUE);
-+
-+    if (schema_table_store_record(thd, table))
-+    {
-+      VOID(pthread_mutex_unlock(&LOCK_global_index_stats));
-+      DBUG_RETURN(1);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_global_index_stats);
-+  DBUG_RETURN(0);
-+}
- /* collect status for all running threads */
-@@ -6606,6 +6690,38 @@
-   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
- };
-+ST_FIELD_INFO user_stats_fields_info[]=
-+{
-+  {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
-+  {"TOTAL_CONNECTIONS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Total_connections", SKIP_OPEN_TABLE},
-+  {"CONCURRENT_CONNECTIONS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Concurrent_connections", SKIP_OPEN_TABLE},
-+  {"CONNECTED_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Connected_time", SKIP_OPEN_TABLE},
-+  {"BUSY_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Busy_time", SKIP_OPEN_TABLE},
-+  {"ROWS_FETCHED", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_fetched", SKIP_OPEN_TABLE},
-+  {"ROWS_UPDATED", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_updated", SKIP_OPEN_TABLE},
-+  {"SELECT_COMMANDS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Select_commands", SKIP_OPEN_TABLE},
-+  {"UPDATE_COMMANDS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Update_commands", SKIP_OPEN_TABLE},
-+  {"OTHER_COMMANDS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Other_commands", SKIP_OPEN_TABLE},
-+  {"COMMIT_TRANSACTIONS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Commit_transactions", SKIP_OPEN_TABLE},
-+  {"ROLLBACK_TRANSACTIONS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rollback_transactions", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+ST_FIELD_INFO table_stats_fields_info[]=
-+{
-+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name", SKIP_OPEN_TABLE},
-+  {"ROWS_READ", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_read", SKIP_OPEN_TABLE},
-+  {"ROWS_CHANGED", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_changed", SKIP_OPEN_TABLE},
-+  {"ROWS_CHANGED_INDEXES", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_changed_x_#indexes", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+ST_FIELD_INFO index_stats_fields_info[]=
-+{
-+  {"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name", SKIP_OPEN_TABLE},
-+  {"ROWS_READ", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_read", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
- /*
-   Description of ST_FIELD_INFO in table.h
-@@ -6824,6 +6824,8 @@
-    fill_status, make_old_format, 0, 0, -1, 0, 0},
-   {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
-    fill_variables, make_old_format, 0, 0, -1, 0, 0},
-+  {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
-+   fill_schema_index_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
-    get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
-    OPEN_TABLE_ONLY},
-@@ -6683,11 +6801,15 @@
-    get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
-   {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
-    fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
-+  {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
-+   fill_schema_table_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"TRIGGERS", triggers_fields_info, create_schema_table,
-    get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
-    OPEN_TABLE_ONLY},
-   {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, 
-    fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
-+  {"USER_STATISTICS", user_stats_fields_info, create_schema_table, 
-+   fill_schema_user_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
-    make_old_format, 0, -1, -1, 1, 0},
-   {"VIEWS", view_fields_info, create_schema_table, 
-diff -r 3ed7e96969f9 sql/sql_update.cc
---- a/sql/sql_update.cc        Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_update.cc        Thu Dec 04 08:54:27 2008 -0800
-@@ -816,6 +816,7 @@
-     thd->row_count_func=
-       (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-     my_ok(thd, (ulong) thd->row_count_func, id, buff);
-+    thd->updated_row_count += thd->row_count_func;
-     DBUG_PRINT("info",("%ld records updated", (long) updated));
-   }
-   thd->count_cuted_fields= CHECK_FIELD_IGNORE;                /* calc cuted fields */
-@@ -2038,5 +2039,6 @@
-   thd->row_count_func=
-     (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-   ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
-+  thd->updated_row_count += thd->row_count_func;
-   DBUG_RETURN(FALSE);
- }
-diff -r 3ed7e96969f9 sql/sql_yacc.yy
---- a/sql/sql_yacc.yy  Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_yacc.yy  Thu Dec 04 08:54:27 2008 -0800
-@@ -738,6 +738,7 @@
- %token  IMPORT
- %token  INDEXES
- %token  INDEX_SYM
-+%token        INDEX_STATS_SYM
- %token  INFILE
- %token  INITIAL_SIZE_SYM
- %token  INNER_SYM                     /* SQL-2003-R */
-@@ -1026,6 +1027,7 @@
- %token  TABLE_REF_PRIORITY
- %token  TABLE_SYM                     /* SQL-2003-R */
- %token  TABLE_CHECKSUM_SYM
-+%token        TABLE_STATS_SYM
- %token  TEMPORARY                     /* SQL-2003-N */
- %token  TEMPTABLE_SYM
- %token  TERMINATED
-@@ -1071,6 +1073,7 @@
- %token  UPGRADE_SYM
- %token  USAGE                         /* SQL-2003-N */
- %token  USER                          /* SQL-2003-R */
-+%token        USER_STATS_SYM
- %token  USE_FRM
- %token  USE_SYM
- %token  USING                         /* SQL-2003-R */
-@@ -10090,6 +10093,27 @@
-           {
-             Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
-           }
-+        | USER_STATS_SYM wild_and_where
-+          {
-+             LEX *lex= Lex;
-+             lex->sql_command= SQLCOM_SHOW_USER_STATS;
-+             if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
-+               MYSQL_YYABORT;
-+          }
-+        | TABLE_STATS_SYM wild_and_where
-+          {
-+             LEX *lex= Lex;
-+             lex->sql_command= SQLCOM_SHOW_TABLE_STATS;
-+             if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
-+               MYSQL_YYABORT;
-+          }
-+        | INDEX_STATS_SYM wild_and_where
-+          {
-+             LEX *lex= Lex;
-+             lex->sql_command= SQLCOM_SHOW_INDEX_STATS;
-+             if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
-+               MYSQL_YYABORT;
-+          }
-         | CREATE PROCEDURE sp_name
-           {
-             LEX *lex= Lex;
-@@ -10304,6 +10328,10 @@
-           { Lex->type|= REFRESH_DES_KEY_FILE; }
-         | RESOURCES
-           { Lex->type|= REFRESH_USER_RESOURCES; }
-+        | TABLE_STATS_SYM
-+          { Lex->type|= REFRESH_TABLE_STATS; }
-+        | INDEX_STATS_SYM
-+          { Lex->type|= REFRESH_INDEX_STATS; }
-         ;
- opt_table_list:
-diff -r 3ed7e96969f9 sql/structs.h
---- a/sql/structs.h    Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/structs.h    Thu Dec 04 08:54:27 2008 -0800
-@@ -226,6 +226,28 @@
-   /* Maximum amount of resources which account is allowed to consume. */
-   USER_RESOURCES user_resources;
- } USER_CONN;
-+
-+typedef struct st_user_stats {
-+  char user[USERNAME_LENGTH + 1];
-+  uint total_connections;
-+  uint concurrent_connections;
-+  time_t connected_time;  // in seconds
-+  double busy_time;       // in seconds
-+  ha_rows rows_fetched, rows_updated;
-+  ulonglong select_commands, update_commands, other_commands;
-+  ulonglong commit_trans, rollback_trans;
-+} USER_STATS;
-+
-+typedef struct st_table_stats {
-+  char table[NAME_LEN * 2 + 2];  // [db] + '.' + [table] + '\0'
-+  ulonglong rows_read, rows_changed;
-+  ulonglong rows_changed_x_indexes;
-+} TABLE_STATS;
-+
-+typedef struct st_index_stats {
-+  char index[NAME_LEN * 3 + 3];  // [db] + '.' + [table] + '.' + [index] + '\0'
-+  ulonglong rows_read;
-+} INDEX_STATS;
-       /* Bits in form->update */
- #define REG_MAKE_DUPP         1       /* Make a copy of record when read */
-diff -r 3ed7e96969f9 sql/table.h
---- a/sql/table.h      Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/table.h      Thu Dec 04 08:54:27 2008 -0800
-@@ -879,6 +879,7 @@
-   SCH_FILES,
-   SCH_GLOBAL_STATUS,
-   SCH_GLOBAL_VARIABLES,
-+  SCH_INDEX_STATS,
-   SCH_KEY_COLUMN_USAGE,
-   SCH_OPEN_TABLES,
-   SCH_PARTITIONS,
-@@ -897,8 +898,10 @@
-   SCH_TABLE_CONSTRAINTS,
-   SCH_TABLE_NAMES,
-   SCH_TABLE_PRIVILEGES,
-+  SCH_TABLE_STATS,
-   SCH_TRIGGERS,
-   SCH_USER_PRIVILEGES,
-+  SCH_USER_STATS,
-   SCH_VARIABLES,
-   SCH_VIEWS
- };
-diff -r 3ed7e96969f9 storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc    Thu Dec 04 08:54:17 2008 -0800
-+++ b/storage/innobase/handler/ha_innodb.cc    Thu Dec 04 08:54:27 2008 -0800
-@@ -3494,6 +3494,8 @@
-       error = row_insert_for_mysql((byte*) record, prebuilt);
-+  if (error == DB_SUCCESS) rows_changed++;
-+
-       /* Handle duplicate key errors */
-       if (auto_inc_used) {
-               ulint           err;
-@@ -3571,6 +3573,8 @@
-                       break;
-               }
-       }
-+
-+      if (error == DB_SUCCESS) rows_changed++;
-       innodb_srv_conc_exit_innodb(prebuilt->trx);
-@@ -4178,6 +4182,8 @@
-               ret = row_search_for_mysql((byte*) buf, mode, prebuilt,
-                                          match_mode, 0);
-+      if (error == DB_SUCCESS) rows_changed++;
-+
-               innodb_srv_conc_exit_innodb(prebuilt->trx);
-       } else {
-@@ -4187,6 +4193,9 @@
-       if (ret == DB_SUCCESS) {
-               error = 0;
-               table->status = 0;
-+              rows_read++;
-+              if (active_index >= 0 && active_index < MAX_KEY)
-+                      index_rows_read[active_index]++;
-       } else if (ret == DB_RECORD_NOT_FOUND) {
-               error = HA_ERR_KEY_NOT_FOUND;
-@@ -4360,6 +4369,9 @@
-       if (ret == DB_SUCCESS) {
-               error = 0;
-               table->status = 0;
-+              rows_read++;
-+              if (active_index >= 0 && active_index < MAX_KEY)
-+                      index_rows_read[active_index]++;
-       } else if (ret == DB_RECORD_NOT_FOUND) {
-               error = HA_ERR_END_OF_FILE;
-diff -r 3ed7e96969f9 storage/myisam/ha_myisam.cc
---- a/storage/myisam/ha_myisam.cc      Thu Dec 04 08:54:17 2008 -0800
-+++ b/storage/myisam/ha_myisam.cc      Thu Dec 04 08:54:27 2008 -0800
-@@ -738,7 +738,9 @@
-     if ((error= update_auto_increment()))
-       return error;
-   }
--  return mi_write(file,buf);
-+  int error=mi_write(file,buf);
-+  if (!error) rows_changed++;
-+  return error;
- }
- int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
-@@ -1589,13 +1591,17 @@
-   ha_statistic_increment(&SSV::ha_update_count);
-   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
-     table->timestamp_field->set_time();
--  return mi_update(file,old_data,new_data);
-+  int error=mi_update(file,old_data,new_data);
-+  if (!error) rows_changed++;
-+  return error;
- }
- int ha_myisam::delete_row(const uchar *buf)
- {
-   ha_statistic_increment(&SSV::ha_delete_count);
--  return mi_delete(file,buf);
-+  int error=mi_delete(file,buf);
-+  if (!error) rows_changed++;
-+  return error;
- }
- int ha_myisam::index_read_map(uchar *buf, const uchar *key,
-@@ -1606,6 +1612,13 @@
-   ha_statistic_increment(&SSV::ha_read_key_count);
-   int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1616,6 +1629,14 @@
-   ha_statistic_increment(&SSV::ha_read_key_count);
-   int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+//    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    int inx = index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1637,6 +1658,13 @@
-   ha_statistic_increment(&SSV::ha_read_next_count);
-   int error=mi_rnext(file,buf,active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1646,6 +1674,13 @@
-   ha_statistic_increment(&SSV::ha_read_prev_count);
-   int error=mi_rprev(file,buf, active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1655,6 +1690,13 @@
-   ha_statistic_increment(&SSV::ha_read_first_count);
-   int error=mi_rfirst(file, buf, active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1664,6 +1706,13 @@
-   ha_statistic_increment(&SSV::ha_read_last_count);
-   int error=mi_rlast(file, buf, active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1679,6 +1728,20 @@
-     error= mi_rnext_same(file,buf);
-   } while (error == HA_ERR_RECORD_DELETED);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1695,6 +1758,7 @@
-   ha_statistic_increment(&SSV::ha_read_rnd_next_count);
-   int error=mi_scan(file, buf);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) rows_read++;
-   return error;
- }
-@@ -1708,6 +1772,7 @@
-   ha_statistic_increment(&SSV::ha_read_rnd_count);
-   int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) rows_read++;
-   return error;
- }
This page took 0.314998 seconds and 4 git commands to generate.