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/ndb/ndbcluster.sh b/mysql-test/ndb/ndbcluster.sh index 848223a091c..2d529f8fe0f 100644 --- a/mysql-test/ndb/ndbcluster.sh +++ b/mysql-test/ndb/ndbcluster.sh @@ -191,7 +191,7 @@ if ( cd "$fs_ndb" ; $exec_mgmtsrvr -f config.ini ) ; then :; else echo "Unable to start $exec_mgmtsrvr from `pwd`" exit 1 fi -if sleep_until_file_created $fs_ndb/ndb_3.pid 30 +if sleep_until_file_created $fs_ndb/ndb_3.pid 120 then :; else exit 1 fi @@ -201,7 +201,7 @@ cat `find "$fs_ndb" -name 'ndb_*.pid'` > "$fs_ndb/$pidfile" echo "Starting ndbd" ( cd "$fs_ndb" ; $exec_ndb $flags_ndb & ) -if sleep_until_file_created $fs_ndb/ndb_1.pid 30 +if sleep_until_file_created $fs_ndb/ndb_1.pid 120 then :; else stop_default_ndbcluster exit 1 @@ -212,7 +212,7 @@ cat `find "$fs_ndb" -name 'ndb_*.pid'` > "$fs_ndb/$pidfile" echo "Starting ndbd" ( cd "$fs_ndb" ; $exec_ndb $flags_ndb & ) -if sleep_until_file_created $fs_ndb/ndb_2.pid 30 +if sleep_until_file_created $fs_ndb/ndb_2.pid 120 then :; else stop_default_ndbcluster exit 1 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/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 800ffe2e361..fa77bc14762 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -98,6 +98,7 @@ static bool fixDepricated(InitConfigFileParser::Context & ctx, const char *); static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *); static bool fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data); static bool fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data); +static bool fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data); const ConfigInfo::SectionRule ConfigInfo::m_SectionRules[] = { @@ -111,6 +112,8 @@ ConfigInfo::m_SectionRules[] = { { "REP", transformNode, 0 }, { "EXTERNAL REP", transformExtNode, 0 }, + { MGM_TOKEN, fixShmUniqueId, 0 }, + { "TCP", checkConnectionSupport, 0 }, { "SHM", checkConnectionSupport, 0 }, { "SCI", checkConnectionSupport, 0 }, @@ -3155,19 +3158,39 @@ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ DBUG_RETURN(true); } +static bool +fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data) +{ + DBUG_ENTER("fixShmUniqueId"); + Uint32 nodes= 0; + ctx.m_userProperties.get(ctx.fname, &nodes); + if (nodes == 1) // first management server + { + Uint32 portno= atoi(NDB_PORT); + ctx.m_currentSection->get("PortNumber", &portno); + ctx.m_userProperties.put("ShmUniqueId", portno); + } + DBUG_RETURN(true); +} + static bool fixShmKey(InitConfigFileParser::Context & ctx, const char *) { + DBUG_ENTER("fixShmKey"); Uint32 id1= 0, id2= 0, key= 0; require(ctx.m_currentSection->get("NodeId1", &id1)); require(ctx.m_currentSection->get("NodeId2", &id2)); if(ctx.m_currentSection->get("ShmKey", &key)) - return true; + { + DBUG_RETURN(true); + } - key= (id1 > id2 ? id1 << 16 | id2 : id2 << 16 | id1); + require(ctx.m_userProperties.get("ShmUniqueId", &key)); + key= key << 16 | (id1 > id2 ? id1 << 8 | id2 : id2 << 8 | id1); ctx.m_currentSection->put("ShmKey", key); - return true; + DBUG_PRINT("info",("Added ShmKey=0x%x", key)); + DBUG_RETURN(true); } /** diff --git a/ndb/test/src/CpcClient.cpp b/ndb/test/src/CpcClient.cpp index 2ef23528360..1d1b4fcb977 100644 --- a/ndb/test/src/CpcClient.cpp +++ b/ndb/test/src/CpcClient.cpp @@ -30,7 +30,7 @@ 0, 0, \ 0, \ (desc), \ - (void *)(value) } + (value) } #define CPC_ARG(name, type, opt, desc) \ { (name), \ @@ -351,17 +351,12 @@ SimpleCpcClient::define_process(Process & p, Properties& reply){ int SimpleCpcClient::list_processes(Vector &procs, Properties& reply) { - enum Proclist { - Proclist_Start, - Proclist_End, - Proclist_Entry - }; + int start, end, entry; const ParserRow_t list_reply[] = { - CPC_CMD("start processes", Proclist_Start, ""), + CPC_CMD("start processes", &start, ""), + CPC_CMD("end processes", &end, ""), - CPC_CMD("end processes", Proclist_End, ""), - - CPC_CMD("process", Proclist_Entry, ""), + CPC_CMD("process", &entry, ""), CPC_ARG("id", Int, Mandatory, "Id of process."), CPC_ARG("name", String, Mandatory, "Name of process"), CPC_ARG("group", String, Mandatory, "Group of process"), @@ -390,26 +385,29 @@ SimpleCpcClient::list_processes(Vector &procs, Properties& reply) { bool done = false; while(!done) { const Properties *proc; - enum Proclist p; - cpc_recv(list_reply, &proc, (void **)&p); + void *p; + cpc_recv(list_reply, &proc, &p); - switch(p) { - case Proclist_Start: + if(p == &start) + { /* do nothing */ - break; - case Proclist_End: + } + else if(p == &end) + { done = true; - break; - case Proclist_Entry: + } + else if(p == &entry) + { if(proc != NULL){ Process p; convert(* proc, p); procs.push_back(p); } - break; - default: - /* ignore */ - break; + } + else + { + ndbout_c("internal error: %d", __LINE__); + return -1; } } return 0; 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 72b02b76ddf..0c8ce7453eb 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4224,6 +4224,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, @@ -5071,6 +5074,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 @@ -5093,8 +5107,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}, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a0728f58372..6082b943b7f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1613,7 +1613,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, table_list.schema_table= schema_table; } - /* command not cachable => no gap for data base name */ + thd->query_length= strlen(packet); // for simplicity: don't optimize if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1))) break; mysql_log.write(thd,command,"%s %s",table_list.table_name, fields); diff --git a/tests/client_test.c b/tests/client_test.c index d815a9abb3e..498b57fdeab 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -12481,6 +12481,30 @@ static void test_truncation_option() mysql_stmt_close(stmt); } + +/* Bug#6761 - mysql_list_fields doesn't work */ + +static void test_bug6761(void) +{ + const char *stmt_text; + MYSQL_RES *res; + int rc; + myheader("test_bug6761"); + + stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + res= mysql_list_fields(mysql, "t1", "%"); + DIE_UNLESS(res && mysql_num_fields(res) == 3); + mysql_free_result(res); + + stmt_text= "DROP TABLE t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -12687,6 +12711,7 @@ static struct my_tests_st my_tests[]= { { "test_bug4172", test_bug4172 }, { "test_conversion", test_conversion }, { "test_rewind", test_rewind }, + { "test_bug6761", test_bug6761 }, { "test_view", test_view }, { "test_view_where", test_view_where }, { "test_view_2where", test_view_2where },