#At lp:maria based on revid:monty@askmonty.org-20100129105202-5pyhpgwqcvxawxhh 2808 Michael Widenius 2010-01-29 Patch set contributed by Alex Budovski (MCA) Fix for Bug#31173: mysqlslap.exe crashes if called without any parameters modified: .bzrignore client/mysqlslap.c mysys/my_thr_init.c sql-common/client.c sql/CMakeLists.txt sql/mysqld.cc sql/sql_profile.cc sql/sql_profile.h sql/udf_example.def storage/maria/ma_close.c per-file messages: .bzrignore Fixed .bzrignore rules. Many were simply not ignoring what they were meant to. client/mysqlslap.c Fixed bug for Bug#31173: mysqlslap.exe crashes if called without any parameters The original patch could cause memory leaks and odd problems depending on how connection was made. This code ensures that all mysql_options() are set for each mysql_real_connect(). (This patch by Monty) mysys/my_thr_init.c Fixed multiply-initialized critical section on Windows, due to code incorrectly checking the wrong field in an attempt to prevent multiple-initialization. sql-common/client.c Don't use shared memory if it's not set (for example after failed mysql_real_connect). Ensure that mysql_close() resets all resources so that it's safe to call it twice. (Patch by monty, related to Bug#31173: mysqlslap.exe crashes if called without any parameters) sql/CMakeLists.txt Added page fault counters for SHOW PROFILE on Windows. sql/mysqld.cc Fixed attempt to set a NULL event. The code now only sets the event if appropriate (i.e. shared memory is being used) sql/sql_profile.cc Added page fault counters for SHOW PROFILE on Windows. sql/sql_profile.h Added page fault counters for SHOW PROFILE on Windows. sql/udf_example.def Some cleanup functions were not exported from udf_example.dll, causing them to never be executed, and as a result multiple-initialization of kernel objects occurred and resources were not being freed correctly. storage/maria/ma_close.c Condition variable share->key_del_cond was never being destroyed, while its containing heap block was being freed in maria_close(), leaking kernel resources. === modified file '.bzrignore' --- a/.bzrignore 2009-12-22 13:50:20 +0000 +++ b/.bzrignore 2010-01-29 18:42:22 +0000 @@ -40,15 +40,15 @@ *.dsp *.Po *.Plo -*/*.dir/* +*.dir/ */*_pure_*warnings */.deps */.libs/* */.pure -*/debug/* -*/minsizerel/* -*/release/* -*/relwithdebinfo/* +debug/ +MinSizeRel/ +Release/ +RelWithDebInfo/ *~ .*.swp ./CMakeCache.txt @@ -96,7 +96,7 @@ BitKeeper/tmp/gone BitKeeper/tmp BitKeeper/log BitKeeper/etc/SCCS -CMakeFiles/* +CMakeFiles/ COPYING COPYING.LIB Docs/#manual.texi# === modified file 'client/mysqlslap.c' --- a/client/mysqlslap.c 2009-12-03 11:34:11 +0000 +++ b/client/mysqlslap.c 2010-01-29 18:42:22 +0000 @@ -292,6 +292,25 @@ static int gettimeofday(struct timeval * } #endif +void set_mysql_connect_options(MYSQL *mysql) +{ + if (opt_compress) + mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS); +#ifdef HAVE_OPENSSL + if (opt_use_ssl) + mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, + opt_ssl_capath, opt_ssl_cipher); +#endif + if (opt_protocol) + mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); +#ifdef HAVE_SMEM + if (shared_memory_base_name) + mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); +#endif + mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset); +} + + int main(int argc, char **argv) { MYSQL mysql; @@ -323,20 +342,7 @@ int main(int argc, char **argv) exit(1); } mysql_init(&mysql); - if (opt_compress) - mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); -#ifdef HAVE_OPENSSL - if (opt_use_ssl) - mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, - opt_ssl_capath, opt_ssl_cipher); -#endif - if (opt_protocol) - mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); -#ifdef HAVE_SMEM - if (shared_memory_base_name) - mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); -#endif - mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); + set_mysql_connect_options(&mysql); if (!opt_only_print) { @@ -1815,6 +1821,7 @@ pthread_handler_t run_task(void *p) my_progname, mysql_error(mysql)); exit(0); } + set_mysql_connect_options(mysql); if (mysql_thread_init()) { @@ -1855,7 +1862,6 @@ limit_not_met: my_progname, mysql_error(mysql)); exit(0); } - if (slap_connect(mysql)) goto end; } @@ -2223,6 +2229,7 @@ slap_connect(MYSQL *mysql) int x, connect_error= 1; for (x= 0; x < 10; x++) { + set_mysql_connect_options(mysql); if (mysql_real_connect(mysql, host, user, opt_password, create_schema_string, opt_mysql_port, === modified file 'mysys/my_thr_init.c' --- a/mysys/my_thr_init.c 2009-12-03 11:19:05 +0000 +++ b/mysys/my_thr_init.c 2010-01-29 18:42:22 +0000 @@ -317,7 +317,7 @@ my_bool my_thread_init(void) /* Skip initialization if the thread specific variable is already initialized */ - if (THR_KEY_mysys.id) + if (THR_KEY_mysys.init) goto end; tmp= &THR_KEY_mysys; #endif === modified file 'sql-common/client.c' --- a/sql-common/client.c 2010-01-29 10:42:31 +0000 +++ b/sql-common/client.c 2010-01-29 18:42:22 +0000 @@ -1940,7 +1940,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons #if defined(HAVE_SMEM) if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) && - (!host || !strcmp(host,LOCAL_HOST))) + (!host || !strcmp(host,LOCAL_HOST)) && + mysql->options.shared_memory_base_name) { if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) == INVALID_HANDLE_VALUE) @@ -1949,7 +1950,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons ("host: '%s' socket: '%s' shared memory: %s have_tcpip: %d", host ? host : "<null>", unix_socket ? unix_socket : "<null>", - (int) mysql->options.shared_memory_base_name, + mysql->options.shared_memory_base_name, (int) have_tcpip)); if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) goto error; @@ -2752,6 +2753,13 @@ void mysql_detach_stmt_list(LIST **stmt_ } +/* + Close a MySQL connection and free all resources attached to it. + + This function is coded in such that it can be called multiple times + (As some clients call this after mysql_real_connect() fails) +*/ + void STDCALL mysql_close(MYSQL *mysql) { DBUG_ENTER("mysql_close"); @@ -2785,10 +2793,16 @@ void STDCALL mysql_close(MYSQL *mysql) } #endif if (mysql != mysql->master) + { mysql_close(mysql->master); + mysql->master= 0; + } #ifndef MYSQL_SERVER if (mysql->thd) + { (*mysql->methods->free_embedded_thd)(mysql); + mysql->thd= 0; + } #endif if (mysql->free_me) my_free((uchar*) mysql,MYF(0)); === modified file 'sql/CMakeLists.txt' --- a/sql/CMakeLists.txt 2009-12-03 11:19:05 +0000 +++ b/sql/CMakeLists.txt 2010-01-29 18:42:22 +0000 @@ -97,7 +97,7 @@ SET_TARGET_PROPERTIES(mysqld PROPERTIES SET (MYSQLD_CORE_LIBS mysys zlib dbug strings yassl taocrypt vio regex sql libevent) TARGET_LINK_LIBRARIES(mysqld ${MYSQLD_CORE_LIBS} ${MYSQLD_STATIC_ENGINE_LIBS}) -TARGET_LINK_LIBRARIES(mysqld ws2_32.lib) +TARGET_LINK_LIBRARIES(mysqld ws2_32.lib psapi.lib) IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS) === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2010-01-28 11:35:10 +0000 +++ b/sql/mysqld.cc 2010-01-29 18:42:22 +0000 @@ -1173,11 +1173,14 @@ static void __cdecl kill_server(int sig_ /* Send event to smem_event_connect_request for aborting */ - if (!SetEvent(smem_event_connect_request)) + if (opt_enable_shared_memory) { - DBUG_PRINT("error", - ("Got error: %ld from SetEvent of smem_event_connect_request", - GetLastError())); + if (!SetEvent(smem_event_connect_request)) + { + DBUG_PRINT("error", + ("Got error: %ld from SetEvent of smem_event_connect_request", + GetLastError())); + } } #endif === modified file 'sql/sql_profile.cc' --- a/sql/sql_profile.cc 2009-10-15 21:38:29 +0000 +++ b/sql/sql_profile.cc 2010-01-29 18:42:22 +0000 @@ -131,6 +131,23 @@ int make_profile_table_for_show(THD *thd #define RUSAGE_USEC(tv) ((tv).tv_sec*1000*1000 + (tv).tv_usec) #define RUSAGE_DIFF_USEC(tv1, tv2) (RUSAGE_USEC((tv1))-RUSAGE_USEC((tv2))) +#ifdef __WIN__ +inline ULONGLONG FileTimeToQuadWord(FILETIME *ft) +{ + ULONGLONG nrv = 0; + nrv |= ft->dwHighDateTime; + nrv <<= 32; + nrv |= ft->dwLowDateTime; + return nrv; +} + + +// Get time difference between to FILETIME objects in seconds. +inline double GetTimeDiffInSeconds(FILETIME *a, FILETIME *b) +{ + return ((FileTimeToQuadWord(a) - FileTimeToQuadWord(b)) / 1e7); +} +#endif /* __WIN__ */ PROF_MEASUREMENT::PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg) @@ -221,6 +238,11 @@ void PROF_MEASUREMENT::collect() time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */ #ifdef HAVE_GETRUSAGE getrusage(RUSAGE_SELF, &rusage); +#elif defined(__WIN__) + FILETIME ftDummy; + GetProcessTimes(GetCurrentProcess(), &ftDummy, &ftDummy, &ftKernel, &ftUser); + GetProcessIoCounters(GetCurrentProcess(), &io_count); + GetProcessMemoryInfo(GetCurrentProcess(), &mem_count, sizeof(mem_count)); #endif } @@ -590,6 +612,23 @@ int PROFILING::fill_statistics_info(THD table->field[5]->store_decimal(&cpu_stime_decimal); table->field[4]->set_notnull(); table->field[5]->set_notnull(); +#elif defined(__WIN__) + my_decimal cpu_utime_decimal, cpu_stime_decimal; + + double2my_decimal(E_DEC_FATAL_ERROR, + GetTimeDiffInSeconds(&entry->ftUser, + &previous->ftUser), + &cpu_utime_decimal); + double2my_decimal(E_DEC_FATAL_ERROR, + GetTimeDiffInSeconds(&entry->ftKernel, + &previous->ftKernel), + &cpu_stime_decimal); + + // Store the result. + table->field[4]->store_decimal(&cpu_utime_decimal); + table->field[5]->store_decimal(&cpu_stime_decimal); + table->field[4]->set_notnull(); + table->field[5]->set_notnull(); #else /* TODO: Add CPU-usage info for non-BSD systems */ #endif @@ -612,6 +651,17 @@ int PROFILING::fill_statistics_info(THD table->field[9]->store((uint32)(entry->rusage.ru_oublock - previous->rusage.ru_oublock)); table->field[9]->set_notnull(); +#elif defined(__WIN__) + ULONGLONG reads_delta = entry->io_count.ReadOperationCount - + previous->io_count.ReadOperationCount; + ULONGLONG writes_delta = entry->io_count.WriteOperationCount - + previous->io_count.WriteOperationCount; + + table->field[8]->store((uint32)reads_delta); + table->field[8]->set_notnull(); + + table->field[9]->store((uint32)writes_delta); + table->field[9]->set_notnull(); #else /* TODO: Add block IO info for non-BSD systems */ #endif @@ -634,6 +684,13 @@ int PROFILING::fill_statistics_info(THD table->field[13]->store((uint32)(entry->rusage.ru_minflt - previous->rusage.ru_minflt), true); table->field[13]->set_notnull(); +#elif defined(__WIN__) + /* Windows APIs don't easily distinguish between hard and soft page + faults, so we just fill the 'major' column and leave the second NULL. + */ + table->field[12]->store((uint32)(entry->mem_count.PageFaultCount - + previous->mem_count.PageFaultCount), true); + table->field[12]->set_notnull(); #else /* TODO: Add page fault info for non-BSD systems */ #endif === modified file 'sql/sql_profile.h' --- a/sql/sql_profile.h 2009-09-07 20:50:10 +0000 +++ b/sql/sql_profile.h 2010-01-29 18:42:22 +0000 @@ -36,6 +36,10 @@ int make_profile_table_for_show(THD *thd #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) #include "mysql_priv.h" +#ifdef __WIN__ +#include <psapi.h> +#endif + #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> #endif @@ -165,6 +169,10 @@ private: char *status; #ifdef HAVE_GETRUSAGE struct rusage rusage; +#elif defined(__WIN__) + FILETIME ftKernel, ftUser; + IO_COUNTERS io_count; + PROCESS_MEMORY_COUNTERS mem_count; #endif char *function; === modified file 'sql/udf_example.def' --- a/sql/udf_example.def 2007-10-29 14:01:40 +0000 +++ b/sql/udf_example.def 2010-01-29 18:42:22 +0000 @@ -3,8 +3,10 @@ VERSION 1.0 EXPORTS lookup lookup_init + lookup_deinit reverse_lookup reverse_lookup_init + reverse_lookup_deinit metaphon_init metaphon_deinit metaphon === modified file 'storage/maria/ma_close.c' --- a/storage/maria/ma_close.c 2009-02-05 22:38:30 +0000 +++ b/storage/maria/ma_close.c 2010-01-29 18:42:22 +0000 @@ -177,6 +177,7 @@ int maria_close(register MARIA_HA *info) { (void) pthread_mutex_destroy(&share->intern_lock); (void) pthread_mutex_destroy(&share->close_lock); + (void) pthread_cond_destroy(&share->key_del_cond); my_free((uchar *)share, MYF(0)); /* If share cannot be freed, it's because checkpoint has previously