From: Ashish Agarwal Date: February 2 2012 12:49pm Subject: bzr push into mysql-5.5 branch (ashish.y.agarwal:3700 to 3701) Bug#11754145 List-Archive: http://lists.mysql.com/commits/142725 X-Bug: 11754145 Message-Id: <201202021249.q12CnwjS014353@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3701 Ashish Agarwal 2012-02-02 BUG#11754145 - 45702: IMPOSSIBE TO SPECIFY MYISAM_SORT_BUFFER > 4GB ON 64 BIT MACHINES PROBLEM: When sorting index during repair of myisam tables, due to improper casting of buffer size variables value of myisam_ sort_buffer_size is not set greater than 4GB. SOLUTION: Proper casting of buffer size variable. myisam_buffer_size changed to unsigned long long to handle size > 4GB on linux as well as windows. modified: include/myisam.h storage/myisam/ha_myisam.cc storage/myisam/ha_myisam.h storage/myisam/mi_check.c storage/myisam/myisamchk.c storage/myisam/myisamdef.h storage/myisam/sort.c 3700 Alexander Barkov 2012-02-02 [merge] Merging from 5.1 modified: mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result === modified file 'include/myisam.h' --- a/include/myisam.h 2011-07-03 23:48:19 +0000 +++ b/include/myisam.h 2012-02-02 12:47:14 +0000 @@ -401,14 +401,14 @@ typedef struct st_mi_check_param ulonglong max_data_file_length; ulonglong keys_in_use; ulonglong max_record_length; + ulonglong sort_buffer_length; my_off_t search_after_block; my_off_t new_file_pos,key_file_blocks; my_off_t keydata,totaldata,key_blocks,start_check_pos; ha_rows total_records,total_deleted; ha_checksum record_checksum,glob_crc; ulonglong use_buffers; - ulong read_buffer_length,write_buffer_length, - sort_buffer_length,sort_key_blocks; + ulong read_buffer_length, write_buffer_length, sort_key_blocks; uint out_flag,warning_printed,error_printed,verbose; uint opt_sort_key,total_files,max_level; uint testflag, key_cache_block_size; === modified file 'storage/myisam/ha_myisam.cc' --- a/storage/myisam/ha_myisam.cc 2011-10-21 05:35:07 +0000 +++ b/storage/myisam/ha_myisam.cc 2012-02-02 12:47:14 +0000 @@ -77,10 +77,10 @@ static MYSQL_THDVAR_ULONG(repair_threads "disables parallel repair", NULL, NULL, 1, 1, ULONG_MAX, 1); -static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG, +static MYSQL_THDVAR_ULONGLONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG, "The buffer that is allocated when sorting the index when doing " "a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE", NULL, NULL, - 8192*1024, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), ULONG_MAX, 1); + 8192 * 1024, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), SIZE_T_MAX, 1); static MYSQL_SYSVAR_BOOL(use_mmap, opt_myisam_use_mmap, PLUGIN_VAR_NOCMDARG, "Use memory mapping for reading and writing MyISAM tables", NULL, NULL, FALSE); === modified file 'storage/myisam/ha_myisam.h' --- a/storage/myisam/ha_myisam.h 2011-07-03 23:48:19 +0000 +++ b/storage/myisam/ha_myisam.h 2012-02-02 12:47:14 +0000 @@ -35,7 +35,6 @@ typedef struct st_ha_create_information #define HA_RECOVER_QUICK 8 /* Don't check rows in data file */ #define HA_RECOVER_OFF 16 /* No automatic recover */ -extern ulong myisam_sort_buffer_size; extern TYPELIB myisam_recover_typelib; extern const char *myisam_recover_names[]; extern ulonglong myisam_recover_options; === modified file 'storage/myisam/mi_check.c' --- a/storage/myisam/mi_check.c 2012-02-02 08:55:43 +0000 +++ b/storage/myisam/mi_check.c 2012-02-02 12:47:14 +0000 @@ -2429,7 +2429,7 @@ int mi_repair_by_sort(MI_CHECK *param, r if (_create_index_by_sort(&sort_param, (my_bool) (!(param->testflag & T_VERBOSE)), - (uint) param->sort_buffer_length)) + param->sort_buffer_length)) { param->retry_repair=1; goto err; === modified file 'storage/myisam/myisamchk.c' --- a/storage/myisam/myisamchk.c 2011-06-30 15:46:53 +0000 +++ b/storage/myisam/myisamchk.c 2012-02-02 12:47:14 +0000 @@ -297,9 +297,9 @@ static struct my_option my_long_options[ INT_MAX32, (long) MALLOC_OVERHEAD, (long) 1L, 0}, { "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "", &check_param.sort_buffer_length, - &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG, + &check_param.sort_buffer_length, 0, GET_ULL, REQUIRED_ARG, (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), - ULONG_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0}, + SIZE_T_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0}, { "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "", &check_param.sort_key_blocks, &check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG, === modified file 'storage/myisam/myisamdef.h' --- a/storage/myisam/myisamdef.h 2011-07-03 23:48:19 +0000 +++ b/storage/myisam/myisamdef.h 2012-02-02 12:47:14 +0000 @@ -320,9 +320,10 @@ typedef struct st_mi_sort_param */ ulonglong unique[MI_MAX_KEY_SEG+1]; ulonglong notnull[MI_MAX_KEY_SEG+1]; + ulonglong sortbuff_size; my_off_t pos,max_pos,filepos,start_recpos; - uint key, key_length,real_key_length,sortbuff_size; + uint key, key_length,real_key_length; uint maxbuffers, keys, find_length, sort_keys_length; my_bool fix_datafile, master; my_bool calc_checksum; /* calculate table checksum */ @@ -771,7 +772,7 @@ pthread_handler_t thr_find_all_keys(void int flush_blocks(MI_CHECK *param, KEY_CACHE *key_cache, File file); int sort_write_record(MI_SORT_PARAM *sort_param); -int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, ulong); +int _create_index_by_sort(MI_SORT_PARAM *info, my_bool no_messages, ulonglong); #ifdef __cplusplus } === modified file 'storage/myisam/sort.c' --- a/storage/myisam/sort.c 2011-06-30 15:46:53 +0000 +++ b/storage/myisam/sort.c 2012-02-02 12:47:14 +0000 @@ -99,10 +99,11 @@ my_var_write(MI_SORT_PARAM *info, IO_CAC */ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, - ulong sortbuff_size) + ulonglong sortbuff_size) { int error,maxbuffer,skr; - uint memavl,old_memavl,keys,sort_length; + uint sort_length, keys; + ulonglong memavl, old_memavl; DYNAMIC_ARRAY buffpek; ha_rows records; uchar **sort_keys; @@ -134,6 +135,9 @@ int _create_index_by_sort(MI_SORT_PARAM sort_length= info->key_length; LINT_INIT(keys); + if ((memavl - sizeof(BUFFPEK)) / (sort_length + sizeof(char *)) > UINT_MAX32) + memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *)); + while (memavl >= MIN_SORT_BUFFER) { if ((records < UINT_MAX32) && @@ -308,7 +312,8 @@ pthread_handler_t thr_find_all_keys(void { MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg; int error; - uint memavl,old_memavl,keys,sort_length; + ulonglong memavl, old_memavl; + uint keys, sort_length; uint idx, maxbuffer; uchar **sort_keys=0; @@ -349,6 +354,10 @@ pthread_handler_t thr_find_all_keys(void sort_length= sort_param->key_length; maxbuffer= 1; + if ((memavl - sizeof(BUFFPEK)) / (sort_length + + sizeof(char *)) > UINT_MAX32) + memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *)); + while (memavl >= MIN_SORT_BUFFER) { if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= No bundle (reason: useless for push emails).