percona-discussion team mailing list archive
-
percona-discussion team
-
Mailing list archive
-
Message #00565
[Merge] lp:~percona-dev/percona-patches/some-backports into lp:percona-patches
Yasufumi Kinoshita has proposed merging lp:~percona-dev/percona-patches/some-backports into lp:percona-patches.
Requested reviews:
Percona developers (percona-dev)
--
https://code.launchpad.net/~percona-dev/percona-patches/some-backports/+merge/6253
Your team Percona developers is subscribed to branch lp:percona-patches.
=== added file 'innodb_extra_rseg.patch'
--- innodb_extra_rseg.patch 1970-01-01 00:00:00 +0000
+++ innodb_extra_rseg.patch 2009-05-06 09:53:18 +0000
@@ -0,0 +1,243 @@
+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@xxxxxxxxxxx>
++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_LONGLONG, 0, 0, ""},
++ {"SPACE_ID", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, ""},
++ {"PAGE_NO", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, ""},
++ {"MAX_SIZE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, ""},
++ {"CURR_SIZE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 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}
+ };
=== modified file 'innodb_io_patches.patch'
--- innodb_io_patches.patch 2009-01-14 04:45:41 +0000
+++ innodb_io_patches.patch 2009-05-06 09:53:18 +0000
@@ -1,6 +1,6 @@
diff -ruN a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c
---- a/innobase/buf/buf0flu.c 2008-12-19 02:19:35.000000000 +0900
-+++ b/innobase/buf/buf0flu.c 2009-01-09 15:51:10.000000000 +0900
+--- a/innobase/buf/buf0flu.c 2009-01-30 06:42:14.000000000 +0900
++++ b/innobase/buf/buf0flu.c 2009-05-06 10:06:28.000000000 +0900
@@ -898,10 +898,17 @@
old_page_count = page_count;
@@ -20,8 +20,8 @@
"Flush type %lu, page no %lu, neighb %lu\n",
flush_type, offset,
diff -ruN a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c
---- a/innobase/buf/buf0rea.c 2009-01-09 15:40:22.000000000 +0900
-+++ b/innobase/buf/buf0rea.c 2009-01-09 15:40:46.000000000 +0900
+--- a/innobase/buf/buf0rea.c 2009-05-06 10:04:12.000000000 +0900
++++ b/innobase/buf/buf0rea.c 2009-05-06 10:06:28.000000000 +0900
@@ -189,6 +189,10 @@
ulint err;
ulint i;
@@ -45,8 +45,8 @@
/* No read-ahead to avoid thread deadlocks */
return(0);
diff -ruN a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c
---- a/innobase/ibuf/ibuf0ibuf.c 2008-12-19 02:19:35.000000000 +0900
-+++ b/innobase/ibuf/ibuf0ibuf.c 2009-01-09 15:53:18.000000000 +0900
+--- a/innobase/ibuf/ibuf0ibuf.c 2009-01-30 06:42:16.000000000 +0900
++++ b/innobase/ibuf/ibuf0ibuf.c 2009-05-06 10:06:28.000000000 +0900
@@ -370,8 +370,9 @@
grow in size, as the references on the upper levels of the tree can
change */
@@ -74,8 +74,8 @@
sync = FALSE;
diff -ruN a/innobase/include/os0file.h b/innobase/include/os0file.h
---- a/innobase/include/os0file.h 2009-01-09 15:40:22.000000000 +0900
-+++ b/innobase/include/os0file.h 2009-01-09 15:40:46.000000000 +0900
+--- a/innobase/include/os0file.h 2009-05-06 10:04:12.000000000 +0900
++++ b/innobase/include/os0file.h 2009-05-06 10:06:28.000000000 +0900
@@ -551,8 +551,10 @@
/*========*/
ulint n, /* in: maximum number of pending aio operations
@@ -90,8 +90,8 @@
/***********************************************************************
Requests an asynchronous i/o operation. */
diff -ruN a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
---- a/innobase/include/srv0srv.h 2009-01-09 15:40:22.000000000 +0900
-+++ b/innobase/include/srv0srv.h 2009-01-09 15:54:33.000000000 +0900
+--- a/innobase/include/srv0srv.h 2009-05-06 10:04:12.000000000 +0900
++++ b/innobase/include/srv0srv.h 2009-05-06 10:19:25.000000000 +0900
@@ -89,6 +89,8 @@
extern ulint srv_lock_table_size;
@@ -101,7 +101,7 @@
#ifdef UNIV_LOG_ARCHIVE
extern ibool srv_log_archive_on;
-@@ -133,6 +135,14 @@
+@@ -133,6 +135,15 @@
extern ulong srv_max_purge_lag;
extern ibool srv_use_awe;
extern ibool srv_use_adaptive_hash_indexes;
@@ -111,14 +111,15 @@
+extern ulint srv_ibuf_active_contract;
+extern ulint srv_ibuf_accel_rate;
+extern ulint srv_flush_neighbor_pages;
++extern ulint srv_enable_unsafe_group_commit;
+extern uint srv_read_ahead;
+extern ulint srv_adaptive_checkpoint;
/*-------------------------------------------*/
extern ulint srv_n_rows_inserted;
diff -ruN a/innobase/log/log0log.c b/innobase/log/log0log.c
---- a/innobase/log/log0log.c 2008-12-19 02:19:36.000000000 +0900
-+++ b/innobase/log/log0log.c 2009-01-09 15:40:46.000000000 +0900
+--- a/innobase/log/log0log.c 2009-01-30 06:42:21.000000000 +0900
++++ b/innobase/log/log0log.c 2009-05-06 10:06:28.000000000 +0900
@@ -3326,6 +3326,15 @@
(ulong) ut_dulint_get_high(log_sys->last_checkpoint_lsn),
(ulong) ut_dulint_get_low(log_sys->last_checkpoint_lsn));
@@ -136,8 +137,8 @@
time_elapsed = 0.001 + difftime(current_time,
diff -ruN a/innobase/os/os0file.c b/innobase/os/os0file.c
---- a/innobase/os/os0file.c 2009-01-09 15:40:23.000000000 +0900
-+++ b/innobase/os/os0file.c 2009-01-09 15:40:46.000000000 +0900
+--- a/innobase/os/os0file.c 2009-05-06 10:04:12.000000000 +0900
++++ b/innobase/os/os0file.c 2009-05-06 10:06:28.000000000 +0900
@@ -2877,8 +2877,10 @@
/*========*/
ulint n, /* in: maximum number of pending aio operations
@@ -211,8 +212,8 @@
array->n_reserved++;
diff -ruN a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
---- a/innobase/srv/srv0srv.c 2009-01-09 15:40:23.000000000 +0900
-+++ b/innobase/srv/srv0srv.c 2009-01-09 15:58:36.000000000 +0900
+--- a/innobase/srv/srv0srv.c 2009-05-06 10:04:12.000000000 +0900
++++ b/innobase/srv/srv0srv.c 2009-05-06 10:20:45.000000000 +0900
@@ -167,6 +167,8 @@
ulint srv_lock_table_size = ULINT_MAX;
@@ -222,7 +223,7 @@
#ifdef UNIV_LOG_ARCHIVE
ibool srv_log_archive_on = FALSE;
-@@ -324,6 +326,22 @@
+@@ -324,6 +326,24 @@
ibool srv_use_awe = FALSE;
ibool srv_use_adaptive_hash_indexes = TRUE;
@@ -240,12 +241,14 @@
+
+ulint srv_flush_neighbor_pages = 1; /* 0:disable 1:enable */
+
++ulint srv_enable_unsafe_group_commit = 0; /* 0:disable 1:enable */
++
+uint srv_read_ahead = 3; /* 1: random 2: linear 3: Both */
+ulint srv_adaptive_checkpoint = 0; /* 0:disable 1:enable */
/*-------------------------------------------*/
ulong srv_n_spin_wait_rounds = 20;
ulong srv_n_free_tickets_to_enter = 500;
-@@ -2214,6 +2232,8 @@
+@@ -2223,6 +2243,8 @@
ibool skip_sleep = FALSE;
ulint i;
@@ -254,7 +257,7 @@
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Master thread starts, id %lu\n",
os_thread_pf(os_thread_get_curr_id()));
-@@ -2302,9 +2322,9 @@
+@@ -2311,9 +2333,9 @@
+ log_sys->n_pending_writes;
n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
@@ -266,7 +269,7 @@
srv_main_thread_op_info = "flushing log";
-@@ -2317,7 +2337,7 @@
+@@ -2326,7 +2348,7 @@
/* Try to keep the number of modified pages in the
buffer pool under the limit wished by the user */
@@ -275,7 +278,7 @@
ut_dulint_max);
/* If we had to do the flush, it may have taken
-@@ -2326,6 +2346,49 @@
+@@ -2335,6 +2357,49 @@
iteration of this loop. */
skip_sleep = TRUE;
@@ -325,7 +328,7 @@
}
if (srv_activity_count == old_activity_count) {
-@@ -2352,10 +2415,10 @@
+@@ -2361,10 +2426,10 @@
n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
@@ -338,7 +341,7 @@
srv_main_thread_op_info = "flushing log";
log_buffer_flush_to_disk();
-@@ -2365,7 +2428,7 @@
+@@ -2374,7 +2439,7 @@
even if the server were active */
srv_main_thread_op_info = "doing insert buffer merge";
@@ -347,7 +350,7 @@
srv_main_thread_op_info = "flushing log";
log_buffer_flush_to_disk();
-@@ -2407,14 +2470,14 @@
+@@ -2416,14 +2481,14 @@
(> 70 %), we assume we can afford reserving the disk(s) for
the time it requires to flush 100 pages */
@@ -364,7 +367,7 @@
ut_dulint_max);
}
-@@ -2503,7 +2566,7 @@
+@@ -2512,7 +2577,7 @@
if (srv_fast_shutdown && srv_shutdown_state > 0) {
n_bytes_merged = 0;
} else {
@@ -373,7 +376,7 @@
}
srv_main_thread_op_info = "reserving kernel mutex";
-@@ -2520,7 +2583,7 @@
+@@ -2529,7 +2594,7 @@
if (srv_fast_shutdown < 2) {
n_pages_flushed =
@@ -383,8 +386,8 @@
/* In the fastest shutdown we do not flush the buffer pool
to data files: we set n_pages_flushed to 0 artificially. */
diff -ruN a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
---- a/innobase/srv/srv0start.c 2008-12-19 02:19:37.000000000 +0900
-+++ b/innobase/srv/srv0start.c 2009-01-09 15:40:46.000000000 +0900
+--- a/innobase/srv/srv0start.c 2009-01-30 06:42:23.000000000 +0900
++++ b/innobase/srv/srv0start.c 2009-05-06 10:06:28.000000000 +0900
@@ -1205,24 +1205,28 @@
return(DB_ERROR);
}
@@ -420,7 +423,7 @@
diff -ruN a/patch_info/innodb_io_patches.info b/patch_info/innodb_io_patches.info
--- /dev/null 1970-01-01 09:00:00.000000000 +0900
-+++ b/patch_info/innodb_io_patches.info 2009-01-09 15:59:05.000000000 +0900
++++ b/patch_info/innodb_io_patches.info 2009-05-06 10:06:28.000000000 +0900
@@ -0,0 +1,11 @@
+File=innodb_io_patches.patch
+Name=Cluster of past InnoDB IO patches
@@ -434,8 +437,8 @@
+2009-01-09
+YK: Some parameters are added
diff -ruN a/sql/ha_innodb.cc b/sql/ha_innodb.cc
---- a/sql/ha_innodb.cc 2009-01-09 15:40:23.000000000 +0900
-+++ b/sql/ha_innodb.cc 2009-01-09 15:40:46.000000000 +0900
+--- a/sql/ha_innodb.cc 2009-05-06 10:04:19.000000000 +0900
++++ b/sql/ha_innodb.cc 2009-05-06 10:52:16.000000000 +0900
@@ -149,6 +149,7 @@
innobase_lock_wait_timeout, innobase_force_recovery,
innobase_open_files;
@@ -453,9 +456,20 @@
srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
srv_force_recovery = (ulint) innobase_force_recovery;
+@@ -7317,6 +7320,10 @@
+ trx_t* trx = check_trx_exists(thd);
+
+ if (thd->lex->sql_command != SQLCOM_XA_PREPARE) {
++ if (srv_enable_unsafe_group_commit && !thd->variables.innodb_support_xa) {
++ /* choose group commit rather than binlog order */
++ return(0);
++ }
+
+ /* For ibbackup to work the order of transactions in binlog
+ and InnoDB must be the same. Consider the situation
diff -ruN a/sql/ha_innodb.h b/sql/ha_innodb.h
---- a/sql/ha_innodb.h 2009-01-09 15:40:23.000000000 +0900
-+++ b/sql/ha_innodb.h 2009-01-09 15:59:41.000000000 +0900
+--- a/sql/ha_innodb.h 2009-05-06 10:04:12.000000000 +0900
++++ b/sql/ha_innodb.h 2009-05-06 10:22:01.000000000 +0900
@@ -204,6 +204,7 @@
extern long innobase_additional_mem_pool_size;
extern long innobase_buffer_pool_awe_mem_mb;
@@ -464,7 +478,7 @@
extern long innobase_force_recovery;
extern long innobase_open_files;
extern char *innobase_data_home_dir, *innobase_data_file_path;
-@@ -234,6 +235,13 @@
+@@ -234,6 +235,14 @@
extern ulong srv_thread_concurrency;
extern ulong srv_commit_concurrency;
extern ulong srv_flush_log_at_trx_commit;
@@ -473,15 +487,16 @@
+extern ulong srv_ibuf_active_contract;
+extern ulong srv_ibuf_accel_rate;
+extern ulong srv_flush_neighbor_pages;
++extern ulong srv_enable_unsafe_group_commit;
+extern uint srv_read_ahead;
+extern ulong srv_adaptive_checkpoint;
}
bool innobase_init(void);
diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc 2009-01-09 15:40:23.000000000 +0900
-+++ b/sql/mysqld.cc 2009-01-09 16:01:25.000000000 +0900
-@@ -5036,6 +5036,15 @@
+--- a/sql/mysqld.cc 2009-05-06 10:04:19.000000000 +0900
++++ b/sql/mysqld.cc 2009-05-06 10:33:23.000000000 +0900
+@@ -5080,6 +5080,16 @@
OPT_INNODB_ROLLBACK_ON_TIMEOUT,
OPT_SECURE_FILE_PRIV,
OPT_KEEP_FILES_ON_CREATE,
@@ -490,6 +505,7 @@
+ OPT_INNODB_IBUF_ACTIVE_CONTRACT,
+ OPT_INNODB_IBUF_ACCEL_RATE,
+ OPT_INNODB_FLUSH_NEIGHBOR_PAGES,
++ OPT_INNODB_ENABLE_UNSAFE_GROUP_COMMIT,
+ OPT_INNODB_READ_AHEAD,
+ OPT_INNODB_ADAPTIVE_CHECKPOINT,
+ OPT_INNODB_READ_IO_THREADS,
@@ -497,7 +513,7 @@
OPT_INNODB_ADAPTIVE_HASH_INDEX,
OPT_FEDERATED
};
-@@ -5344,6 +5353,41 @@
+@@ -5388,6 +5398,45 @@
(gptr*) &global_system_variables.innodb_table_locks,
(gptr*) &global_system_variables.innodb_table_locks,
0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
@@ -528,6 +544,10 @@
+ "Enable/Diasable flushing along modified age. 0:disable 1:enable",
+ (gptr*) &srv_adaptive_checkpoint, (gptr*) &srv_adaptive_checkpoint,
+ 0, GET_ULONG, REQUIRED_ARG, 0, 0, 1, 0, 0, 0},
++ {"innodb_enable_unsafe_group_commit", OPT_INNODB_ENABLE_UNSAFE_GROUP_COMMIT,
++ "Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.",
++ (gptr*) &srv_enable_unsafe_group_commit, (gptr*) &srv_enable_unsafe_group_commit,
++ 0, GET_ULONG, REQUIRED_ARG, 0, 0, 1, 0, 0, 0},
+ {"innodb_read_io_threads", OPT_INNODB_READ_IO_THREADS,
+ "Number of background read I/O threads in InnoDB.",
+ (gptr*) &innobase_read_io_threads, (gptr*) &innobase_read_io_threads,
@@ -539,7 +559,7 @@
#endif /* End HAVE_INNOBASE_DB */
{"isam", OPT_ISAM, "Obsolete. ISAM storage engine is no longer supported.",
(gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 0, 0, 0,
-@@ -7637,6 +7636,22 @@
+@@ -7607,6 +7656,22 @@
case OPT_INNODB_LOG_ARCHIVE:
innobase_log_archive= argument ? test(atoi(argument)) : 1;
break;
@@ -563,9 +583,9 @@
case OPT_MYISAM_RECOVER:
{
diff -ruN a/sql/set_var.cc b/sql/set_var.cc
---- a/sql/set_var.cc 2009-01-09 15:40:23.000000000 +0900
-+++ b/sql/set_var.cc 2009-01-09 16:05:22.000000000 +0900
-@@ -484,6 +484,37 @@
+--- a/sql/set_var.cc 2009-05-06 10:04:19.000000000 +0900
++++ b/sql/set_var.cc 2009-05-06 10:40:03.000000000 +0900
+@@ -486,6 +486,39 @@
sys_var_long_ptr sys_innodb_flush_log_at_trx_commit(
"innodb_flush_log_at_trx_commit",
&srv_flush_log_at_trx_commit);
@@ -598,12 +618,14 @@
+};
+sys_var_enum sys_innodb_read_ahead("innodb_read_ahead", &srv_read_ahead,
+ &innodb_read_ahead_typelib, fix_innodb_read_ahead);
++sys_var_long_ptr sys_innodb_enable_unsafe_group_commit("innodb_enable_unsafe_group_commit",
++ &srv_enable_unsafe_group_commit);
+sys_var_long_ptr sys_innodb_adaptive_checkpoint("innodb_adaptive_checkpoint",
+ &srv_adaptive_checkpoint);
sys_var_const_os_str_ptr sys_innodb_data_file_path("innodb_data_file_path",
&innobase_data_file_path);
sys_var_const_os_str_ptr sys_innodb_data_home_dir("innodb_data_home_dir",
-@@ -847,6 +859,12 @@
+@@ -850,6 +883,13 @@
&sys_innodb_thread_concurrency,
&sys_innodb_commit_concurrency,
&sys_innodb_flush_log_at_trx_commit,
@@ -612,11 +634,12 @@
+ &sys_innodb_ibuf_accel_rate,
+ &sys_innodb_flush_neighbor_pages,
+ &sys_innodb_read_ahead,
++ &sys_innodb_enable_unsafe_group_commit,
+ &sys_innodb_adaptive_checkpoint,
#endif
&sys_trust_routine_creators,
&sys_trust_function_creators,
-@@ -982,6 +1000,15 @@
+@@ -985,6 +1025,16 @@
{sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS},
{sys_innodb_thread_concurrency.name, (char*) &sys_innodb_thread_concurrency, SHOW_SYS},
{sys_innodb_thread_sleep_delay.name, (char*) &sys_innodb_thread_sleep_delay, SHOW_SYS},
@@ -626,16 +649,17 @@
+ {sys_innodb_ibuf_accel_rate.name, (char*) &sys_innodb_ibuf_accel_rate, SHOW_SYS},
+ {sys_innodb_flush_neighbor_pages.name, (char*) &sys_innodb_flush_neighbor_pages, SHOW_SYS},
+ {sys_innodb_read_ahead.name, (char*) &sys_innodb_read_ahead, SHOW_SYS},
++ {sys_innodb_enable_unsafe_group_commit.name, (char*) &sys_innodb_enable_unsafe_group_commit, SHOW_SYS},
+ {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},
#endif
{sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS},
{sys_join_buffer_size.name, (char*) &sys_join_buffer_size, SHOW_SYS},
-@@ -1482,6 +1501,13 @@
+@@ -1443,6 +1493,13 @@
}
}
-
+
+#ifdef HAVE_INNOBASE_DB
+extern void fix_innodb_read_ahead(THD *thd, enum_var_type type)
+{
@@ -647,12 +671,12 @@
{
DBUG_ENTER("fix_max_binlog_size");
diff -ruN a/sql/set_var.h b/sql/set_var.h
---- a/sql/set_var.h 2009-01-12 11:20:31.000000000 +0900
-+++ b/sql/set_var.h 2009-01-12 15:26:35.000000000 +0900
+--- a/sql/set_var.h 2009-05-06 10:04:12.000000000 +0900
++++ b/sql/set_var.h 2009-05-06 10:06:28.000000000 +0900
@@ -31,6 +31,10 @@
-
+
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
-
+
+#ifdef HAVE_INNOBASE_DB
+extern TYPELIB innodb_read_ahead_typelib;
+#endif /* HAVE_INNOBASE_DB */
@@ -660,7 +684,7 @@
typedef int (*sys_check_func)(THD *, set_var *);
typedef bool (*sys_update_func)(THD *, set_var *);
typedef void (*sys_after_update_func)(THD *,enum_var_type);
-@@ -1114,6 +1118,9 @@
+@@ -1148,6 +1152,9 @@
int sql_set_variables(THD *thd, List<set_var_base> *var_list);
bool not_all_support_one_shot(List<set_var_base> *var_list);
void fix_delay_key_write(THD *thd, enum_var_type type);
=== modified file 'innodb_rw_lock.patch'
--- innodb_rw_lock.patch 2009-02-12 01:54:35 +0000
+++ innodb_rw_lock.patch 2009-05-06 09:53:18 +0000
@@ -1,159 +1,6 @@
-diff -r 962aec0d731c innobase/configure
---- a/innobase/configure Thu Oct 09 08:28:53 2008 -0700
-+++ b/innobase/configure Thu Oct 09 08:30:28 2008 -0700
-@@ -20519,6 +20519,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.
-diff -r 962aec0d731c innobase/configure.in
---- a/innobase/configure.in Thu Oct 09 08:28:53 2008 -0700
-+++ b/innobase/configure.in Thu Oct 09 08:30:28 2008 -0700
-@@ -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 -r 962aec0d731c innobase/ib_config.h
---- a/innobase/ib_config.h Thu Oct 09 08:28:53 2008 -0700
-+++ b/innobase/ib_config.h Thu Oct 09 08:30:28 2008 -0700
-@@ -3,6 +3,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 -r 962aec0d731c innobase/ib_config.h.in
---- a/innobase/ib_config.h.in Thu Oct 09 08:28:53 2008 -0700
-+++ b/innobase/ib_config.h.in Thu Oct 09 08:30:28 2008 -0700
-@@ -2,6 +2,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 -r 962aec0d731c innobase/include/sync0rw.h
---- a/innobase/include/sync0rw.h Thu Oct 09 08:28:53 2008 -0700
-+++ b/innobase/include/sync0rw.h Thu Oct 09 08:30:28 2008 -0700
+diff -ruN a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h
+--- a/innobase/include/sync0rw.h 2009-01-30 06:42:20.000000000 +0900
++++ b/innobase/include/sync0rw.h 2009-04-16 16:15:28.000000000 +0900
@@ -325,7 +325,17 @@
Accessor functions for rw lock. */
UNIV_INLINE
@@ -191,7 +38,7 @@
/* 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
-@@ -417,9 +432,9 @@
+@@ -417,9 +438,9 @@
field. Then no new readers are allowed in. */
struct rw_lock_struct {
@@ -204,7 +51,7 @@
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
-@@ -427,31 +442,35 @@
+@@ -427,31 +448,35 @@
thread will be the next one to proceed
once the current the event gets
signalled. See LEMMA 2 in sync0sync.c */
@@ -249,10 +96,10 @@
/* 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 -r 962aec0d731c innobase/include/sync0rw.ic
---- a/innobase/include/sync0rw.ic Thu Oct 09 08:28:53 2008 -0700
-+++ b/innobase/include/sync0rw.ic Thu Oct 09 08:30:28 2008 -0700
-@@ -47,20 +47,52 @@
+diff -ruN a/innobase/include/sync0rw.ic b/innobase/include/sync0rw.ic
+--- a/innobase/include/sync0rw.ic 2009-01-30 06:42:20.000000000 +0900
++++ b/innobase/include/sync0rw.ic 2009-04-16 17:06:53.000000000 +0900
+@@ -47,20 +47,64 @@
Accessor functions for rw lock. */
UNIV_INLINE
ulint
@@ -263,11 +110,13 @@
{
- return(lock->waiters);
+ return(lock->s_waiters);
-+}
-+UNIV_INLINE
+ }
+ UNIV_INLINE
+-void
+-rw_lock_set_waiters(
+ulint
+rw_lock_get_x_waiters(
-+/*================*/
+ /*================*/
+ rw_lock_t* lock)
+{
+ return(lock->x_waiters);
@@ -279,17 +128,19 @@
+ rw_lock_t* lock)
+{
+ return(lock->wait_ex_waiters);
- }
- UNIV_INLINE
- void
--rw_lock_set_waiters(
--/*================*/
++}
++UNIV_INLINE
++void
+rw_lock_set_s_waiters(
rw_lock_t* lock,
ulint flag)
{
- lock->waiters = flag;
++#ifdef HAVE_ATOMIC_BUILTINS
++ __sync_lock_test_and_set(&lock->s_waiters, flag);
++#else
+ lock->s_waiters = flag;
++#endif
+}
+UNIV_INLINE
+void
@@ -297,7 +148,11 @@
+ rw_lock_t* lock,
+ ulint flag)
+{
++#ifdef HAVE_ATOMIC_BUILTINS
++ __sync_lock_test_and_set(&lock->x_waiters, flag);
++#else
+ lock->x_waiters = flag;
++#endif
+}
+UNIV_INLINE
+void
@@ -306,11 +161,15 @@
+ rw_lock_t* lock,
+ ulint flag)
+{
++#ifdef HAVE_ATOMIC_BUILTINS
++ __sync_lock_test_and_set(&lock->wait_ex_waiters, flag);
++#else
+ lock->wait_ex_waiters = flag;
++#endif
}
UNIV_INLINE
ulint
-@@ -68,7 +100,19 @@
+@@ -68,7 +112,19 @@
/*===============*/
rw_lock_t* lock)
{
@@ -330,7 +189,7 @@
}
UNIV_INLINE
void
-@@ -96,6 +140,7 @@
+@@ -96,6 +152,7 @@
{
lock->reader_count = count;
}
@@ -338,7 +197,7 @@
UNIV_INLINE
mutex_t*
rw_lock_get_mutex(
-@@ -104,6 +149,7 @@
+@@ -104,6 +161,7 @@
{
return(&(lock->mutex));
}
@@ -346,7 +205,7 @@
/**********************************************************************
Returns the value of writer_count for the lock. Does not reserve the lock
-@@ -133,14 +179,26 @@
+@@ -133,14 +191,26 @@
const char* file_name, /* in: file name where lock requested */
ulint line) /* in: line where requested */
{
@@ -374,7 +233,7 @@
#ifdef UNIV_SYNC_DEBUG
rw_lock_add_debug_info(lock, pass, RW_LOCK_SHARED, file_name,
-@@ -167,11 +225,15 @@
+@@ -167,11 +237,15 @@
const char* file_name, /* in: file name where requested */
ulint line) /* in: line where lock requested */
{
@@ -391,7 +250,7 @@
lock->last_s_file_name = file_name;
lock->last_s_line = line;
-@@ -199,7 +261,11 @@
+@@ -199,7 +273,11 @@
rw_lock_set_writer(lock, RW_LOCK_EX);
lock->writer_thread = os_thread_get_curr_id();
@@ -403,7 +262,7 @@
lock->pass = 0;
lock->last_x_file_name = file_name;
-@@ -241,15 +307,21 @@
+@@ -241,15 +319,21 @@
ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */
#endif /* UNIV_SYNC_DEBUG */
@@ -425,7 +284,7 @@
rw_lock_s_lock_spin(lock, pass, file_name, line);
-@@ -272,11 +344,23 @@
+@@ -272,11 +356,23 @@
{
ibool success = FALSE;
@@ -449,7 +308,7 @@
#ifdef UNIV_SYNC_DEBUG
rw_lock_add_debug_info(lock, 0, RW_LOCK_SHARED, file_name,
-@@ -289,7 +373,9 @@
+@@ -289,7 +385,9 @@
success = TRUE;
}
@@ -459,20 +318,20 @@
return(success);
}
-@@ -309,6 +395,55 @@
+@@ -309,6 +407,54 @@
{
ibool success = FALSE;
os_thread_id_t curr_thread = os_thread_get_curr_id();
+#ifdef HAVE_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) {
++ if (lock->reader_count == 0) {
++ /* try to lock writer */
++ if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
++ == RW_LOCK_NOT_LOCKED) {
+ /* success */
-+ /* try to lock writer */
-+ if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
-+ == RW_LOCK_NOT_LOCKED) {
++retry_x_lock:
++ /* try x-lock */
++ if(__sync_sub_and_fetch(&(lock->lock_word),
++ RW_LOCK_BIAS) == 0) {
+ /* success */
+ lock->writer_thread = curr_thread;
+ lock->pass = 0;
@@ -492,30 +351,29 @@
+
+ return(TRUE);
+ } else {
-+ /* x-unlock */
-+ __sync_fetch_and_add(&(lock->lock_word),
-+ RW_LOCK_BIAS);
++ /* fail (x-lock) */
++ if (__sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS)
++ == 0)
++ goto retry_x_lock;
+ }
-+ } else {
-+ /* fail (x-lock) */
-+ __sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS);
++
++ __sync_lock_test_and_set(&(lock->writer),RW_LOCK_NOT_LOCKED);
+ }
+ }
+
+ if (lock->pass == 0
-+ && os_thread_eq(lock->writer_thread, curr_thread)
-+ && rw_lock_get_writer(lock) == RW_LOCK_EX) {
++ && os_thread_eq(lock->writer_thread, curr_thread)) {
+ goto relock;
+ }
+
-+ ut_ad(rw_lock_validate(lock));
++ //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)) {
-@@ -339,6 +474,7 @@
+@@ -339,6 +485,7 @@
ut_ad(rw_lock_validate(lock));
return(success);
@@ -523,7 +381,7 @@
}
/**********************************************************************
-@@ -354,16 +490,33 @@
+@@ -354,16 +501,33 @@
#endif
)
{
@@ -558,37 +416,37 @@
#ifdef UNIV_SYNC_DEBUG
rw_lock_remove_debug_info(lock, pass, RW_LOCK_SHARED);
-@@ -372,20 +525,36 @@
+@@ -372,22 +536,39 @@
/* If there may be waiters and this was the last s-lock,
signal the object */
- if (UNIV_UNLIKELY(lock->waiters)
+#ifdef HAVE_ATOMIC_BUILTINS
-+ if (UNIV_UNLIKELY(last && lock->wait_ex_waiters)) {
++ if (UNIV_UNLIKELY(last && __sync_lock_test_and_set(&lock->wait_ex_waiters, 0))) {
++ os_event_set(lock->wait_ex_event);
++ sync_array_object_signalled(sync_primary_wait_array);
++ }
++ else if (UNIV_UNLIKELY(last && __sync_lock_test_and_set(&lock->x_waiters, 0))) {
++ os_event_set(lock->x_event);
++ sync_array_object_signalled(sync_primary_wait_array);
++ }
+#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_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_ATOMIC_BUILTINS
mutex_exit(mutex);
-+#endif
- if (UNIV_UNLIKELY(sg)) {
-#ifdef __WIN__
@@ -601,8 +459,11 @@
+ os_event_set(lock->x_event);
sync_array_object_signalled(sync_primary_wait_array);
}
-
-@@ -409,13 +578,22 @@
++#endif
+
+ ut_ad(rw_lock_validate(lock));
+
+@@ -409,13 +590,22 @@
ut_ad(lock->reader_count > 0);
@@ -625,7 +486,7 @@
ut_ad(rw_lock_validate(lock));
#ifdef UNIV_SYNC_PERF_STAT
rw_s_exit_count++;
-@@ -435,41 +613,81 @@
+@@ -435,41 +625,83 @@
#endif
)
{
@@ -658,10 +519,7 @@
+ /* 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();
++ __sync_lock_test_and_set(&(lock->writer),RW_LOCK_NOT_LOCKED);
+ }
+#else
lock->writer_count--;
@@ -683,9 +541,15 @@
- rw_lock_set_waiters(lock, 0);
+#ifdef HAVE_ATOMIC_BUILTINS
+ if (last) {
++ if(__sync_lock_test_and_set(&lock->s_waiters, 0)){
++ s_sg = TRUE;
++ }
++ if(__sync_lock_test_and_set(&lock->x_waiters, 0)){
++ x_sg = TRUE;
++ }
++ }
+#else
+ if (lock->writer_count == 0) {
-+#endif
+ if(lock->s_waiters){
+ s_sg = TRUE;
+ rw_lock_set_s_waiters(lock, 0);
@@ -696,7 +560,6 @@
+ }
}
-+#ifndef HAVE_ATOMIC_BUILTINS
mutex_exit(&(lock->mutex));
+#endif
@@ -715,7 +578,7 @@
sync_array_object_signalled(sync_primary_wait_array);
}
-@@ -494,9 +712,13 @@
+@@ -494,9 +726,13 @@
ut_ad(lock->writer_count > 0);
@@ -729,7 +592,7 @@
rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
}
-@@ -504,7 +726,12 @@
+@@ -504,7 +740,12 @@
rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX);
#endif
@@ -742,9 +605,9 @@
ut_ad(rw_lock_validate(lock));
#ifdef UNIV_SYNC_PERF_STAT
-diff -r 962aec0d731c innobase/sync/sync0arr.c
---- a/innobase/sync/sync0arr.c Thu Oct 09 08:28:53 2008 -0700
-+++ b/innobase/sync/sync0arr.c Thu Oct 09 08:30:28 2008 -0700
+diff -ruN a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c
+--- a/innobase/sync/sync0arr.c 2009-01-30 06:42:24.000000000 +0900
++++ b/innobase/sync/sync0arr.c 2009-04-16 16:15:28.000000000 +0900
@@ -309,13 +309,13 @@
{
if (type == SYNC_MUTEX) {
@@ -877,9 +740,9 @@
}
}
}
-diff -r 962aec0d731c innobase/sync/sync0rw.c
---- a/innobase/sync/sync0rw.c Thu Oct 09 08:28:53 2008 -0700
-+++ b/innobase/sync/sync0rw.c Thu Oct 09 08:30:28 2008 -0700
+diff -ruN a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c
+--- a/innobase/sync/sync0rw.c 2009-01-30 06:42:24.000000000 +0900
++++ b/innobase/sync/sync0rw.c 2009-04-16 17:33:59.000000000 +0900
@@ -99,6 +99,7 @@
object is created, then the following call initializes
the sync system. */
@@ -1036,7 +899,7 @@
- rw_lock_set_waiters(lock, 1);
+ rw_lock_set_s_waiters(lock, 1);
-
++
+#ifdef HAVE_ATOMIC_BUILTINS
+ /* like sync0sync.c doing */
+ for (i = 0; i < 4; i++) {
@@ -1045,10 +908,10 @@
+ return; /* Success */
+ }
+ }
-+
+
+ /* If wait_ex_waiter stalls, wakes it. */
-+ if (lock->wait_ex_waiters && lock->lock_word == RW_LOCK_BIAS) {
-+ rw_lock_set_wx_waiters(lock, 0);
++ if (lock->reader_count == 0
++ && __sync_lock_test_and_set(&lock->wait_ex_waiters, 0)) {
+ os_event_set(lock->wait_ex_event);
+ sync_array_object_signalled(sync_primary_wait_array);
+ }
@@ -1058,7 +921,7 @@
if (srv_print_latch_waits) {
fprintf(stderr,
-@@ -318,13 +358,19 @@
+@@ -318,13 +365,19 @@
{
ut_ad(rw_lock_is_locked(lock, RW_LOCK_EX));
@@ -1078,13 +941,13 @@
}
/**********************************************************************
-@@ -342,6 +388,89 @@
+@@ -342,6 +395,89 @@
const char* file_name,/* in: file name where lock requested */
ulint line) /* in: line where requested */
{
+#ifdef HAVE_ATOMIC_BUILTINS
+ os_thread_id_t curr_thread = os_thread_get_curr_id();
-+
++retry_writer:
+ /* try to lock writer */
+ if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
+ == RW_LOCK_NOT_LOCKED) {
@@ -1160,15 +1023,15 @@
+
+ break;
+
-+ default: /* ??? */
-+ return(RW_LOCK_NOT_LOCKED);
++ default: /* RW_LOCK_NOT_LOCKED? maybe impossible */
++ goto retry_writer;
+ }
+#else /* HAVE_ATOMIC_BUILTINS */
+
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(rw_lock_get_mutex(lock)));
#endif /* UNIV_SYNC_DEBUG */
-@@ -423,6 +552,7 @@
+@@ -423,6 +559,7 @@
/* Locking succeeded, we may return */
return(RW_LOCK_EX);
}
@@ -1176,7 +1039,7 @@
/* Locking did not succeed */
return(RW_LOCK_NOT_LOCKED);
-@@ -448,19 +578,33 @@
+@@ -448,19 +585,33 @@
ulint line) /* in: line where requested */
{
ulint index; /* index of the reserved wait cell */
@@ -1211,7 +1074,7 @@
if (state == RW_LOCK_EX) {
return; /* Locking succeeded */
-@@ -468,10 +612,9 @@
+@@ -468,10 +619,9 @@
} else if (state == RW_LOCK_NOT_LOCKED) {
/* Spin waiting for the writer field to become free */
@@ -1220,11 +1083,11 @@
- 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) {
++ && lock->lock_word != RW_LOCK_BIAS) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0,
srv_spin_wait_delay));
-@@ -485,9 +628,12 @@
+@@ -485,9 +635,12 @@
} else if (state == RW_LOCK_WAIT_EX) {
/* Spin waiting for the reader count field to become zero */
@@ -1238,7 +1101,7 @@
&& i < SYNC_SPIN_ROUNDS) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0,
-@@ -500,7 +646,6 @@
+@@ -500,7 +653,6 @@
os_thread_yield();
}
} else {
@@ -1246,7 +1109,7 @@
ut_error;
}
-@@ -516,34 +661,69 @@
+@@ -516,34 +668,69 @@
/* We try once again to obtain the lock. Acquire the mutex protecting
the rw-lock fields */
@@ -1269,7 +1132,7 @@
return; /* Locking succeeded */
}
-+
+
+#ifdef HAVE_ATOMIC_BUILTINS
+ /* like sync0sync.c doing */
+ i++;
@@ -1278,7 +1141,7 @@
+ goto spin_loop;
+ }
+#endif
-
++
rw_x_system_call_count++;
sync_array_reserve_cell(sync_primary_wait_array,
@@ -1322,7 +1185,7 @@
if (srv_print_latch_waits) {
fprintf(stderr,
-@@ -718,7 +898,9 @@
+@@ -718,7 +905,9 @@
ut_ad(lock);
ut_ad(rw_lock_validate(lock));
@@ -1332,7 +1195,7 @@
info = UT_LIST_GET_FIRST(lock->debug_list);
-@@ -728,7 +910,9 @@
+@@ -728,7 +917,9 @@
&& (info->pass == 0)
&& (info->lock_type == lock_type)) {
@@ -1342,7 +1205,7 @@
/* Found! */
return(TRUE);
-@@ -736,7 +920,9 @@
+@@ -736,7 +927,9 @@
info = UT_LIST_GET_NEXT(list, info);
}
@@ -1352,7 +1215,7 @@
return(FALSE);
}
-@@ -758,21 +944,25 @@
+@@ -758,21 +951,25 @@
ut_ad(lock);
ut_ad(rw_lock_validate(lock));
@@ -1379,7 +1242,7 @@
return(ret);
}
-@@ -801,16 +991,26 @@
+@@ -801,16 +998,26 @@
count++;
@@ -1409,7 +1272,7 @@
} else {
putc('\n', stderr);
}
-@@ -822,7 +1022,9 @@
+@@ -822,7 +1029,9 @@
}
}
@@ -1419,7 +1282,7 @@
lock = UT_LIST_GET_NEXT(list, lock);
}
-@@ -847,10 +1049,18 @@
+@@ -847,10 +1056,18 @@
if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
|| (rw_lock_get_reader_count(lock) != 0)
@@ -1441,7 +1304,7 @@
} else {
putc('\n', stderr);
}
-@@ -909,14 +1119,18 @@
+@@ -909,14 +1126,18 @@
lock = UT_LIST_GET_FIRST(rw_lock_list);
while (lock != NULL) {
@@ -1460,9 +1323,9 @@
lock = UT_LIST_GET_NEXT(list, lock);
}
-diff -r 962aec0d731c patch_info/innodb_rw_lock.info
---- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/patch_info/innodb_rw_lock.info Thu Oct 09 08:30:28 2008 -0700
+diff -ruN a/patch_info/innodb_rw_lock.info b/patch_info/innodb_rw_lock.info
+--- a/patch_info/innodb_rw_lock.info 1970-01-01 09:00:00.000000000 +0900
++++ b/patch_info/innodb_rw_lock.info 2009-04-16 16:15:28.000000000 +0900
@@ -0,0 +1,6 @@
+File=innodb_rw_lock.patch
+Name=Fix of InnoDB rw_locks
=== added file 'innodb_thread_concurrency_timer_based.patch'
--- innodb_thread_concurrency_timer_based.patch 1970-01-01 00:00:00 +0000
+++ innodb_thread_concurrency_timer_based.patch 2009-05-06 09:53:18 +0000
@@ -0,0 +1,389 @@
+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@xxxxxxxxxxx>
++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},
=== modified file 'series'
--- series 2009-01-26 08:43:23 +0000
+++ series 2009-05-06 09:53:18 +0000
@@ -12,5 +12,7 @@
innodb_fsync_source.patch
innodb_show_hashed_memory.patch
innodb_dict_size_limit.patch
+innodb_extra_rseg.patch
+innodb_thread_concurrency_timer_based.patch
split_buf_pool_mutex_fixed_optimistic_safe.patch
innodb_rw_lock.patch
Follow ups