From 3ed8188bfbf3cc8cf652ec53bb1c486c531d16e8 Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Wed, 14 Nov 2001 17:06:04 +0200 Subject: [PATCH 1/7] buf0flu.c: Fix a bug which could cause InnoDB to complain it cannot find free blocks from the buffer cache during recovery --- innobase/buf/buf0flu.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 4217a3ba99b..cfa814bcb05 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -138,15 +138,11 @@ buf_flush_ready_for_flush( return(TRUE); - } else if ((block->old || (UT_LIST_GET_LEN(buf_pool->LRU) - < BUF_LRU_OLD_MIN_LEN)) - && (block->buf_fix_count == 0)) { + } else if (block->buf_fix_count == 0) { /* If we are flushing the LRU list, to avoid deadlocks we require the block not to be bufferfixed, and hence - not latched. Since LRU flushed blocks are soon moved - to the free list, it is good to flush only old blocks - from the end of the LRU list. */ + not latched. */ return(TRUE); } From 086fe412948897b03832b288c84e4b0a49ce7820 Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Sat, 17 Nov 2001 13:48:39 +0200 Subject: [PATCH 2/7] btr0cur.c, btr0btr.c, dict0dict.h, dict0dict.c: Fix a bug in insert buffer B-tree upper levels; probably caused the crash by B.Fitzpatrick buf0flu.c: Fix a bug in previous change A small optimization for LRU flushes to avoid losing hot pages from the buffer pool --- innobase/btr/btr0btr.c | 24 +++++++++++++----------- innobase/btr/btr0cur.c | 6 +++--- innobase/buf/buf0flu.c | 9 +++++++++ innobase/dict/dict0dict.c | 13 +++++++++++-- innobase/include/dict0dict.h | 4 +++- 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 33a3ac70c90..a96830c24ff 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -21,7 +21,7 @@ Created 6/2/1994 Heikki Tuuri #include "lock0lock.h" #include "ibuf0ibuf.h" -/** +/* Node pointers ------------- Leaf pages of a B-tree contain the index records stored in the @@ -550,14 +550,15 @@ btr_page_get_father_for_rec( ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)); - ut_ad(user_rec != page_get_supremum_rec(page)); - ut_ad(user_rec != page_get_infimum_rec(page)); + ut_a(user_rec != page_get_supremum_rec(page)); + ut_a(user_rec != page_get_infimum_rec(page)); ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page)); heap = mem_heap_create(100); - tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap); + tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap, + btr_page_get_level(page, mtr)); /* In the following, we choose just any index from the tree as the first parameter for btr_cur_search_to_nth_level. */ @@ -569,7 +570,7 @@ btr_page_get_father_for_rec( node_ptr = btr_cur_get_rec(&cursor); - ut_ad(btr_node_ptr_get_child_page_no(node_ptr) == + ut_a(btr_node_ptr_get_child_page_no(node_ptr) == buf_frame_get_page_no(page)); mem_heap_free(heap); @@ -949,8 +950,8 @@ btr_root_raise_and_insert( /* Build the node pointer (= node key and page address) for the child */ - node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap); - + node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap, + level); /* Reorganize the root to get free space */ btr_page_reorganize(root, mtr); @@ -1365,7 +1366,7 @@ btr_attach_half_pages( half */ node_ptr_upper = dict_tree_build_node_ptr(tree, split_rec, - upper_page_no, heap); + upper_page_no, heap, level); /* Insert it next to the pointer to the lower half. Note that this may generate recursion leading to a split on the higher level. */ @@ -2230,7 +2231,7 @@ btr_check_node_ptr( node_ptr_tuple = dict_tree_build_node_ptr( tree, page_rec_get_next(page_get_infimum_rec(page)), - 0, heap); + 0, heap, btr_page_get_level(page, mtr)); ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr) == 0); @@ -2485,10 +2486,11 @@ loop: heap = mem_heap_create(256); node_ptr_tuple = dict_tree_build_node_ptr( - tree, + tree, page_rec_get_next( page_get_infimum_rec(page)), - 0, heap); + 0, heap, + btr_page_get_level(page, &mtr)); if (cmp_dtuple_rec(node_ptr_tuple, node_ptr) != 0) { diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index a64ed8b6fe1..70de09f0fd9 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -2345,9 +2345,9 @@ btr_cur_pessimistic_delete( heap = mem_heap_create(256); node_ptr = dict_tree_build_node_ptr( - tree, page_rec_get_next(rec), - buf_frame_get_page_no(page), - heap); + tree, page_rec_get_next(rec), + buf_frame_get_page_no(page), + heap, btr_page_get_level(page, mtr)); btr_insert_on_non_leaf_level(tree, btr_page_get_level(page, mtr) + 1, diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index cfa814bcb05..8184f10d6e9 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -556,6 +556,15 @@ buf_flush_try_neighbors( block = buf_page_hash_get(space, i); + if (block && flush_type == BUF_FLUSH_LRU && i != offset + && !block->old) { + + /* We avoid flushing 'non-old' blocks in an LRU flush, + because the flushed blocks are soon freed */ + + continue; + } + if (block && buf_flush_ready_for_flush(block, flush_type)) { mutex_exit(&(buf_pool->mutex)); diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 07a9b472d66..e5ac2f3c577 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2411,7 +2411,9 @@ dict_tree_build_node_ptr( dict_tree_t* tree, /* in: index tree */ rec_t* rec, /* in: record for which to build node pointer */ ulint page_no,/* in: page number to put in node pointer */ - mem_heap_t* heap) /* in: memory heap where pointer created */ + mem_heap_t* heap, /* in: memory heap where pointer created */ + ibool level) /* in: level of rec in tree: 0 means leaf + level */ { dtuple_t* tuple; dict_index_t* ind; @@ -2423,9 +2425,16 @@ dict_tree_build_node_ptr( if (tree->type & DICT_UNIVERSAL) { /* In a universal index tree, we take the whole record as - the node pointer */ + the node pointer if the reord is on the leaf level, + on non-leaf levels we remove the last field, which + contains the page number of the child page */ n_unique = rec_get_n_fields(rec); + + if (level > 0) { + ut_a(n_unique > 1); + n_unique--; + } } else { n_unique = dict_index_get_n_unique_in_tree(ind); } diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index a4ab4faa25c..848881bc931 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -622,7 +622,9 @@ dict_tree_build_node_ptr( dict_tree_t* tree, /* in: index tree */ rec_t* rec, /* in: record for which to build node pointer */ ulint page_no,/* in: page number to put in node pointer */ - mem_heap_t* heap); /* in: memory heap where pointer created */ + mem_heap_t* heap, /* in: memory heap where pointer created */ + ibool level); /* in: level of rec in tree: 0 means leaf + level */ /************************************************************************** Copies an initial segment of a physical record, long enough to specify an index entry uniquely. */ From 5b54fab6a09e0905ee7b42c0477a9643fa7dd623 Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Sat, 17 Nov 2001 14:18:27 +0200 Subject: [PATCH 3/7] dict0dict.h, dict0dict.c: Fix wrong (though equivalent) type decl --- innobase/dict/dict0dict.c | 2 +- innobase/include/dict0dict.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index e5ac2f3c577..ba032013baf 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2412,7 +2412,7 @@ dict_tree_build_node_ptr( rec_t* rec, /* in: record for which to build node pointer */ ulint page_no,/* in: page number to put in node pointer */ mem_heap_t* heap, /* in: memory heap where pointer created */ - ibool level) /* in: level of rec in tree: 0 means leaf + ulint level) /* in: level of rec in tree: 0 means leaf level */ { dtuple_t* tuple; diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 848881bc931..ae313398c99 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -623,7 +623,7 @@ dict_tree_build_node_ptr( rec_t* rec, /* in: record for which to build node pointer */ ulint page_no,/* in: page number to put in node pointer */ mem_heap_t* heap, /* in: memory heap where pointer created */ - ibool level); /* in: level of rec in tree: 0 means leaf + ulint level); /* in: level of rec in tree: 0 means leaf level */ /************************************************************************** Copies an initial segment of a physical record, long enough to specify an From 7c7795210610cecb632aedaf432cae3e5cb344fb Mon Sep 17 00:00:00 2001 From: "miguel@light.local" <> Date: Sat, 17 Nov 2001 15:48:22 -0200 Subject: [PATCH 4/7] Removing registry service parameter code --- sql/mysqld.cc | 487 -------------------------------------------------- 1 file changed, 487 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index bfbe8f8a25a..5e6b5c098d7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -376,9 +376,6 @@ static bool read_init_file(char *file_name); #ifdef __NT__ static pthread_handler_decl(handle_connections_namedpipes,arg); #endif -#ifdef __WIN__ -static int get_service_parameters(); -#endif extern pthread_handler_decl(handle_slave,arg); #ifdef SET_RLIMIT_NOFILE static uint set_maximum_open_files(uint max_file_limit); @@ -1620,14 +1617,6 @@ int main(int argc, char **argv) mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */ set_options(); -#ifdef __WIN__ - /* service parameters can be overwritten by options */ - if (get_service_parameters()) - { - my_message( 0, "Can't read MySQL service parameters", MYF(0) ); - exit( 1 ); - } -#endif get_options(argc,argv); if (opt_log || opt_update_log || opt_slow_log || opt_bin_log) strcat(server_version,"-log"); @@ -3925,482 +3914,6 @@ static void get_options(int argc,char **argv) } -#ifdef __WIN__ - -#ifndef KEY_SERVICE_PARAMETERS -#define KEY_SERVICE_PARAMETERS "SYSTEM\\CurrentControlSet\\Services\\MySql\\Parameters" -#endif - -#define COPY_KEY_VALUE(value) if (copy_key_value(hParametersKey,&(value),lpszValue)) return 1 -#define CHECK_KEY_TYPE(type,name) if ( type != dwKeyValueType ) { key_type_error(hParametersKey,name); return 1; } -#define SET_CHANGEABLE_VARVAL(varname) if (set_varval(hParametersKey,varname,szKeyValueName,dwKeyValueType,lpdwValue)) return 1; - -static void key_type_error(HKEY hParametersKey,const char *szKeyValueName) -{ - TCHAR szErrorMsg[512]; - RegCloseKey( hParametersKey ); - strxmov(szErrorMsg,TEXT("Value \""), - szKeyValueName, - TEXT("\" of registry key \"" KEY_SERVICE_PARAMETERS "\" has wrong type\n"),NullS); - fprintf(stderr, szErrorMsg); /* not unicode compatible */ -} - -static bool copy_key_value(HKEY hParametersKey, char **var, const char *value) -{ - if (!(*var=my_strdup(value,MYF(MY_WME)))) - { - RegCloseKey(hParametersKey); - fprintf(stderr, "Couldn't allocate memory for registry key value\n"); - return 1; - } - return 0; -} - -static bool set_varval(HKEY hParametersKey,const char *var, - const char *szKeyValueName, DWORD dwKeyValueType, - LPDWORD lpdwValue) -{ - CHECK_KEY_TYPE(dwKeyValueType, szKeyValueName ); - if (set_changeable_varval(var, *lpdwValue, changeable_vars)) - { - TCHAR szErrorMsg [ 512 ]; - RegCloseKey( hParametersKey ); - strxmov(szErrorMsg, - TEXT("Value \""), - szKeyValueName, - TEXT("\" of registry key \"" KEY_SERVICE_PARAMETERS "\" is invalid\n"),NullS); - fprintf( stderr, szErrorMsg ); /* not unicode compatible */ - return 1; - } - return 0; -} - - -static int get_service_parameters() -{ - DWORD dwLastError; - HKEY hParametersKey; - DWORD dwIndex; - TCHAR szKeyValueName [ 256 ]; - DWORD dwKeyValueName; - DWORD dwKeyValueType; - BYTE bKeyValueBuffer [ 512 ]; - DWORD dwKeyValueBuffer; - LPDWORD lpdwValue = (LPDWORD) &bKeyValueBuffer[0]; - LPCTSTR lpszValue = (LPCTSTR) &bKeyValueBuffer[0]; - - /* open parameters of service */ - dwLastError = (DWORD) RegOpenKeyEx( HKEY_LOCAL_MACHINE, - TEXT(KEY_SERVICE_PARAMETERS), 0, - KEY_READ, &hParametersKey ); - if ( dwLastError == ERROR_FILE_NOT_FOUND ) /* no parameters available */ - return 0; - if ( dwLastError != ERROR_SUCCESS ) - { - fprintf(stderr,"Can't open registry key \"" KEY_SERVICE_PARAMETERS "\" for reading\n" ); - return 1; - } - - /* enumerate all values of key */ - dwIndex = 0; - dwKeyValueName = sizeof( szKeyValueName ) / sizeof( TCHAR ); - dwKeyValueBuffer = sizeof( bKeyValueBuffer ); - while ( (dwLastError = (DWORD) RegEnumValue(hParametersKey, dwIndex, - szKeyValueName, &dwKeyValueName, - NULL, &dwKeyValueType, - &bKeyValueBuffer[0], - &dwKeyValueBuffer)) - != ERROR_NO_MORE_ITEMS ) - { - /* check if error occured */ - if ( dwLastError != ERROR_SUCCESS ) - { - RegCloseKey( hParametersKey ); - fprintf( stderr, "Can't enumerate values of registry key \"" KEY_SERVICE_PARAMETERS "\"\n" ); - return 1; - } - if ( lstrcmp(szKeyValueName, TEXT("BaseDir")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName); - strmov( mysql_home, lpszValue ); /* not unicode compatible */ - } - else if ( lstrcmp(szKeyValueName, TEXT("BindAddress")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName); - - my_bind_addr = (ulong) inet_addr( lpszValue ); - if ( my_bind_addr == (ulong) INADDR_NONE ) - { - struct hostent* ent; - - if ( !(*lpszValue) ) - { - char szHostName [ 256 ]; - if ( gethostname(szHostName, sizeof(szHostName)) == SOCKET_ERROR ) - { - RegCloseKey( hParametersKey ); - fprintf( stderr, "Can't get my own hostname\n" ); - return 1; - } - ent = gethostbyname( szHostName ); - } - else ent = gethostbyname( lpszValue ); - if ( !ent ) - { - RegCloseKey( hParametersKey ); - fprintf( stderr, "Can't resolve hostname!\n" ); - return 1; - } - my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr; - } - } - else if ( lstrcmp(szKeyValueName, TEXT("BigTables")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName); - if ( *lpdwValue ) - thd_startup_options |= OPTION_BIG_TABLES; - else - thd_startup_options &= ~((ulong)OPTION_BIG_TABLES); - } - else if ( lstrcmp(szKeyValueName, TEXT("DataDir")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName ); - strmov( mysql_real_data_home, lpszValue ); /* not unicode compatible */ - } - else if ( lstrcmp(szKeyValueName, TEXT("Locking")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - my_disable_locking = !(*lpdwValue); - } - else if ( lstrcmp(szKeyValueName, TEXT("LogFile")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName ); - opt_log = 1; - COPY_KEY_VALUE( opt_logname ); - } - else if ( lstrcmp(szKeyValueName, TEXT("UpdateLogFile")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName ); - opt_update_log = 1; - COPY_KEY_VALUE( opt_update_logname ); - } - else if ( lstrcmp(szKeyValueName, TEXT("BinaryLogFile")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName ); - opt_bin_log = 1; - COPY_KEY_VALUE( opt_bin_logname ); - } - else if ( lstrcmp(szKeyValueName, TEXT("BinaryLogIndexFile")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName ); - opt_bin_log = 1; - COPY_KEY_VALUE( opt_binlog_index_name ); - } - else if ( lstrcmp(szKeyValueName, TEXT("ISAMLogFile")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName ); - COPY_KEY_VALUE( myisam_log_filename ); - opt_myisam_log=1; - } - else if ( lstrcmp(szKeyValueName, TEXT("LongLogFormat")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - if ( *lpdwValue ) - opt_specialflag |= SPECIAL_LONG_LOG_FORMAT; - else - opt_specialflag &= ~((ulong)SPECIAL_LONG_LOG_FORMAT); - } - else if ( lstrcmp(szKeyValueName, TEXT("LowPriorityUpdates")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - if ( *lpdwValue ) - { - thd_startup_options |= OPTION_LOW_PRIORITY_UPDATES; - low_priority_updates = 1; - } - else - { - thd_startup_options &= ~((ulong)OPTION_LOW_PRIORITY_UPDATES); - low_priority_updates = 0; - } - } - else if ( lstrcmp(szKeyValueName, TEXT("Port")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - mysql_port = (unsigned int) *lpdwValue; - } - else if ( lstrcmp(szKeyValueName, TEXT("OldProtocol")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - protocol_version = *lpdwValue ? PROTOCOL_VERSION - 1 : PROTOCOL_VERSION; - } - else if ( lstrcmp(szKeyValueName, TEXT("HostnameResolving")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - if ( !*lpdwValue ) - opt_specialflag |= SPECIAL_NO_RESOLVE; - else - opt_specialflag &= ~((ulong)SPECIAL_NO_RESOLVE); - } - else if ( lstrcmp(szKeyValueName, TEXT("Networking")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - opt_disable_networking = !(*lpdwValue); - } - else if ( lstrcmp(szKeyValueName, TEXT("ShowDatabase")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - opt_skip_show_db = !(*lpdwValue); - } - else if ( lstrcmp(szKeyValueName, TEXT("HostnameCaching")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - if ( !*lpdwValue ) - opt_specialflag |= SPECIAL_NO_HOST_CACHE; - else - opt_specialflag &= ~((ulong)SPECIAL_NO_HOST_CACHE); - } - else if ( lstrcmp(szKeyValueName, TEXT("ThreadPriority")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - if ( !(*lpdwValue) ) - opt_specialflag |= SPECIAL_NO_PRIOR; - else - opt_specialflag &= ~((ulong)SPECIAL_NO_PRIOR); - } - else if ( lstrcmp(szKeyValueName, TEXT("NamedPipe")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName ); - COPY_KEY_VALUE( mysql_unix_port ); - } - else if ( lstrcmp(szKeyValueName, TEXT("TempDir")) == 0 ) - { - CHECK_KEY_TYPE( REG_SZ, szKeyValueName ); - COPY_KEY_VALUE( mysql_tmpdir ); - } - else if ( lstrcmp(szKeyValueName, TEXT("FlushTables")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - nisam_flush = myisam_flush= *lpdwValue ? 1 : 0; - } - else if ( lstrcmp(szKeyValueName, TEXT("BackLog")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "back_log" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("ConnectTimeout")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "connect_timeout" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("JoinBufferSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "join_buffer" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("KeyBufferSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "key_buffer" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("LongQueryTime")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "long_query_time" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxAllowedPacket")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "max_allowed_packet" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxConnections")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "max_connections" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxUserConnections")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "max_user_connections" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxConnectErrors")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "max_connect_errors" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxInsertDelayedThreads")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "max_delayed_threads" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxJoinSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "max_join_size" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxSortLength")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "max_sort_length" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("NetBufferLength")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "net_buffer_length" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("RecordBufferSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "record_buffer" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("SortBufferSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "sort_buffer" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("TableCacheSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "table_cache" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("TmpTableSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "tmp_table_size" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("ThreadStackSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "thread_stack" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("WaitTimeout")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "wait_timeout" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("DelayedInsertTimeout")) - == 0 ) - { - SET_CHANGEABLE_VARVAL( "delayed_insert_timeout" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("DelayedInsertLimit")) == - 0 ) - { - SET_CHANGEABLE_VARVAL( "delayed_insert_limit" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("DelayedQueueSize")) == 0 - ) - { - SET_CHANGEABLE_VARVAL( "delayed_queue_size" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("FlushTime")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "flush_time" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("InteractiveTimeout")) == - 0 ) - { - SET_CHANGEABLE_VARVAL( "interactive_timeout" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("LowerCaseTableNames")) - == 0 ) - { - SET_CHANGEABLE_VARVAL( "lower_case_table_names" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxHeapTableSize")) == 0 - ) - { - SET_CHANGEABLE_VARVAL( "max_heap_table_size" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxTmpTables")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "max_tmp_tables" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("MaxWriteLockCount")) == - 0 ) - { - SET_CHANGEABLE_VARVAL( "max_write_lock_count" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("NetRetryCount")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "net_retry_count" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("QueryBufferSize")) == 0 - ) - { - SET_CHANGEABLE_VARVAL( "query_buffer_size" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("ThreadConcurrency")) == - 0 ) - { - SET_CHANGEABLE_VARVAL( "thread_concurrency" ); - } -#ifdef HAVE_GEMINI_DB - else if ( lstrcmp(szKeyValueName, TEXT("GeminiLazyCommit")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - if ( *lpdwValue ) - gemini_options |= GEMOPT_FLUSH_LOG; - else - gemini_options &= ~GEMOPT_FLUSH_LOG; - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiFullRecovery")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - if ( *lpdwValue ) - gemini_options &= ~GEMOPT_NO_CRASH_PROTECTION; - else - gemini_options |= GEMOPT_NO_CRASH_PROTECTION; - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiNoRecovery")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - if ( *lpdwValue ) - gemini_options |= GEMOPT_NO_CRASH_PROTECTION; - else - gemini_options &= ~GEMOPT_NO_CRASH_PROTECTION; - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiUnbufferedIO")) == 0 ) - { - CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - if ( *lpdwValue ) - gemini_options |= GEMOPT_UNBUFFERED_IO; - else - gemini_options &= ~GEMOPT_UNBUFFERED_IO; - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiLockTableSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "gemini_lock_table_size" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiBufferCache")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "gemini_buffer_cache" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiSpinRetries")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "gemini_spin_retries" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiIoThreads")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "gemini_io_threads" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiConnectionLimit")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "gemini_connection_limit" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiLogClusterSize")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "gemini_log_cluster_size" ); - } - else if ( lstrcmp(szKeyValueName, TEXT("GeminiLockWaitTimeout")) == 0 ) - { - SET_CHANGEABLE_VARVAL( "gemini_lock_wait_timeout" ); - } -#endif - else - { - TCHAR szErrorMsg [ 512 ]; - RegCloseKey( hParametersKey ); - lstrcpy( szErrorMsg, TEXT("Value \"") ); - lstrcat( szErrorMsg, szKeyValueName ); - lstrcat( szErrorMsg, TEXT("\" of registry key \"" KEY_SERVICE_PARAMETERS "\" is not defined by MySQL\n") ); - fprintf( stderr, szErrorMsg ); /* not unicode compatible */ - return 1; - } - - dwIndex++; - dwKeyValueName = sizeof( szKeyValueName ) / sizeof( TCHAR ); - dwKeyValueBuffer = sizeof( bKeyValueBuffer ); - } - RegCloseKey( hParametersKey ); - - /* paths are fixed by method get_options() */ - return 0; -} -#endif - - static char *get_relative_path(const char *path) { if (test_if_hard_path(path) && From fb1f8c4f0a6f5df43d033b52d8d804cd540cb43c Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sun, 18 Nov 2001 14:08:17 +0200 Subject: [PATCH 5/7] Fixed bug in OPTIMIZE TABLE that reset index cardinality if it was up to date. --- Docs/manual.texi | 8 ++++++++ configure.in | 2 +- mysql-test/r/myisam.result | 10 ++++++++++ mysql-test/t/myisam.test | 12 ++++++++++++ sql/ha_myisam.cc | 38 ++++++++++++++++++++++---------------- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 0f234fcfd21..baa2baca2f7 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46844,6 +46844,14 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.45 @itemize @bullet @item +Fix a bug which could cause InnoDB to complain if it cannot find free blocks +from the buffer cache during recovery. +@item +Fixed a bug in InnoDB insert buffer B-tree handling that could cause crashes. +@item +Fixed bug in @code{OPTIMIZE TABLE} that reset index cardinality if it +was up to date. +@item Fixed problem with @code{t1 LEFT_JOIN t2 ... WHERE t2.date_column IS NULL} when date_column was declared as @code{NOT NULL}. @item diff --git a/configure.in b/configure.in index 6709c6be0fa..bccc323b7bd 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 3.23.44) +AM_INIT_AUTOMAKE(mysql, 3.23.45) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 1152ca24f38..143802a4d05 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -10,3 +10,13 @@ Table Op Msg_type Msg_text test.t1 repair status OK Table Op Msg_type Msg_text test.t1 check status OK +Table Op Msg_type Msg_text +test.t1 optimize status OK +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment +t1 0 PRIMARY 1 a A 5 NULL NULL +t1 1 b 1 b A 1 NULL NULL +Table Op Msg_type Msg_text +test.t1 optimize status Table is already up to date +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment +t1 0 PRIMARY 1 a A 5 NULL NULL +t1 1 b 1 b A 1 NULL NULL diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 0dc7f84efc5..5b483b969bc 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -36,3 +36,15 @@ check table t1; repair table t1; check table t1; drop table t1; + +# +# Test bug: Two optimize in a row reset index cardinality +# + +create table t1 (a int not null auto_increment, b int not null, primary key (a), index(b)); +insert into t1 (b) values (1),(2),(2),(2),(2); +optimize table t1; +show index from t1; +optimize table t1; +show index from t1; +drop table t1; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index c5c29f3c8bc..fb98708c317 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -535,7 +535,7 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) { int error=0; - uint extra_testflag=0; + uint local_testflag=param.testflag; bool optimize_done= !optimize, statistics_done=0; char fixed_name[FN_REFLEN]; const char *old_proc_info=thd->proc_info; @@ -565,19 +565,18 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) (!param.opt_rep_quick || !(share->state.changed & STATE_NOT_OPTIMIZED_KEYS)))) { - ulonglong key_map= ((param.testflag & T_CREATE_MISSING_KEYS) ? + ulonglong key_map= ((local_testflag & T_CREATE_MISSING_KEYS) ? ((ulonglong) 1L << share->base.keys)-1 : share->state.key_map); + uint testflag=param.testflag; if (mi_test_if_sort_rep(file,file->state->records,key_map,0) && - (param.testflag & T_REP_BY_SORT)) + (local_testflag & T_REP_BY_SORT)) { - uint testflag=param.testflag; - extra_testflag= T_STATISTICS; + local_testflag|= T_STATISTICS; param.testflag|= T_STATISTICS; // We get this for free thd->proc_info="Repair by sorting"; statistics_done=1; error = mi_repair_by_sort(¶m, file, fixed_name, param.opt_rep_quick); - param.testflag=testflag; } else { @@ -585,22 +584,28 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) param.testflag &= ~T_REP_BY_SORT; error= mi_repair(¶m, file, fixed_name, param.opt_rep_quick); } + param.testflag=testflag; + optimize_done=1; } if (!error) { - if ((param.testflag & T_SORT_INDEX) && + if ((local_testflag & T_SORT_INDEX) && (share->state.changed & STATE_NOT_SORTED_PAGES)) { optimize_done=1; thd->proc_info="Sorting index"; error=mi_sort_index(¶m,file,fixed_name); } - if (!statistics_done && (param.testflag & T_STATISTICS) && - (share->state.changed & STATE_NOT_ANALYZED)) + if (!statistics_done && (local_testflag & T_STATISTICS)) { - optimize_done=1; - thd->proc_info="Analyzing"; - error = chk_key(¶m, file); + if (share->state.changed & STATE_NOT_ANALYZED) + { + optimize_done=1; + thd->proc_info="Analyzing"; + error = chk_key(¶m, file); + } + else + local_testflag&= ~T_STATISTICS; // Don't update statistics } } thd->proc_info="Saving state"; @@ -615,10 +620,11 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) file->save_state=file->s->state.state; if (file->s->base.auto_key) update_auto_increment_key(¶m, file, 1); - error = update_state_info(¶m, file, - UPDATE_TIME | UPDATE_OPEN_COUNT | - ((param.testflag | extra_testflag) & - T_STATISTICS ? UPDATE_STAT : 0)); + if (optimize_done) + error = update_state_info(¶m, file, + UPDATE_TIME | UPDATE_OPEN_COUNT | + (local_testflag & + T_STATISTICS ? UPDATE_STAT : 0)); info(HA_STATUS_NO_LOCK | HA_STATUS_TIME | HA_STATUS_VARIABLE | HA_STATUS_CONST); if (rows != file->state->records && ! (param.testflag & T_VERY_SILENT)) From c76c42066e27c342b06efe1c6151296fcd5e8247 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sun, 18 Nov 2001 14:13:09 +0200 Subject: [PATCH 6/7] Test of optimize table. --- Docs/manual.texi | 183 ++++++++++++++++++++++++++----------- mysql-test/r/create.result | 9 ++ mysql-test/r/myisam.result | 17 ++++ mysql-test/t/create.test | 10 ++ sql/item_func.cc | 4 +- 5 files changed, 167 insertions(+), 56 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 4d68eed64d2..a9559e32047 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -3460,7 +3460,8 @@ select * from temporary_table, temporary_table as t2; @end example @item -@code{RENAME} doesn't work with @code{TEMPORARY} tables. +@code{RENAME} doesn't work with @code{TEMPORARY} tables or tables used in a +@code{MERGE} table. @item The optimiser may handle @code{DISTINCT} differently if you are using @@ -3554,6 +3555,7 @@ Minimum respective maximum possible @code{double} value. @item @code{LIMIT} on negative numbers are treated as big positive numbers. + @item If you use @code{ALTER TABLE} to first add an @code{UNIQUE} index to a table used in a @code{MERGE} table and then use @code{ALTER TABLE} to @@ -3701,6 +3703,9 @@ able to choose the right index when there is many to choose from. We should also extend the info interface to get the key distribution for each index, of @code{analyze} is run on all sub tables. @item +@code{RENAME TABLE} on a table used in an active @code{MERGE} table may +corrupt the table. +@item @code{SET SQL_DEFAULT_TABLE_TYPE=[MyISAM | INNODB | BDB | HEAP]}. @end itemize @@ -3768,8 +3773,6 @@ in microseconds. Add a configurable prompt to the @code{mysql} command line client, with options like database in use, time and date... @item -Add range checking to @code{MERGE} tables. -@item Link the @code{myisampack} code into the server. @item Port of MySQL to BeOS. @@ -7789,6 +7792,10 @@ Multithreaded clients should use @code{mysql_thread_init()} and If you want to recompile the perl DBD-MySQL module, you must get Msql-Mysql-modules version 1.2218 or newer, because the older DBD modules used the deprecated @code{drop_db()} call. +@item +@code{RAND(seed)} returns a different random number series in 4.0 than in +3.23; This was done to get @code{RAND(seed)} and @code{RAND(seed+1)} more +different. @end itemize @node Upgrading-from-3.22, Upgrading-from-3.21, Upgrading-from-3.23, Upgrade @@ -9137,12 +9144,14 @@ from usage by other threads. This has to do with the fact that on Windows, you can't delete a file that is in use by another threads. (In the future, we may find some way to work around this problem.) -@item @code{DROP TABLE} on a table that is in use by a @code{MERGE} table will not work -The @code{MERGE} handler does its table mapping hidden from MySQL. -Because Windows doesn't allow you to drop files that are open, you first -must flush all @code{MERGE} tables (with @code{FLUSH TABLES}) or drop the -@code{MERGE} table before dropping the table. We will fix this at the same -time we introduce @code{VIEW}s. +@item +@code{DROP TABLE} on a table that is in use by a @code{MERGE} table will +not work on windows becasue @code{MERGE} handler does the table mapping +hidden from the upper layer of MySQL. Because Windows doesn't allow you +to drop files that are open, you first must flush all @code{MERGE} +tables (with @code{FLUSH TABLES}) or drop the @code{MERGE} table before +dropping the table. We will fix this at the same time we introduce +@code{VIEW}s. @item @code{DATA DIRECTORY} and @code{INDEX DIRECTORY} directives in @code{CREATE TABLE} is ignored on windows, because windows doesn't support @@ -13086,7 +13095,7 @@ DROP TABLE tmp; @end example The above way to solve this query is in effect a @code{UNION} of two queries. - +@xref{UNION}. @node Calculating days, example-AUTO_INCREMENT, Searching on two keys, Examples @subsection Calculating visits per day @@ -25105,9 +25114,9 @@ option to @code{DELETE} may help. @xref{DELETE, , @code{DELETE}}. * MySQL indexes:: How MySQL Uses Indexes * Indexes:: Column Indexes * Multiple-column indexes:: Multiple-Column Indexes +* Open tables:: Why So Many Open tables? * Table cache:: How MySQL Opens and Closes Tables * Creating many tables:: Drawbacks to Creating Large Numbers of Tables in the Same Database -* Open tables:: Why So Many Open tables? @end menu @@ -25452,7 +25461,7 @@ created only from @code{VARCHAR} and @code{TEXT} columns. Indexing always happens over the entire column and partial indexing is not supported. See @ref{Fulltext Search} for details. -@node Multiple-column indexes, Table cache, Indexes, Optimising Database Structure +@node Multiple-column indexes, Open tables, Indexes, Optimising Database Structure @subsection Multiple-Column Indexes @cindex multi-column indexes @@ -25513,8 +25522,31 @@ For more information on the manner in which MySQL uses indexes to improve query performance, see @ref{MySQL indexes, , MySQL indexes}. +@node Open tables, Table cache, Multiple-column indexes, Optimising Database Structure +@subsection Why So Many Open tables? -@node Table cache, Creating many tables, Multiple-column indexes, Optimising Database Structure +@cindex tables, open +@cindex open tables + +When you run @code{mysqladmin status}, you'll see something like this: + +@example +Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12 +@end example + +This can be somewhat perplexing if you only have 6 tables. + +MySQL is multithreaded, so it may have many queries on the same table +simultaneously. To minimise the problem with two threads having +different states on the same file, the table is opened independently by +each concurrent thread. This takes some memory but will normaly increase +performance. Wth ISAM and MyISAM tables this also requires one extra file +descriptor for the data file. With these table types the index file +descriptor is shared between all threads. + +You can read more about this topic in the next section. @xref{Table cache}. + +@node Table cache, Creating many tables, Open tables, Optimising Database Structure @subsection How MySQL Opens and Closes Tables @findex table_cache @@ -25549,11 +25581,27 @@ in increase the number of file descriptors available for MySQL with the @code{--open-files-limit=#} startup option. @xref{Not enough file handles}. -The cache of open tables can grow to a maximum of @code{table_cache} -(default 64; this can be changed with the @code{-O table_cache=#} -option to @code{mysqld}). A table is never closed, except when the -cache is full and another thread tries to open a table or if you use -@code{mysqladmin refresh} or @code{mysqladmin flush-tables}. +The cache of open tables will be keept at a level of @code{table_cache} +entries (default 64; this can be changed with the @code{-O +table_cache=#} option to @code{mysqld}). Note that in MySQL may +temporarly open even more tables to be able to execute queries. + +A not used table is closed and removed from the table cache under the +following circumstances: + +@itemize @bullet +@item +When the cache is full and a thread tries to open a table that is not in +the cache. +@item +When the cache contains more than @code{table_cache} entires and +a thread is not anymore using a table. +@item +When someone executes @code{mysqladmin refresh} or +@code{mysqladmin flush-tables}. +@item +When someone executes 'FLUSH TABLES' +@end itemize When the table cache fills up, the server uses the following procedure to locate a cache entry to use: @@ -25584,15 +25632,16 @@ If you are opening a table with the @code{HANDLER table_name OPEN} statement, a dedicated table object is allocated for the thread. This table object is not shared by other threads an will not be closed until the thread calls @code{HANDLER table_name CLOSE} or the thread dies. -@xref{HANDLER}. +@xref{HANDLER}. When this happens, the table is put back in the table_cache +(if it isn't full). You can check if your table cache is too small by checking the mysqld -variable @code{opened_tables}. If this is quite big, even if you +variable @code{Opened_tables}. If this is quite big, even if you haven't done a lot of @code{FLUSH TABLES}, you should increase your table cache. @xref{SHOW STATUS}. -@node Creating many tables, Open tables, Table cache, Optimising Database Structure +@node Creating many tables, , Table cache, Optimising Database Structure @subsection Drawbacks to Creating Large Numbers of Tables in the Same Database @cindex tables, too many @@ -25604,28 +25653,6 @@ every table that has to be opened, another must be closed. You can reduce this overhead by making the table cache larger. -@node Open tables, , Creating many tables, Optimising Database Structure -@subsection Why So Many Open tables? - -@cindex tables, open -@cindex open tables - -When you run @code{mysqladmin status}, you'll see something like this: - -@example -Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12 -@end example - -This can be somewhat perplexing if you only have 6 tables. - -MySQL is multithreaded, so it may have many queries on the same -table simultaneously. To minimise the problem with two threads having -different states on the same file, the table is opened independently by -each concurrent thread. This takes some memory and one extra file -descriptor for the data file. The index file descriptor is shared -between all threads. - - @node Optimising the Server, Disk issues, Optimising Database Structure, MySQL Optimisation @section Optimising the MySQL Server @@ -30315,16 +30342,17 @@ Returns a random floating-point value in the range @code{0} to @code{1.0}. If an integer argument @code{N} is specified, it is used as the seed value: @example mysql> select RAND(); - -> 0.5925 + -> 0.9233482386203 mysql> select RAND(20); - -> 0.1811 + -> 0.15888261251047 mysql> select RAND(20); - -> 0.1811 + -> 0.15888261251047 mysql> select RAND(); - -> 0.2079 + -> 0.63553050033332 mysql> select RAND(); - -> 0.7888 + -> 0.70100469486881 @end example + You can't use a column with @code{RAND()} values in an @code{ORDER BY} clause, because @code{ORDER BY} would evaluate the column multiple times. In MySQL Version 3.23, you can, however, do: @@ -30336,6 +30364,10 @@ table1,table2 WHERE a=b AND c ALTER TABLE tbl_name TYPE = MYISAM; @end example +The embedded MySQL versions doesn't support ISAM tables. @node HEAP, InnoDB, ISAM, Table types @section HEAP Tables @@ -50583,7 +50658,7 @@ Fixed bug in record caches; for some queries, you could get Added user level lock functions @code{GET_LOCK(string,timeout)}, @code{RELEASE_LOCK(string)}. @item -Added @code{opened_tables} to @code{show status}. +Added @code{Opened_tables} to @code{show status}. @item Changed connect timeout to 3 seconds to make it somewhat harder for crackers to kill @code{mysqld} through telnet + TCP/IP. diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 5f14de18735..1bb3249bdc5 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -68,3 +68,12 @@ select * from t2 where b="world"; a B 3 world drop table t1,t2; +create table t1(x varchar(50) ); +create table t2 select x from t1 where 1=2; +describe t1; +Field Type Null Key Default Extra +x varchar(50) YES NULL +describe t2; +Field Type Null Key Default Extra +x char(50) YES NULL +drop table t1,t2; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index dae87d88765..448c1b37592 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -31,3 +31,20 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +create table t1 (a int not null auto_increment, b int not null, primary key (a), index(b)); +insert into t1 (b) values (1),(2),(2),(2),(2); +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +show index from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment +t1 0 PRIMARY 1 a A 5 NULL NULL +t1 1 b 1 b A 1 NULL NULL +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status Table is already up to date +show index from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment +t1 0 PRIMARY 1 a A 5 NULL NULL +t1 1 b 1 b A 1 NULL NULL +drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 3eb4f35bdc2..57edb684744 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -65,3 +65,13 @@ create table t2 (key (b)) select * from t1; explain select * from t2 where b="world"; select * from t2 where b="world"; drop table t1,t2; + +# +# Test types after CREATE ... SELECT +# + +create table t1(x varchar(50) ); +create table t2 select x from t1 where 1=2; +describe t1; +describe t2; +drop table t1,t2; diff --git a/sql/item_func.cc b/sql/item_func.cc index 1ca511be485..6657d860592 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -621,8 +621,8 @@ double Item_func_rand::val() { if (arg_count) { // Only use argument once in query - ulong tmp=((ulong) args[0]->val_int())+55555555L; - randominit(¤t_thd->rand,tmp,tmp/2); + ulong tmp=((ulong) args[0]->val_int()); + randominit(¤t_thd->rand,tmp*0x10001L+55555555L,tmp*0x10000001L); #ifdef DELETE_ITEMS delete args[0]; #endif From 27d2057c5593daff1eee019446e6a1516c5a5d8d Mon Sep 17 00:00:00 2001 From: "monty@tik.mysql.fi" <> Date: Wed, 21 Nov 2001 15:39:00 +0200 Subject: [PATCH 7/7] Added note to manual that usernames in GRANT don't allow wildcards. --- Docs/manual.texi | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 5356e8f4dfe..07259633a89 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -15941,14 +15941,19 @@ You can specify wild cards in the hostname. For example, for any host in the @code{144.155.166} class C subnet. The simple form @code{user} is a synonym for @code{user@@"%"}. + +MySQL doesn't support wildcards in user names. Anonymous users are +defined by inserting entries with @code{User=''} into the +@code{mysql.user} table or creating an user with an empty name with the +@code{GRANT} command. + @strong{Note:} If you allow anonymous users to connect to the MySQL -server (which is the default), you should also add all local users as -@code{user@@localhost} because otherwise the anonymous user entry for the -local host in the @code{mysql.user} table will be used when the user tries to -log into the MySQL server from the local machine! Anonymous users -are defined by inserting entries with @code{User=''} into the -@code{mysql.user} table. You can verify if this applies to you by executing -this query: +server, you should also grant privileges to all local users as +@code{user@@localhost} because otherwise the anonymous user entry for +the local host in the @code{mysql.user} table will be used when the user +tries to log into the MySQL server from the local machine! + +You can verify if this applies to you by executing this query: @example mysql> SELECT Host,User FROM mysql.user WHERE User='';