From c4f87682d3e304d70f43ef34766947c87118ddaa Mon Sep 17 00:00:00 2001
From: unknown <vtkachenko@intelp4d.mysql.com>
Date: Sat, 8 Jan 2005 15:01:37 +0100
Subject: [PATCH] Many files:   - Create innodb_thread_concurrency as dynamic
 variable   - Add innodb_thread_sleep_delay variable   - Add
 innodb_free_tickets_to_enter variable

innobase/include/srv0srv.h:
  - Create innodb_thread_concurrency as dynamic variable
  - Add innodb_thread_sleep_delay variable
  - Add innodb_free_tickets_to_enter variable
innobase/srv/srv0srv.c:
  - Create innodb_thread_concurrency as dynamic variable
  - Add innodb_thread_sleep_delay variable
  - Add innodb_free_tickets_to_enter variable
mysql-test/r/innodb.result:
  - Create innodb_thread_concurrency as dynamic variable
  - Add innodb_thread_sleep_delay variable
  - Add innodb_free_tickets_to_enter variable
mysql-test/t/innodb.test:
  - Create innodb_thread_concurrency as dynamic variable
  - Add innodb_thread_sleep_delay variable
  - Add innodb_free_tickets_to_enter variable
sql/ha_innodb.cc:
  - Create innodb_thread_concurrency as dynamic variable
  - Add innodb_thread_sleep_delay variable
  - Add innodb_free_tickets_to_enter variable
sql/ha_innodb.h:
  - Create innodb_thread_concurrency as dynamic variable
  - Add innodb_thread_sleep_delay variable
  - Add innodb_free_tickets_to_enter variable
sql/mysqld.cc:
  - Create innodb_thread_concurrency as dynamic variable
  - Add innodb_thread_sleep_delay variable
  - Add innodb_free_tickets_to_enter variable
sql/set_var.cc:
  - Create innodb_thread_concurrency as dynamic variable
  - Add innodb_thread_sleep_delay variable
  - Add innodb_free_tickets_to_enter variable
---
 innobase/include/srv0srv.h |  2 ++
 innobase/srv/srv0srv.c     | 16 +++++++++-----
 mysql-test/r/innodb.result | 45 ++++++++++++++++++++++++++++++++++++++
 mysql-test/t/innodb.test   | 27 +++++++++++++++++++++++
 sql/ha_innodb.cc           |  3 +--
 sql/ha_innodb.h            |  3 +++
 sql/mysqld.cc              | 16 +++++++++++++-
 sql/set_var.cc             | 13 ++++++++++-
 8 files changed, 115 insertions(+), 10 deletions(-)

diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
index 5f752717fcc..c5374fd00fa 100644
--- a/innobase/include/srv0srv.h
+++ b/innobase/include/srv0srv.h
@@ -134,6 +134,8 @@ extern ibool	srv_lock_timeout_and_monitor_active;
 extern ibool	srv_error_monitor_active; 
 
 extern ulint	srv_n_spin_wait_rounds;
+extern ulint	srv_n_free_tickets_to_enter;
+extern ulint	srv_thread_sleep_delay;
 extern ulint	srv_spin_wait_delay;
 extern ibool	srv_priority_boost;
 		
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 61bddc9da2c..49403f93f64 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -297,8 +297,8 @@ srv_conc_slot_t* srv_conc_slots;			/* array of wait
 
 /* Number of times a thread is allowed to enter InnoDB within the same
 SQL query after it has once got the ticket at srv_conc_enter_innodb */
-#define SRV_FREE_TICKETS_TO_ENTER	500
-
+#define SRV_FREE_TICKETS_TO_ENTER srv_n_free_tickets_to_enter
+#define SRV_THREAD_SLEEP_DELAY srv_thread_sleep_delay
 /*-----------------------*/
 /* If the following is set TRUE then we do not run purge and insert buffer
 merge to completion before shutdown */
@@ -328,6 +328,8 @@ ulint	srv_max_purge_lag		= 0;
 
 /*-------------------------------------------*/
 ulint	srv_n_spin_wait_rounds	= 20;
+ulint srv_n_free_tickets_to_enter = 500;
+ulint srv_thread_sleep_delay = 10000;
 ulint	srv_spin_wait_delay	= 5;
 ibool	srv_priority_boost	= TRUE;
 
@@ -1025,8 +1027,8 @@ srv_conc_enter_innodb(
 		return;
 	}
 
-	/* If the transaction is not holding resources, let it sleep for 50
-	milliseconds, and try again then */
+	/* If the transaction is not holding resources, 
+  let it sleep for SRV_THREAD_SLEEP_DELAY microseconds, and try again then */
  
 	if (!has_slept && !trx->has_search_latch
 	    && NULL == UT_LIST_GET_FIRST(trx->trx_locks)) {
@@ -1045,8 +1047,10 @@ srv_conc_enter_innodb(
 		situations of lots of thread switches. Simply put some
 		threads aside for a while to reduce the number of thread
 		switches. */
-
-		os_thread_sleep(10000);
+    if (SRV_THREAD_SLEEP_DELAY > 0)
+    {
+      os_thread_sleep(SRV_THREAD_SLEEP_DELAY);
+    }
 
 		trx->op_info = "";
 
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index cdb2c1d6aae..148296de256 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1730,5 +1730,50 @@ set global innodb_sync_spin_loops=20;
 show variables like "innodb_sync_spin_loops";
 Variable_name	Value
 innodb_sync_spin_loops	20
+show variables like "innodb_thread_concurrency";
+Variable_name	Value
+innodb_thread_concurrency	8
+set global innodb_thread_concurrency=1000;
+show variables like "innodb_thread_concurrency";
+Variable_name	Value
+innodb_thread_concurrency	1000
+set global innodb_thread_concurrency=0;
+show variables like "innodb_thread_concurrency";
+Variable_name	Value
+innodb_thread_concurrency	1
+set global innodb_thread_concurrency=16;
+show variables like "innodb_thread_concurrency";
+Variable_name	Value
+innodb_thread_concurrency	16
+show variables like "innodb_free_tickets_to_enter";
+Variable_name	Value
+innodb_free_tickets_to_enter	500
+set global innodb_free_tickets_to_enter=1000;
+show variables like "innodb_free_tickets_to_enter";
+Variable_name	Value
+innodb_free_tickets_to_enter	1000
+set global innodb_free_tickets_to_enter=0;
+show variables like "innodb_free_tickets_to_enter";
+Variable_name	Value
+innodb_free_tickets_to_enter	1
+set global innodb_free_tickets_to_enter=500;
+show variables like "innodb_free_tickets_to_enter";
+Variable_name	Value
+innodb_free_tickets_to_enter	500
+show variables like "innodb_thread_sleep_delay";
+Variable_name	Value
+innodb_thread_sleep_delay	10000
+set global innodb_thread_sleep_delay=100000;
+show variables like "innodb_thread_sleep_delay";
+Variable_name	Value
+innodb_thread_sleep_delay	100000
+set global innodb_thread_sleep_delay=0;
+show variables like "innodb_thread_sleep_delay";
+Variable_name	Value
+innodb_thread_sleep_delay	0
+set global innodb_thread_sleep_delay=10000;
+show variables like "innodb_thread_sleep_delay";
+Variable_name	Value
+innodb_thread_sleep_delay	10000
 create table t1 (v varchar(16384)) engine=innodb;
 ERROR 42000: Column length too big for column 'v' (max = 255); use BLOB instead
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 0ffd9e4e9f5..3870bb01f0a 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1227,6 +1227,33 @@ show variables like "innodb_sync_spin_loops";
 set global innodb_sync_spin_loops=20;
 show variables like "innodb_sync_spin_loops";
 
+# Test for innodb_thread_concurrency variable
+show variables like "innodb_thread_concurrency";
+set global innodb_thread_concurrency=1000;
+show variables like "innodb_thread_concurrency";
+set global innodb_thread_concurrency=0;
+show variables like "innodb_thread_concurrency";
+set global innodb_thread_concurrency=16;
+show variables like "innodb_thread_concurrency";
+
+# Test for innodb_free_tickets_to_enter variable
+show variables like "innodb_free_tickets_to_enter";
+set global innodb_free_tickets_to_enter=1000;
+show variables like "innodb_free_tickets_to_enter";
+set global innodb_free_tickets_to_enter=0;
+show variables like "innodb_free_tickets_to_enter";
+set global innodb_free_tickets_to_enter=500;
+show variables like "innodb_free_tickets_to_enter";
+
+# Test for innodb_thread_sleep_delay variable
+show variables like "innodb_thread_sleep_delay";
+set global innodb_thread_sleep_delay=100000;
+show variables like "innodb_thread_sleep_delay";
+set global innodb_thread_sleep_delay=0;
+show variables like "innodb_thread_sleep_delay";
+set global innodb_thread_sleep_delay=10000;
+show variables like "innodb_thread_sleep_delay";
+
 #
 # Test varchar
 #
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 91517770d04..afaac8ba83b 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -250,7 +250,7 @@ struct show_var_st innodb_status_variables[]= {
   {"rows_updated",
   (char*) &export_vars.innodb_rows_updated,               SHOW_LONG},
   {NullS, NullS, SHOW_LONG}};
-
+      
 /* General functions */
 
 /**********************************************************************
@@ -1132,7 +1132,6 @@ innobase_init(void)
 	srv_n_file_io_threads = (ulint) innobase_file_io_threads;
 
 	srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
-	srv_thread_concurrency = (ulint) innobase_thread_concurrency;
 	srv_force_recovery = (ulint) innobase_force_recovery;
 
 	srv_fast_shutdown = (ibool) innobase_fast_shutdown;
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index e7277ea03a3..0cb55e02ae3 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -213,7 +213,10 @@ extern ulong srv_max_buf_pool_modified_pct;
 extern ulong srv_max_purge_lag;
 extern ulong srv_auto_extend_increment;
 extern ulong srv_n_spin_wait_rounds;
+extern ulong srv_n_free_tickets_to_enter;
+extern ulong srv_thread_sleep_delay;
 extern ulong srv_max_purge_lag;
+extern ulong srv_thread_concurrency;
 }
 
 extern TYPELIB innobase_lock_typelib;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index e88f4eb0e73..82efc51234a 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4200,6 +4200,8 @@ enum options_mysqld
   OPT_INNODB_OPEN_FILES,
   OPT_INNODB_AUTOEXTEND_INCREMENT,
   OPT_INNODB_SYNC_SPIN_LOOPS,
+  OPT_INNODB_FREE_TICKETS_TO_ENTER,
+  OPT_INNODB_THREAD_SLEEP_DELAY,
   OPT_BDB_CACHE_SIZE,
   OPT_BDB_LOG_BUFFER_SIZE,
   OPT_BDB_MAX_LOCK,
@@ -5050,6 +5052,12 @@ log and this option does nothing anymore.",
    (gptr*) &srv_n_spin_wait_rounds,
    (gptr*) &srv_n_spin_wait_rounds,
    0, GET_LONG, REQUIRED_ARG, 20L, 0L, ~0L, 0, 1L, 0},
+  {"innodb_free_tickets_to_enter", OPT_INNODB_FREE_TICKETS_TO_ENTER,
+   "Number of times a thread is allowed to enter InnoDB within the same \
+    SQL query after it has once got the ticket",
+   (gptr*) &srv_n_free_tickets_to_enter,
+   (gptr*) &srv_n_free_tickets_to_enter,
+   0, GET_LONG, REQUIRED_ARG, 500L, 1L, ~0L, 0, 1L, 0},
 #ifdef HAVE_REPLICATION
   /*
     Disabled for the 4.1.3 release. Disabling just this paragraph of code is
@@ -5072,8 +5080,14 @@ log and this option does nothing anymore.",
 #endif
   {"innodb_thread_concurrency", OPT_INNODB_THREAD_CONCURRENCY,
    "Helps in performance tuning in heavily concurrent environments.",
-   (gptr*) &innobase_thread_concurrency, (gptr*) &innobase_thread_concurrency,
+   (gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency,
    0, GET_LONG, REQUIRED_ARG, 8, 1, 1000, 0, 1, 0},
+  {"innodb_thread_sleep_delay", OPT_INNODB_THREAD_SLEEP_DELAY,
+   "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0"
+    " disable a sleep",
+   (gptr*) &srv_thread_sleep_delay,
+   (gptr*) &srv_thread_sleep_delay,
+   0, GET_LONG, REQUIRED_ARG, 10000L, 0L, ~0L, 0, 1L, 0},
 #endif /* HAVE_INNOBASE_DB */
   {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
    "The number of seconds the server waits for activity on an interactive connection before closing it.",
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 3597a4930f8..da41522e3fe 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -380,6 +380,12 @@ sys_var_long_ptr	sys_innodb_autoextend_increment("innodb_autoextend_increment",
 							&srv_auto_extend_increment);
 sys_var_long_ptr	sys_innodb_sync_spin_loops("innodb_sync_spin_loops",
                                              &srv_n_spin_wait_rounds);
+sys_var_long_ptr  sys_innodb_free_tickets_to_enter("innodb_free_tickets_to_enter",
+                                             &srv_n_free_tickets_to_enter);
+sys_var_long_ptr  sys_innodb_thread_sleep_delay("innodb_thread_sleep_delay",
+                                                &srv_thread_sleep_delay);
+sys_var_long_ptr  sys_innodb_thread_concurrency("innodb_thread_concurrency",
+                                                &srv_thread_concurrency);
 #endif
 
 #ifdef HAVE_NDBCLUSTER_DB
@@ -654,6 +660,9 @@ sys_var *sys_variables[]=
   &sys_innodb_max_purge_lag,
   &sys_innodb_autoextend_increment,
   &sys_innodb_sync_spin_loops,
+  &sys_innodb_free_tickets_to_enter,
+  &sys_innodb_thread_sleep_delay,
+  &sys_innodb_thread_concurrency,
 #endif  
 #ifdef HAVE_NDBCLUSTER_DB
   &sys_ndb_autoincrement_prefetch_sz,
@@ -752,6 +761,7 @@ struct show_var_st init_vars[]= {
   {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_INT},
   {"innodb_flush_method",    (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
   {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
+  {sys_innodb_free_tickets_to_enter.name, (char*) &sys_innodb_free_tickets_to_enter, SHOW_SYS},
   {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
   {"innodb_log_arch_dir",   (char*) &innobase_log_arch_dir, 	    SHOW_CHAR_PTR},
   {"innodb_log_archive",    (char*) &innobase_log_archive, 	    SHOW_MY_BOOL},
@@ -765,7 +775,8 @@ struct show_var_st init_vars[]= {
   {sys_innodb_max_purge_lag.name, (char*) &sys_innodb_max_purge_lag, SHOW_SYS},
   {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
   {"innodb_open_files", (char*) &innobase_open_files, SHOW_LONG },
-  {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG },
+  {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},
   {sys_innodb_sync_spin_loops.name, (char*) &sys_innodb_sync_spin_loops, SHOW_SYS},
 #endif
   {sys_interactive_timeout.name,(char*) &sys_interactive_timeout,   SHOW_SYS},
-- 
2.30.9