diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 0f4bc8d7b37..02e65271dbe 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -244,6 +244,7 @@ venu@hundin.mysql.fi venu@myvenu.com venu@work.mysql.com vtkachenko@intelp4d.mysql.com +vtkachenko@mail.mysql.com vva@eagle.mysql.r18.ru vva@genie.(none) vva@mysql.r18.ru 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 15dacdf6333..7da2ee10d27 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 @@ retry: 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 @@ retry: 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 06940d65a79..bdd5ac0bd63 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1715,5 +1715,65 @@ Innodb_row_lock_time_max 0 show status like "Innodb_row_lock_time_avg"; Variable_name Value Innodb_row_lock_time_avg 0 +show variables like "innodb_sync_spin_loops"; +Variable_name Value +innodb_sync_spin_loops 20 +set global innodb_sync_spin_loops=1000; +show variables like "innodb_sync_spin_loops"; +Variable_name Value +innodb_sync_spin_loops 1000 +set global innodb_sync_spin_loops=0; +show variables like "innodb_sync_spin_loops"; +Variable_name Value +innodb_sync_spin_loops 0 +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_concurrency_tickets"; +Variable_name Value +innodb_concurrency_tickets 500 +set global innodb_concurrency_tickets=1000; +show variables like "innodb_concurrency_tickets"; +Variable_name Value +innodb_concurrency_tickets 1000 +set global innodb_concurrency_tickets=0; +show variables like "innodb_concurrency_tickets"; +Variable_name Value +innodb_concurrency_tickets 1 +set global innodb_concurrency_tickets=500; +show variables like "innodb_concurrency_tickets"; +Variable_name Value +innodb_concurrency_tickets 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 cee216e9e29..4fff24a61d5 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1218,6 +1218,42 @@ show status like "Innodb_row_lock_time"; show status like "Innodb_row_lock_time_max"; show status like "Innodb_row_lock_time_avg"; +# Test for innodb_sync_spin_loops variable +show variables like "innodb_sync_spin_loops"; +set global innodb_sync_spin_loops=1000; +show variables like "innodb_sync_spin_loops"; +set global innodb_sync_spin_loops=0; +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_concurrency_tickets variable +show variables like "innodb_concurrency_tickets"; +set global innodb_concurrency_tickets=1000; +show variables like "innodb_concurrency_tickets"; +set global innodb_concurrency_tickets=0; +show variables like "innodb_concurrency_tickets"; +set global innodb_concurrency_tickets=500; +show variables like "innodb_concurrency_tickets"; + +# 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 3df61333b75..02da7f876e2 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 */ /********************************************************************** @@ -1150,7 +1150,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 fcb9165de64..0cb55e02ae3 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -212,7 +212,11 @@ extern "C" { 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 dd7fd98158a..d831913b822 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4201,6 +4201,9 @@ enum options_mysqld OPT_INNODB_TABLE_LOCKS, OPT_INNODB_OPEN_FILES, OPT_INNODB_AUTOEXTEND_INCREMENT, + OPT_INNODB_SYNC_SPIN_LOOPS, + OPT_INNODB_CONCURRENCY_TICKETS, + OPT_INNODB_THREAD_SLEEP_DELAY, OPT_BDB_CACHE_SIZE, OPT_BDB_LOG_BUFFER_SIZE, OPT_BDB_MAX_LOCK, @@ -5046,6 +5049,17 @@ log and this option does nothing anymore.", "How many files at the maximum InnoDB keeps open at the same time.", (gptr*) &innobase_open_files, (gptr*) &innobase_open_files, 0, GET_LONG, REQUIRED_ARG, 300L, 10L, ~0L, 0, 1L, 0}, + {"innodb_sync_spin_loops", OPT_INNODB_SYNC_SPIN_LOOPS, + "Count of spin-loop rounds in InnoDB mutexes", + (gptr*) &srv_n_spin_wait_rounds, + (gptr*) &srv_n_spin_wait_rounds, + 0, GET_LONG, REQUIRED_ARG, 20L, 0L, ~0L, 0, 1L, 0}, + {"innodb_concurrency_tickets", OPT_INNODB_CONCURRENCY_TICKETS, + "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 @@ -5068,8 +5082,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 13e3d375448..a0ec68098cb 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -378,6 +378,14 @@ sys_var_thd_bool sys_innodb_table_locks("innodb_table_locks", &SV::innodb_table_locks); 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_concurrency_tickets("innodb_concurrency_tickets", + &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 @@ -651,6 +659,10 @@ sys_var *sys_variables[]= &sys_innodb_table_locks, &sys_innodb_max_purge_lag, &sys_innodb_autoextend_increment, + &sys_innodb_sync_spin_loops, + &sys_innodb_concurrency_tickets, + &sys_innodb_thread_sleep_delay, + &sys_innodb_thread_concurrency, #endif #ifdef HAVE_NDBCLUSTER_DB &sys_ndb_autoincrement_prefetch_sz, @@ -742,6 +754,7 @@ struct show_var_st init_vars[]= { {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR}, {"innodb_doublewrite", (char*) &innobase_use_doublewrite, SHOW_MY_BOOL}, {"innodb_checksums", (char*) &innobase_use_checksums, SHOW_MY_BOOL}, + {sys_innodb_concurrency_tickets.name, (char*) &sys_innodb_concurrency_tickets, SHOW_SYS}, {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL}, {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG }, {"innodb_file_per_table", (char*) &innobase_file_per_table, SHOW_MY_BOOL}, @@ -760,8 +773,10 @@ 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 }, + {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}, {sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS}, - {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, 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},