From 734d6226ecadfce78548ea61b5a918423363b08a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= Date: Sat, 19 Nov 2011 15:13:39 +0000 Subject: [PATCH] - up to 5.5.17 Changed files: bug45702.patch -> 1.2 bug580324.patch -> 1.5 bug860910.patch -> 1.2 innodb_adaptive_hash_index_partitions.patch -> 1.9 innodb_admin_command_base.patch -> 1.8 innodb_buffer_pool_pages_i_s.patch -> 1.9 innodb_buffer_pool_shm.patch -> 1.9 innodb_deadlock_count.patch -> 1.9 innodb_dict_size_limit.patch -> 1.7 innodb_expand_fast_index_creation.patch -> 1.4 innodb_expand_import.patch -> 1.8 innodb_extend_slow.patch -> 1.9 innodb_extra_rseg.patch -> 1.7 innodb_fake_changes.patch -> 1.2 innodb_fast_checksum.patch -> 1.8 innodb_files_extend.patch -> 1.8 innodb_fix_misc.patch -> 1.10 innodb_io_patches.patch -> 1.8 innodb_kill_idle_transaction.patch -> 1.2 innodb_lru_dump_restore.patch -> 1.8 innodb_opt_lru_count.patch -> 1.6 innodb_overwrite_relay_log_info.patch -> 1.8 innodb_pass_corrupt_table.patch -> 1.10 innodb_recovery_patches.patch -> 1.9 innodb_separate_doublewrite.patch -> 1.11 innodb_show_lock_name.patch -> 1.7 innodb_show_status.patch -> 1.7 innodb_show_status_extend.patch -> 1.8 innodb_show_sys_tables.patch -> 1.8 innodb_split_buf_pool_mutex.patch -> 1.8 innodb_stats.patch -> 1.8 innodb_thread_concurrency_timer_based.patch -> 1.7 log_warnings_suppress.patch -> 1.7 memory_dynamic_rows.patch -> 1.3 microsec_process.patch -> 1.7 mysql.spec -> 1.561 percona_support.patch -> 1.4 processlist_row_stats.patch -> 1.5 query_cache_enhance.patch -> 1.9 response_time_distribution.patch -> 1.8 show_slave_status_nolock.patch -> 1.8 show_temp.patch -> 1.8 slow_extended.patch -> 1.9 sql_no_fcache.patch -> 1.8 subunit.patch -> 1.2 userstat.patch -> 1.9 valgrind_zlib_suppression.patch -> 1.2 --- bug45702.patch | 728 ++++++++++++++++ bug580324.patch | 8 +- bug860910.patch | 92 ++ innodb_adaptive_hash_index_partitions.patch | 201 ++--- innodb_admin_command_base.patch | 25 +- innodb_buffer_pool_pages_i_s.patch | 8 +- innodb_buffer_pool_shm.patch | 10 +- innodb_deadlock_count.patch | 8 +- innodb_dict_size_limit.patch | 26 +- innodb_expand_fast_index_creation.patch | 904 ++++++++++++++++++-- innodb_expand_import.patch | 38 +- innodb_extend_slow.patch | 100 ++- innodb_extra_rseg.patch | 8 +- innodb_fake_changes.patch | 767 +++++++++++++++++ innodb_fast_checksum.patch | 26 +- innodb_files_extend.patch | 31 +- innodb_fix_misc.patch | 54 +- innodb_io_patches.patch | 62 +- innodb_kill_idle_transaction.patch | 455 ++++++++++ innodb_lru_dump_restore.patch | 94 +- innodb_opt_lru_count.patch | 18 +- innodb_overwrite_relay_log_info.patch | 10 +- innodb_pass_corrupt_table.patch | 224 ++--- innodb_recovery_patches.patch | 10 +- innodb_separate_doublewrite.patch | 34 +- innodb_show_lock_name.patch | 16 +- innodb_show_status.patch | 42 +- innodb_show_status_extend.patch | 32 +- innodb_show_sys_tables.patch | 10 +- innodb_split_buf_pool_mutex.patch | 319 ++++--- innodb_stats.patch | 84 +- innodb_thread_concurrency_timer_based.patch | 20 +- log_warnings_suppress.patch | 24 +- memory_dynamic_rows.patch | 101 +-- microsec_process.patch | 10 +- mysql.spec | 69 +- percona_support.patch | 2 +- processlist_row_stats.patch | 4 +- query_cache_enhance.patch | 25 +- response_time_distribution.patch | 537 +++++++++--- show_slave_status_nolock.patch | 306 +++++-- show_temp.patch | 30 +- slow_extended.patch | 335 +++++++- sql_no_fcache.patch | 14 +- subunit.patch | 199 +++++ userstat.patch | 121 ++- valgrind_zlib_suppression.patch | 5 +- 47 files changed, 5102 insertions(+), 1144 deletions(-) create mode 100644 bug45702.patch create mode 100644 bug860910.patch create mode 100644 innodb_fake_changes.patch create mode 100644 innodb_kill_idle_transaction.patch create mode 100644 subunit.patch diff --git a/bug45702.patch b/bug45702.patch new file mode 100644 index 0000000..191ca0e --- /dev/null +++ b/bug45702.patch @@ -0,0 +1,728 @@ +--- a/include/my_sys.h ++++ b/include/my_sys.h +@@ -320,8 +320,8 @@ + typedef struct st_dynamic_array + { + uchar *buffer; +- uint elements,max_element; +- uint alloc_increment; ++ ulong elements, max_element; ++ ulong alloc_increment; + uint size_of_element; + } DYNAMIC_ARRAY; + +@@ -758,21 +758,21 @@ + #define my_init_dynamic_array2(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E) + #define my_init_dynamic_array2_ci(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E) + extern my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, +- void *init_buffer, uint init_alloc, +- uint alloc_increment); ++ void *init_buffer, ulong init_alloc, ++ ulong alloc_increment); + /* init_dynamic_array() function is deprecated */ + extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, +- uint init_alloc, uint alloc_increment); ++ ulong init_alloc, ulong alloc_increment); + extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,uchar * element); + extern uchar *alloc_dynamic(DYNAMIC_ARRAY *array); + extern uchar *pop_dynamic(DYNAMIC_ARRAY*); +-extern my_bool set_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index); +-extern my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements); +-extern void get_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index); ++extern my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar * element, ulong array_index); ++extern my_bool allocate_dynamic(DYNAMIC_ARRAY *array, ulong max_elements); ++extern void get_dynamic(DYNAMIC_ARRAY *array, uchar * element, ulong array_index); + extern void delete_dynamic(DYNAMIC_ARRAY *array); +-extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index); ++extern void delete_dynamic_element(DYNAMIC_ARRAY *array, ulong array_index); + extern void freeze_size(DYNAMIC_ARRAY *array); +-extern int get_index_dynamic(DYNAMIC_ARRAY *array, uchar * element); ++extern long get_index_dynamic(DYNAMIC_ARRAY *array, uchar * element); + #define dynamic_array_ptr(array,array_index) ((array)->buffer+(array_index)*(array)->size_of_element) + #define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index)) + #define push_dynamic(A,B) insert_dynamic((A),(B)) +--- a/mysys/array.c ++++ b/mysys/array.c +@@ -41,8 +41,8 @@ + */ + + my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, +- void *init_buffer, uint init_alloc, +- uint alloc_increment) ++ void *init_buffer, ulong init_alloc, ++ ulong alloc_increment) + { + DBUG_ENTER("init_dynamic_array"); + if (!alloc_increment) +@@ -73,7 +73,7 @@ + } + + my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, +- uint init_alloc, uint alloc_increment) ++ ulong init_alloc, ulong alloc_increment) + { + /* placeholder to preserve ABI */ + return my_init_dynamic_array_ci(array, element_size, init_alloc, +@@ -196,7 +196,7 @@ + FALSE Ok + */ + +-my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx) ++my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, ulong idx) + { + if (idx >= array->elements) + { +@@ -228,11 +228,11 @@ + TRUE Allocation of new memory failed + */ + +-my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements) ++my_bool allocate_dynamic(DYNAMIC_ARRAY *array, ulong max_elements) + { + if (max_elements >= array->max_element) + { +- uint size; ++ ulong size; + uchar *new_ptr; + size= (max_elements + array->alloc_increment)/array->alloc_increment; + size*= array->alloc_increment; +@@ -273,11 +273,11 @@ + idx Index of element wanted. + */ + +-void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx) ++void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, ulong idx) + { + if (idx >= array->elements) + { +- DBUG_PRINT("warning",("To big array idx: %d, array size is %d", ++ DBUG_PRINT("warning",("To big array idx: %lu, array size is %lu", + idx,array->elements)); + bzero(element,array->size_of_element); + return; +@@ -320,7 +320,7 @@ + idx Index of element to be deleted + */ + +-void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx) ++void delete_dynamic_element(DYNAMIC_ARRAY *array, ulong idx) + { + char *ptr= (char*) array->buffer+array->size_of_element*idx; + array->elements--; +@@ -340,7 +340,7 @@ + + void freeze_size(DYNAMIC_ARRAY *array) + { +- uint elements=max(array->elements,1); ++ ulong elements= max(array->elements, 1); + + /* + Do nothing if we are using a static buffer +@@ -368,7 +368,7 @@ + + */ + +-int get_index_dynamic(DYNAMIC_ARRAY *array, uchar* element) ++long get_index_dynamic(DYNAMIC_ARRAY *array, uchar* element) + { + size_t ret; + if (array->buffer > element) +--- a/storage/myisam/mi_check.c ++++ b/storage/myisam/mi_check.c +@@ -2429,7 +2429,7 @@ + + 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; +--- a/storage/myisam/sort.c ++++ b/storage/myisam/sort.c +@@ -45,42 +45,42 @@ + + /* Functions defined in this file */ + +-static ha_rows find_all_keys(MI_SORT_PARAM *info,uint keys, ++static ha_rows find_all_keys(MI_SORT_PARAM *info, ulong keys, + uchar **sort_keys, +- DYNAMIC_ARRAY *buffpek,int *maxbuffer, ++ DYNAMIC_ARRAY *buffpek, long *maxbuffer, + IO_CACHE *tempfile, + IO_CACHE *tempfile_for_exceptions); + static int write_keys(MI_SORT_PARAM *info,uchar **sort_keys, +- uint count, BUFFPEK *buffpek,IO_CACHE *tempfile); ++ ulong count, BUFFPEK *buffpek,IO_CACHE *tempfile); + static int write_key(MI_SORT_PARAM *info, uchar *key, + IO_CACHE *tempfile); + static int write_index(MI_SORT_PARAM *info,uchar * *sort_keys, +- uint count); +-static int merge_many_buff(MI_SORT_PARAM *info,uint keys, ++ ulong count); ++static int merge_many_buff(MI_SORT_PARAM *info, ulong keys, + uchar * *sort_keys, +- BUFFPEK *buffpek,int *maxbuffer, ++ BUFFPEK *buffpek, long *maxbuffer, + IO_CACHE *t_file); +-static uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek, ++static ulong read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek, + uint sort_length); +-static int merge_buffers(MI_SORT_PARAM *info,uint keys, ++static int merge_buffers(MI_SORT_PARAM *info, ulong keys, + IO_CACHE *from_file, IO_CACHE *to_file, + uchar * *sort_keys, BUFFPEK *lastbuff, + BUFFPEK *Fb, BUFFPEK *Tb); +-static int merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int, ++static int merge_index(MI_SORT_PARAM *, ulong, uchar **, BUFFPEK *, long, + IO_CACHE *); + static int flush_ft_buf(MI_SORT_PARAM *info); + + static int write_keys_varlen(MI_SORT_PARAM *info,uchar **sort_keys, +- uint count, BUFFPEK *buffpek, ++ ulong count, BUFFPEK *buffpek, + IO_CACHE *tempfile); +-static uint read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek, +- uint sort_length); ++static ulong read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek, ++ uint sort_length); + static int write_merge_key(MI_SORT_PARAM *info, IO_CACHE *to_file, +- uchar *key, uint sort_length, uint count); ++ uchar *key, uint sort_length, ulong count); + static int write_merge_key_varlen(MI_SORT_PARAM *info, + IO_CACHE *to_file, + uchar* key, uint sort_length, +- uint count); ++ ulong count); + static inline int + my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs); + +@@ -101,8 +101,9 @@ + int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, + ulong sortbuff_size) + { +- int error,maxbuffer,skr; +- uint memavl,old_memavl,keys,sort_length; ++ int error; ++ long maxbuffer, skr; ++ ulong memavl, old_memavl, keys, sort_length; + DYNAMIC_ARRAY buffpek; + ha_rows records; + uchar **sort_keys; +@@ -136,25 +137,25 @@ + + while (memavl >= MIN_SORT_BUFFER) + { +- if ((records < UINT_MAX32) && ++ if ((records < ULONG_MAX) && + ((my_off_t) (records + 1) * + (sort_length + sizeof(char*)) <= (my_off_t) memavl)) +- keys= (uint)records+1; ++ keys= (ulong) records + 1; + else + do + { + skr=maxbuffer; +- if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer || +- (keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/ ++ if (memavl < sizeof(BUFFPEK) * (ulong) maxbuffer || ++ (keys = (memavl - sizeof(BUFFPEK) * (ulong) maxbuffer) / + (sort_length+sizeof(char*))) <= 1 || +- keys < (uint) maxbuffer) ++ keys < (ulong) maxbuffer) + { + mi_check_print_error(info->sort_info->param, + "myisam_sort_buffer_size is too small"); + goto err; + } + } +- while ((maxbuffer= (int) (records/(keys-1)+1)) != skr); ++ while ((maxbuffer= (long) (records / (keys - 1) + 1)) != skr); + + if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+ + HA_FT_MAXBYTELEN, MYF(0)))) +@@ -180,7 +181,7 @@ + (*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */ + + if (!no_messages) +- printf(" - Searching for keys, allocating buffer for %d keys\n",keys); ++ printf(" - Searching for keys, allocating buffer for %lu keys\n", keys); + + if ((records=find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer, + &tempfile,&tempfile_for_exceptions)) +@@ -190,7 +191,7 @@ + { + if (!no_messages) + printf(" - Dumping %lu keys\n", (ulong) records); +- if (write_index(info,sort_keys, (uint) records)) ++ if (write_index(info,sort_keys, (ulong) records)) + goto err; /* purecov: inspected */ + } + else +@@ -253,13 +254,13 @@ + + /* Search after all keys and place them in a temp. file */ + +-static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys, ++static ha_rows find_all_keys(MI_SORT_PARAM *info, ulong keys, + uchar **sort_keys, DYNAMIC_ARRAY *buffpek, +- int *maxbuffer, IO_CACHE *tempfile, ++ long *maxbuffer, IO_CACHE *tempfile, + IO_CACHE *tempfile_for_exceptions) + { + int error; +- uint idx; ++ ulong idx; + DBUG_ENTER("find_all_keys"); + + idx=error=0; +@@ -308,8 +309,8 @@ + { + MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg; + int error; +- uint memavl,old_memavl,keys,sort_length; +- uint idx, maxbuffer; ++ ulong memavl,old_memavl,keys,sort_length; ++ ulong idx, maxbuffer; + uchar **sort_keys=0; + + LINT_INIT(keys); +@@ -345,7 +346,7 @@ + sort_keys= (uchar **) NULL; + + memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER); +- idx= (uint)sort_param->sort_info->max_records; ++ idx= (ulong) sort_param->sort_info->max_records; + sort_length= sort_param->key_length; + maxbuffer= 1; + +@@ -356,21 +357,21 @@ + keys= idx+1; + else + { +- uint skr; ++ ulong skr; + do + { + skr= maxbuffer; + if (memavl < sizeof(BUFFPEK)*maxbuffer || + (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ + (sort_length+sizeof(char*))) <= 1 || +- keys < (uint) maxbuffer) ++ keys < maxbuffer) + { + mi_check_print_error(sort_param->sort_info->param, + "myisam_sort_buffer_size is too small"); + goto err; + } + } +- while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); ++ while ((maxbuffer= (idx/(keys-1)+1)) != skr); + } + if ((sort_keys= (uchar**) + my_malloc(keys*(sort_length+sizeof(char*))+ +@@ -399,7 +400,7 @@ + } + + if (sort_param->sort_info->param->testflag & T_VERBOSE) +- printf("Key %d - Allocating buffer for %d keys\n", ++ printf("Key %d - Allocating buffer for %lu keys\n", + sort_param->key + 1, keys); + sort_param->sort_keys= sort_keys; + +@@ -553,7 +554,7 @@ + } + if (sinfo->buffpek.elements) + { +- uint maxbuffer=sinfo->buffpek.elements-1; ++ ulong maxbuffer=sinfo->buffpek.elements-1; + if (!mergebuf) + { + length=param->sort_buffer_length; +@@ -576,7 +577,7 @@ + printf("Key %d - Merging %u keys\n",sinfo->key+1, sinfo->keys); + if (merge_many_buff(sinfo, keys, (uchar **)mergebuf, + dynamic_element(&sinfo->buffpek, 0, BUFFPEK *), +- (int*) &maxbuffer, &sinfo->tempfile)) ++ (long *) &maxbuffer, &sinfo->tempfile)) + { + got_error=1; + continue; +@@ -640,7 +641,7 @@ + /* Write all keys in memory to file for later merge */ + + static int write_keys(MI_SORT_PARAM *info, register uchar **sort_keys, +- uint count, BUFFPEK *buffpek, IO_CACHE *tempfile) ++ ulong count, BUFFPEK *buffpek, IO_CACHE *tempfile) + { + uchar **end; + uint sort_length=info->key_length; +@@ -682,7 +683,7 @@ + + static int write_keys_varlen(MI_SORT_PARAM *info, + register uchar **sort_keys, +- uint count, BUFFPEK *buffpek, ++ ulong count, BUFFPEK *buffpek, + IO_CACHE *tempfile) + { + uchar **end; +@@ -727,7 +728,7 @@ + /* Write index */ + + static int write_index(MI_SORT_PARAM *info, register uchar **sort_keys, +- register uint count) ++ register ulong count) + { + DBUG_ENTER("write_index"); + +@@ -744,11 +745,11 @@ + + /* Merge buffers to make < MERGEBUFF2 buffers */ + +-static int merge_many_buff(MI_SORT_PARAM *info, uint keys, ++static int merge_many_buff(MI_SORT_PARAM *info, ulong keys, + uchar **sort_keys, BUFFPEK *buffpek, +- int *maxbuffer, IO_CACHE *t_file) ++ long *maxbuffer, IO_CACHE *t_file) + { +- register int i; ++ register long i; + IO_CACHE t_file2, *from_file, *to_file, *temp; + BUFFPEK *lastbuff; + DBUG_ENTER("merge_many_buff"); +@@ -778,7 +779,7 @@ + if (flush_io_cache(to_file)) + break; /* purecov: inspected */ + temp=from_file; from_file=to_file; to_file=temp; +- *maxbuffer= (int) (lastbuff-buffpek)-1; ++ *maxbuffer= (long) (lastbuff-buffpek)-1; + } + cleanup: + close_cached_file(to_file); /* This holds old result */ +@@ -807,18 +808,18 @@ + -1 Error + */ + +-static uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek, +- uint sort_length) ++static ulong read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek, ++ uint sort_length) + { +- register uint count; +- uint length; ++ register ulong count; ++ ulong length; + +- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count))) ++ if ((count=(ulong) min((ha_rows) buffpek->max_keys,buffpek->count))) + { + if (mysql_file_pread(fromfile->file, (uchar*) buffpek->base, + (length= sort_length*count), + buffpek->file_pos, MYF_RW)) +- return((uint) -1); /* purecov: inspected */ ++ return((ulong) -1); /* purecov: inspected */ + buffpek->key=buffpek->base; + buffpek->file_pos+= length; /* New filepos */ + buffpek->count-= count; +@@ -827,15 +828,15 @@ + return (count*sort_length); + } /* read_to_buffer */ + +-static uint read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek, ++static ulong read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek, + uint sort_length) + { +- register uint count; ++ register ulong count; + uint16 length_of_key = 0; +- uint idx; ++ ulong idx; + uchar *buffp; + +- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count))) ++ if ((count=(ulong) min((ha_rows) buffpek->max_keys,buffpek->count))) + { + buffp = buffpek->base; + +@@ -843,11 +844,11 @@ + { + if (mysql_file_pread(fromfile->file, (uchar*)&length_of_key, + sizeof(length_of_key), buffpek->file_pos, MYF_RW)) +- return((uint) -1); ++ return((ulong) -1); + buffpek->file_pos+=sizeof(length_of_key); + if (mysql_file_pread(fromfile->file, (uchar*) buffp, + length_of_key, buffpek->file_pos, MYF_RW)) +- return((uint) -1); ++ return((ulong) -1); + buffpek->file_pos+=length_of_key; + buffp = buffp + sort_length; + } +@@ -861,9 +862,9 @@ + + static int write_merge_key_varlen(MI_SORT_PARAM *info, + IO_CACHE *to_file, uchar* key, +- uint sort_length, uint count) ++ uint sort_length, ulong count) + { +- uint idx; ++ ulong idx; + uchar *bufs = key; + + for (idx=1;idx<=count;idx++) +@@ -879,7 +880,7 @@ + + static int write_merge_key(MI_SORT_PARAM *info __attribute__((unused)), + IO_CACHE *to_file, uchar *key, +- uint sort_length, uint count) ++ uint sort_length, ulong count) + { + return my_b_write(to_file, key, (size_t) sort_length*count); + } +@@ -890,12 +891,13 @@ + */ + + static int +-merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file, ++merge_buffers(MI_SORT_PARAM *info, ulong keys, IO_CACHE *from_file, + IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff, + BUFFPEK *Fb, BUFFPEK *Tb) + { +- int error; +- uint sort_length,maxcount; ++ ulong error; ++ uint sort_length; ++ ulong maxcount; + ha_rows count; + my_off_t UNINIT_VAR(to_start_filepos); + uchar *strpos; +@@ -905,7 +907,7 @@ + DBUG_ENTER("merge_buffers"); + + count=error=0; +- maxcount=keys/((uint) (Tb-Fb) +1); ++ maxcount= keys / ((ulong) (Tb-Fb) + 1); + DBUG_ASSERT(maxcount > 0); + LINT_INIT(to_start_filepos); + if (to_file) +@@ -913,7 +915,7 @@ + strpos=(uchar*) sort_keys; + sort_length=info->key_length; + +- if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0, ++ if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0, + (int (*)(void*, uchar *,uchar*)) info->key_cmp, + (void*) info)) + DBUG_RETURN(1); /* purecov: inspected */ +@@ -923,9 +925,8 @@ + count+= buffpek->count; + buffpek->base= strpos; + buffpek->max_keys=maxcount; +- strpos+= (uint) (error=(int) info->read_to_buffer(from_file,buffpek, +- sort_length)); +- if (error == -1) ++ strpos+= (error= info->read_to_buffer(from_file,buffpek, sort_length)); ++ if (error == (ulong) -1) + goto err; /* purecov: inspected */ + queue_insert(&queue,(uchar*) buffpek); + } +@@ -957,10 +958,10 @@ + buffpek->key+=sort_length; + if (! --buffpek->mem_count) + { +- if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length))) ++ if (!(error= info->read_to_buffer(from_file,buffpek,sort_length))) + { + uchar *base=buffpek->base; +- uint max_keys=buffpek->max_keys; ++ ulong max_keys=buffpek->max_keys; + + (void) queue_remove(&queue,0); + +@@ -985,7 +986,7 @@ + break; /* One buffer have been removed */ + } + } +- else if (error == -1) ++ else if (error == (ulong) -1) + goto err; /* purecov: inspected */ + queue_replaced(&queue); /* Top element has been replaced */ + } +@@ -1018,23 +1019,23 @@ + } + } + } +- while ((error=(int) info->read_to_buffer(from_file,buffpek,sort_length)) != -1 && +- error != 0); ++ while ((error= info->read_to_buffer(from_file,buffpek,sort_length)) ++ != (ulong) -1 && error != 0); + + lastbuff->count=count; + if (to_file) + lastbuff->file_pos=to_start_filepos; + err: + delete_queue(&queue); +- DBUG_RETURN(error); ++ DBUG_RETURN(error != 0); + } /* merge_buffers */ + + + /* Do a merge to output-file (save only positions) */ + + static int +-merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys, +- BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile) ++merge_index(MI_SORT_PARAM *info, ulong keys, uchar **sort_keys, ++ BUFFPEK *buffpek, long maxbuffer, IO_CACHE *tempfile) + { + DBUG_ENTER("merge_index"); + if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek, +--- /dev/null ++++ b/mysql-test/r/percona_bug45702.result +@@ -0,0 +1,21 @@ ++CREATE TABLE t1 (a BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM; ++INSERT INTO t1 VALUES (), (), (), (), (), (), (), (); ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++SET @old_myisam_sort_buffer_size = @@myisam_sort_buffer_size; ++SET @@myisam_sort_buffer_size = 4 * 1024 * 1024 * 1024; ++REPAIR TABLE t1; ++Table Op Msg_type Msg_text ++test.t1 repair status OK ++- recovering (with sort) MyISAM-table 'MYSQLD_DATADIR/test/t1' ++Data records: 4096 ++- Fixing index 1 ++SET @@myisam_sort_buffer_size = @old_myisam_sort_buffer_size; ++DROP TABLE t1; +--- /dev/null ++++ b/mysql-test/t/percona_bug45702.test +@@ -0,0 +1,34 @@ ++############################################################################### ++# Bug #45702: Impossible to specify myisam_sort_buffer > 4GB on 64 bit machines ++############################################################################### ++ ++--source include/have_64bit.inc ++ ++# Check that having data larger than MIN_SORT_BUFFER bytes can be handled by ++# _create_index_by_sort() with myisam_sort_buffer_size = 4 GB without errors. ++# The full test with large data volumes can not be a part of the test suite. ++ ++CREATE TABLE t1 (a BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM; ++INSERT INTO t1 VALUES (), (), (), (), (), (), (), (); ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++INSERT INTO t1 SELECT NULL FROM t1; ++ ++SET @old_myisam_sort_buffer_size = @@myisam_sort_buffer_size; ++SET @@myisam_sort_buffer_size = 4 * 1024 * 1024 * 1024; ++ ++REPAIR TABLE t1; ++ ++--let $MYSQLD_DATADIR= `select @@datadir` ++--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR ++--exec $MYISAMCHK -r --sort_buffer_size=4G $MYSQLD_DATADIR/test/t1 ++ ++SET @@myisam_sort_buffer_size = @old_myisam_sort_buffer_size; ++ ++DROP TABLE t1; +--- a/sql/opt_range.cc ++++ b/sql/opt_range.cc +@@ -11716,7 +11716,7 @@ + } + if (min_max_ranges.elements > 0) + { +- fprintf(DBUG_FILE, "%*susing %d quick_ranges for MIN/MAX:\n", ++ fprintf(DBUG_FILE, "%*susing %lu quick_ranges for MIN/MAX:\n", + indent, "", min_max_ranges.elements); + } + } +--- a/mysys/my_pread.c ++++ b/mysys/my_pread.c +@@ -49,6 +49,7 @@ + myf MyFlags) + { + size_t readbytes; ++ size_t total_readbytes= 0; + int error= 0; + #if !defined (HAVE_PREAD) && !defined (_WIN32) + int save_errno; +@@ -76,8 +77,30 @@ + #endif + error= (readbytes != Count); + #endif ++ if (readbytes > 0) ++ total_readbytes+= readbytes; ++ + if(error) + { ++ if (readbytes > 0 && readbytes < Count && errno == 0) ++ { ++ /* ++ pread() may return less bytes than requested even if enough bytes are ++ available according to the Linux man page. ++ This makes determining the end-of-file condition a bit harder. ++ We just do another pread() call to see if more bytes can be read, ++ since all my_pread() users expect it to always return all available ++ bytes. For end-of-file 0 bytes is returned. This can never be the case ++ for a partial read, since according to the man page, -1 is returned ++ with errno set to EINTR if no data has been read. ++ */ ++ Buffer+= readbytes; ++ offset+= readbytes; ++ Count-= readbytes; ++ ++ continue; ++ } ++ + my_errno= errno ? errno : -1; + if (errno == 0 || (readbytes != (size_t) -1 && + (MyFlags & (MY_NABP | MY_FNABP)))) +@@ -107,7 +130,7 @@ + } + if (MyFlags & (MY_NABP | MY_FNABP)) + DBUG_RETURN(0); /* Read went ok; Return 0 */ +- DBUG_RETURN(readbytes); /* purecov: inspected */ ++ DBUG_RETURN(total_readbytes); /* purecov: inspected */ + } + } /* my_pread */ + +--- a/storage/myisam/myisamdef.h ++++ b/storage/myisam/myisamdef.h +@@ -340,10 +340,10 @@ + int (*key_write)(struct st_mi_sort_param *, const void *); + void (*lock_in_memory)(MI_CHECK *); + int (*write_keys)(struct st_mi_sort_param *, register uchar **, +- uint , struct st_buffpek *, IO_CACHE *); +- uint (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint); ++ ulong , struct st_buffpek *, IO_CACHE *); ++ ulong (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint); + int (*write_key)(struct st_mi_sort_param *, IO_CACHE *,uchar *, +- uint, uint); ++ uint, ulong); + } MI_SORT_PARAM; + + /* Some defines used by isam-funktions */ +--- a/sql/rpl_mi.cc ++++ b/sql/rpl_mi.cc +@@ -491,7 +491,7 @@ + (1 + mi->ignore_server_ids.elements), MYF(MY_WME)); + if (!ignore_server_ids_buf) + DBUG_RETURN(1); +- ulong cur_len= sprintf(ignore_server_ids_buf, "%u", ++ ulong cur_len= sprintf(ignore_server_ids_buf, "%lu", + mi->ignore_server_ids.elements); + for (ulong i= 0; i < mi->ignore_server_ids.elements; i++) + { diff --git a/bug580324.patch b/bug580324.patch index ae15478..5904490 100644 --- a/bug580324.patch +++ b/bug580324.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/sql/sql_base.cc +++ b/sql/sql_base.cc -@@ -251,8 +251,12 @@ +@@ -314,8 +314,12 @@ const TABLE_LIST *table_list, bool tmp_table) { @@ -24,7 +24,7 @@ int4store(key + key_length, thd->server_id); --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc -@@ -1112,11 +1112,18 @@ +@@ -1113,11 +1113,18 @@ break; #else { @@ -44,7 +44,7 @@ /* SHOW statements should not add the used tables to the list of tables used in a transaction. -@@ -1129,24 +1136,23 @@ +@@ -1130,24 +1137,23 @@ /* We have name + wildcard in packet, separated by endzero */ @@ -81,7 +81,7 @@ mysql_reset_thd_for_next_command(thd); lex_start(thd); /* Must be before we init the table list. */ -@@ -1171,9 +1177,6 @@ +@@ -1172,9 +1178,6 @@ table_list.schema_table= schema_table; } diff --git a/bug860910.patch b/bug860910.patch new file mode 100644 index 0000000..20d2251 --- /dev/null +++ b/bug860910.patch @@ -0,0 +1,92 @@ +# name : bug860910.patch +# maintainer : Alexey +# +# Fixes LP bug #860910 / MySQL bug #62557 +# +--- /dev/null ++++ b/mysql-test/suite/rpl/r/percona_bug860910.result +@@ -0,0 +1,17 @@ ++*** Set up master (server_1) <-> master (server_2) replication *** ++include/rpl_init.inc [topology=1->2->1] ++ ++SELECT @@global.log_slave_updates; ++@@global.log_slave_updates ++1 ++SELECT @@global.log_slave_updates; ++@@global.log_slave_updates ++1 ++CREATE TABLE t1(a INT); ++SET @var:=0; ++INSERT INTO t1 VALUES (@var); ++INSERT INTO t1 VALUES (1); ++DROP TABLE t1; ++include/rpl_sync.inc ++include/check_slave_param.inc [Exec_Master_Log_Pos] ++include/rpl_end.inc +--- /dev/null ++++ b/mysql-test/suite/rpl/t/percona_bug860910.cnf +@@ -0,0 +1,8 @@ ++!include ../my.cnf ++ ++[mysqld.1] ++log-slave-updates ++ ++[mysqld.2] ++log-slave-updates ++ +--- /dev/null ++++ b/mysql-test/suite/rpl/t/percona_bug860910.test +@@ -0,0 +1,38 @@ ++######################################################################## ++# Bug #860910: SHOW SLAVE STATUS gives wrong output with master-master ++# and using SET uservars ++######################################################################## ++ ++--echo *** Set up master (server_1) <-> master (server_2) replication *** ++--let $rpl_topology= 1->2->1 ++--source include/rpl_init.inc ++--echo ++ ++--connection server_1 ++SELECT @@global.log_slave_updates; ++ ++--connection server_2 ++SELECT @@global.log_slave_updates; ++ ++--connection server_1 ++CREATE TABLE t1(a INT); ++SET @var:=0; ++INSERT INTO t1 VALUES (@var); ++INSERT INTO t1 VALUES (1); ++ ++DROP TABLE t1; ++ ++# The following would hang with the bug not fixed due to incorrect ++# Exec_Master_Log_Pos ++--source include/rpl_sync.inc ++ ++--connection server_2 ++--let $master_log_pos= query_get_value(SHOW MASTER STATUS, Position, 1) ++ ++--connection server_1 ++--let $slave_param= Exec_Master_Log_Pos ++--let $slave_param_value= $master_log_pos ++--source include/check_slave_param.inc ++ ++# Cleanup ++--source include/rpl_end.inc +--- a/sql/log.cc ++++ b/sql/log.cc +@@ -5090,6 +5090,12 @@ + user_var_event->type, + user_var_event->charset_number, + flags); ++ /* ++ These User_var_log_events must be logged with event_info's ++ server_id, rather than the current one. ++ */ ++ e.server_id= event_info->server_id; ++ + if (e.write(file)) + goto err; + if (file == &log_file) diff --git a/innodb_adaptive_hash_index_partitions.patch b/innodb_adaptive_hash_index_partitions.patch index 0f1a736..f42e243 100644 --- a/innodb_adaptive_hash_index_partitions.patch +++ b/innodb_adaptive_hash_index_partitions.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c -@@ -1518,7 +1518,7 @@ +@@ -1523,7 +1523,7 @@ } ut_a(block); @@ -16,7 +16,7 @@ header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP; #ifdef UNIV_BTR_DEBUG -@@ -1587,7 +1587,7 @@ +@@ -1592,7 +1592,7 @@ #ifndef UNIV_HOTBACKUP if (UNIV_LIKELY(!recovery)) { @@ -25,7 +25,7 @@ } block->check_index_page_at_flush = TRUE; -@@ -1755,7 +1755,7 @@ +@@ -1760,7 +1760,7 @@ ut_a(!page_zip || page_zip_validate(page_zip, page)); #endif /* UNIV_ZIP_DEBUG */ @@ -34,7 +34,7 @@ btr_blob_dbg_remove(page, index, "btr_page_empty"); /* Recreate the page: note that global data on page (possible -@@ -3066,7 +3066,7 @@ +@@ -3093,7 +3093,7 @@ mem_heap_free(heap); } @@ -43,7 +43,7 @@ /* Make the father empty */ btr_page_empty(father_block, father_page_zip, index, page_level, mtr); -@@ -3300,7 +3300,7 @@ +@@ -3317,7 +3317,7 @@ goto err_exit; } @@ -51,8 +51,8 @@ + btr_search_drop_page_hash_index(block, index); /* Remove the page from the level list */ - btr_level_list_remove(space, zip_size, page, mtr); -@@ -3345,7 +3345,7 @@ + btr_level_list_remove(space, zip_size, page, index, mtr); +@@ -3358,7 +3358,7 @@ goto err_exit; } @@ -61,7 +61,7 @@ #ifdef UNIV_BTR_DEBUG if (UNIV_LIKELY_NULL(merge_page_zip)) { -@@ -3469,7 +3469,7 @@ +@@ -3473,7 +3473,7 @@ ut_a(btr_page_get_next(page, mtr) == FIL_NULL); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); @@ -70,7 +70,7 @@ btr_page_get_father(index, block, mtr, &cursor); father = btr_cur_get_block(&cursor); -@@ -3574,7 +3574,7 @@ +@@ -3578,7 +3578,7 @@ page = buf_block_get_frame(block); ut_a(page_is_comp(merge_page) == page_is_comp(page)); @@ -81,7 +81,7 @@ --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c -@@ -498,7 +498,7 @@ +@@ -502,7 +502,7 @@ #ifdef UNIV_SEARCH_PERF_STAT info->n_searches++; #endif @@ -90,7 +90,7 @@ && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ && !estimate -@@ -534,7 +534,7 @@ +@@ -538,7 +538,7 @@ if (has_search_latch) { /* Release possible search latch to obey latching order */ @@ -99,7 +99,7 @@ } /* Store the position of the tree latch we push to mtr so that we -@@ -856,7 +856,7 @@ +@@ -862,7 +862,7 @@ if (has_search_latch) { @@ -108,7 +108,7 @@ } } -@@ -1971,7 +1971,7 @@ +@@ -1992,13 +1992,13 @@ btr_search_update_hash_on_delete(cursor); } @@ -116,50 +116,14 @@ + rw_lock_x_lock(btr_search_get_latch(cursor->index->id)); } - if (!(flags & BTR_KEEP_SYS_FLAG)) { -@@ -1985,7 +1985,7 @@ row_upd_rec_in_place(rec, index, offsets, update, page_zip); - if (block->is_hashed) { + if (is_hashed) { - rw_lock_x_unlock(&btr_search_latch); + rw_lock_x_unlock(btr_search_get_latch(cursor->index->id)); } if (page_zip && !dict_index_is_clust(index) -@@ -2824,7 +2824,7 @@ - } - - if (block->is_hashed) { -- rw_lock_x_lock(&btr_search_latch); -+ rw_lock_x_lock(btr_search_get_latch(index->id)); - } - - page_zip = buf_block_get_page_zip(block); -@@ -2840,7 +2840,7 @@ - } - - if (block->is_hashed) { -- rw_lock_x_unlock(&btr_search_latch); -+ rw_lock_x_unlock(btr_search_get_latch(index->id)); - } - - btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx, -@@ -2967,13 +2967,13 @@ - == dict_table_is_comp(cursor->index->table)); - - if (block->is_hashed) { -- rw_lock_x_lock(&btr_search_latch); -+ rw_lock_x_lock(btr_search_get_latch(cursor->index->id)); - } - - btr_rec_set_deleted_flag(rec, buf_block_get_page_zip(block), val); - - if (block->is_hashed) { -- rw_lock_x_unlock(&btr_search_latch); -+ rw_lock_x_unlock(btr_search_get_latch(cursor->index->id)); - } - - btr_cur_del_mark_set_sec_rec_log(rec, val, mtr); --- a/storage/innobase/btr/btr0sea.c +++ b/storage/innobase/btr/btr0sea.c @@ -48,6 +48,8 @@ @@ -425,7 +389,7 @@ } if (build_index) { -@@ -881,17 +909,17 @@ +@@ -882,17 +910,17 @@ cursor->flag = BTR_CUR_HASH; if (UNIV_LIKELY(!has_search_latch)) { @@ -447,7 +411,7 @@ if (UNIV_UNLIKELY(!rec)) { goto failure_unlock; -@@ -909,7 +937,7 @@ +@@ -910,7 +938,7 @@ goto failure_unlock; } @@ -456,7 +420,7 @@ buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH); } -@@ -1006,7 +1034,7 @@ +@@ -1007,7 +1035,7 @@ /*-------------------------------------------*/ failure_unlock: if (UNIV_LIKELY(!has_search_latch)) { @@ -465,7 +429,7 @@ } failure: cursor->flag = BTR_CUR_HASH_FAIL; -@@ -1029,10 +1057,11 @@ +@@ -1030,10 +1058,11 @@ void btr_search_drop_page_hash_index( /*============================*/ @@ -478,7 +442,7 @@ { hash_table_t* table; ulint n_fields; -@@ -1051,22 +1080,60 @@ +@@ -1052,22 +1081,60 @@ ulint* offsets; #ifdef UNIV_SYNC_DEBUG @@ -544,7 +508,7 @@ #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED) -@@ -1076,14 +1143,14 @@ +@@ -1077,14 +1144,14 @@ n_fields = block->curr_n_fields; n_bytes = block->curr_n_bytes; @@ -561,7 +525,7 @@ ut_a(n_fields + n_bytes > 0); -@@ -1133,7 +1200,7 @@ +@@ -1134,7 +1201,7 @@ mem_heap_free(heap); } @@ -570,7 +534,7 @@ if (UNIV_UNLIKELY(!block->is_hashed)) { /* Someone else has meanwhile dropped the hash index */ -@@ -1149,7 +1216,7 @@ +@@ -1150,7 +1217,7 @@ /* Someone else has meanwhile built a new hash index on the page, with different parameters */ @@ -579,7 +543,7 @@ mem_free(folds); goto retry; -@@ -1165,6 +1232,7 @@ +@@ -1166,6 +1233,7 @@ block->is_hashed = FALSE; block->index = NULL; @@ -587,7 +551,7 @@ cleanup: #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG -@@ -1177,14 +1245,14 @@ +@@ -1178,14 +1246,14 @@ "InnoDB: the hash index to a page of %s," " still %lu hash nodes remain.\n", index->name, (ulong) block->n_pointers); @@ -605,7 +569,7 @@ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ mem_free(folds); -@@ -1216,9 +1284,9 @@ +@@ -1217,9 +1285,9 @@ ulint* offsets; ibool released_search_latch; @@ -617,7 +581,7 @@ for (j = 0; j < srv_buf_pool_instances; j++) { buf_pool_t* buf_pool; -@@ -1252,7 +1320,7 @@ +@@ -1253,7 +1321,7 @@ /* keeping latch order */ @@ -626,7 +590,7 @@ released_search_latch = TRUE; rw_lock_x_lock(&block->lock); -@@ -1304,7 +1372,7 @@ +@@ -1305,7 +1373,7 @@ mem_heap_empty(heap); } @@ -635,7 +599,7 @@ if (UNIV_UNLIKELY(!block->is_hashed)) { goto cleanup; -@@ -1314,12 +1382,12 @@ +@@ -1315,12 +1383,12 @@ if (UNIV_UNLIKELY(block->curr_n_fields != n_fields) || UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) { @@ -650,7 +614,7 @@ goto retry; } -@@ -1333,6 +1401,7 @@ +@@ -1334,6 +1402,7 @@ block->is_hashed = FALSE; block->index = NULL; @@ -658,7 +622,7 @@ cleanup: #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG -@@ -1345,18 +1414,18 @@ +@@ -1346,18 +1415,18 @@ index->name, (ulong) block->n_pointers); } #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ @@ -680,7 +644,7 @@ if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); -@@ -1403,7 +1472,7 @@ +@@ -1404,7 +1473,7 @@ buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH); @@ -689,7 +653,7 @@ } mtr_commit(&mtr); -@@ -1445,26 +1514,26 @@ +@@ -1446,26 +1515,26 @@ ut_ad(index); ut_a(!dict_index_is_ibuf(index)); @@ -722,7 +686,7 @@ } n_recs = page_get_n_recs(page); -@@ -1558,9 +1627,9 @@ +@@ -1559,9 +1628,9 @@ fold = next_fold; } @@ -734,7 +698,7 @@ if (UNIV_UNLIKELY(btr_search_fully_disabled)) { goto exit_func; -@@ -1588,6 +1657,7 @@ +@@ -1589,6 +1658,7 @@ block->curr_n_bytes = n_bytes; block->curr_left_side = left_side; block->index = index; @@ -742,7 +706,7 @@ for (i = 0; i < n_cached; i++) { -@@ -1595,7 +1665,7 @@ +@@ -1596,7 +1666,7 @@ } exit_func: @@ -751,7 +715,7 @@ mem_free(folds); mem_free(recs); -@@ -1634,13 +1704,13 @@ +@@ -1635,13 +1705,13 @@ ut_a(!(new_block->is_hashed || block->is_hashed) || !dict_index_is_ibuf(index)); @@ -768,7 +732,7 @@ return; } -@@ -1655,7 +1725,7 @@ +@@ -1656,7 +1726,7 @@ new_block->n_bytes = block->curr_n_bytes; new_block->left_side = left_side; @@ -777,7 +741,7 @@ ut_a(n_fields + n_bytes > 0); -@@ -1667,7 +1737,7 @@ +@@ -1668,7 +1738,7 @@ return; } @@ -786,7 +750,7 @@ } /********************************************************************//** -@@ -1706,7 +1776,7 @@ +@@ -1707,7 +1777,7 @@ ut_a(block->curr_n_fields + block->curr_n_bytes > 0); ut_a(!dict_index_is_ibuf(cursor->index)); @@ -795,7 +759,7 @@ index_id = cursor->index->id; fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_, -@@ -1715,11 +1785,11 @@ +@@ -1716,11 +1786,11 @@ if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } @@ -809,7 +773,7 @@ } /********************************************************************//** -@@ -1753,21 +1823,21 @@ +@@ -1754,21 +1824,21 @@ ut_a(block->index == cursor->index); ut_a(!dict_index_is_ibuf(cursor->index)); @@ -835,7 +799,7 @@ btr_search_update_hash_on_insert(cursor); } -@@ -1802,9 +1872,9 @@ +@@ -1803,9 +1873,9 @@ ulint* offsets = offsets_; rec_offs_init(offsets_); @@ -847,7 +811,7 @@ rec = btr_cur_get_rec(cursor); -@@ -1849,7 +1919,7 @@ +@@ -1850,7 +1920,7 @@ } else { if (left_side) { @@ -856,7 +820,7 @@ locked = TRUE; -@@ -1863,7 +1933,7 @@ +@@ -1864,7 +1934,7 @@ if (!locked) { @@ -865,7 +829,7 @@ locked = TRUE; } -@@ -1881,7 +1951,7 @@ +@@ -1882,7 +1952,7 @@ if (!left_side) { if (!locked) { @@ -874,7 +838,7 @@ locked = TRUE; } -@@ -1896,7 +1966,7 @@ +@@ -1897,7 +1967,7 @@ if (!locked) { @@ -883,7 +847,7 @@ locked = TRUE; } -@@ -1919,7 +1989,7 @@ +@@ -1920,7 +1990,7 @@ mem_heap_free(heap); } if (locked) { @@ -892,7 +856,7 @@ } } -@@ -1935,7 +2005,7 @@ +@@ -1936,7 +2006,7 @@ ha_node_t* node; ulint n_page_dumps = 0; ibool ok = TRUE; @@ -901,7 +865,7 @@ ulint cell_count; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; -@@ -1947,23 +2017,25 @@ +@@ -1948,23 +2018,25 @@ rec_offs_init(offsets_); @@ -932,7 +896,7 @@ for (; node != NULL; node = node->next) { const buf_block_t* block -@@ -2072,19 +2144,21 @@ +@@ -2073,19 +2145,21 @@ give other queries a chance to run. */ if (i != 0) { buf_pool_page_hash_x_unlock_all(); @@ -960,7 +924,7 @@ } --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c -@@ -949,6 +949,7 @@ +@@ -950,6 +950,7 @@ block->check_index_page_at_flush = FALSE; block->index = NULL; @@ -968,7 +932,7 @@ block->is_hashed = FALSE; -@@ -1413,7 +1414,7 @@ +@@ -1414,7 +1415,7 @@ /* To follow the latching order, we have to release btr_search_latch before acquiring block->latch. */ @@ -977,7 +941,7 @@ /* When we release the search latch, we must rescan all blocks, because some may become hashed again. */ -@@ -1444,11 +1445,11 @@ +@@ -1445,11 +1446,11 @@ anything. block->is_hashed can only be set on uncompressed file pages. */ @@ -991,7 +955,7 @@ ut_ad(!btr_search_enabled); } -@@ -1467,7 +1468,11 @@ +@@ -1468,7 +1469,11 @@ ibool released_search_latch; #ifdef UNIV_SYNC_DEBUG @@ -1004,7 +968,7 @@ #endif /* UNIV_SYNC_DEBUG */ ut_ad(!btr_search_enabled); -@@ -2203,6 +2208,7 @@ +@@ -2204,6 +2209,7 @@ { block->check_index_page_at_flush = FALSE; block->index = NULL; @@ -1055,7 +1019,7 @@ --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c -@@ -1845,7 +1845,7 @@ +@@ -1846,7 +1846,7 @@ zero. */ for (;;) { @@ -1078,7 +1042,7 @@ #ifndef UNIV_HOTBACKUP --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -11718,6 +11718,11 @@ +@@ -11824,6 +11824,11 @@ "Disable with --skip-innodb-adaptive-hash-index.", NULL, innodb_adaptive_hash_index_update, TRUE); @@ -1090,7 +1054,7 @@ static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay, PLUGIN_VAR_RQCMDARG, "Replication thread delay (ms) on the slave server if " -@@ -12085,6 +12090,7 @@ +@@ -12204,6 +12209,7 @@ MYSQL_SYSVAR(use_sys_stats_table), MYSQL_SYSVAR(stats_sample_pages), MYSQL_SYSVAR(adaptive_hash_index), @@ -1283,7 +1247,7 @@ + --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h -@@ -1585,7 +1585,7 @@ +@@ -1576,7 +1576,7 @@ pointers in the adaptive hash index pointing to this frame */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ @@ -1292,7 +1256,7 @@ already been built on this page; note that it does not guarantee that the index is -@@ -1599,6 +1599,7 @@ +@@ -1590,6 +1590,7 @@ unsigned curr_left_side:1;/*!< TRUE or FALSE in hash indexing */ dict_index_t* index; /*!< Index for which the adaptive hash index has been created. */ @@ -1300,17 +1264,6 @@ /* @} */ # ifdef UNIV_SYNC_DEBUG /** @name Debug fields */ ---- a/storage/innobase/include/row0upd.ic -+++ b/storage/innobase/include/row0upd.ic -@@ -158,7 +158,7 @@ - ut_ad(dict_index_is_clust(index)); - ut_ad(rec_offs_validate(rec, index, offsets)); - #ifdef UNIV_SYNC_DEBUG -- if (!rw_lock_own(&btr_search_latch, RW_LOCK_EX)) { -+ if (!rw_lock_own(btr_search_get_latch(index->id), RW_LOCK_EX)) { - ut_ad(!buf_block_align(rec)->is_hashed); - } - #endif /* UNIV_SYNC_DEBUG */ --- a/storage/innobase/page/page0page.c +++ b/storage/innobase/page/page0page.c @@ -218,7 +218,7 @@ @@ -1344,7 +1297,7 @@ ut_ad(block == back_block1); --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c -@@ -2593,7 +2593,7 @@ +@@ -2594,7 +2594,7 @@ /* check adaptive hash entries */ index = dict_table_get_first_index(table); while (index) { @@ -1353,7 +1306,7 @@ if (ref_count) { fprintf(stderr, "InnoDB: Warning:" " hash index ref_count (%lu) is not zero" -@@ -2954,7 +2954,7 @@ +@@ -2955,7 +2955,7 @@ table->space = space; index = dict_table_get_first_index(table); do { @@ -1364,7 +1317,7 @@ fprintf(stderr, "InnoDB: Warning:" --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c -@@ -1211,7 +1211,7 @@ +@@ -1222,7 +1222,7 @@ ut_ad(plan->unique_search); ut_ad(!plan->must_get_clust); #ifdef UNIV_SYNC_DEBUG @@ -1373,7 +1326,7 @@ #endif /* UNIV_SYNC_DEBUG */ row_sel_open_pcur(plan, TRUE, mtr); -@@ -1382,10 +1382,10 @@ +@@ -1393,10 +1393,10 @@ && !plan->must_get_clust && !plan->table->big_rows) { if (!search_latch_locked) { @@ -1386,7 +1339,7 @@ /* There is an x-latch request waiting: release the s-latch for a moment; as an s-latch here is often -@@ -1394,8 +1394,8 @@ +@@ -1405,8 +1405,8 @@ from acquiring an s-latch for a long time, lowering performance significantly in multiprocessors. */ @@ -1397,7 +1350,7 @@ } found_flag = row_sel_try_search_shortcut(node, plan, &mtr); -@@ -1418,7 +1418,7 @@ +@@ -1429,7 +1429,7 @@ } if (search_latch_locked) { @@ -1406,7 +1359,7 @@ search_latch_locked = FALSE; } -@@ -1994,7 +1994,7 @@ +@@ -2005,7 +2005,7 @@ func_exit: if (search_latch_locked) { @@ -1415,7 +1368,7 @@ } if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); -@@ -3357,6 +3357,8 @@ +@@ -3408,6 +3408,8 @@ /* if the returned record was locked and we did a semi-consistent read (fetch the newest committed version), then this is set to TRUE */ @@ -1424,7 +1377,7 @@ #ifdef UNIV_SEARCH_DEBUG ulint cnt = 0; #endif /* UNIV_SEARCH_DEBUG */ -@@ -3447,18 +3449,33 @@ +@@ -3505,18 +3507,33 @@ /* PHASE 0: Release a possible s-latch we are holding on the adaptive hash index latch if there is someone waiting behind */ @@ -1462,7 +1415,7 @@ } /* Reset the new record lock info if srv_locks_unsafe_for_binlog -@@ -3609,9 +3626,28 @@ +@@ -3667,9 +3684,28 @@ hash index semaphore! */ #ifndef UNIV_SEARCH_DEBUG @@ -1494,7 +1447,7 @@ } #endif switch (row_sel_try_search_shortcut_for_mysql( -@@ -3672,7 +3708,11 @@ +@@ -3730,7 +3766,11 @@ trx->search_latch_timeout--; @@ -1507,7 +1460,7 @@ trx->has_search_latch = FALSE; } -@@ -3696,7 +3736,12 @@ +@@ -3754,7 +3794,12 @@ /* PHASE 3: Open or restore index cursor position */ if (trx->has_search_latch) { @@ -1523,7 +1476,7 @@ --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -2045,7 +2045,9 @@ +@@ -2051,7 +2051,9 @@ "-------------------------------------\n", file); ibuf_print(file); @@ -1534,7 +1487,7 @@ fprintf(file, "%.2f hash searches/s, %.2f non-hash searches/s\n", -@@ -2070,14 +2072,15 @@ +@@ -2076,14 +2078,15 @@ ut_total_allocated_memory, mem_pool_get_reserved(mem_comm_pool)); /* Calcurate reserved memories */ @@ -1554,7 +1507,7 @@ lock_sys_subtotal = 0; if (trx_sys) { -@@ -2103,10 +2106,10 @@ +@@ -2109,10 +2112,10 @@ " Recovery system %lu \t(%lu + %lu)\n", (ulong) (btr_search_sys @@ -1569,7 +1522,7 @@ (ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t)), --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c -@@ -1228,7 +1228,6 @@ +@@ -1222,7 +1222,6 @@ case SYNC_OUTER_ANY_LATCH: case SYNC_FILE_FORMAT_TAG: case SYNC_DOUBLEWRITE: @@ -1577,7 +1530,7 @@ case SYNC_SEARCH_SYS_CONF: case SYNC_TRX_LOCK_HEAP: case SYNC_KERNEL: -@@ -1249,6 +1248,7 @@ +@@ -1244,6 +1243,7 @@ ut_error; } break; diff --git a/innodb_admin_command_base.patch b/innodb_admin_command_base.patch index 8cb782b..7c93c5f 100644 --- a/innodb_admin_command_base.patch +++ b/innodb_admin_command_base.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -11880,7 +11880,8 @@ +@@ -11990,7 +11990,8 @@ i_s_innodb_sys_foreign_cols, i_s_innodb_sys_stats, i_s_innodb_table_stats, @@ -19,7 +19,7 @@ /** @brief Initialize the default value of innodb_commit_concurrency. --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc -@@ -4177,3 +4177,139 @@ +@@ -4205,3 +4205,139 @@ STRUCT_FLD(system_vars, NULL), STRUCT_FLD(__reserved1, NULL) }; @@ -183,3 +183,24 @@ +--source include/have_innodb.inc +select * from information_schema.XTRADB_ADMIN_COMMAND; +select * from information_schema.XTRADB_ADMIN_COMMAND /*!XTRA_HELLO*/; +--- a/mysql-test/r/mysqld--help-notwin.result ++++ b/mysql-test/r/mysqld--help-notwin.result +@@ -731,6 +731,10 @@ + -V, --version Output version information and exit. + --wait-timeout=# The number of seconds the server waits for activity on a + connection before closing it ++ --xtradb-admin-command[=name] ++ Enable or disable XTRADB_ADMIN_COMMAND plugin. Possible ++ values are ON, OFF, FORCE (don't start if the plugin ++ fails to load). + + Variables (--variable-name=value) + abort-slave-event-count 0 +@@ -955,6 +959,7 @@ + updatable-views-with-limit YES + verbose TRUE + wait-timeout 28800 ++xtradb-admin-command ON + + To see what values a running MySQL server is using, type + 'mysqladmin variables' instead of 'mysqld --verbose --help'. diff --git a/innodb_buffer_pool_pages_i_s.patch b/innodb_buffer_pool_pages_i_s.patch index 151cb5a..0ff3d4d 100644 --- a/innodb_buffer_pool_pages_i_s.patch +++ b/innodb_buffer_pool_pages_i_s.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c -@@ -4157,6 +4157,36 @@ +@@ -4224,6 +4224,36 @@ mutex_exit(block_mutex); } @@ -46,7 +46,7 @@ @return TRUE */ --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -12165,6 +12165,9 @@ +@@ -12287,6 +12287,9 @@ i_s_innodb_sys_stats, i_s_innodb_table_stats, i_s_innodb_index_stats, @@ -66,7 +66,7 @@ } #define OK(expr) \ -@@ -4344,3 +4345,701 @@ +@@ -4372,3 +4373,701 @@ STRUCT_FLD(system_vars, NULL), STRUCT_FLD(__reserved1, NULL) }; @@ -781,7 +781,7 @@ #endif /* i_s_h */ --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h -@@ -1183,6 +1183,14 @@ +@@ -1174,6 +1174,14 @@ /*===========*/ const buf_pool_t* buf_pool) /*!< in: buffer pool */ __attribute__((nonnull, const)); diff --git a/innodb_buffer_pool_shm.patch b/innodb_buffer_pool_shm.patch index e5c7b47..42b98a2 100644 --- a/innodb_buffer_pool_shm.patch +++ b/innodb_buffer_pool_shm.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c -@@ -1006,10 +1006,12 @@ +@@ -1007,10 +1007,12 @@ buf_block_t* block; byte* frame; ulint i; @@ -20,7 +20,7 @@ /* Reserve space for the block descriptors. */ mem_size += ut_2pow_round((mem_size / UNIV_PAGE_SIZE) * (sizeof *block) + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE); -@@ -1047,6 +1049,10 @@ +@@ -1048,6 +1050,10 @@ chunk->size = size; } @@ -42,7 +42,7 @@ static char* internal_innobase_data_file_path = NULL; -@@ -2675,6 +2677,12 @@ +@@ -2706,6 +2708,12 @@ srv_buf_pool_size = (ulint) innobase_buffer_pool_size; srv_buf_pool_instances = (ulint) innobase_buffer_pool_instances; @@ -55,7 +55,7 @@ srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size; srv_n_file_io_threads = (ulint) innobase_file_io_threads; -@@ -11749,6 +11757,16 @@ +@@ -11855,6 +11863,16 @@ "Number of buffer pool instances, set to higher value on high-end machines to increase scalability", NULL, NULL, 1L, 1L, MAX_BUFFER_POOLS, 1L); @@ -72,7 +72,7 @@ static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency, PLUGIN_VAR_RQCMDARG, "Helps in performance tuning in heavily concurrent environments.", -@@ -12043,6 +12061,8 @@ +@@ -12161,6 +12179,8 @@ MYSQL_SYSVAR(autoextend_increment), MYSQL_SYSVAR(buffer_pool_size), MYSQL_SYSVAR(buffer_pool_instances), diff --git a/innodb_deadlock_count.patch b/innodb_deadlock_count.patch index 44ad06d..4e38012 100644 --- a/innodb_deadlock_count.patch +++ b/innodb_deadlock_count.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -687,6 +687,8 @@ +@@ -691,6 +691,8 @@ (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG}, {"dblwr_writes", (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG}, @@ -28,7 +28,7 @@ Gets the size of a lock struct. --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -758,6 +758,7 @@ +@@ -767,6 +767,7 @@ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/ ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */ ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */ @@ -48,7 +48,7 @@ break; --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -468,6 +468,7 @@ +@@ -474,6 +474,7 @@ static ulint srv_n_rows_deleted_old = 0; static ulint srv_n_rows_read_old = 0; @@ -56,7 +56,7 @@ UNIV_INTERN ulint srv_n_lock_wait_count = 0; UNIV_INTERN ulint srv_n_lock_wait_current_count = 0; UNIV_INTERN ib_int64_t srv_n_lock_wait_time = 0; -@@ -2282,6 +2283,7 @@ +@@ -2290,6 +2291,7 @@ export_vars.innodb_buffer_pool_pages_data = LRU_len; export_vars.innodb_buffer_pool_pages_dirty = flush_list_len; export_vars.innodb_buffer_pool_pages_free = free_len; diff --git a/innodb_dict_size_limit.patch b/innodb_dict_size_limit.patch index e524a07..288b268 100644 --- a/innodb_dict_size_limit.patch +++ b/innodb_dict_size_limit.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/btr/btr0sea.c +++ b/storage/innobase/btr/btr0sea.c -@@ -1185,6 +1185,179 @@ +@@ -1186,6 +1186,179 @@ mem_free(folds); } @@ -355,7 +355,7 @@ /****************************************************************//** If the given column name is reserved for InnoDB system columns, return TRUE. -@@ -1762,6 +1824,11 @@ +@@ -1763,6 +1825,11 @@ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(mutex_own(&(dict_sys->mutex))); @@ -369,7 +369,7 @@ info = index->search_info; --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -675,6 +675,8 @@ +@@ -677,6 +677,8 @@ (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG}, {"dblwr_writes", (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG}, @@ -378,7 +378,7 @@ {"have_atomic_builtins", (char*) &export_vars.innodb_have_atomic_builtins, SHOW_BOOL}, {"log_waits", -@@ -11658,6 +11660,11 @@ +@@ -11765,6 +11767,11 @@ "Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)", NULL, innodb_adaptive_flushing_method_update, 1, &adaptive_flushing_method_typelib); @@ -390,7 +390,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), -@@ -11726,6 +11733,7 @@ +@@ -11834,6 +11841,7 @@ MYSQL_SYSVAR(flush_neighbor_pages), MYSQL_SYSVAR(read_ahead), MYSQL_SYSVAR(adaptive_flushing_method), @@ -426,7 +426,7 @@ Drops possible hash index if the page happens to be in the buffer pool. */ --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h -@@ -1594,6 +1594,15 @@ +@@ -1585,6 +1585,15 @@ #define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b)) /* @} */ @@ -444,7 +444,7 @@ ulint n_page_gets; /*!< number of page gets performed; --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h -@@ -1183,6 +1183,12 @@ +@@ -1200,6 +1200,12 @@ /*====================================*/ dict_table_t* table, /*!< in: table */ const char* name); /*!< in: name of the index to find */ @@ -459,7 +459,7 @@ extern FILE* dict_foreign_err_file; --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic -@@ -824,6 +824,13 @@ +@@ -825,6 +825,13 @@ HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold, dict_table_t*, table, ut_ad(table->cached), !strcmp(table->name, table_name)); @@ -473,7 +473,7 @@ return(table); } -@@ -905,6 +912,12 @@ +@@ -918,6 +925,12 @@ table = dict_load_table_on_id(table_id); } @@ -488,7 +488,7 @@ /* TODO: should get the type information from MySQL */ --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -229,6 +229,7 @@ +@@ -234,6 +234,7 @@ extern ulint srv_read_ahead; extern ulint srv_adaptive_flushing_method; @@ -496,7 +496,7 @@ /*-------------------------------------------*/ extern ulint srv_n_rows_inserted; -@@ -709,6 +710,7 @@ +@@ -714,6 +715,7 @@ ulint innodb_data_writes; /*!< I/O write requests */ ulint innodb_data_written; /*!< Data bytes written */ ulint innodb_data_reads; /*!< I/O read requests */ @@ -506,7 +506,7 @@ ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */ --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -415,6 +415,8 @@ +@@ -417,6 +417,8 @@ UNIV_INTERN ulint srv_enable_unsafe_group_commit = 0; /* 0:disable 1:enable */ UNIV_INTERN ulint srv_read_ahead = 3; /* 1: random 2: linear 3: Both */ UNIV_INTERN ulint srv_adaptive_flushing_method = 0; /* 0: native 1: estimate 2: keep_average */ @@ -515,7 +515,7 @@ /*-------------------------------------------*/ UNIV_INTERN ulong srv_n_spin_wait_rounds = 30; UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500; -@@ -2220,6 +2222,7 @@ +@@ -2222,6 +2224,7 @@ export_vars.innodb_data_reads = os_n_file_reads; export_vars.innodb_data_writes = os_n_file_writes; export_vars.innodb_data_written = srv_data_written; diff --git a/innodb_expand_fast_index_creation.patch b/innodb_expand_fast_index_creation.patch index ed49461..b40e995 100644 --- a/innodb_expand_fast_index_creation.patch +++ b/innodb_expand_fast_index_creation.patch @@ -25,7 +25,7 @@ #include "client_priv.h" #include "mysql.h" -@@ -143,6 +144,8 @@ +@@ -145,6 +146,8 @@ static my_bool server_supports_sql_no_fcache= FALSE; @@ -34,7 +34,7 @@ /* Dynamic_string wrapper functions. In this file use these wrappers, they will terminate the process if there is -@@ -188,6 +191,8 @@ +@@ -190,6 +193,8 @@ HASH ignore_table; @@ -43,7 +43,7 @@ static struct my_option my_long_options[] = { {"all-databases", 'A', -@@ -351,6 +356,11 @@ +@@ -353,6 +358,11 @@ "in dump produced with --dump-slave.", &opt_include_master_host_port, &opt_include_master_host_port, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -55,37 +55,66 @@ {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.", &opt_ignore, &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -@@ -2238,6 +2248,77 @@ +@@ -2240,6 +2250,189 @@ } /* ++ Parse the specified key definition string and check if the key indexes ++ any of the columns from ignored_columns. ++*/ ++static my_bool contains_ignored_column(HASH *ignored_columns, char *keydef) ++{ ++ char *leftp, *rightp; ++ ++ if ((leftp = strchr(keydef, '(')) && ++ (rightp = strchr(leftp, ')')) && ++ rightp > leftp + 3 && /* (`...`) */ ++ leftp[1] == '`' && ++ rightp[-1] == '`' && ++ my_hash_search(ignored_columns, (uchar *) leftp + 2, rightp - leftp - 3)) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++ ++/* + Remove secondary/foreign key definitions from a given SHOW CREATE TABLE string + and store them into a temporary list to be used later. + + SYNOPSIS + skip_secondary_keys() + create_str SHOW CREATE TABLE output ++ has_pk TRUE, if the table has PRIMARY KEY ++ (or UNIQUE key on non-nullable columns) + + + DESCRIPTION + -+ Stores all lines starting with "KEY" or "UNIQUE KEY" or "CONSTRAINT" ++ Stores all lines starting with "KEY" or "UNIQUE KEY" + into skipped_keys_list and removes them from the input string. + Ignoring FOREIGN KEYS constraints when creating the table is ok, because + mysqldump sets foreign_key_checks to 0 anyway. +*/ + -+static void skip_secondary_keys(char *create_str) ++static void skip_secondary_keys(char *create_str, my_bool has_pk) +{ + char *ptr, *strend; + char *last_comma = NULL; ++ HASH ignored_columns; ++ my_bool pk_processed= FALSE; ++ ++ if (my_hash_init(&ignored_columns, charset_info, 16, 0, 0, ++ (my_hash_get_key) get_table_key, my_free, 0)) ++ exit(EX_EOM); + + strend= create_str + strlen(create_str); + + ptr= create_str; + while (*ptr) + { -+ char *tmp, *orig_ptr; ++ char *tmp, *orig_ptr, c; ++ my_bool is_unique= FALSE; + + orig_ptr= ptr; + /* Skip leading whitespace */ @@ -95,11 +124,15 @@ + /* Read the next line */ + for (tmp= ptr; *tmp != '\n' && *tmp != '\0'; tmp++); + ++ c= *tmp; ++ *tmp= '\0'; /* so strstr() only processes the current line */ ++ + /* Is it a secondary index definition? */ -+ if (*tmp == '\n' && -+ (!strncmp(ptr, "UNIQUE KEY ", sizeof("UNIQUE KEY ") - 1) || -+ !strncmp(ptr, "KEY ", sizeof("KEY ") - 1) || -+ !strncmp(ptr, "CONSTRAINT ", sizeof("CONSTRAINT ") - 1))) ++ if (c == '\n' && ++ (((is_unique= !strncmp(ptr, "UNIQUE KEY ", sizeof("UNIQUE KEY ")-1)) && ++ (pk_processed || !has_pk)) || ++ !strncmp(ptr, "KEY ", sizeof("KEY ") - 1)) && ++ !contains_ignored_column(&ignored_columns, ptr)) + { + char *data, *end= tmp - 1; + @@ -117,33 +150,130 @@ + if (last_comma != NULL) + { + *last_comma= ' '; -+ last_comma = NULL; + } + } + else + { ++ char *end; ++ ++ if (last_comma != NULL && *ptr != ')') ++ { ++ /* ++ It's not the last line of CREATE TABLE, so we have skipped a key ++ definition. We have to restore the last removed comma. ++ */ ++ *last_comma= ','; ++ } ++ ++ if ((has_pk && is_unique && !pk_processed) || ++ !strncmp(ptr, "PRIMARY KEY ", sizeof("PRIMARY KEY ") - 1)) ++ pk_processed= TRUE; ++ ++ if (strstr(ptr, "AUTO_INCREMENT") && *ptr == '`') ++ { ++ /* ++ If a secondary key is defined on this column later, ++ it cannot be skipped, as CREATE TABLE would fail on import. ++ */ ++ for (end= ptr + 1; *end != '`' && *end != '\0'; end++); ++ if (*end == '`' && end > ptr + 1 && ++ my_hash_insert(&ignored_columns, ++ (uchar *) my_strndup(ptr + 1, ++ end - ptr - 1, MYF(0)))) ++ { ++ exit(EX_EOM); ++ } ++ } ++ ++ *tmp= c; ++ + if (tmp[-1] == ',') + last_comma= tmp - 1; + ptr= (*tmp == '\0') ? tmp : tmp + 1; + } + } ++ ++ my_hash_free(&ignored_columns); +} + ++/* ++ Check if the table has a primary key defined either explicitly or ++ implicitly (i.e. a unique key on non-nullable columns). ++ ++ SYNOPSIS ++ my_bool has_primary_key(const char *table_name) ++ ++ table_name quoted table name ++ ++ RETURNS TRUE if the table has a primary key ++ ++ DESCRIPTION ++*/ ++ ++static my_bool has_primary_key(const char *table_name) ++{ ++ MYSQL_RES *res= NULL; ++ MYSQL_ROW row; ++ char query_buff[QUERY_LENGTH]; ++ my_bool has_pk= TRUE; ++ ++ my_snprintf(query_buff, sizeof(query_buff), ++ "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE " ++ "TABLE_SCHEMA=DATABASE() AND TABLE_NAME='%s' AND " ++ "COLUMN_KEY='PRI'", table_name); ++ if (mysql_query(mysql, query_buff) || !(res= mysql_store_result(mysql)) || ++ !(row= mysql_fetch_row(res))) ++ { ++ fprintf(stderr, "Warning: Couldn't determine if table %s has a " ++ "primary key (%s). " ++ "--innodb-optimize-keys may work inefficiently.\n", ++ table_name, mysql_error(mysql)); ++ goto cleanup; ++ } ++ ++ has_pk= atoi(row[0]) > 0; ++ ++cleanup: ++ if (res) ++ mysql_free_result(res); ++ ++ return has_pk; ++} ++ ++ +/* get_table_structure -- retrievs database structure, prints out corresponding CREATE statement and fills out insert_pat if the table is the type we will be dumping. -@@ -2478,6 +2559,9 @@ +@@ -2276,6 +2469,7 @@ + int len; + MYSQL_RES *result; + MYSQL_ROW row; ++ my_bool has_pk= FALSE; + DBUG_ENTER("get_table_structure"); + DBUG_PRINT("enter", ("db: %s table: %s", db, table)); + +@@ -2317,6 +2511,9 @@ + result_table= quote_name(table, table_buff, 1); + opt_quoted_table= quote_name(table, table_buff2, 0); + ++ if (opt_innodb_optimize_keys && !strcmp(table_type, "InnoDB")) ++ has_pk= has_primary_key(table); ++ + if (opt_order_by_primary) + order_by= primary_key_fields(result_table); + +@@ -2480,6 +2677,9 @@ row= mysql_fetch_row(result); + if (opt_innodb_optimize_keys && !strcmp(table_type, "InnoDB")) -+ skip_secondary_keys(row[1]); ++ skip_secondary_keys(row[1], has_pk); + fprintf(sql_file, (opt_compatible_mode & 3) ? "%s;\n" : "/*!40101 SET @saved_cs_client = @@character_set_client */;\n" "/*!40101 SET character_set_client = utf8 */;\n" -@@ -3572,6 +3656,27 @@ +@@ -3574,6 +3774,27 @@ goto err; } @@ -173,7 +303,7 @@ { --- /dev/null +++ b/mysql-test/r/percona_mysqldump_innodb_optimize_keys.result -@@ -0,0 +1,109 @@ +@@ -0,0 +1,367 @@ +# +# Test the --innodb-optimize-keys option. +# @@ -247,14 +377,15 @@ + `a` int(11) DEFAULT NULL, + `b` varchar(255) DEFAULT NULL, + `c` decimal(10,3) DEFAULT NULL, -+ PRIMARY KEY (`id`) ++ PRIMARY KEY (`id`), ++ CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t2` (`a`) ON DELETE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES (1,0,'0',0.000),(2,1,'1',1.100),(3,2,'2',2.200); -+ALTER TABLE `t1` ADD UNIQUE KEY `uniq` (`c`,`a`), ADD KEY `b` (`b`), ADD KEY `a` (`a`), ADD CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t2` (`a`) ON DELETE CASCADE; ++ALTER TABLE `t1` ADD UNIQUE KEY `uniq` (`c`,`a`), ADD KEY `b` (`b`), ADD KEY `a` (`a`); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +DROP TABLE IF EXISTS `t2`; @@ -283,49 +414,266 @@ + +###################################### +DROP TABLE t1, t2; ---- a/mysql-test/suite/innodb/r/innodb.result -+++ b/mysql-test/suite/innodb/r/innodb.result -@@ -1673,7 +1673,7 @@ - 71 - SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'; - variable_value - @innodb_rows_inserted_orig --1066 -+1108 - SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'; - variable_value - @innodb_rows_updated_orig - 866 ---- a/mysql-test/suite/innodb/t/innodb-index.test -+++ b/mysql-test/suite/innodb/t/innodb-index.test -@@ -87,6 +87,11 @@ - show create table t1; - --error ER_MULTIPLE_PRI_KEY - alter table t1 add primary key (c); -+# Suppress the error log messages occuring on duplicate key error -+# during ALTER TABLE when using fast index creation -+--disable_query_log -+call mtr.add_suppression("Cannot find index PRIMARY in InnoDB index translation table."); -+--enable_query_log - --error ER_DUP_ENTRY - alter table t1 drop primary key, add primary key (b); - create unique index c on t1 (c); ---- a/mysql-test/suite/innodb/t/innodb.test -+++ b/mysql-test/suite/innodb/t/innodb.test -@@ -21,6 +21,12 @@ - - -- source include/have_innodb.inc - -+# Suppress the error log message occuring on duplicate key error -+# during ALTER TABLE when using fast index creation -+--disable_query_log -+call mtr.add_suppression("Cannot find index v_2 in InnoDB index translation table."); -+--enable_query_log -+ - let $MYSQLD_DATADIR= `select @@datadir`; - - # Save the original values of some variables in order to be able to ++CREATE TABLE t1 ( ++id INT NOT NULL AUTO_INCREMENT, ++KEY (id) ++) ENGINE=InnoDB; ++CREATE TABLE t2 ( ++id INT NOT NULL AUTO_INCREMENT, ++UNIQUE KEY (id) ++) ENGINE=InnoDB; ++INSERT INTO t1 VALUES (), (), (); ++INSERT INTO t2 VALUES (), (), (); ++###################################### ++ ++/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; ++/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; ++/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; ++/*!40101 SET NAMES utf8 */; ++/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; ++/*!40103 SET TIME_ZONE='+00:00' */; ++/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; ++/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; ++/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; ++/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; ++DROP TABLE IF EXISTS `t1`; ++/*!40101 SET @saved_cs_client = @@character_set_client */; ++/*!40101 SET character_set_client = utf8 */; ++CREATE TABLE `t1` ( ++ `id` int(11) NOT NULL AUTO_INCREMENT, ++ KEY `id` (`id`) ++) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; ++/*!40101 SET character_set_client = @saved_cs_client */; ++ ++LOCK TABLES `t1` WRITE; ++/*!40000 ALTER TABLE `t1` DISABLE KEYS */; ++INSERT INTO `t1` VALUES (1),(2),(3); ++/*!40000 ALTER TABLE `t1` ENABLE KEYS */; ++UNLOCK TABLES; ++DROP TABLE IF EXISTS `t2`; ++/*!40101 SET @saved_cs_client = @@character_set_client */; ++/*!40101 SET character_set_client = utf8 */; ++CREATE TABLE `t2` ( ++ `id` int(11) NOT NULL AUTO_INCREMENT, ++ UNIQUE KEY `id` (`id`) ++) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; ++/*!40101 SET character_set_client = @saved_cs_client */; ++ ++LOCK TABLES `t2` WRITE; ++/*!40000 ALTER TABLE `t2` DISABLE KEYS */; ++INSERT INTO `t2` VALUES (1),(2),(3); ++/*!40000 ALTER TABLE `t2` ENABLE KEYS */; ++UNLOCK TABLES; ++/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; ++ ++/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; ++/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; ++/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; ++/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; ++/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; ++/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; ++/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; ++ ++###################################### ++DROP TABLE t1, t2; ++CREATE TABLE t1 ( ++a INT NOT NULL, ++UNIQUE KEY (a)) ENGINE=InnoDB; ++CREATE TABLE t2 ( ++a INT NOT NULL, ++b INT NOT NULL, ++UNIQUE KEY (a,b)) ENGINE=InnoDB; ++CREATE TABLE t3 ( ++a INT, ++b INT, ++UNIQUE KEY (a,b)) ENGINE=InnoDB; ++CREATE TABLE t4 ( ++a INT NOT NULL, ++b INT NOT NULL, ++PRIMARY KEY (a,b), ++UNIQUE KEY(b)) ENGINE=InnoDB; ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE ++TABLE_SCHEMA=DATABASE() AND ++TABLE_NAME='t1' AND ++COLUMN_KEY='PRI'; ++COUNT(*) ++1 ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE ++TABLE_SCHEMA=DATABASE() AND ++TABLE_NAME='t2' AND ++COLUMN_KEY='PRI'; ++COUNT(*) ++2 ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE ++TABLE_SCHEMA=DATABASE() AND ++TABLE_NAME='t3' AND ++COLUMN_KEY='PRI'; ++COUNT(*) ++0 ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE ++TABLE_SCHEMA=DATABASE() AND ++TABLE_NAME='t4' AND ++COLUMN_KEY='PRI'; ++COUNT(*) ++2 ++INSERT INTO t1 VALUES (1), (2), (3); ++INSERT INTO t2 VALUES (1,1), (2,2), (3,3); ++INSERT INTO t3 SELECT * FROM t2; ++INSERT INTO t4 SELECT * FROM t2; ++###################################### ++ ++/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; ++/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; ++/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; ++/*!40101 SET NAMES utf8 */; ++/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; ++/*!40103 SET TIME_ZONE='+00:00' */; ++/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; ++/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; ++/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; ++/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; ++DROP TABLE IF EXISTS `t1`; ++/*!40101 SET @saved_cs_client = @@character_set_client */; ++/*!40101 SET character_set_client = utf8 */; ++CREATE TABLE `t1` ( ++ `a` int(11) NOT NULL, ++ UNIQUE KEY `a` (`a`) ++) ENGINE=InnoDB DEFAULT CHARSET=latin1; ++/*!40101 SET character_set_client = @saved_cs_client */; ++ ++LOCK TABLES `t1` WRITE; ++/*!40000 ALTER TABLE `t1` DISABLE KEYS */; ++INSERT INTO `t1` VALUES (1),(2),(3); ++/*!40000 ALTER TABLE `t1` ENABLE KEYS */; ++UNLOCK TABLES; ++DROP TABLE IF EXISTS `t2`; ++/*!40101 SET @saved_cs_client = @@character_set_client */; ++/*!40101 SET character_set_client = utf8 */; ++CREATE TABLE `t2` ( ++ `a` int(11) NOT NULL, ++ `b` int(11) NOT NULL, ++ UNIQUE KEY `a` (`a`,`b`) ++) ENGINE=InnoDB DEFAULT CHARSET=latin1; ++/*!40101 SET character_set_client = @saved_cs_client */; ++ ++LOCK TABLES `t2` WRITE; ++/*!40000 ALTER TABLE `t2` DISABLE KEYS */; ++INSERT INTO `t2` VALUES (1,1),(2,2),(3,3); ++/*!40000 ALTER TABLE `t2` ENABLE KEYS */; ++UNLOCK TABLES; ++DROP TABLE IF EXISTS `t3`; ++/*!40101 SET @saved_cs_client = @@character_set_client */; ++/*!40101 SET character_set_client = utf8 */; ++CREATE TABLE `t3` ( ++ `a` int(11) DEFAULT NULL, ++ `b` int(11) DEFAULT NULL ++) ENGINE=InnoDB DEFAULT CHARSET=latin1; ++/*!40101 SET character_set_client = @saved_cs_client */; ++ ++LOCK TABLES `t3` WRITE; ++/*!40000 ALTER TABLE `t3` DISABLE KEYS */; ++INSERT INTO `t3` VALUES (1,1),(2,2),(3,3); ++ALTER TABLE `t3` ADD UNIQUE KEY `a` (`a`,`b`); ++/*!40000 ALTER TABLE `t3` ENABLE KEYS */; ++UNLOCK TABLES; ++DROP TABLE IF EXISTS `t4`; ++/*!40101 SET @saved_cs_client = @@character_set_client */; ++/*!40101 SET character_set_client = utf8 */; ++CREATE TABLE `t4` ( ++ `a` int(11) NOT NULL, ++ `b` int(11) NOT NULL, ++ PRIMARY KEY (`a`,`b`) ++) ENGINE=InnoDB DEFAULT CHARSET=latin1; ++/*!40101 SET character_set_client = @saved_cs_client */; ++ ++LOCK TABLES `t4` WRITE; ++/*!40000 ALTER TABLE `t4` DISABLE KEYS */; ++INSERT INTO `t4` VALUES (1,1),(2,2),(3,3); ++ALTER TABLE `t4` ADD UNIQUE KEY `b` (`b`); ++/*!40000 ALTER TABLE `t4` ENABLE KEYS */; ++UNLOCK TABLES; ++/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; ++ ++/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; ++/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; ++/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; ++/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; ++/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; ++/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; ++/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; ++ ++###################################### ++DROP TABLE t1, t2, t3, t4; ++CREATE TABLE t1 ( ++id INT NOT NULL PRIMARY KEY ++) ENGINE=InnoDB; ++CREATE TABLE t2 ( ++id INT NOT NULL AUTO_INCREMENT, ++a INT NOT NULL, ++PRIMARY KEY (id), ++KEY (a), ++FOREIGN KEY (a) REFERENCES t2 (id) ++) ENGINE=InnoDB; ++INSERT INTO t1 VALUES (1), (2), (3); ++INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3); ++###################################### ++ ++/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; ++/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; ++/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; ++/*!40101 SET NAMES utf8 */; ++/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; ++/*!40103 SET TIME_ZONE='+00:00' */; ++/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; ++/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; ++/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; ++/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; ++DROP TABLE IF EXISTS `t1`; ++/*!40101 SET @saved_cs_client = @@character_set_client */; ++/*!40101 SET character_set_client = utf8 */; ++CREATE TABLE `t1` ( ++ `id` int(11) NOT NULL, ++ PRIMARY KEY (`id`) ++) ENGINE=InnoDB DEFAULT CHARSET=latin1; ++/*!40101 SET character_set_client = @saved_cs_client */; ++ ++LOCK TABLES `t1` WRITE; ++/*!40000 ALTER TABLE `t1` DISABLE KEYS */; ++INSERT INTO `t1` VALUES (1),(2),(3); ++/*!40000 ALTER TABLE `t1` ENABLE KEYS */; ++UNLOCK TABLES; ++DROP TABLE IF EXISTS `t2`; ++/*!40101 SET @saved_cs_client = @@character_set_client */; ++/*!40101 SET character_set_client = utf8 */; ++CREATE TABLE `t2` ( ++ `id` int(11) NOT NULL AUTO_INCREMENT, ++ `a` int(11) NOT NULL, ++ PRIMARY KEY (`id`), ++ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t2` (`id`) ++) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1; ++/*!40101 SET character_set_client = @saved_cs_client */; ++ ++LOCK TABLES `t2` WRITE; ++/*!40000 ALTER TABLE `t2` DISABLE KEYS */; ++INSERT INTO `t2` VALUES (1,1),(2,2),(3,3); ++ALTER TABLE `t2` ADD KEY `a` (`a`); ++/*!40000 ALTER TABLE `t2` ENABLE KEYS */; ++UNLOCK TABLES; ++/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; ++ ++/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; ++/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; ++/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; ++/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; ++/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; ++/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; ++/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; ++ ++###################################### ++DROP TABLE t1, t2; --- /dev/null +++ b/mysql-test/t/percona_mysqldump_innodb_optimize_keys.test -@@ -0,0 +1,62 @@ +@@ -0,0 +1,188 @@ +# Embedded server doesn't support external clients +--source include/not_embedded.inc + @@ -356,8 +704,8 @@ +DROP TABLE t1; + + -+# Check that for InnoDB tables secondary and foreign keys are created -+# after the data is dumped ++# Check that for InnoDB tables secondary keys are created after the data is ++# dumped but foreign ones are left in CREATE TABLE + +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES (0), (1), (2); @@ -386,11 +734,137 @@ + +DROP TABLE t1, t2; + ++######################################################################## ++# Bug #812179: AUTO_INCREMENT columns must be skipped by the ++# --innodb-optimize-keys optimization in mysqldump ++######################################################################## ++ ++CREATE TABLE t1 ( ++ id INT NOT NULL AUTO_INCREMENT, ++ KEY (id) ++) ENGINE=InnoDB; ++ ++CREATE TABLE t2 ( ++ id INT NOT NULL AUTO_INCREMENT, ++ UNIQUE KEY (id) ++) ENGINE=InnoDB; ++ ++INSERT INTO t1 VALUES (), (), (); ++INSERT INTO t2 VALUES (), (), (); ++ ++--exec $MYSQL_DUMP --skip-comments --innodb-optimize-keys test t1 t2 >$file ++ ++--echo ###################################### ++--cat_file $file ++--echo ###################################### ++ ++# Check that the resulting dump can be imported back ++ ++--exec $MYSQL test < $file ++ ++--remove_file $file ++ ++DROP TABLE t1, t2; ++ ++######################################################################## ++# Bug #851674: --innodb-optimize-keys does not work correctly with table ++# without PRIMARY KEY ++######################################################################## ++ ++CREATE TABLE t1 ( ++ a INT NOT NULL, ++ UNIQUE KEY (a)) ENGINE=InnoDB; ++ ++CREATE TABLE t2 ( ++ a INT NOT NULL, ++ b INT NOT NULL, ++ UNIQUE KEY (a,b)) ENGINE=InnoDB; ++ ++CREATE TABLE t3 ( ++ a INT, ++ b INT, ++ UNIQUE KEY (a,b)) ENGINE=InnoDB; ++ ++CREATE TABLE t4 ( ++ a INT NOT NULL, ++ b INT NOT NULL, ++ PRIMARY KEY (a,b), ++ UNIQUE KEY(b)) ENGINE=InnoDB; ++ ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE ++ TABLE_SCHEMA=DATABASE() AND ++ TABLE_NAME='t1' AND ++ COLUMN_KEY='PRI'; ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE ++ TABLE_SCHEMA=DATABASE() AND ++ TABLE_NAME='t2' AND ++ COLUMN_KEY='PRI'; ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE ++ TABLE_SCHEMA=DATABASE() AND ++ TABLE_NAME='t3' AND ++ COLUMN_KEY='PRI'; ++SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE ++ TABLE_SCHEMA=DATABASE() AND ++ TABLE_NAME='t4' AND ++ COLUMN_KEY='PRI'; ++ ++INSERT INTO t1 VALUES (1), (2), (3); ++INSERT INTO t2 VALUES (1,1), (2,2), (3,3); ++INSERT INTO t3 SELECT * FROM t2; ++INSERT INTO t4 SELECT * FROM t2; ++ ++--exec $MYSQL_DUMP --skip-comments --innodb-optimize-keys test t1 t2 t3 t4 >$file ++ ++--echo ###################################### ++--cat_file $file ++--echo ###################################### ++ ++# Check that the resulting dump can be imported back ++ ++--exec $MYSQL test < $file ++ ++--remove_file $file ++ ++DROP TABLE t1, t2, t3, t4; ++ ++######################################################################## ++# Bug #859078: --innodb-optimize-keys should ignore foreign keys ++######################################################################## ++ ++CREATE TABLE t1 ( ++ id INT NOT NULL PRIMARY KEY ++) ENGINE=InnoDB; ++ ++CREATE TABLE t2 ( ++ id INT NOT NULL AUTO_INCREMENT, ++ a INT NOT NULL, ++ PRIMARY KEY (id), ++ KEY (a), ++ FOREIGN KEY (a) REFERENCES t2 (id) ++) ENGINE=InnoDB; ++ ++INSERT INTO t1 VALUES (1), (2), (3); ++INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3); ++ ++--exec $MYSQL_DUMP --skip-comments --innodb-optimize-keys test t1 t2 >$file ++ ++--echo ###################################### ++--cat_file $file ++--echo ###################################### ++ ++# Check that the resulting dump can be imported back ++ ++--exec $MYSQL test < $file ++ ++--remove_file $file ++ ++DROP TABLE t1, t2; ++ +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc -@@ -1630,6 +1630,9 @@ +@@ -1632,6 +1632,9 @@ alter_list(rhs.alter_list, mem_root), key_list(rhs.key_list, mem_root), create_list(rhs.create_list, mem_root), @@ -400,7 +874,7 @@ flags(rhs.flags), keys_onoff(rhs.keys_onoff), tablespace_op(rhs.tablespace_op), -@@ -1652,6 +1655,7 @@ +@@ -1654,6 +1657,7 @@ list_copy_and_replace_each_value(alter_list, mem_root); list_copy_and_replace_each_value(key_list, mem_root); list_copy_and_replace_each_value(create_list, mem_root); @@ -410,7 +884,7 @@ --- a/sql/sql_lex.h +++ b/sql/sql_lex.h -@@ -1009,6 +1009,9 @@ +@@ -1013,6 +1013,9 @@ List alter_list; List key_list; List create_list; @@ -420,7 +894,7 @@ uint flags; enum enum_enable_or_disable keys_onoff; enum tablespace_op_type tablespace_op; -@@ -1020,6 +1023,8 @@ +@@ -1024,6 +1027,8 @@ Alter_info() : @@ -429,7 +903,7 @@ flags(0), keys_onoff(LEAVE_AS_IS), tablespace_op(NO_TABLESPACE_OP), -@@ -1035,6 +1040,9 @@ +@@ -1039,6 +1044,9 @@ alter_list.empty(); key_list.empty(); create_list.empty(); @@ -441,24 +915,7 @@ tablespace_op= NO_TABLESPACE_OP; --- a/sql/sql_table.cc +++ b/sql/sql_table.cc -@@ -2776,7 +2776,7 @@ - file The handler for the new table. - key_info_buffer OUT An array of KEY structs for the indexes. - key_count OUT The number of elements in the array. -- select_field_count The number of fields coming from a select table. -+ select_field_count The number of fields coming from a select table. - - DESCRIPTION - Prepares the table and key structures for table creation. -@@ -3122,7 +3122,6 @@ - } - - /* Create keys */ -- - List_iterator key_iterator(alter_info->key_list); - List_iterator key_iterator2(alter_info->key_list); - uint key_parts=0, fk_key_count=0; -@@ -3220,6 +3219,14 @@ +@@ -3220,6 +3220,14 @@ if (!*key_info_buffer || ! key_part_info) DBUG_RETURN(TRUE); // Out of memory @@ -473,7 +930,7 @@ key_iterator.rewind(); key_number=0; for (; (key=key_iterator++) ; key_number++) -@@ -3638,6 +3645,22 @@ +@@ -3638,6 +3646,22 @@ key_info->comment.str= key->key_create_info.comment.str; } @@ -496,7 +953,7 @@ key_info++; } if (!unique_key && !primary_key && -@@ -5256,6 +5279,10 @@ +@@ -5256,6 +5280,10 @@ List new_create_list; /* New key definitions are added here */ List new_key_list; @@ -507,7 +964,7 @@ List_iterator drop_it(alter_info->drop_list); List_iterator def_it(alter_info->create_list); List_iterator alter_it(alter_info->alter_list); -@@ -5268,6 +5295,7 @@ +@@ -5268,6 +5296,7 @@ uint used_fields= create_info->used_fields; KEY *key_info=table->key_info; bool rc= TRUE; @@ -515,7 +972,7 @@ DBUG_ENTER("mysql_prepare_alter_table"); -@@ -5457,7 +5485,23 @@ +@@ -5457,7 +5486,26 @@ /* Collect all keys which isn't in drop list. Add only those for which some fields exists. @@ -525,6 +982,8 @@ + the InnoDB fast index creation. The following conditions must be + met: + ++ - fast_index_creation is enabled for the current session ++ - expand_fast_index_creation is enabled for the current session; + - we are going to create an InnoDB table (this is checked later when the + target engine is known); + - the key most be a non-UNIQUE one; @@ -534,13 +993,14 @@ + key constraints in the table. + */ + -+ skip_secondary= ++ skip_secondary= thd->variables.online_alter_index && ++ thd->variables.expand_fast_index_creation && + !table->file->get_foreign_key_list(thd, &f_key_list) && + f_key_list.elements == 0; for (uint i=0 ; i < table->s->keys ; i++,key_info++) { -@@ -5574,6 +5618,8 @@ +@@ -5574,6 +5622,8 @@ test(key_info->flags & HA_GENERATED_KEY), key_parts); new_key_list.push_back(key); @@ -549,7 +1009,7 @@ } } { -@@ -5581,7 +5627,21 @@ +@@ -5581,7 +5631,21 @@ while ((key=key_it++)) // Add new keys { if (key->type != Key::FOREIGN_KEY) @@ -571,7 +1031,7 @@ if (key->name.str && !my_strcasecmp(system_charset_info, key->name.str, primary_key_name)) { -@@ -5630,12 +5690,104 @@ +@@ -5630,12 +5694,104 @@ rc= FALSE; alter_info->create_list.swap(new_create_list); alter_info->key_list.swap(new_key_list); @@ -676,7 +1136,7 @@ Alter table SYNOPSIS -@@ -6428,19 +6580,38 @@ +@@ -6428,19 +6584,38 @@ */ if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER)) { @@ -715,3 +1175,261 @@ } else { +--- /dev/null ++++ b/mysql-test/r/percona_innodb_expand_fast_index_creation.result +@@ -0,0 +1,64 @@ ++CREATE TABLE t1( ++id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, ++a CHAR(1) NOT NULL, ++b CHAR(36) NOT NULL) ENGINE=InnoDB; ++INSERT INTO t1(a,b) VALUES ('a','b'); ++INSERT INTO t1(a,b) SELECT a,b FROM t1; ++INSERT INTO t1(a,b) SELECT a,b FROM t1; ++INSERT INTO t1(a,b) SELECT a,b FROM t1; ++INSERT INTO t1(a,b) SELECT a,b FROM t1; ++ALTER TABLE t1 ADD KEY (a); ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 ++EXPLAIN SELECT COUNT(*) FROM t1, t1 t2 WHERE t1.a = t2.a AND t1.b = t2.b; ++id 1 ++select_type SIMPLE ++table t1 ++type ALL ++possible_keys a ++key NULL ++key_len NULL ++ref NULL ++rows 16 ++Extra ++id 1 ++select_type SIMPLE ++table t2 ++type ref ++possible_keys a ++key a ++key_len 1 ++ref test.t1.a ++rows 1 ++Extra Using where ++ALTER TABLE t1 DROP KEY a; ++SET expand_fast_index_creation = 1; ++SELECT @@expand_fast_index_creation; ++@@expand_fast_index_creation ++1 ++ALTER TABLE t1 ADD KEY (a); ++affected rows: 0 ++info: Records: 0 Duplicates: 0 Warnings: 0 ++EXPLAIN SELECT COUNT(*) FROM t1, t1 t2 WHERE t1.a = t2.a AND t1.b = t2.b; ++id 1 ++select_type SIMPLE ++table t1 ++type ALL ++possible_keys a ++key NULL ++key_len NULL ++ref NULL ++rows 16 ++Extra ++id 1 ++select_type SIMPLE ++table t2 ++type ALL ++possible_keys a ++key NULL ++key_len NULL ++ref NULL ++rows 16 ++Extra Using where; Using join buffer ++SET expand_fast_index_creation = 0; ++DROP TABLE t1; +--- /dev/null ++++ b/mysql-test/t/percona_innodb_expand_fast_index_creation.test +@@ -0,0 +1,45 @@ ++--source include/have_innodb.inc ++ ++######################################################################## ++# Bug #857590: Fast index creation does not update index statistics ++######################################################################## ++ ++CREATE TABLE t1( ++ id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, ++ a CHAR(1) NOT NULL, ++ b CHAR(36) NOT NULL) ENGINE=InnoDB; ++ ++INSERT INTO t1(a,b) VALUES ('a','b'); ++INSERT INTO t1(a,b) SELECT a,b FROM t1; ++INSERT INTO t1(a,b) SELECT a,b FROM t1; ++INSERT INTO t1(a,b) SELECT a,b FROM t1; ++INSERT INTO t1(a,b) SELECT a,b FROM t1; ++ ++# Check that fast index creation is used ++--enable_info ++ALTER TABLE t1 ADD KEY (a); ++--disable_info ++ ++# The default (wrong) plan due to bogus statistics ++--vertical_results ++EXPLAIN SELECT COUNT(*) FROM t1, t1 t2 WHERE t1.a = t2.a AND t1.b = t2.b; ++--horizontal_results ++ ++ALTER TABLE t1 DROP KEY a; ++ ++SET expand_fast_index_creation = 1; ++SELECT @@expand_fast_index_creation; ++ ++# Check that stats are updated with the option enabled ++ ++--enable_info ++ALTER TABLE t1 ADD KEY (a); ++--disable_info ++ ++--vertical_results ++EXPLAIN SELECT COUNT(*) FROM t1, t1 t2 WHERE t1.a = t2.a AND t1.b = t2.b; ++--horizontal_results ++ ++SET expand_fast_index_creation = 0; ++ ++DROP TABLE t1; +--- a/storage/innobase/row/row0merge.c ++++ b/storage/innobase/row/row0merge.c +@@ -56,6 +56,7 @@ + #include "log0log.h" + #include "ut0sort.h" + #include "handler0alter.h" ++#include "ha_prototypes.h" + + /* Ignore posix_fadvise() on those platforms where it does not exist */ + #if defined __WIN__ +@@ -2673,6 +2674,9 @@ + } + } + ++ if (trx->mysql_thd && thd_expand_fast_index_creation(trx->mysql_thd)) ++ dict_update_statistics(new_table, FALSE, TRUE); ++ + func_exit: + row_merge_file_destroy_low(tmpfd); + +--- a/sql/sql_class.h ++++ b/sql/sql_class.h +@@ -556,6 +556,7 @@ + + double long_query_time_double; + ++ my_bool expand_fast_index_creation; + } SV; + + +--- a/sql/sys_vars.cc ++++ b/sql/sys_vars.cc +@@ -710,6 +710,14 @@ + ON_CHECK(event_scheduler_check), ON_UPDATE(event_scheduler_update)); + #endif + ++static Sys_var_mybool Sys_expand_fast_index_creation( ++ "expand_fast_index_creation", ++ "Enable/disable improvements to the InnoDB fast index creation " ++ "functionality. Has no effect when fast index creation is disabled with " ++ "the fast-index-creation option", ++ SESSION_VAR(expand_fast_index_creation), CMD_LINE(OPT_ARG), ++ DEFAULT(FALSE)); ++ + static Sys_var_ulong Sys_expire_logs_days( + "expire_logs_days", + "If non-zero, binary logs will be purged after expire_logs_days " +--- a/storage/innobase/handler/ha_innodb.cc ++++ b/storage/innobase/handler/ha_innodb.cc +@@ -999,6 +999,19 @@ + return(THDVAR((THD*) thd, flush_log_at_trx_commit)); + } + ++/******************************************************************//** ++Returns true if expand_fast_index_creation is enabled for the current ++session. ++@return the value of the server's expand_fast_index_creation variable */ ++extern "C" UNIV_INTERN ++ibool ++thd_expand_fast_index_creation( ++/*================================*/ ++ void* thd) ++{ ++ return((ibool) (((THD*) thd)->variables.expand_fast_index_creation)); ++} ++ + /********************************************************************//** + Obtain the InnoDB transaction of a MySQL thread. + @return reference to transaction pointer */ +--- a/storage/innobase/include/ha_prototypes.h ++++ b/storage/innobase/include/ha_prototypes.h +@@ -303,4 +303,15 @@ + innobase_get_lower_case_table_names(void); + /*=====================================*/ + ++/******************************************************************//** ++Returns true if innodb_expand_fast_index_creation is enabled for the current ++session. ++@return the value of the server's innodb_expand_fast_index_creation variable */ ++ ++ibool ++thd_expand_fast_index_creation( ++/*==================*/ ++ void* thd); /*!< in: thread handle (THD*) */ ++ ++ + #endif +--- /dev/null ++++ b/mysql-test/suite/sys_vars/r/expand_fast_index_creation_basic.result +@@ -0,0 +1,6 @@ ++SELECT @@global.expand_fast_index_creation; ++@@global.expand_fast_index_creation ++0 ++SELECT @@local.expand_fast_index_creation; ++@@local.expand_fast_index_creation ++0 +--- /dev/null ++++ b/mysql-test/suite/sys_vars/t/expand_fast_index_creation_basic.test +@@ -0,0 +1,2 @@ ++SELECT @@global.expand_fast_index_creation; ++SELECT @@local.expand_fast_index_creation; +--- a/mysql-test/r/mysqld--help-notwin.result ++++ b/mysql-test/r/mysqld--help-notwin.result +@@ -140,6 +140,10 @@ + and DISABLED (keep the event scheduler completely + deactivated, it cannot be activated run-time) + -T, --exit-info[=#] Used for debugging. Use at your own risk. ++ --expand-fast-index-creation ++ Enable/disable improvements to the InnoDB fast index ++ creation functionality. Has no effect when fast index ++ creation is disabled with the fast-index-creation option + --expire-logs-days=# + If non-zero, binary logs will be purged after + expire_logs_days days; possible purges happen at startup +@@ -821,6 +825,7 @@ + div-precision-increment 4 + engine-condition-pushdown TRUE + event-scheduler OFF ++expand-fast-index-creation FALSE + expire-logs-days 0 + external-locking FALSE + flush FALSE +--- a/mysql-test/r/mysqld--help-win.result ++++ b/mysql-test/r/mysqld--help-win.result +@@ -140,6 +140,10 @@ + and DISABLED (keep the event scheduler completely + deactivated, it cannot be activated run-time) + -T, --exit-info[=#] Used for debugging. Use at your own risk. ++ --expand-fast-index-creation ++ Enable/disable improvements to InnoDB fast index creation ++ functionality. Has no effect when fast index creation is ++ disabled with the fast-index-creation option + --expire-logs-days=# + If non-zero, binary logs will be purged after + expire_logs_days days; possible purges happen at startup +@@ -775,6 +779,7 @@ + div-precision-increment 4 + engine-condition-pushdown TRUE + event-scheduler OFF ++expand-fast-index-creation FALSE + expire-logs-days 0 + external-locking FALSE + flush FALSE diff --git a/innodb_expand_import.patch b/innodb_expand_import.patch index ce589e8..e4549ab 100644 --- a/innodb_expand_import.patch +++ b/innodb_expand_import.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c -@@ -837,7 +837,7 @@ +@@ -838,7 +838,7 @@ /**************************************************************//** Creates a new index page (not the root, and also not used in page reorganization). @see btr_page_empty(). */ @@ -16,7 +16,7 @@ void btr_page_create( /*============*/ -@@ -1707,7 +1707,7 @@ +@@ -1712,7 +1712,7 @@ #ifndef UNIV_HOTBACKUP /*************************************************************//** Empties an index page. @see btr_page_create(). */ @@ -25,7 +25,7 @@ void btr_page_empty( /*===========*/ -@@ -2269,7 +2269,7 @@ +@@ -2274,7 +2274,7 @@ /**************************************************************//** Attaches the halves of an index page on the appropriate level in an index tree. */ @@ -865,7 +865,7 @@ #endif /* !UNIV_HOTBACKUP */ --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -7388,6 +7388,14 @@ +@@ -7423,6 +7423,14 @@ err = row_discard_tablespace_for_mysql(dict_table->name, trx); } else { err = row_import_tablespace_for_mysql(dict_table->name, trx); @@ -880,7 +880,7 @@ } err = convert_error_code_to_mysql(err, dict_table->flags, NULL); -@@ -11665,6 +11673,11 @@ +@@ -11772,6 +11780,11 @@ "Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)", NULL, innodb_adaptive_flushing_method_update, 1, &adaptive_flushing_method_typelib); @@ -892,7 +892,7 @@ static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit, PLUGIN_VAR_RQCMDARG, "Limit the allocated memory for dictionary cache. (0: unlimited)", -@@ -11738,6 +11751,7 @@ +@@ -11846,6 +11859,7 @@ MYSQL_SYSVAR(flush_neighbor_pages), MYSQL_SYSVAR(read_ahead), MYSQL_SYSVAR(adaptive_flushing_method), @@ -902,10 +902,10 @@ MYSQL_SYSVAR(use_native_aio), --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h -@@ -219,6 +219,17 @@ +@@ -238,6 +238,17 @@ @return the uncompressed page frame */ - # define btr_page_get(space,zip_size,page_no,mode,mtr) \ - buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,mtr)) + # define btr_page_get(space,zip_size,page_no,mode,idx,mtr) \ + buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,idx,mtr)) +/**************************************************************//** +Sets the index id field of a page. */ +UNIV_INLINE @@ -920,7 +920,7 @@ #endif /* !UNIV_HOTBACKUP */ /**************************************************************//** Gets the index id field of a page. -@@ -256,6 +267,17 @@ +@@ -275,6 +286,17 @@ const page_t* page, /*!< in: index page */ mtr_t* mtr); /*!< in: mini-transaction handle */ /********************************************************//** @@ -938,7 +938,7 @@ Gets the previous index page number. @return prev page number */ UNIV_INLINE -@@ -264,6 +286,17 @@ +@@ -283,6 +305,17 @@ /*==============*/ const page_t* page, /*!< in: index page */ mtr_t* mtr); /*!< in: mini-transaction handle */ @@ -956,7 +956,7 @@ /*************************************************************//** Gets pointer to the previous user record in the tree. It is assumed that the caller has appropriate latches on the page and its neighbor. -@@ -309,6 +342,18 @@ +@@ -328,6 +361,18 @@ /*===========================*/ const rec_t* rec, /*!< in: node pointer record */ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ @@ -975,7 +975,7 @@ /************************************************************//** Creates the root node for a new index tree. @return page number of the created root, FIL_NULL if did not succeed */ -@@ -379,6 +424,17 @@ +@@ -397,6 +442,17 @@ dict_index_t* index, /*!< in: record descriptor */ mtr_t* mtr); /*!< in: mtr */ /*************************************************************//** @@ -993,7 +993,7 @@ Decides if the page should be split at the convergence point of inserts converging to left. @return TRUE if split recommended */ -@@ -437,6 +493,20 @@ +@@ -455,6 +511,20 @@ # define btr_insert_on_non_leaf_level(i,l,t,m) \ btr_insert_on_non_leaf_level_func(i,l,t,__FILE__,__LINE__,m) #endif /* !UNIV_HOTBACKUP */ @@ -1006,7 +1006,7 @@ +/*==================*/ + dict_index_t* index, /*!< in: the index tree */ + buf_block_t* block, /*!< in/out: page to be split */ -+ const rec_t* split_rec, /*!< in: first record on upper ++ rec_t* split_rec, /*!< in: first record on upper + half page */ + buf_block_t* new_block, /*!< in/out: the new half page */ + ulint direction, /*!< in: FSP_UP or FSP_DOWN */ @@ -1016,7 +1016,7 @@ UNIV_INTERN --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -229,6 +229,8 @@ +@@ -234,6 +234,8 @@ extern ulint srv_read_ahead; extern ulint srv_adaptive_flushing_method; @@ -1027,7 +1027,7 @@ --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c -@@ -2546,6 +2546,11 @@ +@@ -2547,6 +2547,11 @@ current_lsn = log_get_lsn(); @@ -1039,7 +1039,7 @@ /* It is possible, though very improbable, that the lsn's in the tablespace to be imported have risen above the current system lsn, if a lengthy purge, ibuf merge, or rollback was performed on a backup -@@ -2657,6 +2662,11 @@ +@@ -2658,6 +2663,11 @@ trx->op_info = ""; @@ -1053,7 +1053,7 @@ --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -416,6 +416,8 @@ +@@ -418,6 +418,8 @@ UNIV_INTERN ulint srv_read_ahead = 3; /* 1: random 2: linear 3: Both */ UNIV_INTERN ulint srv_adaptive_flushing_method = 0; /* 0: native 1: estimate 2: keep_average */ diff --git a/innodb_extend_slow.patch b/innodb_extend_slow.patch index 33e3755..4960386 100644 --- a/innodb_extend_slow.patch +++ b/innodb_extend_slow.patch @@ -48,7 +48,7 @@ /* IMPLEMENTATION OF THE BUFFER POOL -@@ -1930,8 +1964,16 @@ +@@ -1931,8 +1965,16 @@ mutex_t* block_mutex; ibool must_read; unsigned access_time; @@ -65,7 +65,7 @@ buf_pool->stat.n_page_gets++; for (;;) { -@@ -1949,7 +1991,7 @@ +@@ -1950,7 +1992,7 @@ //buf_pool_mutex_exit(buf_pool); rw_lock_s_unlock(&buf_pool->page_hash_latch); @@ -74,7 +74,7 @@ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG ut_a(++buf_dbg_counter % 37 || buf_validate()); -@@ -2045,6 +2087,13 @@ +@@ -2046,6 +2088,13 @@ /* Let us wait until the read operation completes */ @@ -88,7 +88,7 @@ for (;;) { enum buf_io_fix io_fix; -@@ -2059,6 +2108,12 @@ +@@ -2060,6 +2109,12 @@ break; } } @@ -101,7 +101,7 @@ } #ifdef UNIV_IBUF_COUNT_DEBUG -@@ -2374,6 +2429,11 @@ +@@ -2375,6 +2430,11 @@ ibool must_read; ulint retries = 0; mutex_t* block_mutex = NULL; @@ -113,7 +113,7 @@ buf_pool_t* buf_pool = buf_pool_get(space, offset); ut_ad(mtr); -@@ -2403,6 +2463,9 @@ +@@ -2404,6 +2464,9 @@ || ibuf_page_low(space, zip_size, offset, FALSE, file, line, NULL)); #endif @@ -123,16 +123,19 @@ buf_pool->stat.n_page_gets++; fold = buf_page_address_fold(space, offset); loop: -@@ -2473,7 +2536,7 @@ +@@ -2474,9 +2537,9 @@ return(NULL); } - if (buf_read_page(space, zip_size, offset)) { + if (buf_read_page(space, zip_size, offset, trx)) { + buf_read_ahead_random(space, zip_size, offset, +- ibuf_inside(mtr)); ++ ibuf_inside(mtr), trx); + retries = 0; } else if (retries < BUF_PAGE_READ_MAX_RETRIES) { - ++retries; -@@ -2782,6 +2845,13 @@ +@@ -2786,6 +2849,13 @@ /* Let us wait until the read operation completes */ @@ -146,7 +149,7 @@ for (;;) { enum buf_io_fix io_fix; -@@ -2796,6 +2866,12 @@ +@@ -2800,6 +2870,12 @@ break; } } @@ -159,7 +162,7 @@ } fix_type = MTR_MEMO_BUF_FIX; -@@ -2822,13 +2898,17 @@ +@@ -2826,13 +2902,17 @@ read-ahead */ buf_read_ahead_linear(space, zip_size, offset, @@ -178,7 +181,7 @@ return(block); } -@@ -2852,6 +2932,7 @@ +@@ -2856,6 +2936,7 @@ unsigned access_time; ibool success; ulint fix_type; @@ -186,7 +189,7 @@ ut_ad(block); ut_ad(mtr); -@@ -2929,6 +3010,10 @@ +@@ -2933,6 +3014,10 @@ #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG ut_a(block->page.file_page_was_freed == FALSE); #endif @@ -197,7 +200,7 @@ if (UNIV_UNLIKELY(!access_time)) { /* In the case of a first access, try to apply linear read-ahead */ -@@ -2936,7 +3021,7 @@ +@@ -2940,7 +3025,7 @@ buf_read_ahead_linear(buf_block_get_space(block), buf_block_get_zip_size(block), buf_block_get_page_no(block), @@ -206,7 +209,7 @@ } #ifdef UNIV_IBUF_COUNT_DEBUG -@@ -2946,6 +3031,9 @@ +@@ -2950,6 +3035,9 @@ buf_pool = buf_pool_from_block(block); buf_pool->stat.n_page_gets++; @@ -216,7 +219,7 @@ return(TRUE); } -@@ -2968,6 +3056,7 @@ +@@ -2972,6 +3060,7 @@ buf_pool_t* buf_pool; ibool success; ulint fix_type; @@ -224,7 +227,7 @@ ut_ad(mtr); ut_ad(mtr->state == MTR_ACTIVE); -@@ -3054,6 +3143,11 @@ +@@ -3058,6 +3147,11 @@ #endif buf_pool->stat.n_page_gets++; @@ -238,7 +241,7 @@ --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c -@@ -77,7 +77,8 @@ +@@ -79,7 +79,8 @@ treat the tablespace as dropped; this is a timestamp we use to stop dangling page reads from a tablespace which we have DISCARDed + IMPORTed back */ @@ -248,7 +251,7 @@ { buf_page_t* bpage; ulint wake_later; -@@ -179,15 +180,15 @@ +@@ -181,15 +182,15 @@ thd_wait_begin(NULL, THD_WAIT_DISKIO); if (zip_size) { @@ -268,7 +271,27 @@ } thd_wait_end(NULL); ut_a(*err == DB_SUCCESS); -@@ -213,7 +214,8 @@ +@@ -226,8 +227,9 @@ + or 0 */ + ulint offset, /*!< in: page number of a page which + the current thread wants to access */ +- ibool inside_ibuf) /*!< in: TRUE if we are inside ibuf ++ ibool inside_ibuf, /*!< in: TRUE if we are inside ibuf + routine */ ++ trx_t* trx) + { + buf_pool_t* buf_pool = buf_pool_get(space, offset); + ib_int64_t tablespace_version; +@@ -330,7 +332,7 @@ + &err, FALSE, + ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER, + space, zip_size, FALSE, +- tablespace_version, i); ++ tablespace_version, i, trx); + if (err == DB_TABLESPACE_DELETED) { + ut_print_timestamp(stderr); + fprintf(stderr, +@@ -380,7 +382,8 @@ /*==========*/ ulint space, /*!< in: space id */ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ @@ -278,7 +301,7 @@ { buf_pool_t* buf_pool = buf_pool_get(space, offset); ib_int64_t tablespace_version; -@@ -227,7 +229,7 @@ +@@ -394,7 +397,7 @@ count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space, zip_size, FALSE, @@ -287,7 +310,7 @@ srv_buf_pool_reads += count; if (err == DB_TABLESPACE_DELETED) { ut_print_timestamp(stderr); -@@ -279,7 +281,8 @@ +@@ -446,7 +449,8 @@ ulint space, /*!< in: space id */ ulint zip_size, /*!< in: compressed page size in bytes, or 0 */ ulint offset, /*!< in: page number; see NOTE 3 above */ @@ -297,7 +320,7 @@ { buf_pool_t* buf_pool = buf_pool_get(space, offset); ib_int64_t tablespace_version; -@@ -498,7 +501,7 @@ +@@ -665,7 +669,7 @@ count += buf_read_page_low( &err, FALSE, ibuf_mode, @@ -306,7 +329,7 @@ if (err == DB_TABLESPACE_DELETED) { ut_print_timestamp(stderr); fprintf(stderr, -@@ -591,7 +594,7 @@ +@@ -758,7 +762,7 @@ buf_read_page_low(&err, sync && (i + 1 == n_stored), BUF_READ_ANY_PAGE, space_ids[i], zip_size, TRUE, space_versions[i], @@ -315,7 +338,7 @@ if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) { tablespace_deleted: -@@ -733,12 +736,12 @@ +@@ -900,12 +904,12 @@ if ((i + 1 == n_stored) && sync) { buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space, zip_size, TRUE, tablespace_version, @@ -372,7 +395,7 @@ --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -1578,6 +1578,16 @@ +@@ -1584,6 +1584,16 @@ trx->check_unique_secondary = !thd_test_options( thd, OPTION_RELAXED_UNIQUE_CHECKS); @@ -389,7 +412,7 @@ DBUG_VOID_RETURN; } -@@ -1632,6 +1642,32 @@ +@@ -1638,6 +1648,32 @@ return(trx); } @@ -422,7 +445,7 @@ /*********************************************************************//** Note that a transaction has been registered with MySQL. @return true if transaction is registered with MySQL 2PC coordinator */ -@@ -9312,6 +9348,25 @@ +@@ -9409,6 +9445,25 @@ statement has ended */ if (trx->n_mysql_tables_in_use == 0) { @@ -464,11 +487,22 @@ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ - ulint offset);/*!< in: page number */ + ulint offset, /*!< in: page number */ ++ trx_t* trx); + /********************************************************************//** + Applies a random read-ahead in buf_pool if there are at least a threshold + value of accessed pages from the random read-ahead area. Does not read any +@@ -65,8 +67,9 @@ + or 0 */ + ulint offset, /*!< in: page number of a page which + the current thread wants to access */ +- ibool inside_ibuf); /*!< in: TRUE if we are inside ibuf ++ ibool inside_ibuf, /*!< in: TRUE if we are inside ibuf + routine */ + trx_t* trx); /********************************************************************//** Applies linear read-ahead if in the buf_pool the page is a border page of a linear read-ahead area and all the pages in the area have been accessed. -@@ -73,7 +75,8 @@ +@@ -98,7 +101,8 @@ ulint space, /*!< in: space id */ ulint zip_size, /*!< in: compressed page size in bytes, or 0 */ ulint offset, /*!< in: page number; see NOTE 3 above */ @@ -853,7 +887,7 @@ /* The following counter is incremented whenever there is some user activity in the server */ UNIV_INTERN ulint srv_activity_count = 0; -@@ -1232,6 +1235,10 @@ +@@ -1234,6 +1237,10 @@ ibool has_slept = FALSE; srv_conc_slot_t* slot = NULL; ulint i; @@ -864,7 +898,7 @@ #ifdef UNIV_SYNC_DEBUG ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch)); -@@ -1312,6 +1319,7 @@ +@@ -1314,6 +1321,7 @@ switches. */ if (SRV_THREAD_SLEEP_DELAY > 0) { os_thread_sleep(SRV_THREAD_SLEEP_DELAY); @@ -872,7 +906,7 @@ } trx->op_info = ""; -@@ -1371,6 +1379,14 @@ +@@ -1373,6 +1381,14 @@ #ifdef UNIV_SYNC_DEBUG ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch)); #endif /* UNIV_SYNC_DEBUG */ @@ -887,7 +921,7 @@ trx->op_info = "waiting in InnoDB queue"; thd_wait_begin(trx->mysql_thd, THD_WAIT_USER_LOCK); -@@ -1379,6 +1395,12 @@ +@@ -1381,6 +1397,12 @@ trx->op_info = ""; diff --git a/innodb_extra_rseg.patch b/innodb_extra_rseg.patch index 6f77c37..fed745d 100644 --- a/innodb_extra_rseg.patch +++ b/innodb_extra_rseg.patch @@ -7,9 +7,9 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -11545,6 +11545,7 @@ - innobase_system_variables, /* system variables */ - NULL /* reserved */ +@@ -11655,6 +11655,7 @@ + NULL, /* reserved */ + 0, /* flags */ }, +i_s_innodb_rseg, i_s_innodb_trx, @@ -26,7 +26,7 @@ } #define OK(expr) \ -@@ -1779,3 +1781,166 @@ +@@ -1807,3 +1809,166 @@ DBUG_RETURN(0); } diff --git a/innodb_fake_changes.patch b/innodb_fake_changes.patch new file mode 100644 index 0000000..41eb152 --- /dev/null +++ b/innodb_fake_changes.patch @@ -0,0 +1,767 @@ +# name : innodb_fake_changes.patch +# introduced : 5.5.15 +# maintainer : Yasufumi +# +#!!! notice !!! +# Any small change to this file in the main branch +# should be done or reviewed by the maintainer! +--- a/storage/innobase/btr/btr0cur.c ++++ b/storage/innobase/btr/btr0cur.c +@@ -1173,6 +1173,11 @@ + rec_t* rec; + roll_ptr_t roll_ptr; + ++ if (thr && thr_get_trx(thr)->fake_changes) { ++ /* skip LOCK, UNDO */ ++ return(DB_SUCCESS); ++ } ++ + /* Check if we have to wait for a lock: enqueue an explicit lock + request if yes */ + +@@ -1304,7 +1309,7 @@ + } + #endif /* UNIV_DEBUG */ + +- ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); ++ ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); + max_size = page_get_max_insert_size_after_reorganize(page, 1); + leaf = page_is_leaf(page); + +@@ -1399,6 +1404,12 @@ + goto fail_err; + } + ++ if (thr && thr_get_trx(thr)->fake_changes) { ++ /* skip CHANGE, LOG */ ++ *big_rec = big_rec_vec; ++ return(err); /* == DB_SUCCESS */ ++ } ++ + page_cursor = btr_cur_get_page_cur(cursor); + + /* Now, try the insert */ +@@ -1541,10 +1552,10 @@ + + *big_rec = NULL; + +- ut_ad(mtr_memo_contains(mtr, ++ ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, + dict_index_get_lock(btr_cur_get_index(cursor)), + MTR_MEMO_X_LOCK)); +- ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor), ++ ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, btr_cur_get_block(cursor), + MTR_MEMO_PAGE_X_FIX)); + + /* Try first an optimistic insert; reset the cursor flag: we do not +@@ -1610,6 +1621,16 @@ + } + } + ++ if (thr && thr_get_trx(thr)->fake_changes) { ++ /* skip CHANGE, LOG */ ++ if (n_extents > 0) { ++ fil_space_release_free_extents(index->space, ++ n_reserved); ++ } ++ *big_rec = big_rec_vec; ++ return(DB_SUCCESS); ++ } ++ + if (dict_index_get_page(index) + == buf_block_get_page_no(btr_cur_get_block(cursor))) { + +@@ -1666,6 +1687,11 @@ + + ut_ad(cursor && update && thr && roll_ptr); + ++ if (thr && thr_get_trx(thr)->fake_changes) { ++ /* skip LOCK, UNDO */ ++ return(DB_SUCCESS); ++ } ++ + rec = btr_cur_get_rec(cursor); + index = cursor->index; + +@@ -1965,6 +1991,14 @@ + return(err); + } + ++ if (trx->fake_changes) { ++ /* skip CHANGE, LOG */ ++ if (UNIV_LIKELY_NULL(heap)) { ++ mem_heap_free(heap); ++ } ++ return(err); /* == DB_SUCCESS */ ++ } ++ + if (!(flags & BTR_KEEP_SYS_FLAG)) { + row_upd_rec_sys_fields(rec, NULL, + index, offsets, trx, roll_ptr); +@@ -2074,7 +2108,7 @@ + rec = btr_cur_get_rec(cursor); + index = cursor->index; + ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); +- ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); ++ ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); + /* The insert buffer tree should never be updated in place. */ + ut_ad(!dict_index_is_ibuf(index)); + +@@ -2187,6 +2221,11 @@ + goto err_exit; + } + ++ if (thr && thr_get_trx(thr)->fake_changes) { ++ /* skip CHANGE, LOG */ ++ goto err_exit; /* == DB_SUCCESS */ ++ } ++ + /* Ok, we may do the replacement. Store on the page infimum the + explicit locks on rec, before deleting rec (see the comment in + btr_cur_pessimistic_update). */ +@@ -2337,9 +2376,9 @@ + rec = btr_cur_get_rec(cursor); + index = cursor->index; + +- ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index), ++ ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, dict_index_get_lock(index), + MTR_MEMO_X_LOCK)); +- ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); ++ ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); + #ifdef UNIV_ZIP_DEBUG + ut_a(!page_zip || page_zip_validate(page_zip, page)); + #endif /* UNIV_ZIP_DEBUG */ +@@ -2427,6 +2466,9 @@ + + ut_ad(big_rec_vec == NULL); + ++ /* fake_changes should not cause undo. so never reaches here */ ++ ut_ad(!(trx->fake_changes)); ++ + btr_rec_free_updated_extern_fields( + index, rec, page_zip, offsets, update, + trx_is_recv(trx) ? RB_RECOVERY : RB_NORMAL, mtr); +@@ -2461,6 +2503,12 @@ + } + } + ++ if (trx->fake_changes) { ++ /* skip CHANGE, LOG */ ++ err = DB_SUCCESS; ++ goto return_after_reservations; ++ } ++ + /* Store state of explicit locks on rec on the page infimum record, + before deleting rec. The page infimum acts as a dummy carrier of the + locks, taking care also of lock releases, before we can move the locks +@@ -2763,6 +2811,11 @@ + ut_ad(dict_index_is_clust(index)); + ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); + ++ if (thr && thr_get_trx(thr)->fake_changes) { ++ /* skip LOCK, UNDO, CHANGE, LOG */ ++ return(DB_SUCCESS); ++ } ++ + err = lock_clust_rec_modify_check_and_lock(flags, block, + rec, index, offsets, thr); + +@@ -2897,6 +2950,11 @@ + rec_t* rec; + ulint err; + ++ if (thr && thr_get_trx(thr)->fake_changes) { ++ /* skip LOCK, CHANGE, LOG */ ++ return(DB_SUCCESS); ++ } ++ + block = btr_cur_get_block(cursor); + rec = btr_cur_get_rec(cursor); + +--- a/storage/innobase/handler/ha_innodb.cc ++++ b/storage/innobase/handler/ha_innodb.cc +@@ -488,6 +488,12 @@ + " or 2 (write at commit, flush once per second).", + NULL, NULL, 1, 0, 2, 0); + ++static MYSQL_THDVAR_BOOL(fake_changes, PLUGIN_VAR_OPCMDARG, ++ "In the transaction after enabled, UPDATE, INSERT and DELETE only move the cursor to the records " ++ "and do nothing other operations (no changes, no ibuf, no undo, no transaction log) in the transaction. " ++ "This is to cause replication prefetch IO. ATTENTION: the transaction started after enabled is affected.", ++ NULL, NULL, FALSE); ++ + + static handler *innobase_create_handler(handlerton *hton, + TABLE_SHARE *table, +@@ -1689,6 +1695,8 @@ + trx->check_unique_secondary = !thd_test_options( + thd, OPTION_RELAXED_UNIQUE_CHECKS); + ++ trx->fake_changes = THDVAR(thd, fake_changes); ++ + #ifdef EXTENDED_SLOWLOG + if (thd_log_slow_verbosity(thd) & SLOG_V_INNODB) { + trx->take_stats = TRUE; +@@ -3196,6 +3204,11 @@ + trx_search_latch_release_if_reserved(trx); + } + ++ if (trx->fake_changes && (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) { ++ innobase_rollback(hton, thd, all); /* rollback implicitly */ ++ thd->stmt_da->reset_diagnostics_area(); /* because debug assertion code complains, if something left */ ++ DBUG_RETURN(HA_ERR_WRONG_COMMAND); ++ } + /* Transaction is deregistered only in a commit or a rollback. If + it is deregistered we know there cannot be resources to be freed + and we could return immediately. For the time being, we play safe +@@ -7545,6 +7558,12 @@ + + trx = innobase_trx_allocate(thd); + ++ if (trx->fake_changes) { ++ innobase_commit_low(trx); ++ trx_free_for_mysql(trx); ++ DBUG_RETURN(HA_ERR_WRONG_COMMAND); ++ } ++ + /* Latch the InnoDB data dictionary exclusively so that no deadlocks + or lock waits can happen in it during a table create operation. + Drop table etc. do this latching in row0mysql.c. */ +@@ -7765,6 +7784,10 @@ + DBUG_RETURN(HA_ERR_CRASHED); + } + ++ if (prebuilt->trx->fake_changes) { ++ DBUG_RETURN(HA_ERR_WRONG_COMMAND); ++ } ++ + /* Truncate the table in InnoDB */ + + error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); +@@ -7821,6 +7844,12 @@ + + trx = innobase_trx_allocate(thd); + ++ if (trx->fake_changes) { ++ innobase_commit_low(trx); ++ trx_free_for_mysql(trx); ++ DBUG_RETURN(HA_ERR_WRONG_COMMAND); ++ } ++ + name_len = strlen(name); + + ut_a(name_len < 1000); +@@ -7907,6 +7936,12 @@ + trx->mysql_thd = NULL; + #else + trx = innobase_trx_allocate(thd); ++ if (trx->fake_changes) { ++ my_free(namebuf); ++ innobase_commit_low(trx); ++ trx_free_for_mysql(trx); ++ return; /* ignore */ ++ } + #endif + row_drop_database_for_mysql(namebuf, trx); + my_free(namebuf); +@@ -8012,6 +8047,11 @@ + trx_search_latch_release_if_reserved(parent_trx); + + trx = innobase_trx_allocate(thd); ++ if (trx->fake_changes) { ++ innobase_commit_low(trx); ++ trx_free_for_mysql(trx); ++ DBUG_RETURN(HA_ERR_WRONG_COMMAND); ++ } + + error = innobase_rename_table(trx, from, to, TRUE); + +@@ -10872,6 +10912,10 @@ + return(0); + } + ++ if (trx->fake_changes) { ++ return(0); ++ } ++ + thd_get_xid(thd, (MYSQL_XID*) &trx->xid); + + /* Release a possible FIFO ticket and search latch. Since we will +@@ -12420,6 +12464,7 @@ + MYSQL_SYSVAR(rollback_segments), + MYSQL_SYSVAR(corrupt_table_action), + MYSQL_SYSVAR(lazy_drop_table), ++ MYSQL_SYSVAR(fake_changes), + NULL + }; + +--- a/storage/innobase/handler/handler0alter.cc ++++ b/storage/innobase/handler/handler0alter.cc +@@ -695,6 +695,10 @@ + possible adaptive hash latch to avoid deadlocks of threads. */ + trx_search_latch_release_if_reserved(prebuilt->trx); + ++ if (prebuilt->trx->fake_changes) { ++ DBUG_RETURN(HA_ERR_WRONG_COMMAND); ++ } ++ + /* Check if the index name is reserved. */ + if (innobase_index_name_is_reserved(user_thd, key_info, num_of_keys)) { + DBUG_RETURN(-1); +@@ -732,6 +736,13 @@ + /* Create a background transaction for the operations on + the data dictionary tables. */ + trx = innobase_trx_allocate(user_thd); ++ if (trx->fake_changes) { ++ mem_heap_free(heap); ++ trx_general_rollback_for_mysql(trx, NULL); ++ trx_free_for_mysql(trx); ++ DBUG_RETURN(HA_ERR_WRONG_COMMAND); ++ } ++ + trx_start_if_not_started(trx); + + /* Create table containing all indexes to be built in this +@@ -1092,6 +1103,10 @@ + trx_search_latch_release_if_reserved(prebuilt->trx); + trx = prebuilt->trx; + ++ if (trx->fake_changes) { ++ DBUG_RETURN(HA_ERR_WRONG_COMMAND); ++ } ++ + /* Test and mark all the indexes to be dropped */ + + row_mysql_lock_data_dictionary(trx); +@@ -1296,6 +1311,12 @@ + /* Create a background transaction for the operations on + the data dictionary tables. */ + trx = innobase_trx_allocate(user_thd); ++ if (trx->fake_changes) { ++ trx_general_rollback_for_mysql(trx, NULL); ++ trx_free_for_mysql(trx); ++ DBUG_RETURN(HA_ERR_WRONG_COMMAND); ++ } ++ + trx_start_if_not_started(trx); + + /* Flag this transaction as a dictionary operation, so that +--- a/storage/innobase/ibuf/ibuf0ibuf.c ++++ b/storage/innobase/ibuf/ibuf0ibuf.c +@@ -3496,6 +3496,8 @@ + + ut_a(trx_sys_multiple_tablespace_format); + ++ ut_ad(!(thr_get_trx(thr)->fake_changes)); ++ + do_merge = FALSE; + + /* Perform dirty reads of ibuf->size and ibuf->max_size, to +--- a/storage/innobase/include/trx0trx.h ++++ b/storage/innobase/include/trx0trx.h +@@ -512,6 +512,7 @@ + FALSE, one can save CPU time and about + 150 bytes in the undo log size as then + we skip XA steps */ ++ ulint fake_changes; + ulint flush_log_later;/* In 2PC, we hold the + prepare_commit mutex across + both phases. In that case, we +--- a/storage/innobase/lock/lock0lock.c ++++ b/storage/innobase/lock/lock0lock.c +@@ -3912,6 +3912,10 @@ + + trx = thr_get_trx(thr); + ++ if (trx->fake_changes && mode == LOCK_IX) { ++ mode = LOCK_IS; ++ } ++ + lock_mutex_enter_kernel(); + + /* Look for stronger locks the same trx already has on the table */ +@@ -5114,6 +5118,11 @@ + } + + trx = thr_get_trx(thr); ++ ++ if (trx->fake_changes) { ++ return(DB_SUCCESS); ++ } ++ + next_rec = page_rec_get_next_const(rec); + next_rec_heap_no = page_rec_get_heap_no(next_rec); + +@@ -5282,6 +5291,10 @@ + return(DB_SUCCESS); + } + ++ if (thr && thr_get_trx(thr)->fake_changes) { ++ return(DB_SUCCESS); ++ } ++ + heap_no = rec_offs_comp(offsets) + ? rec_get_heap_no_new(rec) + : rec_get_heap_no_old(rec); +@@ -5340,6 +5353,10 @@ + return(DB_SUCCESS); + } + ++ if (thr && thr_get_trx(thr)->fake_changes) { ++ return(DB_SUCCESS); ++ } ++ + heap_no = page_rec_get_heap_no(rec); + + /* Another transaction cannot have an implicit lock on the record, +@@ -5427,6 +5444,10 @@ + return(DB_SUCCESS); + } + ++ if (thr && thr_get_trx(thr)->fake_changes && mode == LOCK_X) { ++ mode = LOCK_S; ++ } ++ + heap_no = page_rec_get_heap_no(rec); + + lock_mutex_enter_kernel(); +@@ -5503,6 +5524,10 @@ + return(DB_SUCCESS); + } + ++ if (thr && thr_get_trx(thr)->fake_changes && mode == LOCK_X) { ++ mode = LOCK_S; ++ } ++ + heap_no = page_rec_get_heap_no(rec); + + lock_mutex_enter_kernel(); +--- a/storage/innobase/que/que0que.c ++++ b/storage/innobase/que/que0que.c +@@ -1417,6 +1417,12 @@ + + ut_a(trx->error_state == DB_SUCCESS); + ++ if (trx->fake_changes) { ++ /* fake_changes should not access to system tables */ ++ fprintf(stderr, "InnoDB: ERROR: innodb_fake_changes tried to access to system tables.\n"); ++ return(DB_ERROR); ++ } ++ + if (reserve_dict_mutex) { + mutex_enter(&dict_sys->mutex); + } +--- a/storage/innobase/row/row0ins.c ++++ b/storage/innobase/row/row0ins.c +@@ -1502,6 +1502,11 @@ + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } ++ ++ if (trx->fake_changes) { ++ err = DB_SUCCESS; ++ } ++ + return(err); + } + +@@ -2007,7 +2012,7 @@ + } + + btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, +- search_mode, ++ thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : search_mode, + &cursor, 0, __FILE__, __LINE__, &mtr); + + if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) { +@@ -2067,7 +2072,7 @@ + + btr_cur_search_to_nth_level(index, 0, entry, + PAGE_CUR_LE, +- mode | BTR_INSERT, ++ thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : (mode | BTR_INSERT), + &cursor, 0, + __FILE__, __LINE__, &mtr); + } +@@ -2121,6 +2126,22 @@ + if (UNIV_LIKELY_NULL(big_rec)) { + rec_t* rec; + ulint* offsets; ++ ++ if (thr_get_trx(thr)->fake_changes) { ++ /* skip store extern */ ++ if (modify) { ++ dtuple_big_rec_free(big_rec); ++ } else { ++ dtuple_convert_back_big_rec(index, entry, big_rec); ++ } ++ ++ if (UNIV_LIKELY_NULL(heap)) { ++ mem_heap_free(heap); ++ } ++ ++ return(err); ++ } ++ + mtr_start(&mtr); + + btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, +--- a/storage/innobase/row/row0mysql.c ++++ b/storage/innobase/row/row0mysql.c +@@ -1246,6 +1246,7 @@ + prebuilt->table->stat_n_rows--; + } + ++ if (!(trx->fake_changes)) + row_update_statistics_if_needed(prebuilt->table); + trx->op_info = ""; + +@@ -1505,6 +1506,7 @@ + that changes indexed columns, UPDATEs that change only non-indexed + columns would not affect statistics. */ + if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { ++ if (!(trx->fake_changes)) + row_update_statistics_if_needed(prebuilt->table); + } + +@@ -1722,6 +1724,7 @@ + srv_n_rows_updated++; + } + ++ if (!(trx->fake_changes)) + row_update_statistics_if_needed(table); + + return(err); +--- a/storage/innobase/row/row0upd.c ++++ b/storage/innobase/row/row0upd.c +@@ -1603,7 +1603,8 @@ + mode |= BTR_DELETE_MARK; + } + +- search_result = row_search_index_entry(index, entry, mode, ++ search_result = row_search_index_entry(index, entry, ++ trx->fake_changes ? BTR_SEARCH_LEAF : mode, + &pcur, &mtr); + + btr_cur = btr_pcur_get_btr_cur(&pcur); +@@ -1850,9 +1851,11 @@ + the previous invocation of this function. Mark the + off-page columns in the entry inherited. */ + ++ if (!(trx->fake_changes)) { + change_ownership = row_upd_clust_rec_by_insert_inherit( + NULL, NULL, entry, node->update); + ut_a(change_ownership); ++ } + /* fall through */ + case UPD_NODE_INSERT_CLUSTERED: + /* A lock wait occurred in row_ins_index_entry() in +@@ -1882,7 +1885,7 @@ + delete-marked old record, mark them disowned by the + old record and owned by the new entry. */ + +- if (rec_offs_any_extern(offsets)) { ++ if (rec_offs_any_extern(offsets) && !(trx->fake_changes)) { + change_ownership = row_upd_clust_rec_by_insert_inherit( + rec, offsets, entry, node->update); + +@@ -2012,7 +2015,8 @@ + the same transaction do not modify the record in the meantime. + Therefore we can assert that the restoration of the cursor succeeds. */ + +- ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr)); ++ ut_a(btr_pcur_restore_position(thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : BTR_MODIFY_TREE, ++ pcur, mtr)); + + ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur), + dict_table_is_comp(index->table))); +@@ -2022,7 +2026,8 @@ + node->cmpl_info, thr, mtr); + mtr_commit(mtr); + +- if (err == DB_SUCCESS && big_rec) { ++ /* skip store extern for fake_changes */ ++ if (err == DB_SUCCESS && big_rec && !(thr_get_trx(thr)->fake_changes)) { + ulint offsets_[REC_OFFS_NORMAL_SIZE]; + rec_t* rec; + rec_offs_init(offsets_); +@@ -2146,7 +2151,8 @@ + + ut_a(pcur->rel_pos == BTR_PCUR_ON); + +- success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr); ++ success = btr_pcur_restore_position(thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : BTR_MODIFY_LEAF, ++ pcur, mtr); + + if (!success) { + err = DB_RECORD_NOT_FOUND; +--- a/storage/innobase/trx/trx0trx.c ++++ b/storage/innobase/trx/trx0trx.c +@@ -121,6 +121,8 @@ + + trx->support_xa = TRUE; + ++ trx->fake_changes = FALSE; ++ + trx->check_foreigns = TRUE; + trx->check_unique_secondary = TRUE; + +--- /dev/null ++++ b/mysql-test/r/percona_innodb_fake_changes.result +@@ -0,0 +1,55 @@ ++DROP TABLE IF EXISTS t1; ++# Checking variables ++SHOW VARIABLES LIKE 'innodb_fake_changes'; ++Variable_name Value ++innodb_fake_changes OFF ++SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes'; ++VARIABLE_VALUE ++OFF ++SET innodb_fake_changes=1; ++SHOW VARIABLES LIKE 'innodb_fake_changes'; ++Variable_name Value ++innodb_fake_changes ON ++SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes'; ++VARIABLE_VALUE ++ON ++SET innodb_fake_changes=default; ++SHOW VARIABLES LIKE 'innodb_fake_changes'; ++Variable_name Value ++innodb_fake_changes OFF ++SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes'; ++VARIABLE_VALUE ++OFF ++# Explicit COMMIT should fail when innodb_fake_changes is enabled ++# DML should be fine ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++INSERT INTO t1 VALUES (1); ++SET autocommit=0; ++SET innodb_fake_changes=1; ++BEGIN; ++INSERT INTO t1 VALUES (2); ++UPDATE t1 SET a=0; ++DELETE FROM t1 LIMIT 1; ++SELECT * FROM t1; ++a ++1 ++COMMIT; ++ERROR HY000: Got error 131 during COMMIT ++SET innodb_fake_changes=default; ++DROP TABLE t1; ++# DDL must result in error ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++SET autocommit=0; ++SET innodb_fake_changes=1; ++BEGIN; ++CREATE TABLE t2 (a INT) ENGINE=InnoDB; ++ERROR HY000: Can't create table 'test.t2' (errno: 131) ++DROP TABLE t1; ++ERROR 42S02: Unknown table 't1' ++TRUNCATE TABLE t1; ++ERROR HY000: Got error 131 during COMMIT ++ALTER TABLE t1 ENGINE=MyISAM; ++ERROR HY000: Got error 131 during COMMIT ++ROLLBACK; ++SET innodb_fake_changes=default; ++DROP TABLE t1; +--- /dev/null ++++ b/mysql-test/r/percona_innodb_fake_changes_locks.result +@@ -0,0 +1,19 @@ ++DROP TABLE IF EXISTS t1; ++# Verifying that X_LOCK not acquired ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++INSERT INTO t1 VALUES (1); ++SET autocommit=0; ++SET innodb_fake_changes=1; ++BEGIN; ++SELECT * FROM t1 FOR UPDATE; ++a ++1 ++SET innodb_lock_wait_timeout=3; ++UPDATE t1 SET a=2; ++ERROR HY000: Lock wait timeout exceeded; try restarting transaction ++SELECT * FROM t1 LOCK IN SHARE MODE; ++a ++1 ++ROLLBACK; ++SET innodb_fake_changes=default; ++DROP TABLE t1; +--- /dev/null ++++ b/mysql-test/t/percona_innodb_fake_changes.test +@@ -0,0 +1,49 @@ ++--source include/have_innodb.inc ++ ++--disable_warnings ++DROP TABLE IF EXISTS t1; ++--enable_warnings ++ ++ ++--echo # Checking variables ++SHOW VARIABLES LIKE 'innodb_fake_changes'; ++SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes'; ++SET innodb_fake_changes=1; ++SHOW VARIABLES LIKE 'innodb_fake_changes'; ++SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes'; ++SET innodb_fake_changes=default; ++SHOW VARIABLES LIKE 'innodb_fake_changes'; ++SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='innodb_fake_changes'; ++ ++--echo # Explicit COMMIT should fail when innodb_fake_changes is enabled ++--echo # DML should be fine ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++INSERT INTO t1 VALUES (1); ++SET autocommit=0; ++SET innodb_fake_changes=1; ++BEGIN; ++INSERT INTO t1 VALUES (2); ++UPDATE t1 SET a=0; ++DELETE FROM t1 LIMIT 1; ++SELECT * FROM t1; ++--error 1180 ++COMMIT; ++SET innodb_fake_changes=default; ++DROP TABLE t1; ++ ++--echo # DDL must result in error ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++SET autocommit=0; ++SET innodb_fake_changes=1; ++BEGIN; ++--error 1005 ++CREATE TABLE t2 (a INT) ENGINE=InnoDB; ++--error 1051 ++DROP TABLE t1; ++--error 1180 ++TRUNCATE TABLE t1; ++--error 1180 ++ALTER TABLE t1 ENGINE=MyISAM; ++ROLLBACK; ++SET innodb_fake_changes=default; ++DROP TABLE t1; +--- /dev/null ++++ b/mysql-test/t/percona_innodb_fake_changes_locks.test +@@ -0,0 +1,24 @@ ++--source include/have_innodb.inc ++ ++--disable_warnings ++DROP TABLE IF EXISTS t1; ++--enable_warnings ++ ++--echo # Verifying that X_LOCK not acquired ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++INSERT INTO t1 VALUES (1); ++--connect (conn1,localhost,root,,) ++--connection conn1 ++SET autocommit=0; ++SET innodb_fake_changes=1; ++BEGIN; ++SELECT * FROM t1 FOR UPDATE; ++--connection default ++SET innodb_lock_wait_timeout=3; ++--error 1205 ++UPDATE t1 SET a=2; ++SELECT * FROM t1 LOCK IN SHARE MODE; ++--connection conn1 ++ROLLBACK; ++SET innodb_fake_changes=default; ++DROP TABLE t1; diff --git a/innodb_fast_checksum.patch b/innodb_fast_checksum.patch index b935388..382c401 100644 --- a/innodb_fast_checksum.patch +++ b/innodb_fast_checksum.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c -@@ -511,6 +511,27 @@ +@@ -512,6 +512,27 @@ return(checksum); } @@ -35,7 +35,7 @@ /********************************************************************//** In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only looked at the first few bytes of the page. This calculates that old -@@ -627,9 +648,21 @@ +@@ -628,9 +649,21 @@ /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id (always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */ @@ -58,7 +58,7 @@ != buf_calc_page_new_checksum(read_buf)) { return(TRUE); -@@ -653,6 +686,7 @@ +@@ -654,6 +687,7 @@ dict_index_t* index; #endif /* !UNIV_HOTBACKUP */ ulint checksum; @@ -66,7 +66,7 @@ ulint old_checksum; ulint size = zip_size; -@@ -739,12 +773,14 @@ +@@ -740,12 +774,14 @@ checksum = srv_use_checksums ? buf_calc_page_new_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC; @@ -82,7 +82,7 @@ " checksum %lu\n" "InnoDB: stored checksum %lu, prior-to-4.0.14-form" " stored checksum %lu\n" -@@ -753,7 +789,7 @@ +@@ -754,7 +790,7 @@ "InnoDB: Page number (if stored to page already) %lu,\n" "InnoDB: space id (if created with >= MySQL-4.1.1" " and stored already) %lu\n", @@ -153,15 +153,15 @@ static my_bool innobase_recovery_stats = TRUE; static my_bool innobase_locks_unsafe_for_binlog = FALSE; static my_bool innobase_overwrite_relay_log_info = FALSE; -@@ -2625,6 +2626,7 @@ +@@ -2656,6 +2657,7 @@ srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite; srv_use_checksums = (ibool) innobase_use_checksums; + srv_fast_checksum = (ibool) innobase_fast_checksum; - #ifdef HAVE_LARGE_PAGES - if ((os_use_large_pages = (ibool) my_use_large_pages)) -@@ -11432,6 +11434,15 @@ + srv_blocking_lru_restore = (ibool) innobase_blocking_lru_restore; + +@@ -11533,6 +11535,15 @@ "Disable with --skip-innodb-checksums.", NULL, NULL, TRUE); @@ -177,7 +177,7 @@ static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir, PLUGIN_VAR_READONLY, "The common part for InnoDB table spaces.", -@@ -11946,6 +11957,7 @@ +@@ -12064,6 +12075,7 @@ MYSQL_SYSVAR(buffer_pool_size), MYSQL_SYSVAR(buffer_pool_instances), MYSQL_SYSVAR(checksums), @@ -187,7 +187,7 @@ MYSQL_SYSVAR(data_file_path), --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h -@@ -643,6 +643,11 @@ +@@ -634,6 +634,11 @@ buf_calc_page_new_checksum( /*=======================*/ const byte* page); /*!< in: buffer page */ @@ -211,7 +211,7 @@ #define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /*!< the low 4 bytes of this are used --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -224,6 +224,7 @@ +@@ -229,6 +229,7 @@ extern ibool srv_use_doublewrite_buf; extern ibool srv_use_checksums; @@ -268,7 +268,7 @@ +} --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -414,6 +414,7 @@ +@@ -419,6 +419,7 @@ UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE; UNIV_INTERN ibool srv_use_checksums = TRUE; diff --git a/innodb_files_extend.patch b/innodb_files_extend.patch index ba531fe..dde4b9d 100644 --- a/innodb_files_extend.patch +++ b/innodb_files_extend.patch @@ -109,7 +109,7 @@ static my_bool innobase_thread_concurrency_timer_based; static long long innobase_buffer_pool_size, innobase_log_file_size; -@@ -2321,6 +2324,65 @@ +@@ -2352,6 +2355,65 @@ } #endif /* DBUG_OFF */ @@ -175,7 +175,7 @@ #ifndef MYSQL_SERVER innodb_overwrite_relay_log_info = FALSE; #endif -@@ -7252,9 +7314,9 @@ +@@ -7291,9 +7353,9 @@ | DICT_TF_COMPACT | DICT_TF_FORMAT_ZIP << DICT_TF_FORMAT_SHIFT; @@ -188,7 +188,7 @@ } } -@@ -11443,6 +11505,16 @@ +@@ -11544,6 +11606,16 @@ "#### Attention: The checksum is not compatible for normal or disabled version! ####", NULL, NULL, FALSE); @@ -205,7 +205,7 @@ static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir, PLUGIN_VAR_READONLY, "The common part for InnoDB table spaces.", -@@ -11952,6 +12024,8 @@ +@@ -12070,6 +12142,8 @@ NULL, NULL, 0, &corrupt_table_action_typelib); static struct st_mysql_sys_var* innobase_system_variables[]= { @@ -216,7 +216,7 @@ MYSQL_SYSVAR(buffer_pool_size), --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h -@@ -1722,7 +1722,7 @@ +@@ -1715,7 +1715,7 @@ time_t last_printout_time; /*!< when buf_print_io was last time called */ @@ -225,7 +225,7 @@ /*!< Statistics of buddy system, indexed by block size */ buf_pool_stat_t stat; /*!< current statistics */ -@@ -1820,7 +1820,7 @@ +@@ -1813,7 +1813,7 @@ UT_LIST_BASE_NODE_T(buf_page_t) zip_clean; /*!< unmodified compressed pages */ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ @@ -234,7 +234,7 @@ /*!< buddy free lists */ buf_page_t watch[BUF_POOL_WATCH_SIZE]; -@@ -1828,9 +1828,9 @@ +@@ -1821,9 +1821,9 @@ pool watches. Protected by buf_pool->mutex. */ @@ -358,7 +358,7 @@ #define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000) --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i -@@ -310,9 +310,13 @@ +@@ -313,9 +313,13 @@ */ /* The 2-logarithm of UNIV_PAGE_SIZE: */ @@ -374,7 +374,7 @@ /* Maximum number of parallel threads in a parallelized operation */ #define UNIV_MAX_PARALLELISM 32 -@@ -431,7 +435,7 @@ +@@ -434,7 +438,7 @@ stored part of the field in the tablespace. The length field then contains the sum of the following flag and the locally stored len. */ @@ -383,7 +383,7 @@ /* Some macros to improve branch prediction and reduce cache misses */ #if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER) -@@ -534,4 +538,6 @@ +@@ -537,4 +541,6 @@ UNIV_MEM_ALLOC(addr, size); \ } while (0) @@ -521,10 +521,11 @@ --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -234,6 +234,13 @@ - UNIV_INTERN ulint srv_n_read_io_threads = ULINT_MAX; - UNIV_INTERN ulint srv_n_write_io_threads = ULINT_MAX; +@@ -236,6 +236,14 @@ + /* Switch to enable random read ahead. */ + UNIV_INTERN my_bool srv_random_read_ahead = FALSE; ++ +/* The universal page size of the database */ +UNIV_INTERN ulint srv_page_size_shift = 0; +UNIV_INTERN ulint srv_page_size = 0; @@ -537,7 +538,7 @@ readahead request. */ --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c -@@ -1561,11 +1561,13 @@ +@@ -1562,11 +1562,13 @@ } #endif /* UNIV_LOG_ARCHIVE */ @@ -553,7 +554,7 @@ return(DB_ERROR); } -@@ -1574,7 +1576,7 @@ +@@ -1575,7 +1577,7 @@ for (i = 0; i < srv_n_data_files; i++) { #ifndef __WIN__ diff --git a/innodb_fix_misc.patch b/innodb_fix_misc.patch index 794ed60..981ea10 100644 --- a/innodb_fix_misc.patch +++ b/innodb_fix_misc.patch @@ -12,7 +12,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c -@@ -2040,6 +2040,27 @@ +@@ -2041,6 +2041,27 @@ #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ } @@ -40,7 +40,7 @@ if (UNIV_UNLIKELY(!bpage->zip.data)) { /* There is no compressed page. */ err_exit: -@@ -2549,6 +2570,27 @@ +@@ -2550,6 +2571,27 @@ block = (buf_block_t*) buf_page_hash_get_low( buf_pool, space, offset, fold); if (block) { @@ -68,7 +68,7 @@ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block); ut_a(block_mutex); } -@@ -3467,11 +3509,28 @@ +@@ -3472,11 +3514,28 @@ fold = buf_page_address_fold(space, offset); @@ -97,7 +97,7 @@ if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) { /* The page is already in the buffer pool. */ watch_page = NULL; -@@ -3602,6 +3661,7 @@ +@@ -3607,6 +3666,7 @@ bpage->state = BUF_BLOCK_ZIP_PAGE; bpage->space = space; bpage->offset = offset; @@ -105,7 +105,7 @@ #ifdef UNIV_DEBUG bpage->in_page_hash = FALSE; -@@ -3686,6 +3746,7 @@ +@@ -3691,6 +3751,7 @@ fold = buf_page_address_fold(space, offset); @@ -113,7 +113,7 @@ //buf_pool_mutex_enter(buf_pool); mutex_enter(&buf_pool->LRU_list_mutex); rw_lock_x_lock(&buf_pool->page_hash_latch); -@@ -3693,6 +3754,21 @@ +@@ -3698,6 +3759,21 @@ block = (buf_block_t*) buf_page_hash_get_low( buf_pool, space, offset, fold); @@ -135,7 +135,7 @@ if (block && buf_page_in_file(&block->page) && !buf_pool_watch_is_sentinel(buf_pool, &block->page)) { -@@ -3984,8 +4060,11 @@ +@@ -4051,8 +4127,11 @@ } if (io_type == BUF_IO_WRITE @@ -452,7 +452,7 @@ ut_a(ret); --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -12023,6 +12023,12 @@ +@@ -12141,6 +12141,12 @@ "except for the deletion.", NULL, NULL, 0, &corrupt_table_action_typelib); @@ -465,7 +465,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(page_size), MYSQL_SYSVAR(log_block_size), -@@ -12114,6 +12120,7 @@ +@@ -12235,6 +12241,7 @@ MYSQL_SYSVAR(purge_batch_size), MYSQL_SYSVAR(rollback_segments), MYSQL_SYSVAR(corrupt_table_action), @@ -473,7 +473,7 @@ NULL }; -@@ -12123,7 +12130,7 @@ +@@ -12244,7 +12251,7 @@ &innobase_storage_engine, innobase_hton_name, plugin_author, @@ -484,7 +484,7 @@ NULL, /* Plugin Deinit */ --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h -@@ -1477,6 +1477,7 @@ +@@ -1468,6 +1468,7 @@ 0 if the block was never accessed in the buffer pool */ /* @} */ @@ -494,7 +494,7 @@ ibool file_page_was_freed; --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic -@@ -408,6 +408,7 @@ +@@ -426,6 +426,7 @@ buf_block_set_state(block, BUF_BLOCK_FILE_PAGE); block->page.space = space; block->page.offset = page_no; @@ -612,7 +612,7 @@ --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -244,6 +244,8 @@ +@@ -249,6 +249,8 @@ extern ulint srv_pass_corrupt_table; extern ulint srv_dict_size_limit; @@ -623,17 +623,17 @@ extern ulint srv_n_rows_inserted; --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h -@@ -693,6 +693,7 @@ +@@ -690,6 +690,7 @@ #define SYNC_BUF_POOL 150 /* Buffer pool mutex */ #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */ #define SYNC_DOUBLEWRITE 140 +#define SYNC_OUTER_ANY_LATCH 136 #define SYNC_ANY_LATCH 135 - #define SYNC_THR_LOCAL 133 #define SYNC_MEM_HASH 131 + #define SYNC_MEM_POOL 130 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i -@@ -52,6 +52,11 @@ +@@ -53,6 +53,11 @@ #define INNODB_VERSION_MINOR 1 #define INNODB_VERSION_BUGFIX 8 @@ -645,7 +645,7 @@ /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; calculated in make_version_string() in sql/sql_show.cc like this: -@@ -64,7 +69,8 @@ +@@ -65,7 +70,8 @@ #define INNODB_VERSION_STR \ IB_TO_STR(INNODB_VERSION_MAJOR) "." \ IB_TO_STR(INNODB_VERSION_MINOR) "." \ @@ -764,7 +764,7 @@ /** Provide optional 4.x backwards compatibility for 5.0 and above */ UNIV_INTERN ibool row_rollback_on_timeout = FALSE; -@@ -1191,6 +1192,13 @@ +@@ -1192,6 +1193,13 @@ thr = que_fork_get_first_thr(prebuilt->ins_graph); @@ -778,7 +778,7 @@ if (prebuilt->sql_stat_start) { node->state = INS_NODE_SET_IX_LOCK; prebuilt->sql_stat_start = FALSE; -@@ -2575,10 +2583,29 @@ +@@ -2576,10 +2584,29 @@ err = DB_ERROR; } else { @@ -808,7 +808,7 @@ } } -@@ -2927,6 +2954,19 @@ +@@ -2928,6 +2955,19 @@ table->space = space; index = dict_table_get_first_index(table); do { @@ -830,7 +830,7 @@ } while (index); --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c -@@ -3367,6 +3367,7 @@ +@@ -3418,6 +3418,7 @@ ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; ibool table_lock_waited = FALSE; @@ -838,7 +838,7 @@ rec_offs_init(offsets_); -@@ -3738,6 +3739,17 @@ +@@ -3796,6 +3797,17 @@ /* Do some start-of-statement preparations */ @@ -856,7 +856,7 @@ if (!prebuilt->sql_stat_start) { /* No need to set an intention lock or assign a read view */ -@@ -3748,6 +3760,18 @@ +@@ -3806,6 +3818,18 @@ " perform a consistent read\n" "InnoDB: but the read view is not assigned!\n", stderr); @@ -877,7 +877,7 @@ ut_error; --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -441,6 +441,8 @@ +@@ -447,6 +447,8 @@ UNIV_INTERN ulint srv_pass_corrupt_table = 0; /* 0:disable 1:enable */ UNIV_INTERN ulint srv_dict_size_limit = 0; @@ -888,7 +888,7 @@ UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500; --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c -@@ -2161,7 +2161,7 @@ +@@ -2167,7 +2167,7 @@ if (srv_print_verbose_log) { ut_print_timestamp(stderr); fprintf(stderr, @@ -899,9 +899,9 @@ } --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c -@@ -1225,6 +1225,7 @@ +@@ -1219,6 +1219,7 @@ + case SYNC_LOG: case SYNC_LOG_FLUSH_ORDER: - case SYNC_THR_LOCAL: case SYNC_ANY_LATCH: + case SYNC_OUTER_ANY_LATCH: case SYNC_FILE_FORMAT_TAG: diff --git a/innodb_io_patches.patch b/innodb_io_patches.patch index 9f57852..8ffa03c 100644 --- a/innodb_io_patches.patch +++ b/innodb_io_patches.patch @@ -45,8 +45,8 @@ --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c -@@ -260,6 +260,10 @@ - = BUF_READ_AHEAD_LINEAR_AREA(buf_pool); +@@ -427,6 +427,10 @@ + = BUF_READ_AHEAD_AREA(buf_pool); ulint threshold; + if (!(srv_read_ahead & 2)) { @@ -147,7 +147,7 @@ static handler *innobase_create_handler(handlerton *hton, TABLE_SHARE *table, -@@ -839,6 +845,17 @@ +@@ -841,6 +847,17 @@ } } @@ -165,7 +165,7 @@ /********************************************************************//** Obtain the InnoDB transaction of a MySQL thread. @return reference to transaction pointer */ -@@ -2442,6 +2459,9 @@ +@@ -2471,6 +2488,9 @@ srv_n_read_io_threads = (ulint) innobase_read_io_threads; srv_n_write_io_threads = (ulint) innobase_write_io_threads; @@ -175,7 +175,7 @@ srv_force_recovery = (ulint) innobase_force_recovery; srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite; -@@ -11036,7 +11056,7 @@ +@@ -11133,7 +11153,7 @@ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Purge threads can be either 0 or 1.", NULL, NULL, @@ -184,7 +184,7 @@ 0, /* Minimum value */ 1, 0); /* Maximum value */ -@@ -11078,12 +11098,18 @@ +@@ -11175,12 +11195,18 @@ innodb_file_format_max_validate, innodb_file_format_max_update, "Antelope"); @@ -209,7 +209,7 @@ static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, -@@ -11183,7 +11209,7 @@ +@@ -11285,7 +11311,7 @@ static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", @@ -218,7 +218,7 @@ static MYSQL_SYSVAR_LONG(buffer_pool_instances, innobase_buffer_pool_instances, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, -@@ -11335,6 +11361,95 @@ +@@ -11442,6 +11468,95 @@ "trigger a readahead.", NULL, NULL, 56, 0, 64, 0); @@ -314,7 +314,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), -@@ -11355,6 +11470,7 @@ +@@ -11462,6 +11577,7 @@ MYSQL_SYSVAR(file_format_check), MYSQL_SYSVAR(file_format_max), MYSQL_SYSVAR(flush_log_at_trx_commit), @@ -322,7 +322,7 @@ MYSQL_SYSVAR(flush_method), MYSQL_SYSVAR(force_recovery), MYSQL_SYSVAR(large_prefix), -@@ -11393,6 +11509,13 @@ +@@ -11501,6 +11617,13 @@ MYSQL_SYSVAR(show_verbose_locks), MYSQL_SYSVAR(show_locks_held), MYSQL_SYSVAR(version), @@ -365,7 +365,7 @@ --- a/storage/innobase/include/buf0rea.h +++ b/storage/innobase/include/buf0rea.h -@@ -124,8 +124,7 @@ +@@ -149,8 +149,7 @@ /** The size in pages of the area which the read-ahead algorithms read if invoked */ @@ -474,8 +474,8 @@ +extern char srv_use_global_flush_log_at_trx_commit; extern char srv_adaptive_flushing; - -@@ -216,6 +217,16 @@ + /* If this flag is TRUE, then we will load the indexes' (and tables') metadata +@@ -221,6 +222,16 @@ extern ulong srv_max_purge_lag; extern ulong srv_replication_delay; @@ -492,7 +492,7 @@ /*-------------------------------------------*/ extern ulint srv_n_rows_inserted; -@@ -394,8 +405,9 @@ +@@ -399,8 +410,9 @@ when writing data files, but do flush after writing to log files */ SRV_UNIX_NOSYNC, /*!< do not flush after writing */ @@ -852,7 +852,7 @@ /* Try to flush dirty pages so as to avoid IO bursts at the checkpoints. */ -@@ -402,6 +403,17 @@ +@@ -404,6 +405,17 @@ UNIV_INTERN ulong srv_replication_delay = 0; @@ -870,7 +870,7 @@ /*-------------------------------------------*/ UNIV_INTERN ulong srv_n_spin_wait_rounds = 30; UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500; -@@ -2709,7 +2721,7 @@ +@@ -2713,7 +2725,7 @@ ut_ad(!mutex_own(&kernel_mutex)); @@ -879,7 +879,7 @@ do { /* Check for shutdown and change in purge config. */ -@@ -2742,6 +2754,7 @@ +@@ -2746,6 +2758,7 @@ ulint n_pages_purged = 0; ulint n_bytes_merged; ulint n_pages_flushed; @@ -887,7 +887,7 @@ ulint n_bytes_archived; ulint n_tables_to_drop; ulint n_ios; -@@ -2749,7 +2762,20 @@ +@@ -2753,7 +2766,20 @@ ulint n_ios_very_old; ulint n_pend_ios; ulint next_itr_time; @@ -908,7 +908,7 @@ #ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Master thread starts, id %lu\n", -@@ -2771,6 +2797,9 @@ +@@ -2775,6 +2801,9 @@ mutex_exit(&kernel_mutex); @@ -918,7 +918,7 @@ loop: /*****************************************************************/ /* ---- When there is database activity by users, we cycle in this -@@ -2801,9 +2830,13 @@ +@@ -2805,9 +2834,13 @@ /* Sleep for 1 second on entrying the for loop below the first time. */ next_itr_time = ut_time_ms() + 1000; @@ -932,7 +932,7 @@ /* ALTER TABLE in MySQL requires on Unix that the table handler can drop tables lazily after there no longer are SELECT queries to them. */ -@@ -2827,6 +2860,7 @@ +@@ -2831,6 +2864,7 @@ srv_main_thread_op_info = "sleeping"; srv_main_1_second_loops++; @@ -940,7 +940,7 @@ if (next_itr_time > cur_time && srv_shutdown_state == SRV_SHUTDOWN_NONE) { -@@ -2837,10 +2871,26 @@ +@@ -2841,10 +2875,26 @@ (next_itr_time - cur_time) * 1000)); srv_main_sleeps++; @@ -967,7 +967,7 @@ /* Flush logs if needed */ srv_sync_log_buffer_in_background(); -@@ -2860,7 +2910,7 @@ +@@ -2864,7 +2914,7 @@ if (n_pend_ios < SRV_PEND_IO_THRESHOLD && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) { srv_main_thread_op_info = "doing insert buffer merge"; @@ -976,7 +976,7 @@ /* Flush logs if needed */ srv_sync_log_buffer_in_background(); -@@ -2877,7 +2927,11 @@ +@@ -2881,7 +2931,11 @@ n_pages_flushed = buf_flush_list( PCT_IO(100), IB_ULONGLONG_MAX); @@ -989,7 +989,7 @@ /* Try to keep the rate of flushing of dirty pages such that redo log generation does not -@@ -2893,6 +2947,224 @@ +@@ -2897,6 +2951,224 @@ n_flush, IB_ULONGLONG_MAX); } @@ -1214,7 +1214,7 @@ } if (srv_activity_count == old_activity_count) { -@@ -2941,12 +3213,12 @@ +@@ -2945,12 +3217,12 @@ even if the server were active */ srv_main_thread_op_info = "doing insert buffer merge"; @@ -1229,7 +1229,7 @@ srv_main_thread_op_info = "master purging"; srv_master_do_purge(); -@@ -3024,7 +3296,7 @@ +@@ -3028,7 +3300,7 @@ } } @@ -1238,7 +1238,7 @@ srv_main_thread_op_info = "master purging"; srv_master_do_purge(); -@@ -3049,7 +3321,7 @@ +@@ -3053,7 +3325,7 @@ buf_flush_list below. Otherwise, the system favors clean pages over cleanup throughput. */ n_bytes_merged = ibuf_contract_for_n_pages(FALSE, @@ -1247,7 +1247,7 @@ } srv_main_thread_op_info = "reserving kernel mutex"; -@@ -3189,6 +3461,7 @@ +@@ -3193,6 +3465,7 @@ srv_slot_t* slot; ulint retries = 0; ulint n_total_purged = ULINT_UNDEFINED; @@ -1255,7 +1255,7 @@ ut_a(srv_n_purge_threads == 1); -@@ -3209,9 +3482,12 @@ +@@ -3213,9 +3486,12 @@ mutex_exit(&kernel_mutex); @@ -1268,7 +1268,7 @@ /* If there are very few records to purge or the last purge didn't purge any records then wait for activity. -@@ -3258,6 +3534,16 @@ +@@ -3262,6 +3538,16 @@ } while (n_pages_purged > 0 && !srv_fast_shutdown); srv_sync_log_buffer_in_background(); diff --git a/innodb_kill_idle_transaction.patch b/innodb_kill_idle_transaction.patch new file mode 100644 index 0000000..eb7334b --- /dev/null +++ b/innodb_kill_idle_transaction.patch @@ -0,0 +1,455 @@ +# name : innodb_kill_idle_transaction.patch +# introduced : 5.5.15 +# maintainer : Yasufumi +# +#!!! notice !!! +# Any small change to this file in the main branch +# should be done or reviewed by the maintainer! +--- a/include/mysql/plugin.h ++++ b/include/mysql/plugin.h +@@ -634,6 +634,12 @@ + */ + void thd_set_ha_data(MYSQL_THD thd, const struct handlerton *hton, + const void *ha_data); ++ ++int thd_command(const MYSQL_THD thd); ++long long thd_start_time(const MYSQL_THD thd); ++void thd_kill(unsigned long id); ++#define EXTENDED_FOR_KILLIDLE ++ + #ifdef __cplusplus + } + #endif +--- a/include/mysql/plugin_audit.h.pp ++++ b/include/mysql/plugin_audit.h.pp +@@ -196,6 +196,9 @@ + void *thd_get_ha_data(const void* thd, const struct handlerton *hton); + void thd_set_ha_data(void* thd, const struct handlerton *hton, + const void *ha_data); ++int thd_command(const void* thd); ++long long thd_start_time(const void* thd); ++void thd_kill(unsigned long id); + struct mysql_event_general + { + unsigned int event_subclass; +--- a/include/mysql/plugin_auth.h.pp ++++ b/include/mysql/plugin_auth.h.pp +@@ -196,6 +196,9 @@ + void *thd_get_ha_data(const void* thd, const struct handlerton *hton); + void thd_set_ha_data(void* thd, const struct handlerton *hton, + const void *ha_data); ++int thd_command(const void* thd); ++long long thd_start_time(const void* thd); ++void thd_kill(unsigned long id); + #include + typedef struct st_plugin_vio_info + { +--- a/include/mysql/plugin_ftparser.h.pp ++++ b/include/mysql/plugin_ftparser.h.pp +@@ -149,6 +149,9 @@ + void *thd_get_ha_data(const void* thd, const struct handlerton *hton); + void thd_set_ha_data(void* thd, const struct handlerton *hton, + const void *ha_data); ++int thd_command(const void* thd); ++long long thd_start_time(const void* thd); ++void thd_kill(unsigned long id); + enum enum_ftparser_mode + { + MYSQL_FTPARSER_SIMPLE_MODE= 0, +--- a/sql/sql_class.cc ++++ b/sql/sql_class.cc +@@ -713,6 +713,42 @@ + return buffer; + } + ++/* extend for kill session of idle transaction from engine */ ++extern "C" ++int thd_command(const THD* thd) ++{ ++ return (int) thd->command; ++} ++ ++extern "C" ++long long thd_start_time(const THD* thd) ++{ ++ return (long long) thd->start_time; ++} ++ ++extern "C" ++void thd_kill(ulong id) ++{ ++ THD *tmp; ++ mysql_mutex_lock(&LOCK_thread_count); ++ I_List_iterator it(threads); ++ while ((tmp=it++)) ++ { ++ if (tmp->command == COM_DAEMON) ++ continue; ++ if (tmp->thread_id == id) ++ { ++ mysql_mutex_lock(&tmp->LOCK_thd_data); ++ break; ++ } ++ } ++ mysql_mutex_unlock(&LOCK_thread_count); ++ if (tmp) ++ { ++ tmp->awake(THD::KILL_CONNECTION); ++ mysql_mutex_unlock(&tmp->LOCK_thd_data); ++ } ++} + + /** + Implementation of Drop_table_error_handler::handle_condition(). +--- a/storage/innobase/handler/ha_innodb.cc ++++ b/storage/innobase/handler/ha_innodb.cc +@@ -2860,6 +2860,10 @@ + + innobase_commit_concurrency_init_default(); + ++#ifndef EXTENDED_FOR_KILLIDLE ++ srv_kill_idle_transaction = 0; ++#endif ++ + #ifdef HAVE_PSI_INTERFACE + /* Register keys with MySQL performance schema */ + if (PSI_server) { +@@ -11686,6 +11690,57 @@ + return(false); + } + ++/*********************************************************************** ++functions for kill session of idle transaction */ ++extern "C" ++ibool ++innobase_thd_is_idle( ++/*=================*/ ++ const void* thd) /*!< in: thread handle (THD*) */ ++{ ++#ifdef EXTENDED_FOR_KILLIDLE ++ return(thd_command((const THD*) thd) == COM_SLEEP); ++#else ++ return(FALSE); ++#endif ++} ++ ++extern "C" ++ib_int64_t ++innobase_thd_get_start_time( ++/*========================*/ ++ const void* thd) /*!< in: thread handle (THD*) */ ++{ ++#ifdef EXTENDED_FOR_KILLIDLE ++ return((ib_int64_t)thd_start_time((const THD*) thd)); ++#else ++ return(0); /*dummy value*/ ++#endif ++} ++ ++extern "C" ++void ++innobase_thd_kill( ++/*==============*/ ++ ulong thd_id) ++{ ++#ifdef EXTENDED_FOR_KILLIDLE ++ thd_kill(thd_id); ++#else ++ return; ++#endif ++} ++ ++extern "C" ++ulong ++innobase_thd_get_thread_id( ++/*=======================*/ ++ const void* thd) ++{ ++ return(thd_get_thread_id((const THD*) thd)); ++} ++ ++ + static SHOW_VAR innodb_status_variables_export[]= { + {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC}, + {NullS, NullS, SHOW_LONG} +@@ -11977,6 +12032,15 @@ + "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket", + NULL, NULL, 500L, 1L, ~0L, 0); + ++static MYSQL_SYSVAR_LONG(kill_idle_transaction, srv_kill_idle_transaction, ++ PLUGIN_VAR_RQCMDARG, ++#ifdef EXTENDED_FOR_KILLIDLE ++ "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB.", ++#else ++ "No effect for this build.", ++#endif ++ NULL, NULL, 0, 0, LONG_MAX, 0); ++ + static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR, + "Number of file I/O threads in InnoDB.", +@@ -12279,6 +12343,7 @@ + MYSQL_SYSVAR(fast_checksum), + MYSQL_SYSVAR(commit_concurrency), + MYSQL_SYSVAR(concurrency_tickets), ++ MYSQL_SYSVAR(kill_idle_transaction), + MYSQL_SYSVAR(data_file_path), + MYSQL_SYSVAR(doublewrite_file), + MYSQL_SYSVAR(data_home_dir), +--- a/storage/innobase/include/srv0srv.h ++++ b/storage/innobase/include/srv0srv.h +@@ -296,6 +296,7 @@ + extern ulint srv_activity_count; + extern ulint srv_fatal_semaphore_wait_threshold; + extern ulint srv_dml_needed_delay; ++extern lint srv_kill_idle_transaction; + + extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs, + query threads, and lock table: we allocate +--- a/storage/innobase/include/trx0trx.h ++++ b/storage/innobase/include/trx0trx.h +@@ -594,6 +594,8 @@ + replication has processed */ + const char* mysql_relay_log_file_name; + ib_int64_t mysql_relay_log_pos; ++ time_t idle_start; ++ ib_int64_t last_stmt_start; + /*------------------------------*/ + ulint n_mysql_tables_in_use; /* number of Innobase tables + used in the processing of the current +--- a/storage/innobase/srv/srv0srv.c ++++ b/storage/innobase/srv/srv0srv.c +@@ -87,6 +87,12 @@ + #include "mysql/plugin.h" + #include "mysql/service_thd_wait.h" + ++/* prototypes of new functions added to ha_innodb.cc for kill_idle_transaction */ ++ibool innobase_thd_is_idle(const void* thd); ++ib_int64_t innobase_thd_get_start_time(const void* thd); ++void innobase_thd_kill(ulong thd_id); ++ulong innobase_thd_get_thread_id(const void* thd); ++ + /* prototypes for new functions added to ha_innodb.cc */ + ibool innobase_get_slow_log(); + +@@ -97,6 +103,9 @@ + /* The following is the maximum allowed duration of a lock wait. */ + UNIV_INTERN ulint srv_fatal_semaphore_wait_threshold = 600; + ++/**/ ++UNIV_INTERN lint srv_kill_idle_transaction = 0; ++ + /* How much data manipulation language (DML) statements need to be delayed, + in microseconds, in order to reduce the lagging of the purge thread. */ + UNIV_INTERN ulint srv_dml_needed_delay = 0; +@@ -2834,6 +2843,36 @@ + old_sema = sema; + } + ++ if (srv_kill_idle_transaction && trx_sys) { ++ trx_t* trx; ++ time_t now; ++rescan_idle: ++ now = time(NULL); ++ mutex_enter(&kernel_mutex); ++ trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list); ++ while (trx) { ++ if (trx->conc_state == TRX_ACTIVE ++ && trx->mysql_thd ++ && innobase_thd_is_idle(trx->mysql_thd)) { ++ ib_int64_t start_time = innobase_thd_get_start_time(trx->mysql_thd); ++ ulong thd_id = innobase_thd_get_thread_id(trx->mysql_thd); ++ ++ if (trx->last_stmt_start != start_time) { ++ trx->idle_start = now; ++ trx->last_stmt_start = start_time; ++ } else if (difftime(now, trx->idle_start) ++ > srv_kill_idle_transaction) { ++ /* kill the session */ ++ mutex_exit(&kernel_mutex); ++ innobase_thd_kill(thd_id); ++ goto rescan_idle; ++ } ++ } ++ trx = UT_LIST_GET_NEXT(mysql_trx_list, trx); ++ } ++ mutex_exit(&kernel_mutex); ++ } ++ + /* Flush stderr so that a database user gets the output + to possible MySQL error file */ + +--- a/storage/innobase/trx/trx0trx.c ++++ b/storage/innobase/trx/trx0trx.c +@@ -143,6 +143,9 @@ + trx->mysql_relay_log_file_name = ""; + trx->mysql_relay_log_pos = 0; + ++ trx->idle_start = 0; ++ trx->last_stmt_start = 0; ++ + mutex_create(trx_undo_mutex_key, &trx->undo_mutex, SYNC_TRX_UNDO); + + trx->rseg = NULL; +--- /dev/null ++++ b/mysql-test/r/percona_innodb_kill_idle_trx.result +@@ -0,0 +1,41 @@ ++DROP TABLE IF EXISTS t1; ++SET autocommit=0; ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction'; ++Variable_name Value ++innodb_kill_idle_transaction 0 ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction'; ++VARIABLE_NAME VARIABLE_VALUE ++INNODB_KILL_IDLE_TRANSACTION 0 ++SET GLOBAL innodb_kill_idle_transaction=1; ++SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction'; ++Variable_name Value ++innodb_kill_idle_transaction 1 ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction'; ++VARIABLE_NAME VARIABLE_VALUE ++INNODB_KILL_IDLE_TRANSACTION 1 ++BEGIN; ++INSERT INTO t1 VALUES (1),(2),(3); ++COMMIT; ++SELECT * FROM t1; ++a ++1 ++2 ++3 ++BEGIN; ++INSERT INTO t1 VALUES (4),(5),(6); ++SELECT * FROM t1; ++ERROR HY000: MySQL server has gone away ++SELECT * FROM t1; ++a ++1 ++2 ++3 ++DROP TABLE t1; ++SET GLOBAL innodb_kill_idle_transaction=0; ++SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction'; ++Variable_name Value ++innodb_kill_idle_transaction 0 ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction'; ++VARIABLE_NAME VARIABLE_VALUE ++INNODB_KILL_IDLE_TRANSACTION 0 +--- /dev/null ++++ b/mysql-test/r/percona_innodb_kill_idle_trx_locks.result +@@ -0,0 +1,45 @@ ++DROP TABLE IF EXISTS t1; ++SET autocommit=0; ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction'; ++Variable_name Value ++innodb_kill_idle_transaction 0 ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction'; ++VARIABLE_NAME VARIABLE_VALUE ++INNODB_KILL_IDLE_TRANSACTION 0 ++SET GLOBAL innodb_kill_idle_transaction=5; ++SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction'; ++Variable_name Value ++innodb_kill_idle_transaction 5 ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction'; ++VARIABLE_NAME VARIABLE_VALUE ++INNODB_KILL_IDLE_TRANSACTION 5 ++BEGIN; ++INSERT INTO t1 VALUES (1),(2),(3); ++COMMIT; ++SELECT * FROM t1; ++a ++1 ++2 ++3 ++### Locking rows. Lock should be released when idle trx is killed. ++BEGIN; ++SELECT * FROM t1 FOR UPDATE; ++a ++1 ++2 ++3 ++UPDATE t1 set a=4; ++SELECT * FROM t1; ++a ++4 ++4 ++4 ++DROP TABLE t1; ++SET GLOBAL innodb_kill_idle_transaction=0; ++SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction'; ++Variable_name Value ++innodb_kill_idle_transaction 0 ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction'; ++VARIABLE_NAME VARIABLE_VALUE ++INNODB_KILL_IDLE_TRANSACTION 0 +--- /dev/null ++++ b/mysql-test/t/percona_innodb_kill_idle_trx.test +@@ -0,0 +1,28 @@ ++--source include/have_innodb.inc ++--disable_warnings ++DROP TABLE IF EXISTS t1; ++--enable_warnings ++ ++SET autocommit=0; ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++ ++--source include/percona_innodb_kill_idle_trx_show.inc ++SET GLOBAL innodb_kill_idle_transaction=1; ++--source include/percona_innodb_kill_idle_trx_show.inc ++ ++BEGIN; ++INSERT INTO t1 VALUES (1),(2),(3); ++COMMIT; ++SELECT * FROM t1; ++ ++BEGIN; ++INSERT INTO t1 VALUES (4),(5),(6); ++sleep 3; ++ ++--enable_reconnect ++--error 2006 --error CR_SERVER_GONE_ERROR ++SELECT * FROM t1; ++SELECT * FROM t1; ++DROP TABLE t1; ++SET GLOBAL innodb_kill_idle_transaction=0; ++--source include/percona_innodb_kill_idle_trx_show.inc +--- /dev/null ++++ b/mysql-test/t/percona_innodb_kill_idle_trx_locks.test +@@ -0,0 +1,31 @@ ++--source include/have_innodb.inc ++--disable_warnings ++DROP TABLE IF EXISTS t1; ++--enable_warnings ++ ++SET autocommit=0; ++CREATE TABLE t1 (a INT) ENGINE=InnoDB; ++ ++--source include/percona_innodb_kill_idle_trx_show.inc ++SET GLOBAL innodb_kill_idle_transaction=5; ++--source include/percona_innodb_kill_idle_trx_show.inc ++ ++connect (conn1,localhost,root,,); ++connection conn1; ++ ++BEGIN; ++INSERT INTO t1 VALUES (1),(2),(3); ++COMMIT; ++SELECT * FROM t1; ++ ++--echo ### Locking rows. Lock should be released when idle trx is killed. ++BEGIN; ++SELECT * FROM t1 FOR UPDATE; ++ ++connection default; ++UPDATE t1 set a=4; ++ ++SELECT * FROM t1; ++DROP TABLE t1; ++SET GLOBAL innodb_kill_idle_transaction=0; ++--source include/percona_innodb_kill_idle_trx_show.inc +--- /dev/null ++++ b/mysql-test/include/percona_innodb_kill_idle_trx_show.inc +@@ -0,0 +1,2 @@ ++SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction'; diff --git a/innodb_lru_dump_restore.patch b/innodb_lru_dump_restore.patch index 060b243..ed753f7 100644 --- a/innodb_lru_dump_restore.patch +++ b/innodb_lru_dump_restore.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c -@@ -2167,6 +2167,284 @@ +@@ -2183,6 +2183,289 @@ memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur); } @@ -174,6 +174,11 @@ + " InnoDB: cannot open %s\n", LRU_DUMP_FILE); + goto end; + } ++ ++ ut_print_timestamp(stderr); ++ fprintf(stderr, " InnoDB: Restoring buffer pool pages from %s\n", ++ LRU_DUMP_FILE); ++ + if (size == 0 || size_high > 0 || size % 8) { + fprintf(stderr, " InnoDB: broken LRU dump file\n"); + goto end; @@ -275,7 +280,7 @@ + + ut_print_timestamp(stderr); + fprintf(stderr, -+ " InnoDB: reading pages based on the dumped LRU list was done." ++ " InnoDB: Completed reading buffer pool pages" + " (requested: %lu, read: %lu)\n", req, reads); + ret = TRUE; +end: @@ -294,7 +299,7 @@ Validates the LRU list for one buffer pool instance. */ --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c -@@ -58,7 +58,7 @@ +@@ -60,7 +60,7 @@ which case it is never read into the pool, or if the tablespace does not exist or is being dropped @return 1 if read request is issued. 0 if it is not */ @@ -378,7 +383,25 @@ Waits for an aio operation to complete. This function is used to write the --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -11809,6 +11809,12 @@ +@@ -196,6 +196,8 @@ + + static char* innodb_version_str = (char*) INNODB_VERSION_STR; + ++static my_bool innobase_blocking_lru_restore = FALSE; ++ + /** Possible values for system variable "innodb_stats_method". The values + are defined the same as its corresponding MyISAM system variable + "myisam_stats_method"(see "myisam_stats_method_names"), for better usability */ +@@ -2652,6 +2654,8 @@ + srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite; + srv_use_checksums = (ibool) innobase_use_checksums; + ++ srv_blocking_lru_restore = (ibool) innobase_blocking_lru_restore; ++ + #ifdef HAVE_LARGE_PAGES + if ((os_use_large_pages = (ibool) my_use_large_pages)) + os_large_page_size = (ulint) opt_large_page_size; +@@ -11916,6 +11920,19 @@ "Limit the allocated memory for dictionary cache. (0: unlimited)", NULL, NULL, 0, 0, LONG_MAX, 0); @@ -387,15 +410,23 @@ + "Time in seconds between automatic buffer pool dumps. " + "0 (the default) disables automatic dumps.", + NULL, NULL, 0, 0, UINT_MAX32, 0); ++ ++static MYSQL_SYSVAR_BOOL(blocking_buffer_pool_restore, ++ innobase_blocking_lru_restore, ++ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, ++ "Block XtraDB startup process until buffer pool is full restored from a " ++ "dump file (if present). Disabled by default.", ++ NULL, NULL, FALSE); + static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), -@@ -11891,6 +11897,7 @@ - #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ +@@ -12000,6 +12017,8 @@ + MYSQL_SYSVAR(random_read_ahead), MYSQL_SYSVAR(read_ahead_threshold), MYSQL_SYSVAR(io_capacity), + MYSQL_SYSVAR(buffer_pool_restore_at_startup), ++ MYSQL_SYSVAR(blocking_buffer_pool_restore), MYSQL_SYSVAR(purge_threads), MYSQL_SYSVAR(purge_batch_size), MYSQL_SYSVAR(rollback_segments), @@ -409,7 +440,7 @@ } #define OK(expr) \ -@@ -4270,6 +4271,36 @@ +@@ -4298,6 +4299,36 @@ "Hello!"); goto end_func; } @@ -465,8 +496,8 @@ +buf_LRU_file_restore(void); +/*======================*/ - #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG - /**********************************************************************//** + /******************************************************************//** + Remove one page from LRU list and put it to free list */ --- a/storage/innobase/include/buf0rea.h +++ b/storage/innobase/include/buf0rea.h @@ -31,6 +31,37 @@ @@ -526,17 +557,20 @@ handler for completed requests. The aio array of pending requests is divided --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -356,6 +356,9 @@ +@@ -361,6 +361,12 @@ reading of a disk page */ extern ulint srv_buf_pool_reads; +/** Time in seconds between automatic buffer pool dumps */ +extern uint srv_auto_lru_dump; ++ ++/** Whether startup should be blocked until buffer pool is fully restored */ ++extern ibool srv_blocking_lru_restore; + /** Status variables to be passed to MySQL */ typedef struct export_var_struct export_struc; -@@ -661,6 +664,16 @@ +@@ -666,6 +672,16 @@ /*=====================*/ void* arg); /*!< in: a dummy parameter required by os_thread_create */ @@ -555,17 +589,20 @@ @return FALSE if not all information printed --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -330,6 +330,9 @@ +@@ -332,6 +332,12 @@ reading of a disk page */ UNIV_INTERN ulint srv_buf_pool_reads = 0; +/** Time in seconds between automatic buffer pool dumps */ +UNIV_INTERN uint srv_auto_lru_dump = 0; ++ ++/** Whether startup should be blocked until buffer pool is fully restored */ ++UNIV_INTERN ibool srv_blocking_lru_restore; + /* structure to pass status variables to MySQL */ UNIV_INTERN export_struc export_vars; -@@ -2706,6 +2709,56 @@ +@@ -2710,6 +2716,58 @@ OS_THREAD_DUMMY_RETURN; } @@ -590,7 +627,9 @@ + os_thread_pf(os_thread_get_curr_id())); +#endif + -+ if (srv_auto_lru_dump) ++ /* If srv_blocking_lru_restore is TRUE, restore will be done ++ synchronously on startup. */ ++ if (srv_auto_lru_dump && !srv_blocking_lru_restore) + buf_LRU_file_restore(); + + last_dump_time = time(NULL); @@ -624,7 +663,15 @@ @return FALSE if all are are suspended or have exited. */ --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c -@@ -120,9 +120,9 @@ +@@ -87,6 +87,7 @@ + # include "btr0pcur.h" + # include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */ + # include "zlib.h" /* for ZLIB_VERSION */ ++# include "buf0lru.h" /* for buf_LRU_file_restore() */ + + /** Log sequence number immediately after startup */ + UNIV_INTERN ib_uint64_t srv_start_lsn; +@@ -120,9 +121,9 @@ static os_file_t files[1000]; /** io_handler_thread parameters for thread identification */ @@ -636,14 +683,29 @@ /** We use this mutex to test the return value of pthread_mutex_trylock on successful locking. HP-UX does NOT return 0, though Linux et al do. */ -@@ -1821,6 +1821,10 @@ +@@ -1821,6 +1822,15 @@ os_thread_create(&srv_monitor_thread, NULL, thread_ids + 4 + SRV_MAX_N_IO_THREADS); + /* Create the thread which automaticaly dumps/restore buffer pool */ + os_thread_create(&srv_LRU_dump_restore_thread, NULL, + thread_ids + 5 + SRV_MAX_N_IO_THREADS); ++ ++ /* If srv_blocking_lru_restore is TRUE, load buffer pool contents ++ synchronously */ ++ if (srv_auto_lru_dump && srv_blocking_lru_restore) ++ buf_LRU_file_restore(); + srv_is_being_started = FALSE; err = dict_create_or_check_foreign_constraint_tables(); +--- /dev/null ++++ b/mysql-test/suite/sys_vars/r/innodb_blocking_buffer_pool_restore_basic.result +@@ -0,0 +1,3 @@ ++SELECT @@global.innodb_blocking_buffer_pool_restore; ++@@global.innodb_blocking_buffer_pool_restore ++0 +--- /dev/null ++++ b/mysql-test/suite/sys_vars/t/innodb_blocking_buffer_pool_restore_basic.test +@@ -0,0 +1 @@ ++SELECT @@global.innodb_blocking_buffer_pool_restore; diff --git a/innodb_opt_lru_count.patch b/innodb_opt_lru_count.patch index b894c1c..029cd62 100644 --- a/innodb_opt_lru_count.patch +++ b/innodb_opt_lru_count.patch @@ -18,7 +18,7 @@ ut_a(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE); --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c -@@ -881,9 +881,9 @@ +@@ -882,9 +882,9 @@ block->page.in_zip_hash = FALSE; block->page.in_flush_list = FALSE; block->page.in_free_list = FALSE; @@ -29,7 +29,7 @@ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG block->n_pointers = 0; #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ -@@ -1428,7 +1428,7 @@ +@@ -1429,7 +1429,7 @@ memcpy(dpage, bpage, sizeof *dpage); @@ -38,7 +38,7 @@ ut_d(bpage->in_page_hash = FALSE); /* relocate buf_pool->LRU */ -@@ -3279,8 +3279,8 @@ +@@ -3284,8 +3284,8 @@ bpage->in_zip_hash = FALSE; bpage->in_flush_list = FALSE; bpage->in_free_list = FALSE; @@ -48,7 +48,7 @@ ut_d(bpage->in_page_hash = TRUE); -@@ -3445,7 +3445,7 @@ +@@ -3450,7 +3450,7 @@ ibuf_merge_or_delete_for_page(NULL, space, offset, zip_size, TRUE); /* Flush pages from the end of the LRU list if necessary */ @@ -233,7 +233,7 @@ --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c -@@ -200,7 +200,7 @@ +@@ -367,7 +367,7 @@ } /* Flush pages from the end of the LRU list if necessary */ @@ -242,7 +242,7 @@ /* Increment number of I/O operations used for LRU policy. */ buf_LRU_stat_inc_io(); -@@ -474,7 +474,7 @@ +@@ -641,7 +641,7 @@ os_aio_simulated_wake_handler_threads(); /* Flush pages from the end of the LRU list if necessary */ @@ -251,7 +251,7 @@ #ifdef UNIV_DEBUG if (buf_debug_prints && (count > 0)) { -@@ -562,7 +562,7 @@ +@@ -729,7 +729,7 @@ os_aio_simulated_wake_handler_threads(); /* Flush pages from the end of all the LRU lists if necessary */ @@ -260,7 +260,7 @@ #ifdef UNIV_DEBUG if (buf_debug_prints) { -@@ -656,7 +656,7 @@ +@@ -823,7 +823,7 @@ os_aio_simulated_wake_handler_threads(); /* Flush pages from the end of all the LRU lists if necessary */ @@ -271,7 +271,7 @@ if (buf_debug_prints) { --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h -@@ -1426,11 +1426,11 @@ +@@ -1417,11 +1417,11 @@ UT_LIST_NODE_T(buf_page_t) LRU; /*!< node of the LRU list */ diff --git a/innodb_overwrite_relay_log_info.patch b/innodb_overwrite_relay_log_info.patch index 40a6273..fc89718 100644 --- a/innodb_overwrite_relay_log_info.patch +++ b/innodb_overwrite_relay_log_info.patch @@ -55,7 +55,7 @@ static my_bool innobase_rollback_on_timeout = FALSE; static my_bool innobase_create_status_file = FALSE; static my_bool innobase_stats_on_metadata = TRUE; -@@ -2253,6 +2273,89 @@ +@@ -2282,6 +2302,89 @@ } #endif /* DBUG_OFF */ @@ -145,7 +145,7 @@ /* Check that values don't overflow on 32-bit systems. */ if (sizeof(ulint) == 4) { if (innobase_buffer_pool_size > UINT_MAX32) { -@@ -2551,6 +2654,76 @@ +@@ -2580,6 +2683,76 @@ goto mem_free_and_error; } @@ -222,7 +222,7 @@ innobase_old_blocks_pct = buf_LRU_old_ratio_update( innobase_old_blocks_pct, TRUE); -@@ -2665,6 +2838,25 @@ +@@ -2694,6 +2867,25 @@ trx_t* trx) /*!< in: transaction handle */ { if (trx_is_started(trx)) { @@ -248,7 +248,7 @@ trx_commit_for_mysql(trx); } -@@ -11025,6 +11217,12 @@ +@@ -11122,6 +11314,12 @@ "The common part for InnoDB table spaces.", NULL, NULL, NULL); @@ -261,7 +261,7 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite, PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, "Enable InnoDB doublewrite buffer (enabled by default). " -@@ -11491,6 +11689,7 @@ +@@ -11599,6 +11797,7 @@ MYSQL_SYSVAR(old_blocks_pct), MYSQL_SYSVAR(old_blocks_time), MYSQL_SYSVAR(open_files), diff --git a/innodb_pass_corrupt_table.patch b/innodb_pass_corrupt_table.patch index 2eb7828..bab5571 100644 --- a/innodb_pass_corrupt_table.patch +++ b/innodb_pass_corrupt_table.patch @@ -7,10 +7,10 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c -@@ -691,6 +691,12 @@ - root_page_no = dict_index_get_page(index); +@@ -692,6 +692,12 @@ - block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr); + block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, + index, mtr); + + if (srv_pass_corrupt_table && !block) { + return(0); @@ -20,7 +20,7 @@ ut_a((ibool)!!page_is_comp(buf_block_get_frame(block)) == dict_table_is_comp(index->table)); #ifdef UNIV_BTR_DEBUG -@@ -977,6 +983,12 @@ +@@ -978,6 +984,12 @@ root = btr_root_get(index, &mtr); @@ -33,24 +33,24 @@ if (flag == BTR_N_LEAF_PAGES) { seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF; -@@ -1433,6 +1445,13 @@ - mtr_start(&mtr); +@@ -1437,6 +1449,13 @@ - root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr); + root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, + NULL, &mtr); + + if (srv_pass_corrupt_table && !root) { + mtr_commit(&mtr); + return; + } + ut_a(root); -+ ++ #ifdef UNIV_BTR_DEBUG ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + root, space)); -@@ -1455,6 +1474,12 @@ - mtr_start(&mtr); +@@ -1460,6 +1479,12 @@ - root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr); + root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, + NULL, &mtr); + + if (srv_pass_corrupt_table && !root) { + mtr_commit(&mtr); @@ -60,9 +60,9 @@ #ifdef UNIV_BTR_DEBUG ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP + root, space)); -@@ -1488,6 +1513,11 @@ - - block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr); +@@ -1493,6 +1518,11 @@ + block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, + NULL, mtr); + if (srv_pass_corrupt_table && !block) { + return; @@ -74,10 +74,10 @@ header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP; --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c -@@ -250,6 +250,11 @@ - case BTR_MODIFY_LEAF: +@@ -251,6 +251,11 @@ mode = latch_mode == BTR_SEARCH_LEAF ? RW_S_LATCH : RW_X_LATCH; - get_block = btr_block_get(space, zip_size, page_no, mode, mtr); + get_block = btr_block_get( + space, zip_size, page_no, mode, cursor->index, mtr); + + if (srv_pass_corrupt_table && !get_block) { + return; @@ -86,10 +86,10 @@ #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); #endif /* UNIV_BTR_DEBUG */ -@@ -263,6 +268,11 @@ - get_block = btr_block_get(space, zip_size, - left_page_no, - RW_X_LATCH, mtr); +@@ -264,6 +269,11 @@ + get_block = btr_block_get( + space, zip_size, left_page_no, + RW_X_LATCH, cursor->index, mtr); + + if (srv_pass_corrupt_table && !get_block) { + return; @@ -98,10 +98,10 @@ #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); -@@ -274,6 +284,11 @@ - - get_block = btr_block_get(space, zip_size, page_no, - RW_X_LATCH, mtr); +@@ -276,6 +286,11 @@ + get_block = btr_block_get( + space, zip_size, page_no, + RW_X_LATCH, cursor->index, mtr); + + if (srv_pass_corrupt_table && !get_block) { + return; @@ -110,10 +110,10 @@ #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); #endif /* UNIV_BTR_DEBUG */ -@@ -285,6 +300,11 @@ - get_block = btr_block_get(space, zip_size, - right_page_no, - RW_X_LATCH, mtr); +@@ -287,6 +302,11 @@ + get_block = btr_block_get( + space, zip_size, right_page_no, + RW_X_LATCH, cursor->index, mtr); + + if (srv_pass_corrupt_table && !get_block) { + return; @@ -122,9 +122,9 @@ #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); -@@ -306,6 +326,11 @@ - get_block = btr_block_get(space, zip_size, - left_page_no, mode, mtr); +@@ -309,6 +329,11 @@ + space, zip_size, + left_page_no, mode, cursor->index, mtr); cursor->left_block = get_block; + + if (srv_pass_corrupt_table && !get_block) { @@ -134,10 +134,10 @@ #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); -@@ -316,6 +341,11 @@ - } +@@ -320,6 +345,11 @@ - get_block = btr_block_get(space, zip_size, page_no, mode, mtr); + get_block = btr_block_get( + space, zip_size, page_no, mode, cursor->index, mtr); + + if (srv_pass_corrupt_table && !get_block) { + return; @@ -146,7 +146,7 @@ #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); #endif /* UNIV_BTR_DEBUG */ -@@ -588,6 +618,19 @@ +@@ -592,6 +622,19 @@ file, line, mtr); if (block == NULL) { @@ -166,7 +166,7 @@ /* This must be a search to perform an insert/delete mark/ delete; try using the insert/delete buffer */ -@@ -662,6 +705,16 @@ +@@ -666,6 +709,16 @@ block->check_index_page_at_flush = TRUE; page = buf_block_get_frame(block); @@ -183,7 +183,7 @@ if (rw_latch != RW_NO_LATCH) { #ifdef UNIV_ZIP_DEBUG const page_zip_des_t* page_zip -@@ -866,6 +919,17 @@ +@@ -872,6 +925,17 @@ RW_NO_LATCH, NULL, BUF_GET, file, line, mtr); page = buf_block_get_frame(block); @@ -201,7 +201,7 @@ ut_ad(index->id == btr_page_get_index_id(page)); block->check_index_page_at_flush = TRUE; -@@ -986,6 +1050,14 @@ +@@ -992,6 +1056,14 @@ RW_NO_LATCH, NULL, BUF_GET, file, line, mtr); page = buf_block_get_frame(block); @@ -216,7 +216,7 @@ ut_ad(index->id == btr_page_get_index_id(page)); if (height == ULINT_UNDEFINED) { -@@ -1199,6 +1271,12 @@ +@@ -1205,6 +1277,12 @@ *big_rec = NULL; block = btr_cur_get_block(cursor); @@ -229,7 +229,7 @@ page = buf_block_get_frame(block); index = cursor->index; zip_size = buf_block_get_zip_size(block); -@@ -2988,6 +3066,11 @@ +@@ -2937,6 +3015,11 @@ block = btr_cur_get_block(cursor); @@ -241,7 +241,7 @@ ut_ad(page_is_leaf(buf_block_get_frame(block))); rec = btr_cur_get_rec(cursor); -@@ -3701,6 +3784,11 @@ +@@ -3650,6 +3733,11 @@ page = btr_cur_get_page(&cursor); @@ -277,9 +277,9 @@ index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor)); page_cursor = btr_pcur_get_page_cur(cursor); -@@ -419,6 +425,15 @@ - next_block = btr_block_get(space, zip_size, next_page_no, - cursor->latch_mode, mtr); +@@ -395,6 +401,15 @@ + cursor->latch_mode, + btr_pcur_get_btr_cur(cursor)->index, mtr); next_page = buf_block_get_frame(next_block); + + if (srv_pass_corrupt_table && !next_page) { @@ -326,7 +326,7 @@ /* prototypes for new functions added to ha_innodb.cc */ trx_t* innobase_get_trx(); -@@ -1135,6 +1136,11 @@ +@@ -1136,6 +1137,11 @@ ready = buf_flush_ready_for_replace(&block->page); mutex_exit(&block->mutex); @@ -338,7 +338,7 @@ if (!ready) { return(block); -@@ -2006,6 +2012,13 @@ +@@ -2007,6 +2013,13 @@ return(NULL); } @@ -352,7 +352,7 @@ block_mutex = buf_page_get_mutex_enter(bpage); rw_lock_s_unlock(&buf_pool->page_hash_latch); -@@ -2583,6 +2596,13 @@ +@@ -2587,6 +2600,13 @@ return(NULL); } @@ -366,7 +366,7 @@ switch (buf_block_get_state(block)) { buf_page_t* bpage; ibool success; -@@ -3257,6 +3277,7 @@ +@@ -3261,6 +3281,7 @@ bpage->newest_modification = 0; bpage->oldest_modification = 0; HASH_INVALIDATE(bpage, hash); @@ -374,7 +374,7 @@ #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG bpage->file_page_was_freed = FALSE; #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */ -@@ -3841,6 +3862,7 @@ +@@ -3899,6 +3920,7 @@ (ulong) bpage->offset); } @@ -382,7 +382,7 @@ /* From version 3.23.38 up we store the page checksum to the 4 first bytes of the page end lsn field */ -@@ -3882,6 +3904,23 @@ +@@ -3940,6 +3962,23 @@ REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); @@ -404,17 +404,17 @@ + bpage->is_corrupt = TRUE; + } else if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { - fputs("InnoDB: Ending processing because of" - " a corrupt database page.\n", -@@ -3889,6 +3928,7 @@ - exit(1); + /* If page space id is larger than TRX_SYS_SPACE + (0), we will attempt to mark the corresponding +@@ -3956,6 +3995,7 @@ + } } } + } /**/ if (recv_recovery_is_on()) { /* Pages must be uncompressed for crash recovery. */ -@@ -3898,8 +3938,11 @@ +@@ -3965,8 +4005,11 @@ if (uncompressed && !recv_no_ibuf_operations) { ibuf_merge_or_delete_for_page( @@ -428,7 +428,7 @@ } --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c -@@ -193,7 +193,14 @@ +@@ -195,7 +195,14 @@ ((buf_block_t*) bpage)->frame, bpage, trx); } thd_wait_end(NULL); @@ -445,10 +445,10 @@ /* The i/o is already completed when we arrive from --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c -@@ -54,6 +54,7 @@ - #include "row0merge.h" +@@ -55,6 +55,7 @@ #include "m_ctype.h" /* my_isspace() */ #include "ha_prototypes.h" /* innobase_strcasecmp(), innobase_casedn_str()*/ + #include "row0upd.h" +#include "srv0start.h" /* SRV_LOG_SPACE_FIRST_ID */ #include @@ -471,7 +471,7 @@ goto next_loop; cached_foreign_tables = 0; -@@ -4366,6 +4367,12 @@ +@@ -4367,6 +4368,12 @@ heap = mem_heap_create(1000); while (index) { @@ -484,7 +484,7 @@ size = btr_get_size(index, BTR_TOTAL_SIZE); index->stat_index_size = size; -@@ -4513,6 +4520,12 @@ +@@ -4514,6 +4521,12 @@ heap = mem_heap_create(1000); while (index) { @@ -497,7 +497,7 @@ /*===========================================*/ { dict_table_t* sys_stats; -@@ -4705,6 +4718,13 @@ +@@ -4706,6 +4719,13 @@ || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO && dict_index_is_clust(index)))) { ulint size; @@ -511,9 +511,9 @@ size = btr_get_size(index, BTR_TOTAL_SIZE); index->stat_index_size = size; -@@ -5501,4 +5521,42 @@ - rw_lock_free(&dict_table_stats_latches[i]); - } +@@ -5685,4 +5705,42 @@ + + index->type |= DICT_CORRUPT; } + +/************************************************************************* @@ -787,7 +787,7 @@ if (descr != NULL) { --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -3979,6 +3979,12 @@ +@@ -4012,6 +4012,12 @@ DBUG_RETURN(1); } @@ -800,7 +800,7 @@ /* Create buffers for packing the fields of a record. Why table->reclength did not work here? Obviously, because char fields when packed actually became 1 byte longer, when we also -@@ -4006,6 +4012,19 @@ +@@ -4039,6 +4045,19 @@ /* Get pointer to a table object in InnoDB dictionary cache */ ib_table = dict_table_get(norm_name, TRUE); @@ -811,16 +811,16 @@ + DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + } + -+ if (share->ib_table) { -+ ut_a(share->ib_table == ib_table); -+ } else { -+ share->ib_table = ib_table; -+ } ++ share->ib_table = ib_table; ++ ++ ++ ++ + if (NULL == ib_table) { if (is_part && retries < 10) { ++retries; -@@ -5174,6 +5193,10 @@ +@@ -5188,6 +5207,10 @@ ha_statistic_increment(&SSV::ha_write_count); @@ -831,7 +831,7 @@ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); -@@ -5391,6 +5414,10 @@ +@@ -5405,6 +5428,10 @@ func_exit: innobase_active_small(); @@ -842,7 +842,7 @@ DBUG_RETURN(error_result); } -@@ -5567,6 +5594,10 @@ +@@ -5581,6 +5608,10 @@ ha_statistic_increment(&SSV::ha_update_count); @@ -853,7 +853,7 @@ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); -@@ -5656,6 +5687,10 @@ +@@ -5670,6 +5701,10 @@ innobase_active_small(); @@ -864,7 +864,7 @@ DBUG_RETURN(error); } -@@ -5677,6 +5712,10 @@ +@@ -5691,6 +5726,10 @@ ha_statistic_increment(&SSV::ha_delete_count); @@ -875,7 +875,7 @@ if (!prebuilt->upd_node) { row_get_prebuilt_update_vector(prebuilt); } -@@ -5703,6 +5742,10 @@ +@@ -5717,6 +5756,10 @@ innobase_active_small(); @@ -886,7 +886,7 @@ DBUG_RETURN(error); } -@@ -5942,6 +5985,10 @@ +@@ -5956,6 +5999,10 @@ ha_statistic_increment(&SSV::ha_read_key_count); @@ -896,8 +896,8 @@ + index = prebuilt->index; - if (UNIV_UNLIKELY(index == NULL)) { -@@ -6007,6 +6054,10 @@ + if (UNIV_UNLIKELY(index == NULL) || dict_index_is_corrupted(index)) { +@@ -6023,6 +6070,10 @@ ret = DB_UNSUPPORTED; } @@ -908,7 +908,7 @@ switch (ret) { case DB_SUCCESS: error = 0; -@@ -6122,6 +6173,10 @@ +@@ -6138,6 +6189,10 @@ { DBUG_ENTER("change_active_index"); @@ -919,7 +919,7 @@ ut_ad(user_thd == ha_thd()); ut_a(prebuilt->trx == thd_to_trx(user_thd)); -@@ -6212,6 +6267,10 @@ +@@ -6251,6 +6306,10 @@ DBUG_ENTER("general_fetch"); @@ -930,7 +930,7 @@ ut_a(prebuilt->trx == thd_to_trx(user_thd)); innodb_srv_conc_enter_innodb(prebuilt->trx); -@@ -6221,6 +6280,10 @@ +@@ -6260,6 +6319,10 @@ innodb_srv_conc_exit_innodb(prebuilt->trx); @@ -941,7 +941,7 @@ switch (ret) { case DB_SUCCESS: error = 0; -@@ -7487,10 +7550,18 @@ +@@ -7526,10 +7589,18 @@ update_thd(ha_thd()); @@ -960,7 +960,7 @@ error = convert_error_code_to_mysql(error, prebuilt->table->flags, NULL); -@@ -7991,6 +8062,16 @@ +@@ -8034,6 +8105,16 @@ return(ranges + (double) rows / (double) total_rows * time_for_scan); } @@ -977,7 +977,7 @@ /*********************************************************************//** Calculates the key number used inside MySQL for an Innobase index. We will first check the "index translation table" for a match of the index to get -@@ -8168,7 +8249,7 @@ +@@ -8211,7 +8292,7 @@ ib_table = prebuilt->table; if (flag & HA_STATUS_TIME) { @@ -986,7 +986,7 @@ /* In sql_show we call with this flag: update then statistics so that they are up-to-date */ -@@ -8461,10 +8542,18 @@ +@@ -8511,10 +8592,18 @@ THD* thd, /*!< in: connection thread handle */ HA_CHECK_OPT* check_opt) /*!< in: currently ignored */ { @@ -1005,7 +1005,7 @@ return(0); } -@@ -8646,6 +8735,10 @@ +@@ -8747,6 +8836,10 @@ my_error(ER_QUERY_INTERRUPTED, MYF(0)); } @@ -1016,7 +1016,7 @@ DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT); } -@@ -9416,6 +9509,10 @@ +@@ -9517,6 +9610,10 @@ update_thd(thd); @@ -1027,9 +1027,9 @@ if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) { ut_print_timestamp(stderr); fprintf(stderr, -@@ -11823,6 +11920,26 @@ - "0 (the default) disables automatic dumps.", - NULL, NULL, 0, 0, UINT_MAX32, 0); +@@ -11941,6 +12038,26 @@ + "dump file (if present). Disabled by default.", + NULL, NULL, FALSE); +const char *corrupt_table_action_names[]= +{ @@ -1054,7 +1054,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), -@@ -11910,6 +12027,7 @@ +@@ -12031,6 +12148,7 @@ MYSQL_SYSVAR(purge_threads), MYSQL_SYSVAR(purge_batch_size), MYSQL_SYSVAR(rollback_segments), @@ -1091,7 +1091,7 @@ #define BTR_MAX_NODE_LEVEL 50 /*!< Maximum B-tree page level (not really a hard limit). Used in debug assertions -@@ -55,7 +55,9 @@ +@@ -59,7 +59,9 @@ block = buf_page_get_gen(space, zip_size, page_no, mode, NULL, BUF_GET, file, line, mtr); @@ -1100,11 +1100,11 @@ + + if (block && mode != RW_NO_LATCH) { - buf_block_dbg_add_level(block, SYNC_TREE_NODE); - } + buf_block_dbg_add_level( + block, index != NULL && dict_index_is_ibuf(index) --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h -@@ -1025,7 +1025,7 @@ +@@ -1016,7 +1016,7 @@ const buf_block_t* block) /*!< in: pointer to the control block */ __attribute__((pure)); #else /* UNIV_DEBUG */ @@ -1113,7 +1113,7 @@ #endif /* UNIV_DEBUG */ /*********************************************************************//** Gets the space id of a block. -@@ -1472,6 +1472,7 @@ +@@ -1463,6 +1463,7 @@ 0 if the block was never accessed in the buffer pool */ /* @} */ @@ -1132,7 +1132,7 @@ /*********************************************************************//** Gets the current size of buffer buf_pool in bytes. @return size in bytes */ -@@ -619,6 +619,12 @@ +@@ -637,6 +637,12 @@ /*================*/ const buf_block_t* block) /*!< in: pointer to the control block */ { @@ -1147,9 +1147,9 @@ switch (buf_block_get_state(block)) { --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h -@@ -1258,6 +1258,15 @@ - dict_close(void); - /*============*/ +@@ -1326,6 +1326,15 @@ + /*========================*/ + ulint space_id); /*!< in: space ID */ +/************************************************************************* +set is_corrupt flag by space_id*/ @@ -1165,7 +1165,7 @@ #endif --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h -@@ -666,6 +666,7 @@ +@@ -670,6 +670,7 @@ the AUTOINC lock on this table. */ /* @} */ /*----------------------*/ @@ -1220,7 +1220,7 @@ buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK); --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h -@@ -527,7 +527,7 @@ +@@ -497,7 +497,7 @@ page_is_leaf( /*=========*/ const page_t* page) /*!< in: page */ @@ -1254,7 +1254,7 @@ Decompress a page. This function should tolerate errors on the compressed --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -240,6 +240,7 @@ +@@ -245,6 +245,7 @@ extern ulint srv_adaptive_flushing_method; extern ulint srv_expand_import; @@ -1277,7 +1277,7 @@ ut_ad(page_simple_validate_new((page_t*) page)); --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c -@@ -1335,6 +1335,12 @@ +@@ -1338,6 +1338,12 @@ const rec_t* rec = btr_pcur_get_rec(&pcur); const buf_block_t* block = btr_pcur_get_block(&pcur); @@ -1308,7 +1308,7 @@ --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c -@@ -3854,6 +3854,13 @@ +@@ -3912,6 +3912,13 @@ /* PHASE 4: Look for matching records in a loop */ rec = btr_pcur_get_rec(pcur); @@ -1322,7 +1322,7 @@ ut_ad(!!page_rec_is_comp(rec) == comp); #ifdef UNIV_SEARCH_DEBUG /* -@@ -3931,7 +3938,13 @@ +@@ -3989,7 +3996,13 @@ if (UNIV_UNLIKELY(next_offs >= UNIV_PAGE_SIZE - PAGE_DIR)) { wrong_offs: @@ -1337,7 +1337,7 @@ ut_print_timestamp(stderr); buf_page_print(page_align(rec), 0); fprintf(stderr, -@@ -3982,7 +3995,8 @@ +@@ -4040,7 +4053,8 @@ offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); @@ -1349,7 +1349,7 @@ fprintf(stderr, --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -430,6 +430,7 @@ +@@ -435,6 +435,7 @@ UNIV_INTERN ulint srv_adaptive_flushing_method = 0; /* 0: native 1: estimate 2: keep_average */ UNIV_INTERN ulint srv_expand_import = 0; /* 0:disable 1:enable */ @@ -1359,7 +1359,7 @@ /*-------------------------------------------*/ --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c -@@ -2149,6 +2149,13 @@ +@@ -2155,6 +2155,13 @@ os_fast_mutex_free(&srv_os_test_mutex); diff --git a/innodb_recovery_patches.patch b/innodb_recovery_patches.patch index 0ee2be3..9be9df1 100644 --- a/innodb_recovery_patches.patch +++ b/innodb_recovery_patches.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c -@@ -122,6 +122,46 @@ +@@ -124,6 +124,46 @@ bpage = buf_page_init_for_read(err, mode, space, zip_size, unzip, tablespace_version, offset); if (bpage == NULL) { @@ -54,7 +54,7 @@ return(0); } -@@ -610,6 +650,50 @@ +@@ -777,6 +817,50 @@ /* It is a single table tablespace and the .ibd file is missing: do nothing */ @@ -115,7 +115,7 @@ static my_bool innobase_locks_unsafe_for_binlog = FALSE; static my_bool innobase_overwrite_relay_log_info = FALSE; static my_bool innobase_rollback_on_timeout = FALSE; -@@ -2581,6 +2582,8 @@ +@@ -2610,6 +2611,8 @@ srv_force_recovery = (ulint) innobase_force_recovery; @@ -124,7 +124,7 @@ srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite; srv_use_checksums = (ibool) innobase_use_checksums; -@@ -11285,6 +11288,11 @@ +@@ -11382,6 +11385,11 @@ "The common part for InnoDB table spaces.", NULL, NULL, NULL); @@ -136,7 +136,7 @@ static MYSQL_SYSVAR_BOOL(recovery_update_relay_log, innobase_overwrite_relay_log_info, PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, "During InnoDB crash recovery on slave overwrite relay-log.info " -@@ -11763,6 +11771,7 @@ +@@ -11870,6 +11878,7 @@ MYSQL_SYSVAR(data_file_path), MYSQL_SYSVAR(data_home_dir), MYSQL_SYSVAR(doublewrite), diff --git a/innodb_separate_doublewrite.patch b/innodb_separate_doublewrite.patch index 34ca885..c1f2581 100644 --- a/innodb_separate_doublewrite.patch +++ b/innodb_separate_doublewrite.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c -@@ -3810,7 +3810,8 @@ +@@ -3868,7 +3868,8 @@ read_space_id = mach_read_from_4( frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); @@ -50,7 +50,7 @@ and in recovery we will find them in the doublewrite buffer --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c -@@ -88,7 +88,9 @@ +@@ -90,7 +90,9 @@ wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER; mode = mode & ~OS_AIO_SIMULATED_WAKE_LATER; @@ -71,7 +71,7 @@ /** Following are six InnoDB system tables */ -@@ -811,7 +812,7 @@ +@@ -816,7 +817,7 @@ mtr_commit(&mtr); @@ -80,7 +80,7 @@ /* The system tablespace always exists. */ } else if (in_crash_recovery) { /* Check that the tablespace (the .ibd file) really -@@ -1682,7 +1683,7 @@ +@@ -1727,7 +1728,7 @@ space = mach_read_from_4(field); /* Check if the tablespace exists and has the right name */ @@ -89,7 +89,7 @@ flags = dict_sys_tables_get_flags(rec); if (UNIV_UNLIKELY(flags == ULINT_UNDEFINED)) { -@@ -1835,7 +1836,7 @@ +@@ -1880,7 +1881,7 @@ goto err_exit; } @@ -341,7 +341,7 @@ /* The highest file format being used in the database. The value can be set by user, however, it will be adjusted to the newer file format if -@@ -2477,6 +2478,8 @@ +@@ -2508,6 +2509,8 @@ goto error; } @@ -350,7 +350,7 @@ srv_use_sys_stats_table = (ibool) innobase_use_sys_stats_table; /* -------------- Log files ---------------------------*/ -@@ -11657,6 +11660,11 @@ +@@ -11763,6 +11766,11 @@ "Path to individual files and their sizes.", NULL, NULL, NULL); @@ -362,7 +362,7 @@ static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "The AUTOINC lock modes supported by InnoDB: " -@@ -11824,6 +11832,7 @@ +@@ -11942,6 +11950,7 @@ MYSQL_SYSVAR(commit_concurrency), MYSQL_SYSVAR(concurrency_tickets), MYSQL_SYSVAR(data_file_path), @@ -506,7 +506,7 @@ UNIV_INLINE --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c -@@ -3425,7 +3425,7 @@ +@@ -3436,7 +3436,7 @@ /* Do not drop possible .ibd tablespace if something went wrong: we do not want to delete valuable data of the user */ @@ -528,7 +528,7 @@ /* if TRUE, then we auto-extend the last data file */ --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c -@@ -714,6 +714,7 @@ +@@ -715,6 +715,7 @@ /*======================*/ ibool* create_new_db, /*!< out: TRUE if new database should be created */ @@ -536,7 +536,7 @@ #ifdef UNIV_LOG_ARCHIVE ulint* min_arch_log_no,/*!< out: min of archived log numbers in data files */ -@@ -746,6 +747,7 @@ +@@ -747,6 +748,7 @@ *sum_of_new_sizes = 0; *create_new_db = FALSE; @@ -544,7 +544,7 @@ srv_normalize_path_for_win(srv_data_home); -@@ -983,6 +985,142 @@ +@@ -984,6 +986,142 @@ srv_data_file_is_raw_partition[i] != 0); } @@ -687,7 +687,7 @@ return(DB_SUCCESS); } -@@ -996,6 +1134,7 @@ +@@ -997,6 +1135,7 @@ /*====================================*/ { ibool create_new_db; @@ -695,7 +695,7 @@ ibool log_file_created; ibool log_created = FALSE; ibool log_opened = FALSE; -@@ -1461,6 +1600,7 @@ +@@ -1462,6 +1601,7 @@ } err = open_or_create_data_files(&create_new_db, @@ -703,7 +703,7 @@ #ifdef UNIV_LOG_ARCHIVE &min_arch_log_no, &max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ -@@ -1628,6 +1768,14 @@ +@@ -1629,6 +1769,14 @@ after the double write buffer has been created. */ trx_sys_create(); @@ -718,7 +718,7 @@ dict_create(); srv_startup_is_before_trx_rollback_phase = FALSE; -@@ -1661,6 +1809,13 @@ +@@ -1662,6 +1810,13 @@ recv_recovery_from_archive_finish(); #endif /* UNIV_LOG_ARCHIVE */ } else { @@ -732,7 +732,7 @@ /* Check if we support the max format that is stamped on the system tablespace. -@@ -1747,6 +1902,17 @@ +@@ -1748,6 +1903,17 @@ we have finished the recovery process so that the image of TRX_SYS_PAGE_NO is not stale. */ trx_sys_file_format_tag_init(); diff --git a/innodb_show_lock_name.patch b/innodb_show_lock_name.patch index 0bfda2b..d544a04 100644 --- a/innodb_show_lock_name.patch +++ b/innodb_show_lock_name.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -9604,9 +9604,8 @@ +@@ -9701,9 +9701,8 @@ rw_lock_wait_time += mutex->lspent_time; } #else /* UNIV_DEBUG */ @@ -19,7 +19,7 @@ buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu", (ulong) mutex->count_os_wait); -@@ -9621,10 +9620,8 @@ +@@ -9718,10 +9717,8 @@ if (block_mutex) { buf1len = (uint) my_snprintf(buf1, sizeof buf1, @@ -32,7 +32,7 @@ buf2len = (uint) my_snprintf(buf2, sizeof buf2, "os_waits=%lu", (ulong) block_mutex_oswait_count); -@@ -9653,9 +9650,8 @@ +@@ -9750,9 +9747,8 @@ continue; } @@ -44,7 +44,7 @@ buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu", (ulong) lock->count_os_wait); -@@ -9669,10 +9665,8 @@ +@@ -9766,10 +9762,8 @@ if (block_lock) { buf1len = (uint) my_snprintf(buf1, sizeof buf1, @@ -244,7 +244,7 @@ /******************************************************************//** NOTE! Please use the corresponding macro mutex_enter(), not directly this function! -@@ -733,9 +733,9 @@ +@@ -729,9 +729,9 @@ ulint line; /*!< Line where the mutex was locked */ ulint level; /*!< Level in the global latching order */ #endif /* UNIV_SYNC_DEBUG */ @@ -255,7 +255,7 @@ os_thread_id_t thread_id; /*!< The thread id of the thread which locked the mutex. */ ulint magic_n; /*!< MUTEX_MAGIC_N */ -@@ -750,9 +750,9 @@ +@@ -746,9 +746,9 @@ ulong count_os_yield; /*!< count of os_wait */ ulonglong lspent_time; /*!< mutex os_wait timer msec */ ulonglong lmax_spent_time;/*!< mutex os_wait timer msec */ @@ -268,7 +268,7 @@ instrumentation hook */ --- a/storage/innobase/include/sync0sync.ic +++ b/storage/innobase/include/sync0sync.ic -@@ -321,13 +321,13 @@ +@@ -320,13 +320,13 @@ mysql_pfs_key_t key, /*!< in: Performance Schema key */ mutex_t* mutex, /*!< in: pointer to memory */ # ifdef UNIV_DEBUG @@ -285,7 +285,7 @@ { mutex->pfs_psi = (PSI_server && PFS_IS_INSTRUMENTED(key)) ? PSI_server->init_mutex(key, mutex) -@@ -335,13 +335,13 @@ +@@ -334,13 +334,13 @@ mutex_create_func(mutex, # ifdef UNIV_DEBUG diff --git a/innodb_show_status.patch b/innodb_show_status.patch index 0be7859..2522447 100644 --- a/innodb_show_status.patch +++ b/innodb_show_status.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c -@@ -4365,6 +4365,7 @@ +@@ -4426,6 +4426,7 @@ } total_info->pool_size += pool_info->pool_size; @@ -15,7 +15,7 @@ total_info->lru_len += pool_info->lru_len; total_info->old_lru_len += pool_info->old_lru_len; total_info->free_list_len += pool_info->free_list_len; -@@ -4428,6 +4429,8 @@ +@@ -4491,6 +4492,8 @@ pool_info->pool_size = buf_pool->curr_size; @@ -24,7 +24,7 @@ pool_info->lru_len = UT_LIST_GET_LEN(buf_pool->LRU); pool_info->old_lru_len = buf_pool->LRU_old_len; -@@ -4544,14 +4547,16 @@ +@@ -4612,14 +4615,16 @@ ut_ad(pool_info); fprintf(file, @@ -101,7 +101,7 @@ {"buffer_pool_pages_free", (char*) &export_vars.innodb_buffer_pool_pages_free, SHOW_LONG}, #ifdef UNIV_DEBUG -@@ -11097,6 +11099,16 @@ +@@ -11199,6 +11201,16 @@ "Force InnoDB to not use next-key locking, to use only row-level locking.", NULL, NULL, FALSE); @@ -118,7 +118,7 @@ #ifdef UNIV_LOG_ARCHIVE static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, -@@ -11284,7 +11296,7 @@ +@@ -11386,7 +11398,7 @@ static MYSQL_SYSVAR_STR(version, innodb_version_str, PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY, @@ -127,7 +127,7 @@ static MYSQL_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc, PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, -@@ -11378,6 +11390,8 @@ +@@ -11486,6 +11498,8 @@ MYSQL_SYSVAR(thread_concurrency), MYSQL_SYSVAR(thread_sleep_delay), MYSQL_SYSVAR(autoinc_lock_mode), @@ -178,9 +178,9 @@ Create a consistent cursor view for mysql to be used in cursors. In this --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -142,6 +142,9 @@ - extern char srv_adaptive_flushing; - +@@ -146,6 +146,9 @@ + corrupted index and table */ + extern my_bool srv_load_corrupted; +extern ulint srv_show_locks_held; +extern ulint srv_show_verbose_locks; @@ -188,7 +188,7 @@ /* The sort order table of the MySQL latin1_swedish_ci character set collation */ extern const byte* srv_latin1_ordering; -@@ -323,6 +326,8 @@ +@@ -328,6 +331,8 @@ buffer pool to disk */ extern ulint srv_buf_pool_flushed; @@ -197,14 +197,14 @@ /** Number of buffer pool reads that led to the reading of a disk page */ extern ulint srv_buf_pool_reads; -@@ -702,6 +707,7 @@ +@@ -707,6 +712,7 @@ ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */ ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */ ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */ + ulint innodb_buffer_pool_pages_LRU_flushed; /*!< buf_lru_flush_page_count */ ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */ + ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */ ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */ - ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/ --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -4377,6 +4377,7 @@ @@ -308,7 +308,7 @@ /** Maximum number of times allowed to conditionally acquire mutex before switching to blocking wait on the mutex */ #define MAX_MUTEX_NOWAIT 20 -@@ -314,6 +318,7 @@ +@@ -316,6 +320,7 @@ /* variable to count the number of pages that were written from buffer pool to the disk */ UNIV_INTERN ulint srv_buf_pool_flushed = 0; @@ -316,7 +316,7 @@ /** Number of buffer pool reads that led to the reading of a disk page */ -@@ -1823,6 +1828,13 @@ +@@ -1825,6 +1830,13 @@ ulint n_reserved; ibool ret; @@ -330,7 +330,7 @@ mutex_enter(&srv_innodb_monitor_mutex); current_time = time(NULL); -@@ -1871,31 +1883,6 @@ +@@ -1873,31 +1885,6 @@ mutex_exit(&dict_foreign_err_mutex); @@ -362,7 +362,7 @@ fputs("--------\n" "FILE I/O\n" "--------\n", file); -@@ -1926,10 +1913,78 @@ +@@ -1928,10 +1915,78 @@ "BUFFER POOL AND MEMORY\n" "----------------------\n", file); fprintf(file, @@ -445,7 +445,7 @@ fprintf(file, "Dictionary memory allocated " ULINTPF "\n", dict_sys->size); -@@ -1945,6 +2000,16 @@ +@@ -1947,6 +2002,16 @@ fprintf(file, "%lu read views open inside InnoDB\n", UT_LIST_GET_LEN(trx_sys->view_list)); @@ -462,7 +462,7 @@ n_reserved = fil_space_get_n_reserved_extents(0); if (n_reserved > 0) { fprintf(file, -@@ -1988,6 +2053,31 @@ +@@ -1990,6 +2055,31 @@ srv_n_rows_deleted_old = srv_n_rows_deleted; srv_n_rows_read_old = srv_n_rows_read; @@ -494,14 +494,14 @@ fputs("----------------------------\n" "END OF INNODB MONITOR OUTPUT\n" "============================\n", file); -@@ -2031,6 +2121,7 @@ +@@ -2033,6 +2123,7 @@ = srv_buf_pool_write_requests; export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free; export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed; + export_vars.innodb_buffer_pool_pages_LRU_flushed = buf_lru_flush_page_count; export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads; - export_vars.innodb_buffer_pool_read_ahead - = stat.n_ra_pages_read; + export_vars.innodb_buffer_pool_read_ahead_rnd + = stat.n_ra_pages_read_rnd; --- a/storage/innobase/sync/sync0arr.c +++ b/storage/innobase/sync/sync0arr.c @@ -478,7 +478,7 @@ diff --git a/innodb_show_status_extend.patch b/innodb_show_status_extend.patch index 2faeff7..8e9cabe 100644 --- a/innodb_show_status_extend.patch +++ b/innodb_show_status_extend.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -639,6 +639,16 @@ +@@ -641,6 +641,16 @@ trx_t* trx); /*!< in: transaction handle */ static SHOW_VAR innodb_status_variables[]= { @@ -24,7 +24,7 @@ {"buffer_pool_pages_data", (char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG}, {"buffer_pool_pages_dirty", -@@ -653,8 +663,14 @@ +@@ -655,8 +665,14 @@ {"buffer_pool_pages_latched", (char*) &export_vars.innodb_buffer_pool_pages_latched, SHOW_LONG}, #endif /* UNIV_DEBUG */ @@ -38,8 +38,8 @@ + (char*) &export_vars.innodb_buffer_pool_pages_old, SHOW_LONG}, {"buffer_pool_pages_total", (char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG}, - {"buffer_pool_read_ahead", -@@ -669,6 +685,12 @@ + {"buffer_pool_read_ahead_rnd", +@@ -673,6 +689,12 @@ (char*) &export_vars.innodb_buffer_pool_wait_free, SHOW_LONG}, {"buffer_pool_write_requests", (char*) &export_vars.innodb_buffer_pool_write_requests, SHOW_LONG}, @@ -52,7 +52,7 @@ {"data_fsyncs", (char*) &export_vars.innodb_data_fsyncs, SHOW_LONG}, {"data_pending_fsyncs", -@@ -695,12 +717,66 @@ +@@ -699,12 +721,66 @@ (char*) &export_vars.innodb_dict_tables, SHOW_LONG}, {"have_atomic_builtins", (char*) &export_vars.innodb_have_atomic_builtins, SHOW_BOOL}, @@ -119,7 +119,7 @@ {"os_log_fsyncs", (char*) &export_vars.innodb_os_log_fsyncs, SHOW_LONG}, {"os_log_pending_fsyncs", -@@ -717,8 +793,14 @@ +@@ -721,8 +797,14 @@ (char*) &export_vars.innodb_pages_read, SHOW_LONG}, {"pages_written", (char*) &export_vars.innodb_pages_written, SHOW_LONG}, @@ -134,7 +134,7 @@ {"row_lock_time", (char*) &export_vars.innodb_row_lock_time, SHOW_LONGLONG}, {"row_lock_time_avg", -@@ -735,8 +817,20 @@ +@@ -739,8 +821,20 @@ (char*) &export_vars.innodb_rows_read, SHOW_LONG}, {"rows_updated", (char*) &export_vars.innodb_rows_updated, SHOW_LONG}, @@ -240,7 +240,7 @@ /** The lock system */ --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -731,6 +731,11 @@ +@@ -739,6 +739,11 @@ /** Status variables to be passed to MySQL */ struct export_var_struct{ @@ -252,7 +252,7 @@ ulint innodb_data_pending_reads; /*!< Pending reads */ ulint innodb_data_pending_writes; /*!< Pending writes */ ulint innodb_data_pending_fsyncs; /*!< Pending fsyncs */ -@@ -748,6 +753,9 @@ +@@ -756,6 +761,9 @@ #ifdef UNIV_DEBUG ulint innodb_buffer_pool_pages_latched; /*!< Latched pages */ #endif /* UNIV_DEBUG */ @@ -262,8 +262,8 @@ ulint innodb_buffer_pool_read_requests; /*!< buf_pool->stat.n_page_gets */ ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */ ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */ -@@ -756,13 +764,43 @@ - ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */ +@@ -765,13 +773,43 @@ + ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */ ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/ + ulint innodb_checkpoint_age; @@ -306,7 +306,7 @@ ulint innodb_os_log_written; /*!< srv_os_log_written */ ulint innodb_os_log_fsyncs; /*!< fil_n_log_flushes */ ulint innodb_os_log_pending_writes; /*!< srv_os_log_pending_writes */ -@@ -771,6 +809,8 @@ +@@ -780,6 +818,8 @@ ulint innodb_pages_created; /*!< buf_pool->stat.n_pages_created */ ulint innodb_pages_read; /*!< buf_pool->stat.n_pages_read */ ulint innodb_pages_written; /*!< buf_pool->stat.n_pages_written */ @@ -315,7 +315,7 @@ ulint innodb_row_lock_waits; /*!< srv_n_lock_wait_count */ ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */ ib_int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time -@@ -780,11 +820,18 @@ +@@ -789,11 +829,18 @@ / srv_n_lock_wait_count */ ulint innodb_row_lock_time_max; /*!< srv_n_lock_max_wait_time / 1000 */ @@ -336,7 +336,7 @@ /** Thread slot in the thread table */ --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h -@@ -771,6 +771,10 @@ +@@ -767,6 +767,10 @@ #define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds @@ -383,7 +383,7 @@ } --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -2253,12 +2253,49 @@ +@@ -2259,12 +2259,49 @@ ulint LRU_len; ulint free_len; ulint flush_list_len; @@ -433,7 +433,7 @@ export_vars.innodb_data_pending_reads = os_n_pending_reads; export_vars.innodb_data_pending_writes -@@ -2295,6 +2332,92 @@ +@@ -2303,6 +2340,92 @@ export_vars.innodb_buffer_pool_pages_misc = buf_pool_get_n_pages() - LRU_len - free_len; diff --git a/innodb_show_sys_tables.patch b/innodb_show_sys_tables.patch index ce986ab..6e793d7 100644 --- a/innodb_show_sys_tables.patch +++ b/innodb_show_sys_tables.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c -@@ -437,7 +437,7 @@ +@@ -442,7 +442,7 @@ } @@ -16,7 +16,7 @@ /********************************************************************//** This function parses a SYS_FOREIGN record and populate a dict_foreign_t structure with the information from the record. For detail information -@@ -513,9 +513,9 @@ +@@ -518,9 +518,9 @@ return(NULL); } @@ -28,7 +28,7 @@ /********************************************************************//** This function parses a SYS_FOREIGN_COLS record and extract necessary information from the record and return to caller. -@@ -579,7 +579,7 @@ +@@ -584,7 +584,7 @@ return(NULL); } @@ -39,7 +39,7 @@ Determine the flags of a table described in SYS_TABLES. --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc -@@ -11789,7 +11789,14 @@ +@@ -11899,7 +11899,14 @@ i_s_innodb_cmp, i_s_innodb_cmp_reset, i_s_innodb_cmpmem, @@ -69,7 +69,7 @@ #include "dict0mem.h" #include "dict0types.h" #include "ha_prototypes.h" /* for innobase_convert_name() */ -@@ -1784,6 +1786,1675 @@ +@@ -1812,6 +1814,1675 @@ DBUG_RETURN(0); } diff --git a/innodb_split_buf_pool_mutex.patch b/innodb_split_buf_pool_mutex.patch index 4cb6509..9fbd5ee 100644 --- a/innodb_split_buf_pool_mutex.patch +++ b/innodb_split_buf_pool_mutex.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c -@@ -4142,7 +4142,8 @@ +@@ -4091,7 +4091,8 @@ mtr_commit(mtr); @@ -17,7 +17,7 @@ mutex_enter(&block->mutex); /* Only free the block if it is still allocated to -@@ -4153,16 +4154,21 @@ +@@ -4102,16 +4103,21 @@ && buf_block_get_space(block) == space && buf_block_get_page_no(block) == page_no) { @@ -45,7 +45,7 @@ --- a/storage/innobase/btr/btr0sea.c +++ b/storage/innobase/btr/btr0sea.c -@@ -1943,7 +1943,7 @@ +@@ -1944,7 +1944,7 @@ rec_offs_init(offsets_); rw_lock_x_lock(&btr_search_latch); @@ -54,7 +54,7 @@ cell_count = hash_get_n_cells(btr_search_sys->hash_index); -@@ -1951,11 +1951,11 @@ +@@ -1952,11 +1952,11 @@ /* We release btr_search_latch every once in a while to give other queries a chance to run. */ if ((i != 0) && ((i % chunk_size) == 0)) { @@ -68,7 +68,7 @@ } node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node; -@@ -2066,11 +2066,11 @@ +@@ -2067,11 +2067,11 @@ /* We release btr_search_latch every once in a while to give other queries a chance to run. */ if (i != 0) { @@ -82,7 +82,7 @@ } if (!ha_validate(btr_search_sys->hash_index, i, end_index)) { -@@ -2078,7 +2078,7 @@ +@@ -2079,7 +2079,7 @@ } } @@ -283,7 +283,7 @@ { buf_page_t* bpage; const ulint size = BUF_BUDDY_LOW << i; -@@ -335,13 +362,20 @@ +@@ -334,13 +361,20 @@ ulint space; ulint page_no; @@ -305,7 +305,7 @@ /* We assume that all memory from buf_buddy_alloc() is used for compressed page frames. */ -@@ -375,6 +409,11 @@ +@@ -374,6 +408,11 @@ added to buf_pool->page_hash yet. Obviously, it cannot be relocated. */ @@ -317,7 +317,7 @@ return(FALSE); } -@@ -384,18 +423,27 @@ +@@ -383,18 +422,27 @@ For the sake of simplicity, give up. */ ut_ad(page_zip_get_size(&bpage->zip) < size); @@ -346,8 +346,8 @@ - if (buf_page_can_relocate(bpage)) { + if (mutex && buf_page_can_relocate(bpage)) { /* Relocate the compressed page. */ + ullint usec = ut_time_us(NULL); ut_a(bpage->zip.data == src); - memcpy(dst, src, size); @@ -409,10 +457,22 @@ buddy_stat->relocated_usec += ut_time_us(NULL) - usec; @@ -449,7 +449,7 @@ UNIV_INTERN mysql_pfs_key_t flush_list_mutex_key; #endif /* UNIV_PFS_MUTEX */ -@@ -881,9 +886,13 @@ +@@ -882,9 +887,13 @@ block->page.in_zip_hash = FALSE; block->page.in_flush_list = FALSE; block->page.in_free_list = FALSE; @@ -464,7 +464,7 @@ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG block->n_pointers = 0; #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ -@@ -981,9 +990,11 @@ +@@ -982,9 +991,11 @@ memset(block->frame, '\0', UNIV_PAGE_SIZE); #endif /* Add the block to the free list */ @@ -477,7 +477,7 @@ ut_ad(buf_pool_from_block(block) == buf_pool); block++; -@@ -1038,7 +1049,8 @@ +@@ -1039,7 +1050,8 @@ buf_chunk_t* chunk = buf_pool->chunks; ut_ad(buf_pool); @@ -487,7 +487,7 @@ for (n = buf_pool->n_chunks; n--; chunk++) { buf_block_t* block = buf_chunk_contains_zip(chunk, data); -@@ -1144,9 +1156,21 @@ +@@ -1145,9 +1157,21 @@ ------------------------------- */ mutex_create(buf_pool_mutex_key, &buf_pool->mutex, SYNC_BUF_POOL); @@ -509,7 +509,7 @@ buf_pool_mutex_enter(buf_pool); if (buf_pool_size > 0) { -@@ -1159,6 +1183,8 @@ +@@ -1160,6 +1184,8 @@ mem_free(chunk); mem_free(buf_pool); @@ -518,7 +518,7 @@ buf_pool_mutex_exit(buf_pool); return(DB_ERROR); -@@ -1189,6 +1215,8 @@ +@@ -1190,6 +1216,8 @@ /* All fields are initialized by mem_zalloc(). */ @@ -527,7 +527,7 @@ buf_pool_mutex_exit(buf_pool); return(DB_SUCCESS); -@@ -1401,7 +1429,11 @@ +@@ -1402,7 +1430,11 @@ ulint fold; buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); @@ -540,7 +540,7 @@ ut_ad(mutex_own(buf_page_get_mutex(bpage))); ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE); ut_a(bpage->buf_fix_count == 0); -@@ -1512,21 +1544,32 @@ +@@ -1513,21 +1545,32 @@ buf_page_t* bpage; ulint i; buf_pool_t* buf_pool = buf_pool_get(space, offset); @@ -574,7 +574,7 @@ for (i = 0; i < BUF_POOL_WATCH_SIZE; i++) { bpage = &buf_pool->watch[i]; -@@ -1550,10 +1593,12 @@ +@@ -1551,10 +1594,12 @@ bpage->space = space; bpage->offset = offset; bpage->buf_fix_count = 1; @@ -588,7 +588,7 @@ return(NULL); case BUF_BLOCK_ZIP_PAGE: ut_ad(bpage->in_page_hash); -@@ -1571,6 +1616,8 @@ +@@ -1572,6 +1617,8 @@ ut_error; /* Fix compiler warning */ @@ -597,7 +597,7 @@ return(NULL); } -@@ -1588,7 +1635,11 @@ +@@ -1589,7 +1636,11 @@ space, offset) */ buf_page_t* watch) /*!< in/out: sentinel for watch */ { @@ -610,7 +610,7 @@ HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, watch); ut_d(watch->in_page_hash = FALSE); -@@ -1610,28 +1661,31 @@ +@@ -1611,28 +1662,31 @@ buf_pool_t* buf_pool = buf_pool_get(space, offset); ulint fold = buf_page_address_fold(space, offset); @@ -646,7 +646,7 @@ } /****************************************************************//** -@@ -1651,14 +1705,16 @@ +@@ -1652,14 +1706,16 @@ buf_pool_t* buf_pool = buf_pool_get(space, offset); ulint fold = buf_page_address_fold(space, offset); @@ -665,7 +665,7 @@ return(ret); } -@@ -1675,13 +1731,15 @@ +@@ -1676,13 +1732,15 @@ { buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); @@ -683,7 +683,7 @@ } /********************************************************************//** -@@ -1705,14 +1763,20 @@ +@@ -1706,14 +1764,20 @@ ut_a(buf_page_in_file(bpage)); if (buf_page_peek_if_too_old(bpage)) { @@ -708,7 +708,7 @@ } } -@@ -1729,7 +1793,8 @@ +@@ -1730,7 +1794,8 @@ buf_block_t* block; buf_pool_t* buf_pool = buf_pool_get(space, offset); @@ -718,7 +718,7 @@ block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset); -@@ -1738,7 +1803,8 @@ +@@ -1739,7 +1804,8 @@ block->check_index_page_at_flush = FALSE; } @@ -728,7 +728,7 @@ } /********************************************************************//** -@@ -1757,7 +1823,8 @@ +@@ -1758,7 +1824,8 @@ ibool is_hashed; buf_pool_t* buf_pool = buf_pool_get(space, offset); @@ -738,7 +738,7 @@ block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset); -@@ -1768,7 +1835,8 @@ +@@ -1769,7 +1836,8 @@ is_hashed = block->is_hashed; } @@ -748,7 +748,7 @@ return(is_hashed); } -@@ -1790,7 +1858,8 @@ +@@ -1791,7 +1859,8 @@ buf_page_t* bpage; buf_pool_t* buf_pool = buf_pool_get(space, offset); @@ -758,7 +758,7 @@ bpage = buf_page_hash_get(buf_pool, space, offset); -@@ -1801,7 +1870,8 @@ +@@ -1802,7 +1871,8 @@ bpage->file_page_was_freed = TRUE; } @@ -768,7 +768,7 @@ return(bpage); } -@@ -1822,7 +1892,8 @@ +@@ -1823,7 +1893,8 @@ buf_page_t* bpage; buf_pool_t* buf_pool = buf_pool_get(space, offset); @@ -778,7 +778,7 @@ bpage = buf_page_hash_get(buf_pool, space, offset); -@@ -1831,7 +1902,8 @@ +@@ -1832,7 +1903,8 @@ bpage->file_page_was_freed = FALSE; } @@ -788,7 +788,7 @@ return(bpage); } -@@ -1863,8 +1935,9 @@ +@@ -1864,8 +1936,9 @@ buf_pool->stat.n_page_gets++; for (;;) { @@ -799,7 +799,7 @@ bpage = buf_page_hash_get(buf_pool, space, offset); if (bpage) { ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage)); -@@ -1873,7 +1946,8 @@ +@@ -1874,7 +1947,8 @@ /* Page not in buf_pool: needs to be read from file */ @@ -809,7 +809,7 @@ buf_read_page(space, zip_size, offset); -@@ -1885,10 +1959,15 @@ +@@ -1886,10 +1960,15 @@ if (UNIV_UNLIKELY(!bpage->zip.data)) { /* There is no compressed page. */ err_exit: @@ -826,7 +826,7 @@ ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage)); switch (buf_page_get_state(bpage)) { -@@ -1897,24 +1976,43 @@ +@@ -1898,24 +1977,43 @@ case BUF_BLOCK_MEMORY: case BUF_BLOCK_REMOVE_HASH: case BUF_BLOCK_ZIP_FREE: @@ -875,7 +875,7 @@ buf_block_buf_fix_inc((buf_block_t*) bpage, __FILE__, __LINE__); goto got_block; -@@ -1927,7 +2025,7 @@ +@@ -1928,7 +2026,7 @@ must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ; access_time = buf_page_is_accessed(bpage); @@ -884,7 +884,7 @@ mutex_exit(block_mutex); -@@ -2239,7 +2337,7 @@ +@@ -2240,7 +2338,7 @@ const buf_block_t* block) /*!< in: pointer to block, not dereferenced */ { @@ -893,7 +893,7 @@ if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) { /* The pointer should be aligned. */ -@@ -2275,6 +2373,7 @@ +@@ -2276,6 +2374,7 @@ ulint fix_type; ibool must_read; ulint retries = 0; @@ -901,7 +901,7 @@ buf_pool_t* buf_pool = buf_pool_get(space, offset); ut_ad(mtr); -@@ -2308,18 +2407,24 @@ +@@ -2309,18 +2408,24 @@ fold = buf_page_address_fold(space, offset); loop: block = guess; @@ -928,7 +928,7 @@ block = guess = NULL; } else { ut_ad(!block->page.in_zip_hash); -@@ -2328,12 +2433,19 @@ +@@ -2329,12 +2434,19 @@ } if (block == NULL) { @@ -948,7 +948,7 @@ block = NULL; } -@@ -2345,12 +2457,14 @@ +@@ -2346,12 +2458,14 @@ space, offset, fold); if (UNIV_LIKELY_NULL(block)) { @@ -965,7 +965,7 @@ if (mode == BUF_GET_IF_IN_POOL || mode == BUF_PEEK_IF_IN_POOL -@@ -2400,7 +2514,8 @@ +@@ -2404,7 +2518,8 @@ /* The page is being read to buffer pool, but we cannot wait around for the read to complete. */ @@ -975,7 +975,7 @@ return(NULL); } -@@ -2410,38 +2525,49 @@ +@@ -2414,38 +2529,49 @@ ibool success; case BUF_BLOCK_FILE_PAGE: @@ -1032,7 +1032,7 @@ { buf_page_t* hash_bpage; -@@ -2454,35 +2580,47 @@ +@@ -2458,35 +2584,47 @@ while buf_pool->mutex was released. Free the block that was allocated. */ @@ -1086,7 +1086,7 @@ buf_block_init_low(block); block->lock_hash_val = lock_rec_hash(space, offset); -@@ -2492,7 +2630,7 @@ +@@ -2496,7 +2634,7 @@ if (buf_page_get_state(&block->page) == BUF_BLOCK_ZIP_PAGE) { #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG @@ -1095,7 +1095,7 @@ &block->page); #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ ut_ad(!block->page.in_flush_list); -@@ -2510,18 +2648,23 @@ +@@ -2514,18 +2652,23 @@ /* Insert at the front of unzip_LRU list */ buf_unzip_LRU_add_block(block, FALSE); @@ -1121,7 +1121,7 @@ buf_page_free_descriptor(bpage); /* Decompress the page and apply buffered operations -@@ -2535,12 +2678,15 @@ +@@ -2539,12 +2682,15 @@ } /* Unfix and unlatch the block. */ @@ -1140,7 +1140,7 @@ rw_lock_x_unlock(&block->lock); break; -@@ -2556,7 +2702,7 @@ +@@ -2560,7 +2706,7 @@ ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); @@ -1149,7 +1149,7 @@ #if UNIV_WORD_SIZE == 4 /* On 32-bit systems, there is no padding in buf_page_t. On other systems, Valgrind could complain about uninitialized pad -@@ -2569,8 +2715,8 @@ +@@ -2573,8 +2719,8 @@ /* Try to evict the block from the buffer pool, to use the insert buffer (change buffer) as much as possible. */ @@ -1160,7 +1160,7 @@ if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) { /* Set the watch, as it would have been set if the page were not in the -@@ -2579,6 +2725,9 @@ +@@ -2583,6 +2729,9 @@ space, offset, fold); if (UNIV_LIKELY_NULL(block)) { @@ -1170,7 +1170,7 @@ /* The page entered the buffer pool for some reason. Try to -@@ -2586,7 +2735,7 @@ +@@ -2590,7 +2739,7 @@ goto got_block; } } @@ -1179,7 +1179,7 @@ fprintf(stderr, "innodb_change_buffering_debug evict %u %u\n", (unsigned) space, (unsigned) offset); -@@ -2608,13 +2757,14 @@ +@@ -2612,13 +2761,14 @@ ut_a(mode == BUF_GET_POSSIBLY_FREED || !block->page.file_page_was_freed); #endif @@ -1196,7 +1196,7 @@ if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) { buf_page_set_accessed_make_young(&block->page, access_time); -@@ -2847,9 +2997,11 @@ +@@ -2851,9 +3001,11 @@ buf_pool = buf_pool_from_block(block); if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) { @@ -1210,7 +1210,7 @@ } else if (!buf_page_is_accessed(&block->page)) { /* Above, we do a dirty read on purpose, to avoid mutex contention. The field buf_page_t::access_time -@@ -2857,9 +3009,11 @@ +@@ -2861,9 +3013,11 @@ field must be protected by mutex, however. */ ulint time_ms = ut_time_ms(); @@ -1224,7 +1224,7 @@ } ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD); -@@ -2926,18 +3080,21 @@ +@@ -2930,18 +3084,21 @@ ut_ad(mtr); ut_ad(mtr->state == MTR_ACTIVE); @@ -1249,10 +1249,10 @@ #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); -@@ -3026,7 +3183,10 @@ +@@ -3031,7 +3188,10 @@ buf_page_t* hash_page; - buf_pool_t* buf_pool = buf_pool_get(space, offset); + ut_ad(buf_pool == buf_pool_get(space, offset)); - ut_ad(buf_pool_mutex_own(buf_pool)); + //ut_ad(buf_pool_mutex_own(buf_pool)); +#ifdef UNIV_SYNC_DEBUG @@ -1261,7 +1261,7 @@ ut_ad(mutex_own(&(block->mutex))); ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE); -@@ -3055,11 +3215,14 @@ +@@ -3060,11 +3220,14 @@ if (UNIV_LIKELY(!hash_page)) { } else if (buf_pool_watch_is_sentinel(buf_pool, hash_page)) { /* Preserve the reference count. */ @@ -1277,7 +1277,7 @@ } else { fprintf(stderr, "InnoDB: Error: page %lu %lu already found" -@@ -3069,7 +3232,8 @@ +@@ -3074,7 +3237,8 @@ (const void*) hash_page, (const void*) block); #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG mutex_exit(&block->mutex); @@ -1287,7 +1287,7 @@ buf_print(); buf_LRU_print(); buf_validate(); -@@ -3152,7 +3316,9 @@ +@@ -3157,7 +3321,9 @@ fold = buf_page_address_fold(space, offset); @@ -1298,7 +1298,7 @@ watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold); if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) { -@@ -3161,9 +3327,15 @@ +@@ -3166,9 +3332,15 @@ err_exit: if (block) { mutex_enter(&block->mutex); @@ -1315,16 +1315,16 @@ bpage = NULL; goto func_exit; -@@ -3186,6 +3358,8 @@ +@@ -3191,6 +3363,8 @@ - buf_page_init(space, offset, fold, block); + buf_page_init(buf_pool, space, offset, fold, block); + rw_lock_x_unlock(&buf_pool->page_hash_latch); + /* The block must be put to the LRU list, to the old blocks */ buf_LRU_add_block(bpage, TRUE/* to old blocks */); -@@ -3213,7 +3387,7 @@ +@@ -3218,7 +3392,7 @@ been added to buf_pool->LRU and buf_pool->page_hash. */ mutex_exit(&block->mutex); @@ -1333,7 +1333,7 @@ mutex_enter(&block->mutex); block->page.zip.data = data; -@@ -3226,13 +3400,14 @@ +@@ -3231,13 +3405,14 @@ buf_unzip_LRU_add_block(block, TRUE); } @@ -1349,7 +1349,7 @@ /* If buf_buddy_alloc() allocated storage from the LRU list, it released and reacquired buf_pool->mutex. Thus, we must -@@ -3248,7 +3423,10 @@ +@@ -3253,7 +3428,10 @@ /* The block was added by some other thread. */ watch_page = NULL; @@ -1361,7 +1361,7 @@ bpage = NULL; goto func_exit; -@@ -3296,20 +3474,26 @@ +@@ -3301,20 +3479,26 @@ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold, bpage); @@ -1389,7 +1389,7 @@ if (mode == BUF_READ_IBUF_PAGES_ONLY) { -@@ -3351,7 +3535,9 @@ +@@ -3356,7 +3540,9 @@ fold = buf_page_address_fold(space, offset); @@ -1400,7 +1400,7 @@ block = (buf_block_t*) buf_page_hash_get_low( buf_pool, space, offset, fold); -@@ -3367,7 +3553,9 @@ +@@ -3372,7 +3558,9 @@ #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */ /* Page can be found in buf_pool */ @@ -1411,15 +1411,15 @@ buf_block_free(free_block); -@@ -3389,6 +3577,7 @@ +@@ -3394,6 +3582,7 @@ mutex_enter(&block->mutex); - buf_page_init(space, offset, fold, block); + buf_page_init(buf_pool, space, offset, fold, block); + rw_lock_x_unlock(&buf_pool->page_hash_latch); /* The block must be put to the LRU list */ buf_LRU_add_block(&block->page, FALSE); -@@ -3415,7 +3604,7 @@ +@@ -3420,7 +3609,7 @@ the reacquisition of buf_pool->mutex. We also must defer this operation until after the block descriptor has been added to buf_pool->LRU and buf_pool->page_hash. */ @@ -1428,7 +1428,7 @@ mutex_enter(&block->mutex); block->page.zip.data = data; -@@ -3433,7 +3622,8 @@ +@@ -3438,7 +3627,8 @@ buf_page_set_accessed(&block->page, time_ms); @@ -1438,7 +1438,35 @@ mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX); -@@ -3484,6 +3674,8 @@ +@@ -3493,7 +3683,9 @@ + ibool ret = TRUE; + + /* First unfix and release lock on the bpage */ +- buf_pool_mutex_enter(buf_pool); ++ //buf_pool_mutex_enter(buf_pool); ++ mutex_enter(&buf_pool->LRU_list_mutex); ++ rw_lock_x_lock(&buf_pool->page_hash_latch); + mutex_enter(buf_page_get_mutex(bpage)); + ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ); + ut_ad(bpage->buf_fix_count == 0); +@@ -3514,11 +3706,15 @@ + ret = FALSE; + } + ++ buf_pool_mutex_enter(buf_pool); + ut_ad(buf_pool->n_pend_reads > 0); + buf_pool->n_pend_reads--; ++ buf_pool_mutex_exit(buf_pool); + + mutex_exit(buf_page_get_mutex(bpage)); +- buf_pool_mutex_exit(buf_pool); ++ //buf_pool_mutex_exit(buf_pool); ++ mutex_exit(&buf_pool->LRU_list_mutex); ++ rw_lock_x_unlock(&buf_pool->page_hash_latch); + + return(ret); + } +@@ -3536,6 +3732,8 @@ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); const ibool uncompressed = (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); @@ -1447,7 +1475,7 @@ ut_a(buf_page_in_file(bpage)); -@@ -3617,8 +3809,26 @@ +@@ -3678,8 +3876,26 @@ } } @@ -1475,7 +1503,7 @@ #ifdef UNIV_IBUF_COUNT_DEBUG if (io_type == BUF_IO_WRITE || uncompressed) { -@@ -3641,6 +3851,7 @@ +@@ -3702,6 +3918,7 @@ the x-latch to this OS thread: do not let this confuse you in debugging! */ @@ -1483,7 +1511,7 @@ ut_ad(buf_pool->n_pend_reads > 0); buf_pool->n_pend_reads--; buf_pool->stat.n_pages_read++; -@@ -3658,6 +3869,9 @@ +@@ -3719,6 +3936,9 @@ buf_flush_write_complete(bpage); @@ -1493,7 +1521,7 @@ if (uncompressed) { rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock, BUF_IO_WRITE); -@@ -3680,8 +3894,8 @@ +@@ -3741,8 +3961,8 @@ } #endif /* UNIV_DEBUG */ @@ -1503,7 +1531,7 @@ } /*********************************************************************//** -@@ -3698,7 +3912,9 @@ +@@ -3759,7 +3979,9 @@ ut_ad(buf_pool); @@ -1514,7 +1542,7 @@ chunk = buf_pool->chunks; -@@ -3715,7 +3931,9 @@ +@@ -3776,7 +3998,9 @@ } } @@ -1525,7 +1553,7 @@ return(TRUE); } -@@ -3763,7 +3981,8 @@ +@@ -3824,7 +4048,8 @@ freed = buf_LRU_search_and_free_block(buf_pool, 100); } @@ -1535,7 +1563,7 @@ ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0); ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0); -@@ -3776,7 +3995,8 @@ +@@ -3837,7 +4062,8 @@ memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat)); buf_refresh_io_stats(buf_pool); @@ -1545,7 +1573,7 @@ } /*********************************************************************//** -@@ -3818,7 +4038,10 @@ +@@ -3879,7 +4105,10 @@ ut_ad(buf_pool); @@ -1557,7 +1585,7 @@ chunk = buf_pool->chunks; -@@ -3913,7 +4136,7 @@ +@@ -3974,7 +4203,7 @@ /* Check clean compressed-only blocks. */ for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b; @@ -1566,7 +1594,7 @@ ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE); switch (buf_page_get_io_fix(b)) { case BUF_IO_NONE: -@@ -3944,7 +4167,7 @@ +@@ -4005,7 +4234,7 @@ buf_flush_list_mutex_enter(buf_pool); for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b; @@ -1575,7 +1603,7 @@ ut_ad(b->in_flush_list); ut_a(b->oldest_modification); n_flush++; -@@ -4003,6 +4226,8 @@ +@@ -4064,6 +4293,8 @@ } ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru); @@ -1584,7 +1612,7 @@ if (UT_LIST_GET_LEN(buf_pool->free) != n_free) { fprintf(stderr, "Free list len %lu, free blocks %lu\n", (ulong) UT_LIST_GET_LEN(buf_pool->free), -@@ -4013,8 +4238,11 @@ +@@ -4074,8 +4305,11 @@ ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush); ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush); ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush); @@ -1597,7 +1625,7 @@ ut_a(buf_LRU_validate()); ut_a(buf_flush_validate(buf_pool)); -@@ -4070,7 +4298,9 @@ +@@ -4131,7 +4365,9 @@ index_ids = mem_alloc(size * sizeof *index_ids); counts = mem_alloc(sizeof(ulint) * size); @@ -1608,7 +1636,7 @@ buf_flush_list_mutex_enter(buf_pool); fprintf(stderr, -@@ -4139,7 +4369,9 @@ +@@ -4200,7 +4436,9 @@ } } @@ -1619,7 +1647,7 @@ for (i = 0; i < n_found; i++) { index = dict_index_get_if_in_cache(index_ids[i]); -@@ -4196,7 +4428,7 @@ +@@ -4257,7 +4495,7 @@ buf_chunk_t* chunk; ulint fixed_pages_number = 0; @@ -1628,7 +1656,7 @@ chunk = buf_pool->chunks; -@@ -4230,7 +4462,7 @@ +@@ -4291,7 +4529,7 @@ /* Traverse the lists of clean and dirty compressed-only blocks. */ for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b; @@ -1637,7 +1665,7 @@ ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE); ut_a(buf_page_get_io_fix(b) != BUF_IO_WRITE); -@@ -4242,7 +4474,7 @@ +@@ -4303,7 +4541,7 @@ buf_flush_list_mutex_enter(buf_pool); for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b; @@ -1646,7 +1674,7 @@ ut_ad(b->in_flush_list); switch (buf_page_get_state(b)) { -@@ -4268,7 +4500,7 @@ +@@ -4329,7 +4567,7 @@ buf_flush_list_mutex_exit(buf_pool); mutex_exit(&buf_pool->zip_mutex); @@ -1655,7 +1683,7 @@ return(fixed_pages_number); } -@@ -4424,6 +4656,8 @@ +@@ -4487,6 +4725,8 @@ /* Find appropriate pool_info to store stats for this buffer pool */ pool_info = &all_pool_info[pool_id]; @@ -1664,7 +1692,7 @@ buf_pool_mutex_enter(buf_pool); buf_flush_list_mutex_enter(buf_pool); -@@ -4534,6 +4768,8 @@ +@@ -4602,6 +4842,8 @@ pool_info->unzip_cur = buf_LRU_stat_cur.unzip; buf_refresh_io_stats(buf_pool); @@ -1673,7 +1701,7 @@ buf_pool_mutex_exit(buf_pool); } -@@ -4775,11 +5011,13 @@ +@@ -4846,11 +5088,13 @@ { ulint len; @@ -2953,8 +2981,17 @@ + buf_LRU_block_free_non_file_page(block, have_page_hash_mutex); } - /**********************************************************************//** -@@ -1909,7 +2063,8 @@ + /******************************************************************//** +@@ -1897,7 +2051,7 @@ + { + if (buf_LRU_block_remove_hashed_page(bpage, TRUE) + != BUF_BLOCK_ZIP_FREE) { +- buf_LRU_block_free_hashed_page((buf_block_t*) bpage); ++ buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE); + } + } + +@@ -1925,7 +2079,8 @@ } if (adjust) { @@ -2964,7 +3001,7 @@ if (ratio != buf_pool->LRU_old_ratio) { buf_pool->LRU_old_ratio = ratio; -@@ -1921,7 +2076,8 @@ +@@ -1937,7 +2092,8 @@ } } @@ -2974,7 +3011,7 @@ } else { buf_pool->LRU_old_ratio = ratio; } -@@ -2026,7 +2182,8 @@ +@@ -2042,7 +2198,8 @@ ulint new_len; ut_ad(buf_pool); @@ -2984,7 +3021,7 @@ if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) { -@@ -2087,16 +2244,22 @@ +@@ -2103,16 +2260,22 @@ ut_a(buf_pool->LRU_old_len == old_len); @@ -3009,7 +3046,7 @@ UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU, ut_ad(ut_list_node_313->in_unzip_LRU_list && ut_list_node_313->page.in_LRU_list)); -@@ -2110,7 +2273,8 @@ +@@ -2126,7 +2289,8 @@ ut_a(buf_page_belongs_to_unzip_LRU(&block->page)); } @@ -3019,7 +3056,7 @@ } /**********************************************************************//** -@@ -2146,7 +2310,8 @@ +@@ -2162,7 +2326,8 @@ const buf_page_t* bpage; ut_ad(buf_pool); @@ -3029,7 +3066,7 @@ bpage = UT_LIST_GET_FIRST(buf_pool->LRU); -@@ -2203,7 +2368,8 @@ +@@ -2219,7 +2384,8 @@ bpage = UT_LIST_GET_NEXT(LRU, bpage); } @@ -3041,7 +3078,7 @@ /**********************************************************************//** --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c -@@ -311,6 +311,7 @@ +@@ -478,6 +478,7 @@ return(0); } @@ -3049,7 +3086,7 @@ /* Check that almost all pages in the area have been accessed; if offset == low, the accesses must be in a descending order, otherwise, -@@ -329,6 +330,7 @@ +@@ -496,6 +497,7 @@ fail_count = 0; @@ -3057,7 +3094,7 @@ for (i = low; i < high; i++) { bpage = buf_page_hash_get(buf_pool, space, i); -@@ -356,7 +358,8 @@ +@@ -523,7 +525,8 @@ if (fail_count > threshold) { /* Too many failures: return */ @@ -3067,7 +3104,7 @@ return(0); } -@@ -371,7 +374,8 @@ +@@ -538,7 +541,8 @@ bpage = buf_page_hash_get(buf_pool, space, offset); if (bpage == NULL) { @@ -3077,7 +3114,7 @@ return(0); } -@@ -397,7 +401,8 @@ +@@ -564,7 +568,8 @@ pred_offset = fil_page_get_prev(frame); succ_offset = fil_page_get_next(frame); @@ -3110,7 +3147,7 @@ # endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */ --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc -@@ -1563,7 +1563,8 @@ +@@ -1583,7 +1583,8 @@ buf_pool = buf_pool_from_array(i); @@ -3120,7 +3157,7 @@ for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) { buf_buddy_stat_t* buddy_stat; -@@ -1593,7 +1594,8 @@ +@@ -1613,7 +1614,8 @@ } } @@ -3258,7 +3295,7 @@ #ifdef UNIV_MATERIALIZE --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h -@@ -208,6 +208,20 @@ +@@ -212,6 +212,20 @@ /*==========================*/ /********************************************************************//** @@ -3279,7 +3316,7 @@ Creates the buffer pool. @return own: buf_pool object, NULL if not enough memory or error */ UNIV_INTERN -@@ -873,6 +887,15 @@ +@@ -864,6 +878,15 @@ const buf_page_t* bpage) /*!< in: pointer to control block */ __attribute__((pure)); @@ -3295,7 +3332,7 @@ /*********************************************************************//** Get the flush type of a page. @return flush type */ -@@ -1354,7 +1377,7 @@ +@@ -1345,7 +1368,7 @@ All these are protected by buf_pool->mutex. */ /* @{ */ @@ -3304,7 +3341,7 @@ /*!< based on state, this is a list node, protected either by buf_pool->mutex or by -@@ -1382,6 +1405,10 @@ +@@ -1373,6 +1396,10 @@ BUF_BLOCK_REMOVE_HASH or BUF_BLOCK_READY_IN_USE. */ @@ -3315,7 +3352,7 @@ #ifdef UNIV_DEBUG ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list; when buf_pool->flush_list_mutex is -@@ -1474,11 +1501,11 @@ +@@ -1465,11 +1492,11 @@ a block is in the unzip_LRU list if page.state == BUF_BLOCK_FILE_PAGE and page.zip.data != NULL */ @@ -3329,7 +3366,7 @@ mutex_t mutex; /*!< mutex protecting this block: state (also protected by the buffer pool mutex), io_fix, buf_fix_count, -@@ -1653,6 +1680,11 @@ +@@ -1646,6 +1673,11 @@ pool instance, protects compressed only pages (of type buf_page_t, not buf_block_t */ @@ -3341,7 +3378,7 @@ ulint instance_no; /*!< Array index of this buffer pool instance */ ulint old_pool_size; /*!< Old pool size in bytes */ -@@ -1806,8 +1838,8 @@ +@@ -1799,8 +1831,8 @@ /** Test if a buffer pool mutex is owned. */ #define buf_pool_mutex_own(b) mutex_own(&b->mutex) /** Acquire a buffer pool mutex. */ @@ -3353,7 +3390,7 @@ --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic -@@ -274,7 +274,7 @@ +@@ -292,7 +292,7 @@ case BUF_BLOCK_ZIP_FREE: /* This is a free page in buf_pool->zip_free[]. Such pages should only be accessed by the buddy allocator. */ @@ -3362,7 +3399,7 @@ break; case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_DIRTY: -@@ -317,9 +317,16 @@ +@@ -335,9 +335,16 @@ { buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); @@ -3380,7 +3417,7 @@ return(NULL); case BUF_BLOCK_ZIP_PAGE: case BUF_BLOCK_ZIP_DIRTY: -@@ -329,6 +336,28 @@ +@@ -347,6 +354,28 @@ } } @@ -3409,7 +3446,7 @@ /*********************************************************************//** Get the flush type of a page. @return flush type */ -@@ -425,8 +454,8 @@ +@@ -443,8 +472,8 @@ enum buf_io_fix io_fix) /*!< in: io_fix state */ { #ifdef UNIV_DEBUG @@ -3420,7 +3457,7 @@ #endif ut_ad(mutex_own(buf_page_get_mutex(bpage))); -@@ -456,14 +485,14 @@ +@@ -474,14 +503,14 @@ const buf_page_t* bpage) /*!< control block being relocated */ { #ifdef UNIV_DEBUG @@ -3439,7 +3476,7 @@ && bpage->buf_fix_count == 0); } -@@ -477,8 +506,8 @@ +@@ -495,8 +524,8 @@ const buf_page_t* bpage) /*!< in: control block */ { #ifdef UNIV_DEBUG @@ -3450,7 +3487,7 @@ #endif ut_ad(buf_page_in_file(bpage)); -@@ -498,7 +527,8 @@ +@@ -516,7 +545,8 @@ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); #endif /* UNIV_DEBUG */ ut_a(buf_page_in_file(bpage)); @@ -3460,7 +3497,7 @@ ut_ad(bpage->in_LRU_list); #ifdef UNIV_LRU_DEBUG -@@ -545,9 +575,10 @@ +@@ -563,9 +593,10 @@ ulint time_ms) /*!< in: ut_time_ms() */ { #ifdef UNIV_DEBUG @@ -3473,7 +3510,7 @@ ut_a(buf_page_in_file(bpage)); if (!bpage->access_time) { -@@ -790,19 +821,19 @@ +@@ -808,19 +839,19 @@ /*===========*/ buf_block_t* block) /*!< in, own: block to be freed */ { @@ -3497,7 +3534,7 @@ } #endif /* !UNIV_HOTBACKUP */ -@@ -850,17 +881,17 @@ +@@ -868,17 +899,17 @@ page frame */ { ib_uint64_t lsn; @@ -3520,7 +3557,7 @@ return(lsn); } -@@ -878,7 +909,7 @@ +@@ -896,7 +927,7 @@ #ifdef UNIV_SYNC_DEBUG buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block); @@ -3529,7 +3566,7 @@ && (block->page.buf_fix_count == 0)) || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); #endif /* UNIV_SYNC_DEBUG */ -@@ -995,7 +1026,11 @@ +@@ -1026,7 +1057,11 @@ buf_page_t* bpage; ut_ad(buf_pool); @@ -3542,7 +3579,7 @@ ut_ad(fold == buf_page_address_fold(space, offset)); /* Look for the page in the hash table */ -@@ -1080,11 +1115,13 @@ +@@ -1111,11 +1146,13 @@ const buf_page_t* bpage; buf_pool_t* buf_pool = buf_pool_get(space, offset); @@ -3558,7 +3595,7 @@ return(bpage != NULL); } -@@ -1212,4 +1249,38 @@ +@@ -1243,4 +1280,38 @@ buf_pool_mutex_exit(buf_pool); } } @@ -3643,7 +3680,7 @@ extern mysql_pfs_key_t cache_last_read_mutex_key; extern mysql_pfs_key_t dict_foreign_err_mutex_key; extern mysql_pfs_key_t dict_sys_mutex_key; -@@ -670,7 +674,7 @@ +@@ -667,7 +671,7 @@ #define SYNC_TRX_SYS_HEADER 290 #define SYNC_PURGE_QUEUE 200 #define SYNC_LOG 170 @@ -3652,7 +3689,7 @@ #define SYNC_RECV 168 #define SYNC_WORK_QUEUE 162 #define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */ -@@ -680,8 +684,13 @@ +@@ -677,8 +681,13 @@ SYNC_SEARCH_SYS, as memory allocation can call routines there! Otherwise the level is SYNC_MEM_HASH. */ @@ -3667,7 +3704,7 @@ #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */ #define SYNC_DOUBLEWRITE 140 #define SYNC_ANY_LATCH 135 -@@ -713,7 +722,7 @@ +@@ -709,7 +718,7 @@ os_fast_mutex; /*!< We use this OS mutex in place of lock_word when atomic operations are not enabled */ #endif @@ -3678,7 +3715,7 @@ Otherwise, this is 0. */ --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -3098,7 +3098,7 @@ +@@ -3102,7 +3102,7 @@ level += log_sys->max_checkpoint_age - (lsn - oldest_modification); } @@ -3687,7 +3724,7 @@ n_blocks++; } -@@ -3184,7 +3184,7 @@ +@@ -3188,7 +3188,7 @@ found = TRUE; break; } @@ -3731,7 +3768,7 @@ } /******************************************************************//** -@@ -1239,7 +1249,12 @@ +@@ -1234,7 +1244,12 @@ ut_error; } break; @@ -3744,7 +3781,7 @@ case SYNC_BUF_POOL: /* We can have multiple mutexes of this type therefore we can only check whether the greater than condition holds. */ -@@ -1257,7 +1272,8 @@ +@@ -1252,7 +1267,8 @@ buffer block (block->mutex or buf_pool->zip_mutex). */ if (!sync_thread_levels_g(array, level, FALSE)) { ut_a(sync_thread_levels_g(array, level - 1, TRUE)); diff --git a/innodb_stats.patch b/innodb_stats.patch index 8d8d783..4f4ee62 100644 --- a/innodb_stats.patch +++ b/innodb_stats.patch @@ -356,7 +356,7 @@ } return(table); -@@ -4343,6 +4343,295 @@ +@@ -4344,6 +4344,295 @@ } /*********************************************************************//** @@ -652,7 +652,7 @@ Calculates new estimates for table and index statistics. The statistics are used in query optimization. */ UNIV_INTERN -@@ -4350,10 +4639,11 @@ +@@ -4351,10 +4640,11 @@ dict_update_statistics( /*===================*/ dict_table_t* table, /*!< in/out: table */ @@ -665,7 +665,7 @@ { dict_index_t* index; ulint sum_of_index_sizes = 0; -@@ -4370,6 +4660,27 @@ +@@ -4371,6 +4661,27 @@ return; } @@ -693,7 +693,7 @@ /* Find out the sizes of the indexes and how many different values for the key they approximately have */ -@@ -4434,6 +4745,11 @@ +@@ -4435,6 +4746,11 @@ index = dict_table_get_next_index(index); } while (index); @@ -705,7 +705,7 @@ index = dict_table_get_first_index(table); table->stat_n_rows = index->stat_n_diff_key_vals[ -@@ -4451,6 +4767,78 @@ +@@ -4452,6 +4768,78 @@ dict_table_stats_unlock(table, RW_X_LATCH); } @@ -784,7 +784,7 @@ /**********************************************************************//** Prints info of a foreign key constraint. */ static -@@ -4528,7 +4916,8 @@ +@@ -4529,7 +4917,8 @@ ut_ad(mutex_own(&(dict_sys->mutex))); @@ -804,9 +804,9 @@ + "SYS_FOREIGN_COLS", + "SYS_STATS" }; - /****************************************************************//** - Compare the name of an index column. -@@ -343,12 +344,13 @@ + + /* If this flag is TRUE, then we will load the cluster index's (and tables') +@@ -348,12 +349,13 @@ } if ((status & DICT_TABLE_UPDATE_STATS) @@ -821,7 +821,7 @@ } return(NULL); -@@ -582,6 +584,75 @@ +@@ -587,6 +589,75 @@ //#endif /* FOREIGN_NOT_USED */ /********************************************************************//** @@ -907,7 +907,7 @@ static char* internal_innobase_data_file_path = NULL; -@@ -2439,6 +2440,8 @@ +@@ -2468,6 +2469,8 @@ goto error; } @@ -916,7 +916,7 @@ /* -------------- Log files ---------------------------*/ /* The default dir for log files is the datadir of MySQL */ -@@ -5247,6 +5250,10 @@ +@@ -5257,6 +5260,10 @@ error = row_insert_for_mysql((byte*) record, prebuilt); @@ -927,7 +927,7 @@ /* Handle duplicate key errors */ if (auto_inc_used) { ulint err; -@@ -5583,6 +5590,10 @@ +@@ -5593,6 +5600,10 @@ } } @@ -938,7 +938,7 @@ innodb_srv_conc_exit_innodb(trx); error = convert_error_code_to_mysql(error, -@@ -5636,6 +5647,10 @@ +@@ -5646,6 +5657,10 @@ error = row_update_for_mysql((byte*) record, prebuilt); @@ -949,7 +949,7 @@ innodb_srv_conc_exit_innodb(trx); error = convert_error_code_to_mysql( -@@ -5954,6 +5969,11 @@ +@@ -5966,6 +5981,11 @@ case DB_SUCCESS: error = 0; table->status = 0; @@ -961,7 +961,7 @@ break; case DB_RECORD_NOT_FOUND: error = HA_ERR_KEY_NOT_FOUND; -@@ -6163,6 +6183,11 @@ +@@ -6198,6 +6218,11 @@ case DB_SUCCESS: error = 0; table->status = 0; @@ -973,7 +973,7 @@ break; case DB_RECORD_NOT_FOUND: error = HA_ERR_END_OF_FILE; -@@ -8105,11 +8130,35 @@ +@@ -8144,11 +8169,35 @@ /* In sql_show we call with this flag: update then statistics so that they are up-to-date */ @@ -1010,7 +1010,7 @@ prebuilt->trx->op_info = "returning various info to MySQL"; } -@@ -8187,7 +8236,7 @@ +@@ -8233,7 +8282,7 @@ are asked by MySQL to avoid locking. Another reason to avoid the call is that it uses quite a lot of CPU. See Bug#38185. */ @@ -1019,7 +1019,7 @@ || !(flag & HA_STATUS_VARIABLE_EXTRA)) { /* We do not update delete_length if no locking is requested so the "old" value can -@@ -11401,6 +11450,26 @@ +@@ -11503,6 +11552,26 @@ "The number of index pages to sample when calculating statistics (default 8)", NULL, NULL, 8, 1, ~0ULL, 0); @@ -1046,7 +1046,7 @@ static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled, PLUGIN_VAR_OPCMDARG, "Enable InnoDB adaptive hash index (enabled by default). " -@@ -11727,6 +11796,9 @@ +@@ -11835,6 +11904,9 @@ MYSQL_SYSVAR(recovery_update_relay_log), MYSQL_SYSVAR(rollback_on_timeout), MYSQL_SYSVAR(stats_on_metadata), @@ -1056,7 +1056,7 @@ MYSQL_SYSVAR(stats_sample_pages), MYSQL_SYSVAR(adaptive_hash_index), MYSQL_SYSVAR(stats_method), -@@ -11796,7 +11868,10 @@ +@@ -11906,7 +11978,10 @@ i_s_innodb_sys_columns, i_s_innodb_sys_fields, i_s_innodb_sys_foreign, @@ -1078,7 +1078,7 @@ } #define OK(expr) \ -@@ -3455,6 +3456,221 @@ +@@ -3483,6 +3484,221 @@ STRUCT_FLD(__reserved1, NULL) }; @@ -1300,7 +1300,7 @@ /*********************************************************************** */ static ST_FIELD_INFO i_s_innodb_rseg_fields_info[] = -@@ -3617,3 +3833,347 @@ +@@ -3645,3 +3861,347 @@ /* void* */ STRUCT_FLD(__reserved1, NULL) }; @@ -1682,8 +1682,8 @@ +#define DICT_HDR_XTRADB_MARK 256 /* Flag to distinguish expansion of XtraDB */ /*-------------------------------------------------------------*/ - /* The field number of the page number field in the sys_indexes table -@@ -144,11 +148,16 @@ + /* The field numbers in the SYS_TABLES clustered index */ +@@ -146,11 +150,16 @@ #define DICT_SYS_INDEXES_TYPE_FIELD 6 #define DICT_SYS_INDEXES_NAME_FIELD 4 @@ -1757,7 +1757,7 @@ #include "dict0crea.ic" --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h -@@ -1109,10 +1109,18 @@ +@@ -1126,10 +1126,18 @@ dict_update_statistics( /*===================*/ dict_table_t* table, /*!< in/out: table */ @@ -1777,7 +1777,7 @@ /********************************************************************//** Reserves the dictionary system mutex for MySQL. */ UNIV_INTERN -@@ -1227,6 +1235,7 @@ +@@ -1244,6 +1252,7 @@ dict_table_t* sys_columns; /*!< SYS_COLUMNS table */ dict_table_t* sys_indexes; /*!< SYS_INDEXES table */ dict_table_t* sys_fields; /*!< SYS_FIELDS table */ @@ -1854,7 +1854,7 @@ should be called after the indexes for a table have been created. --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -211,6 +211,9 @@ +@@ -216,6 +216,9 @@ extern ibool srv_innodb_status; extern unsigned long long srv_stats_sample_pages; @@ -1908,7 +1908,7 @@ } else { --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c -@@ -2013,6 +2013,8 @@ +@@ -2015,6 +2015,8 @@ } #ifdef UNIV_DEBUG @@ -1930,7 +1930,7 @@ /* Drop the index definition and the B-tree. */ --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c -@@ -921,6 +921,9 @@ +@@ -922,6 +922,9 @@ table->stat_modified_counter = counter + 1; @@ -1940,7 +1940,7 @@ /* Calculate new statistics if 1 / 16 of table has been modified since the last time a statistics batch was run, or if stat_modified_counter > 2 000 000 000 (to avoid wrap-around). -@@ -931,7 +934,7 @@ +@@ -932,7 +935,7 @@ || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) { dict_update_statistics(table, FALSE /* update even if stats @@ -1949,7 +1949,7 @@ } } -@@ -2076,6 +2079,71 @@ +@@ -2077,6 +2080,71 @@ } /*********************************************************************//** @@ -2021,7 +2021,7 @@ Scans a table create SQL string and adds to the data dictionary the foreign key constraints declared in the string. This function should be called after the indexes for a table have been created. -@@ -3000,7 +3068,7 @@ +@@ -3001,7 +3069,7 @@ dict_table_autoinc_initialize(table, 1); dict_table_autoinc_unlock(table); dict_update_statistics(table, FALSE /* update even if stats are @@ -2030,7 +2030,7 @@ trx_commit_for_mysql(trx); -@@ -3302,6 +3370,8 @@ +@@ -3312,6 +3380,8 @@ " IF (SQL % NOTFOUND) THEN\n" " found := 0;\n" " ELSE\n" @@ -2041,7 +2041,7 @@ " DELETE FROM SYS_INDEXES\n" --- a/storage/innobase/row/row0row.c +++ b/storage/innobase/row/row0row.c -@@ -373,6 +373,14 @@ +@@ -364,6 +364,14 @@ rec_len = rec_offs_n_fields(offsets); @@ -2056,7 +2056,7 @@ entry = dtuple_create(heap, rec_len); dtuple_set_n_fields_cmp(entry, -@@ -384,6 +392,14 @@ +@@ -375,6 +383,14 @@ for (i = 0; i < rec_len; i++) { dfield = dtuple_get_nth_field(entry, i); @@ -2107,7 +2107,7 @@ dfield = dtuple_get_nth_field(entry, i); --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -398,6 +398,9 @@ +@@ -400,6 +400,9 @@ /* When estimating number of different key values in an index, sample this many index pages */ UNIV_INTERN unsigned long long srv_stats_sample_pages = 8; @@ -2119,12 +2119,12 @@ UNIV_INTERN ibool srv_use_checksums = TRUE; --- a/storage/innobase/trx/trx0rec.c +++ b/storage/innobase/trx/trx0rec.c -@@ -669,15 +669,27 @@ +@@ -669,14 +669,27 @@ /* Save to the undo log the old values of the columns to be updated. */ if (update) { + ulint extended = 0; - ++ if (trx_undo_left(undo_page, ptr) < 5) { return(0); @@ -2135,8 +2135,7 @@ + && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes)) { + for (i = 0; i < upd_get_n_fields(update); i++) { + ulint pos = upd_get_nth_field(update, i)->field_no; - -- for (i = 0; i < upd_get_n_fields(update); i++) { ++ + if (pos >= rec_offs_n_fields(offsets)) { + extended++; + } @@ -2144,7 +2143,8 @@ + } + + ptr += mach_write_compressed(ptr, upd_get_n_fields(update) - extended); -+ + +- for (i = 0; i < upd_get_n_fields(update); i++) { + for (i = 0; i < upd_get_n_fields(update) - extended; i++) { ulint pos = upd_get_nth_field(update, i)->field_no; diff --git a/innodb_thread_concurrency_timer_based.patch b/innodb_thread_concurrency_timer_based.patch index 767a038..322961d 100644 --- a/innodb_thread_concurrency_timer_based.patch +++ b/innodb_thread_concurrency_timer_based.patch @@ -15,7 +15,7 @@ static long long innobase_buffer_pool_size, innobase_log_file_size; /** Percentage of the buffer pool to reserve for 'old' blocks. -@@ -2548,6 +2549,9 @@ +@@ -2577,6 +2578,9 @@ srv_n_log_files = (ulint) innobase_log_files_in_group; srv_log_file_size = (ulint) innobase_log_file_size; @@ -25,7 +25,7 @@ #ifdef UNIV_LOG_ARCHIVE srv_log_archive_on = (ulint) innobase_log_archive; #endif /* UNIV_LOG_ARCHIVE */ -@@ -11491,6 +11495,12 @@ +@@ -11593,6 +11597,12 @@ "Maximum delay between polling for a spin lock (6 by default)", NULL, NULL, 6L, 0L, ~0L, 0); @@ -38,7 +38,7 @@ static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency, PLUGIN_VAR_RQCMDARG, "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.", -@@ -11703,6 +11713,7 @@ +@@ -11811,6 +11821,7 @@ MYSQL_SYSVAR(spin_wait_delay), MYSQL_SYSVAR(table_locks), MYSQL_SYSVAR(thread_concurrency), @@ -48,18 +48,18 @@ MYSQL_SYSVAR(show_verbose_locks), --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h -@@ -161,6 +161,8 @@ +@@ -165,6 +165,8 @@ extern ulint srv_mem_pool_size; extern ulint srv_lock_table_size; +extern ibool srv_thread_concurrency_timer_based; + extern ulint srv_n_file_io_threads; + extern my_bool srv_random_read_ahead; extern ulong srv_read_ahead_threshold; - extern ulint srv_n_read_io_threads; --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c -@@ -347,6 +347,7 @@ +@@ -349,6 +349,7 @@ computer. Bigger computers need bigger values. Value 0 will disable the concurrency check. */ @@ -67,7 +67,7 @@ UNIV_INTERN ulong srv_thread_concurrency = 0; /* this mutex protects srv_conc data structures */ -@@ -1143,6 +1144,75 @@ +@@ -1145,6 +1146,75 @@ /*********************************************************************//** Puts an OS thread to wait if there are too many concurrent threads (>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */ @@ -143,7 +143,7 @@ UNIV_INTERN void srv_conc_enter_innodb( -@@ -1177,6 +1247,13 @@ +@@ -1179,6 +1249,13 @@ return; } @@ -157,7 +157,7 @@ os_fast_mutex_lock(&srv_conc_mutex); retry: if (trx->declared_to_be_inside_innodb) { -@@ -1330,6 +1407,14 @@ +@@ -1332,6 +1409,14 @@ } ut_ad(srv_conc_n_threads >= 0); @@ -172,7 +172,7 @@ os_fast_mutex_lock(&srv_conc_mutex); -@@ -1363,6 +1448,13 @@ +@@ -1365,6 +1450,13 @@ return; } diff --git a/log_warnings_suppress.patch b/log_warnings_suppress.patch index cf41b7f..821a9cb 100644 --- a/log_warnings_suppress.patch +++ b/log_warnings_suppress.patch @@ -41,7 +41,7 @@ using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr(). --- a/sql/sql_class.cc +++ b/sql/sql_class.cc -@@ -4854,7 +4854,7 @@ +@@ -4874,7 +4874,7 @@ ER_BINLOG_UNSAFE_STATEMENT, ER(ER_BINLOG_UNSAFE_STATEMENT), ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type])); @@ -62,7 +62,7 @@ SLAVE_EXEC_MODE_LAST_BIT}; --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc -@@ -1470,6 +1470,15 @@ +@@ -1493,6 +1493,15 @@ READ_ONLY GLOBAL_VAR(mysqld_port), CMD_LINE(REQUIRED_ARG, 'P'), VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1)); @@ -166,3 +166,23 @@ + print "Occurrences: $count\n"; + close(FILE); +EOF +--- a/mysql-test/r/mysqld--help-notwin.result ++++ b/mysql-test/r/mysqld--help-notwin.result +@@ -281,6 +281,9 @@ + --log-tc-size=# Size of transaction coordinator log. + -W, --log-warnings[=#] + Log some not critical warnings to the log file ++ --log-warnings-suppress=name ++ disable logging of enumerated warnings: 1592: unsafe ++ statements for binary logging; possible values : [1592] + --long-query-time=# Log all queries that have taken more than long_query_time + seconds to execute to file. The argument will be treated + as a decimal value with microsecond precision +@@ -863,6 +866,7 @@ + log-tc tc.log + log-tc-size 24576 + log-warnings 1 ++log-warnings-suppress + long-query-time 10 + low-priority-updates FALSE + lower-case-table-names 1 diff --git a/memory_dynamic_rows.patch b/memory_dynamic_rows.patch index dbea06b..5b6da12 100644 --- a/memory_dynamic_rows.patch +++ b/memory_dynamic_rows.patch @@ -19,7 +19,7 @@ #define HP_MAX_LEVELS 4 /* 128^5 records is enough */ #define HP_PTRS_IN_NOD 128 -@@ -130,22 +140,58 @@ +@@ -131,22 +141,58 @@ uint (*get_key_length)(struct st_hp_keydef *keydef, const uchar *key); } HP_KEYDEF; @@ -83,9 +83,9 @@ uint open_count; - uchar *del_link; /* Link to next block with del. rec */ char * name; /* Name of "memory-file" */ + time_t create_time; THR_LOCK lock; - mysql_mutex_t intern_lock; /* Locking for use with _locking */ -@@ -154,6 +200,7 @@ +@@ -156,6 +202,7 @@ uint auto_key; uint auto_key_type; /* real type of the auto key segment */ ulonglong auto_increment; @@ -93,7 +93,7 @@ } HP_SHARE; struct st_hp_hash_info; -@@ -163,7 +210,7 @@ +@@ -165,7 +212,7 @@ HP_SHARE *s; uchar *current_ptr; struct st_hp_hash_info *current_hash_ptr; @@ -102,7 +102,7 @@ int lastinx,errkey; int mode; /* Mode of file (READONLY..) */ uint opt_flag,update; -@@ -176,6 +223,9 @@ +@@ -178,6 +225,9 @@ my_bool implicit_emptied; THR_LOCK_DATA lock; LIST open_list; @@ -112,7 +112,7 @@ } HP_INFO; -@@ -197,6 +247,14 @@ +@@ -199,6 +249,14 @@ open_count to 1. Is only looked at if not internal_table. */ my_bool pin_share; @@ -127,7 +127,7 @@ } HP_CREATE_INFO; /* Prototypes for heap-functions */ -@@ -213,9 +271,8 @@ +@@ -215,9 +273,8 @@ extern int heap_scan(register HP_INFO *info, uchar *record); extern int heap_delete(HP_INFO *info,const uchar *buff); extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag); @@ -318,7 +318,7 @@ } } -@@ -428,6 +435,13 @@ +@@ -429,6 +436,13 @@ return 0; } @@ -332,7 +332,7 @@ int ha_heap::extra(enum ha_extra_function operation) { -@@ -645,23 +659,70 @@ +@@ -646,23 +660,70 @@ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table, HP_CREATE_INFO *hp_create_info) { @@ -405,7 +405,7 @@ seg= reinterpret_cast(keydef + keys); for (key= 0; key < keys; key++) { -@@ -677,11 +738,11 @@ +@@ -678,11 +739,11 @@ case HA_KEY_ALG_UNDEF: case HA_KEY_ALG_HASH: keydef[key].algorithm= HA_KEY_ALG_HASH; @@ -419,7 +419,7 @@ break; default: DBUG_ASSERT(0); // cannot happen -@@ -706,6 +767,16 @@ +@@ -707,6 +768,16 @@ seg->length= (uint) key_part->length; seg->flag= key_part->key_part_flag; @@ -436,7 +436,7 @@ if (field->flags & (ENUM_FLAG | SET_FLAG)) seg->charset= &my_charset_bin; else -@@ -731,9 +802,75 @@ +@@ -732,9 +803,75 @@ auto_key= key+ 1; auto_key_type= field->key_type(); } @@ -513,7 +513,7 @@ if (table_arg->found_next_number_field) { keydef[share->next_number_index].flag|= HA_AUTO_KEY; -@@ -744,16 +881,19 @@ +@@ -745,16 +882,19 @@ hp_create_info->max_table_size=current_thd->variables.max_heap_table_size; hp_create_info->with_auto_increment= found_real_auto_increment; hp_create_info->internal_table= internal_table; @@ -539,7 +539,7 @@ return 0; } -@@ -773,6 +913,7 @@ +@@ -774,6 +914,7 @@ create_info->auto_increment_value - 1 : 0); error= heap_create(name, &hp_create_info, &internal_share, &created); my_free(hp_create_info.keydef); @@ -547,7 +547,7 @@ DBUG_ASSERT(file == 0); return (error); } -@@ -783,6 +924,13 @@ +@@ -784,6 +925,13 @@ table->file->info(HA_STATUS_AUTO); if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) create_info->auto_increment_value= stats.auto_increment_value; @@ -964,7 +964,7 @@ /* Fix keys */ memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys)); for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++) -@@ -177,15 +310,35 @@ +@@ -177,16 +310,36 @@ share->min_records= min_records; share->max_records= max_records; share->max_table_size= create_info->max_table_size; @@ -979,6 +979,7 @@ share->auto_key= create_info->auto_key; share->auto_key_type= create_info->auto_key_type; share->auto_increment= create_info->auto_increment; + share->create_time= (long) time((time_t*) 0); + + share->fixed_data_length= fixed_data_length; + share->fixed_column_count= fixed_column_count; @@ -1002,7 +1003,7 @@ /* Must be allocated separately for rename to work */ if (!(share->name= my_strdup(name,MYF(0)))) { -@@ -227,7 +380,7 @@ +@@ -228,7 +381,7 @@ param->search_flag, not_used); } @@ -1011,7 +1012,7 @@ ulong max_records) { uint i,recbuffer,records_in_block; -@@ -235,7 +388,12 @@ +@@ -236,7 +389,12 @@ max_records= max(min_records,max_records); if (!max_records) max_records= 1000; /* As good as quess as anything */ @@ -3944,7 +3945,7 @@ +PRIMARY KEY (f1)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC ++t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC +DROP TABLE t1; +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=33 ENGINE=HEAP ROW_FORMAT=DYNAMIC; @@ -3955,25 +3956,25 @@ +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=34 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=34 ++t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=34 +DROP TABLE t1; +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=123 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=123 ++t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=123 +DROP TABLE t1; +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=1000 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=1000 ++t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=1000 +DROP TABLE t1; +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), +PRIMARY KEY (f1)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC ++t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC +DROP TABLE t1; +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=33 ENGINE=HEAP ROW_FORMAT=DYNAMIC; @@ -3984,19 +3985,19 @@ +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=34 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=34 ++t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=34 +DROP TABLE t1; +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=121 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=121 ++t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=121 +DROP TABLE t1; +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=1000 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=1000 ++t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=1000 +DROP TABLE t1; --- /dev/null +++ b/mysql-test/r/percona_heap_bug784464_32bit.result @@ -4005,13 +4006,13 @@ +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=124 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=124 ++t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=124 +DROP TABLE t1; +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=122 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=122 ++t1 MEMORY 10 Dynamic 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=122 +DROP TABLE t1; --- /dev/null +++ b/mysql-test/r/percona_heap_bug784464_64bit.result @@ -4020,13 +4021,13 @@ +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=124 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=124 ++t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=124 +DROP TABLE t1; +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), +PRIMARY KEY (f1)) KEY_BLOCK_SIZE=122 ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=122 ++t1 MEMORY 10 Fixed 0 X 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC KEY_BLOCK_SIZE=122 +DROP TABLE t1; --- /dev/null +++ b/mysql-test/r/percona_heap_bug784468.result @@ -4034,17 +4035,17 @@ +CREATE TABLE t1 ( f1 VARCHAR(30)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Fixed 0 32 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC ++t1 MEMORY 10 Fixed 0 32 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC +DROP TABLE t1; +CREATE TABLE t1 ( f1 VARCHAR(31)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Fixed 0 33 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC ++t1 MEMORY 10 Fixed 0 33 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC +DROP TABLE t1; +CREATE TABLE t1 ( f1 VARCHAR(32)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -+t1 MEMORY 10 Fixed 0 34 0 X 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL row_format=DYNAMIC ++t1 MEMORY 10 Fixed 0 34 0 X 0 0 NULL X X NULL latin1_swedish_ci NULL row_format=DYNAMIC +DROP TABLE t1; --- /dev/null +++ b/mysql-test/r/percona_heap_bug788544.result @@ -4996,7 +4997,7 @@ +DROP TABLE local_1_1; --- /dev/null +++ b/mysql-test/t/percona_heap_bug784464.test -@@ -0,0 +1,64 @@ +@@ -0,0 +1,66 @@ +# +# Bug #784464: Silent conversion from Dynamic to Fixed row_format for certain +# values of key_block_size. @@ -5005,59 +5006,61 @@ + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), + PRIMARY KEY (f1)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +--error ER_CANT_USE_OPTION_HERE +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=33 ENGINE=HEAP ROW_FORMAT=DYNAMIC; ++--replace_column 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=34 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=123 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=1000 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), + PRIMARY KEY (f1)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +--error ER_CANT_USE_OPTION_HERE +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=33 ENGINE=HEAP ROW_FORMAT=DYNAMIC; ++--replace_column 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=34 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=121 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=1000 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + @@ -5070,13 +5073,13 @@ + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=124 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=122 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; --- /dev/null @@ -5088,13 +5091,13 @@ + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(32), f3 VARCHAR(32), f4 VARCHAR(32), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=124 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +CREATE TABLE t1 (f1 VARCHAR(32), f2 VARCHAR(96), + PRIMARY KEY (f1)) KEY_BLOCK_SIZE=122 ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 6 X 8 X ++--replace_column 6 X 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; --- /dev/null @@ -5105,17 +5108,17 @@ +# + +CREATE TABLE t1 ( f1 VARCHAR(30)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 8 X ++--replace_column 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +CREATE TABLE t1 ( f1 VARCHAR(31)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 8 X ++--replace_column 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + +CREATE TABLE t1 ( f1 VARCHAR(32)) ENGINE=HEAP ROW_FORMAT=DYNAMIC; -+--replace_column 8 X ++--replace_column 8 X 12 X 13 X +SHOW TABLE STATUS LIKE 't1'; +DROP TABLE t1; + diff --git a/microsec_process.patch b/microsec_process.patch index 0f9842a..4a17c29 100644 --- a/microsec_process.patch +++ b/microsec_process.patch @@ -5,8 +5,8 @@ #!!! notice !!! # Any small change to this file in the main branch # should be done or reviewed by the maintainer! ---- /dev/null 1970-01-01 09:00:00.000000000 +0900 -+++ b/patch_info/microsec_process.info 2010-12-02 20:41:41.616069579 +0900 +--- /dev/null ++++ b/patch_info/microsec_process.info @@ -0,0 +1,8 @@ +File=microsec_process.patch +Name=Adds INFOMATION_SCHEMA.PROCESSLIST with TIME_MS column @@ -16,8 +16,8 @@ +Comment= +2010-01 +Ported to 5.1.42 ---- a/sql/sql_show.cc 2010-12-02 19:22:40.054024541 +0900 -+++ b/sql/sql_show.cc 2010-12-02 20:41:41.622941425 +0900 +--- a/sql/sql_show.cc ++++ b/sql/sql_show.cc @@ -1890,7 +1890,8 @@ TABLE *table= tables->table; CHARSET_INFO *cs= system_charset_info; @@ -39,7 +39,7 @@ if (schema_table_store_record(thd, table)) { mysql_mutex_unlock(&LOCK_thread_count); -@@ -7409,6 +7414,8 @@ +@@ -7464,6 +7469,8 @@ {"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE}, {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info", SKIP_OPEN_TABLE}, diff --git a/mysql.spec b/mysql.spec index 2887e47..75d3d13 100644 --- a/mysql.spec +++ b/mysql.spec @@ -35,13 +35,13 @@ Summary(ru.UTF-8): MySQL - быстрый SQL-сервер Summary(uk.UTF-8): MySQL - швидкий SQL-сервер Summary(zh_CN.UTF-8): MySQL数据库服务器 Name: mysql -Version: 5.5.15 -Release: 3 +Version: 5.5.17 +Release: 1 License: GPL + MySQL FLOSS Exception Group: Applications/Databases # Source0Download: http://dev.mysql.com/downloads/mysql/5.5.html#downloads Source0: http://vesta.informatik.rwth-aachen.de/mysql/Downloads/MySQL-5.5/%{name}-%{version}.tar.gz -# Source0-md5: 306b5549c7bd72e8e705a890db0da82b +# Source0-md5: dcb6a06e68c5e8f30f57b15300730c9c Source100: http://www.sphinxsearch.com/files/sphinx-2.0.1-beta.tar.gz # Source100-md5: 95c217d81d0b7a4ff73d5297318c3481 Source1: %{name}.init @@ -108,31 +108,36 @@ Patch127: innodb_adaptive_hash_index_partitions.patch Patch128: innodb_buffer_pool_pages_i_s.patch Patch129: innodb_buffer_pool_shm.patch Patch130: innodb_show_status_extend.patch -Patch131: slow_extended.patch -Patch132: percona_support.patch -Patch133: query_cache_enhance.patch -Patch134: log_connection_error.patch -Patch135: mysql_syslog.patch -Patch136: error_pad.patch -Patch137: response_time_distribution.patch -Patch138: remove_fcntl_excessive_calls.patch -Patch139: sql_no_fcache.patch -Patch140: show_slave_status_nolock.patch -Patch141: log_warnings_suppress.patch -Patch142: userstat.patch -Patch143: bug580324.patch -Patch144: mysql_remove_eol_carret.patch -Patch145: processlist_row_stats.patch -Patch146: innodb_expand_fast_index_creation.patch -Patch147: innodb_bug60788.patch -Patch148: start-stop-messages.patch -Patch149: file-contents.patch -Patch150: slave_timeout_fix.patch -Patch151: utf8_general50_ci.patch -Patch152: bug813587.patch -Patch153: valgrind_zlib_suppression.patch -Patch154: memory_dynamic_rows.patch -Patch155: xtradb_bug317074.patch +Patch131: innodb_kill_idle_transaction.patch +Patch132: innodb_fake_changes.patch +Patch133: slow_extended.patch +Patch134: percona_support.patch +Patch135: query_cache_enhance.patch +Patch136: log_connection_error.patch +Patch137: mysql_syslog.patch +Patch138: error_pad.patch +Patch139: response_time_distribution.patch +Patch140: remove_fcntl_excessive_calls.patch +Patch141: sql_no_fcache.patch +Patch142: show_slave_status_nolock.patch +Patch143: log_warnings_suppress.patch +Patch144: userstat.patch +Patch145: bug580324.patch +Patch146: mysql_remove_eol_carret.patch +Patch147: processlist_row_stats.patch +Patch148: innodb_expand_fast_index_creation.patch +Patch149: innodb_bug60788.patch +Patch150: start-stop-messages.patch +Patch151: file-contents.patch +Patch152: slave_timeout_fix.patch +Patch153: utf8_general50_ci.patch +Patch154: bug813587.patch +Patch155: valgrind_zlib_suppression.patch +Patch156: memory_dynamic_rows.patch +Patch157: xtradb_bug317074.patch +Patch158: subunit.patch +Patch159: bug860910.patch +Patch160: bug45702.patch # URL: http://www.mysql.com/products/community/ BuildRequires: bison @@ -624,6 +629,11 @@ cd ../.. %patch153 -p1 %patch154 -p1 %patch155 -p1 +%patch156 -p1 +%patch157 -p1 +%patch158 -p1 +%patch159 -p1 +%patch160 -p1 # # to get these files rebuild @@ -746,6 +756,7 @@ mv $RPM_BUILD_ROOT%{_mandir}/man1/{,mysql_}resolve_stack_dump.1 %{?debug:nm -n $RPM_BUILD_ROOT%{_sbindir}/mysqld > $RPM_BUILD_ROOT%{_datadir}/%{name}/mysqld.sym} # do not clobber users $PATH +mv $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}}/mysql_plugin mv $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}}/mysql_upgrade mv $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}}/innochecksum mv $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}}/myisamchk @@ -992,6 +1003,7 @@ done %attr(755,root,root) %{_sbindir}/myisamlog %attr(755,root,root) %{_sbindir}/myisampack #%attr(755,root,root) %{_sbindir}/mysql_fix_privilege_tables +%attr(755,root,root) %{_sbindir}/mysql_plugin %attr(755,root,root) %{_sbindir}/mysql_upgrade %attr(755,root,root) %{_sbindir}/mysqlcheck %attr(755,root,root) %{_sbindir}/mysqld @@ -1021,6 +1033,7 @@ done %{_mandir}/man1/myisamlog.1* %{_mandir}/man1/myisampack.1* #%{_mandir}/man1/mysql_fix_privilege_tables.1* +%{_mandir}/man1/mysql_plugin.1* %{_mandir}/man1/mysql_upgrade.1* %{_mandir}/man1/mysqlcheck.1* %{_mandir}/man8/mysqld.8* diff --git a/percona_support.patch b/percona_support.patch index e3e718b..63c951a 100644 --- a/percona_support.patch +++ b/percona_support.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh -@@ -476,6 +476,9 @@ +@@ -481,6 +481,9 @@ echo echo "Please report any problems with the $scriptdir/mysqlbug script!" echo diff --git a/processlist_row_stats.patch b/processlist_row_stats.patch index 8553406..f4dd3df 100644 --- a/processlist_row_stats.patch +++ b/processlist_row_stats.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/sql/sql_class.cc +++ b/sql/sql_class.cc -@@ -2288,6 +2288,7 @@ +@@ -2308,6 +2308,7 @@ thd->sent_row_count++; thd->sent_row_count_2++; @@ -87,7 +87,7 @@ if (schema_table_store_record(thd, table)) { mysql_mutex_unlock(&LOCK_thread_count); -@@ -8117,6 +8143,12 @@ +@@ -8140,6 +8166,12 @@ SKIP_OPEN_TABLE}, {"TIME_MS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Time_ms", SKIP_OPEN_TABLE}, diff --git a/query_cache_enhance.patch b/query_cache_enhance.patch index 827e0b3..e8680d9 100644 --- a/query_cache_enhance.patch +++ b/query_cache_enhance.patch @@ -452,7 +452,7 @@ class Reprepare_observer; class Relay_log_info; -@@ -760,6 +763,9 @@ +@@ -764,6 +767,9 @@ statement lifetime. FIXME: must be const */ ulong id; @@ -464,7 +464,7 @@ MARK_COLUMNS_NONE: Means mark_used_colums is not set and no indicator to --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc -@@ -1786,6 +1786,11 @@ +@@ -1809,6 +1809,11 @@ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_query_cache_size)); @@ -3094,3 +3094,24 @@ +--disconnect conn +DROP TABLE t; +SET GLOBAL query_cache_size=0; +--- a/mysql-test/r/mysqld--help-notwin.result ++++ b/mysql-test/r/mysqld--help-notwin.result +@@ -491,6 +491,10 @@ + The minimum size for blocks allocated by the query cache + --query-cache-size=# + The memory allocated to store results from old queries ++ --query-cache-strip-comments ++ Enable and disable optimisation "strip comment for query ++ cache" - optimisation strip all comments from query while ++ search query result in query cache + --query-cache-type=name + OFF = Don't cache or retrieve results. ON = Cache all + results except SELECT SQL_NO_CACHE ... queries. DEMAND = +@@ -928,6 +932,7 @@ + query-cache-limit 1048576 + query-cache-min-res-unit 4096 + query-cache-size 0 ++query-cache-strip-comments FALSE + query-cache-type ON + query-cache-wlock-invalidate FALSE + query-prealloc-size 8192 diff --git a/response_time_distribution.patch b/response_time_distribution.patch index c1b646e..76e6c56 100644 --- a/response_time_distribution.patch +++ b/response_time_distribution.patch @@ -48,12 +48,16 @@ +enable_query_log; --- /dev/null +++ b/mysql-test/include/query_response_time.inc -@@ -0,0 +1,39 @@ +@@ -0,0 +1,43 @@ +SET SESSION query_exec_time=0.1; + +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; +EVAL SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=$base; +FLUSH QUERY_RESPONSE_TIME; ++# Following two queries check works of FLUSH and ++# respecting of "QUERY_RESPONSE_TIME_STATS" variable (see launchpad bug #855312) ++SHOW QUERY_RESPONSE_TIME; ++SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; + +SET SESSION query_exec_time=0.31; SELECT 1; @@ -254,7 +258,7 @@ +query_response_time_range_base 2 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -270,7 +274,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 3 0.300000 ++ 0.125000 1 0.100000 + 0.250000 0 0.000000 + 0.500000 30 10.650000 + 1.000000 3 1.500000 @@ -300,7 +304,7 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -316,7 +320,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 4 0.400000 ++ 0.125000 1 0.100000 + 0.250000 0 0.000000 + 0.500000 30 10.650000 + 1.000000 3 1.500000 @@ -405,7 +409,7 @@ +query_response_time_range_base 2 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -421,7 +425,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 3 0.300000 ++ 0.125000 1 0.100000 + 0.250000 0 0.000000 + 0.500000 30 10.650000 + 1.000000 3 1.500000 @@ -451,7 +455,7 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -467,7 +471,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 4 0.400000 ++ 0.125000 1 0.100000 + 0.250000 0 0.000000 + 0.500000 30 10.650000 + 1.000000 3 1.500000 @@ -556,13 +560,13 @@ +query_response_time_range_base 10 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.000010 0 0.000000 + 0.000100 0 0.000000 + 0.001000 0 0.000000 + 0.010000 0 0.000000 + 0.100000 0 0.000000 -+ 1.000000 36 12.450000 ++ 1.000000 34 12.250000 + 10.000000 33 77.099997 + 100.000000 0 0.000000 + 1000.000000 0 0.000000 @@ -572,13 +576,13 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.000010 0 0.000000 + 0.000100 0 0.000000 + 0.001000 0 0.000000 + 0.010000 0 0.000000 + 0.100000 0 0.000000 -+ 1.000000 37 12.550000 ++ 1.000000 34 12.250000 + 10.000000 33 77.099997 + 100.000000 0 0.000000 + 1000.000000 0 0.000000 @@ -647,13 +651,13 @@ +query_response_time_range_base 7 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.000008 0 0.000000 + 0.000059 0 0.000000 + 0.000416 0 0.000000 + 0.002915 0 0.000000 + 0.020408 0 0.000000 -+ 0.142857 3 0.300000 ++ 0.142857 1 0.100000 + 1.000000 33 12.150000 + 7.000000 33 77.099997 + 49.000000 0 0.000000 @@ -666,13 +670,13 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.000008 0 0.000000 + 0.000059 0 0.000000 + 0.000416 0 0.000000 + 0.002915 0 0.000000 + 0.020408 0 0.000000 -+ 0.142857 4 0.400000 ++ 0.142857 1 0.100000 + 1.000000 33 12.150000 + 7.000000 33 77.099997 + 49.000000 0 0.000000 @@ -744,18 +748,18 @@ +query_response_time_range_base 156 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000041 2 0.000000 ++ 0.000041 1 0.000000 + 0.006410 0 0.000000 -+ 1.000000 36 12.450000 ++ 1.000000 34 12.250000 + 156.000000 33 77.099997 + 24336.000000 0 0.000000 + 3796416.00000 0 0.000000 +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000041 2 0.000000 ++ 0.000041 1 0.000000 + 0.006410 0 0.000000 -+ 1.000000 37 12.550000 ++ 1.000000 34 12.250000 + 156.000000 33 77.099997 + 24336.000000 0 0.000000 + 3796416.00000 0 0.000000 @@ -821,17 +825,17 @@ +query_response_time_range_base 1000 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.001000 0 0.000000 -+ 1.000000 36 12.450000 ++ 1.000000 34 12.250000 + 1000.000000 33 77.099997 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.001000 0 0.000000 -+ 1.000000 37 12.550000 ++ 1.000000 34 12.250000 + 1000.000000 33 77.099997 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG @@ -898,17 +902,17 @@ +query_response_time_range_base 1000 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.001000 0 0.000000 -+ 1.000000 36 12.450000 ++ 1.000000 34 12.250000 + 1000.000000 33 77.099997 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 2 0.000000 ++ 0.000001 1 0.000000 + 0.001000 0 0.000000 -+ 1.000000 37 12.550000 ++ 1.000000 34 12.250000 + 1000.000000 33 77.099997 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG @@ -920,13 +924,105 @@ +SET GLOBAL query_exec_time=default; --- /dev/null +++ b/mysql-test/r/percona_query_response_time.result -@@ -0,0 +1,1003 @@ +@@ -0,0 +1,1307 @@ +SET SESSION query_exec_time=0.1; +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1; +Warnings: +Warning 1292 Truncated incorrect query_response_time_range_base value: '1' +FLUSH QUERY_RESPONSE_TIME; ++SHOW QUERY_RESPONSE_TIME; ++ ++ 0.000001 0 0.000000 ++ 0.000003 0 0.000000 ++ 0.000007 0 0.000000 ++ 0.000015 0 0.000000 ++ 0.000030 0 0.000000 ++ 0.000061 0 0.000000 ++ 0.000122 0 0.000000 ++ 0.000244 0 0.000000 ++ 0.000488 0 0.000000 ++ 0.000976 0 0.000000 ++ 0.001953 0 0.000000 ++ 0.003906 0 0.000000 ++ 0.007812 0 0.000000 ++ 0.015625 0 0.000000 ++ 0.031250 0 0.000000 ++ 0.062500 0 0.000000 ++ 0.125000 0 0.000000 ++ 0.250000 0 0.000000 ++ 0.500000 0 0.000000 ++ 1.000000 0 0.000000 ++ 2.000000 0 0.000000 ++ 4.000000 0 0.000000 ++ 8.000000 0 0.000000 ++ 16.000000 0 0.000000 ++ 32.000000 0 0.000000 ++ 64.000000 0 0.000000 ++ 128.000000 0 0.000000 ++ 256.000000 0 0.000000 ++ 512.000000 0 0.000000 ++ 1024.000000 0 0.000000 ++ 2048.000000 0 0.000000 ++ 4096.000000 0 0.000000 ++ 8192.000000 0 0.000000 ++ 16384.000000 0 0.000000 ++ 32768.000000 0 0.000000 ++ 65536.000000 0 0.000000 ++ 131072.000000 0 0.000000 ++ 262144.000000 0 0.000000 ++ 524288.000000 0 0.000000 ++ 1048576.00000 0 0.000000 ++ 2097152.00000 0 0.000000 ++ 4194304.00000 0 0.000000 ++ 8388608.00000 0 0.000000 ++TOO LONG 0 TOO LONG ++SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; ++time count total ++ 0.000001 0 0.000000 ++ 0.000003 0 0.000000 ++ 0.000007 0 0.000000 ++ 0.000015 0 0.000000 ++ 0.000030 0 0.000000 ++ 0.000061 0 0.000000 ++ 0.000122 0 0.000000 ++ 0.000244 0 0.000000 ++ 0.000488 0 0.000000 ++ 0.000976 0 0.000000 ++ 0.001953 0 0.000000 ++ 0.003906 0 0.000000 ++ 0.007812 0 0.000000 ++ 0.015625 0 0.000000 ++ 0.031250 0 0.000000 ++ 0.062500 0 0.000000 ++ 0.125000 0 0.000000 ++ 0.250000 0 0.000000 ++ 0.500000 0 0.000000 ++ 1.000000 0 0.000000 ++ 2.000000 0 0.000000 ++ 4.000000 0 0.000000 ++ 8.000000 0 0.000000 ++ 16.000000 0 0.000000 ++ 32.000000 0 0.000000 ++ 64.000000 0 0.000000 ++ 128.000000 0 0.000000 ++ 256.000000 0 0.000000 ++ 512.000000 0 0.000000 ++ 1024.000000 0 0.000000 ++ 2048.000000 0 0.000000 ++ 4096.000000 0 0.000000 ++ 8192.000000 0 0.000000 ++ 16384.000000 0 0.000000 ++ 32768.000000 0 0.000000 ++ 65536.000000 0 0.000000 ++ 131072.000000 0 0.000000 ++ 262144.000000 0 0.000000 ++ 524288.000000 0 0.000000 ++ 1048576.00000 0 0.000000 ++ 2097152.00000 0 0.000000 ++ 4194304.00000 0 0.000000 ++ 8388608.00000 0 0.000000 ++TOO LONG 0 TOO LONG +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; +SET SESSION query_exec_time=0.31; +SELECT 1; @@ -1023,7 +1119,7 @@ +query_response_time_range_base 2 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -1039,7 +1135,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 2 0.200000 ++ 0.125000 0 0.000000 + 0.250000 0 0.000000 + 0.500000 10 3.550000 + 1.000000 1 0.500000 @@ -1069,7 +1165,7 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -1085,7 +1181,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 3 0.300000 ++ 0.125000 0 0.000000 + 0.250000 0 0.000000 + 0.500000 10 3.550000 + 1.000000 1 0.500000 @@ -1118,6 +1214,98 @@ +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=2; +FLUSH QUERY_RESPONSE_TIME; ++SHOW QUERY_RESPONSE_TIME; ++ ++ 0.000001 0 0.000000 ++ 0.000003 0 0.000000 ++ 0.000007 0 0.000000 ++ 0.000015 0 0.000000 ++ 0.000030 0 0.000000 ++ 0.000061 0 0.000000 ++ 0.000122 0 0.000000 ++ 0.000244 0 0.000000 ++ 0.000488 0 0.000000 ++ 0.000976 0 0.000000 ++ 0.001953 0 0.000000 ++ 0.003906 0 0.000000 ++ 0.007812 0 0.000000 ++ 0.015625 0 0.000000 ++ 0.031250 0 0.000000 ++ 0.062500 0 0.000000 ++ 0.125000 0 0.000000 ++ 0.250000 0 0.000000 ++ 0.500000 0 0.000000 ++ 1.000000 0 0.000000 ++ 2.000000 0 0.000000 ++ 4.000000 0 0.000000 ++ 8.000000 0 0.000000 ++ 16.000000 0 0.000000 ++ 32.000000 0 0.000000 ++ 64.000000 0 0.000000 ++ 128.000000 0 0.000000 ++ 256.000000 0 0.000000 ++ 512.000000 0 0.000000 ++ 1024.000000 0 0.000000 ++ 2048.000000 0 0.000000 ++ 4096.000000 0 0.000000 ++ 8192.000000 0 0.000000 ++ 16384.000000 0 0.000000 ++ 32768.000000 0 0.000000 ++ 65536.000000 0 0.000000 ++ 131072.000000 0 0.000000 ++ 262144.000000 0 0.000000 ++ 524288.000000 0 0.000000 ++ 1048576.00000 0 0.000000 ++ 2097152.00000 0 0.000000 ++ 4194304.00000 0 0.000000 ++ 8388608.00000 0 0.000000 ++TOO LONG 0 TOO LONG ++SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; ++time count total ++ 0.000001 0 0.000000 ++ 0.000003 0 0.000000 ++ 0.000007 0 0.000000 ++ 0.000015 0 0.000000 ++ 0.000030 0 0.000000 ++ 0.000061 0 0.000000 ++ 0.000122 0 0.000000 ++ 0.000244 0 0.000000 ++ 0.000488 0 0.000000 ++ 0.000976 0 0.000000 ++ 0.001953 0 0.000000 ++ 0.003906 0 0.000000 ++ 0.007812 0 0.000000 ++ 0.015625 0 0.000000 ++ 0.031250 0 0.000000 ++ 0.062500 0 0.000000 ++ 0.125000 0 0.000000 ++ 0.250000 0 0.000000 ++ 0.500000 0 0.000000 ++ 1.000000 0 0.000000 ++ 2.000000 0 0.000000 ++ 4.000000 0 0.000000 ++ 8.000000 0 0.000000 ++ 16.000000 0 0.000000 ++ 32.000000 0 0.000000 ++ 64.000000 0 0.000000 ++ 128.000000 0 0.000000 ++ 256.000000 0 0.000000 ++ 512.000000 0 0.000000 ++ 1024.000000 0 0.000000 ++ 2048.000000 0 0.000000 ++ 4096.000000 0 0.000000 ++ 8192.000000 0 0.000000 ++ 16384.000000 0 0.000000 ++ 32768.000000 0 0.000000 ++ 65536.000000 0 0.000000 ++ 131072.000000 0 0.000000 ++ 262144.000000 0 0.000000 ++ 524288.000000 0 0.000000 ++ 1048576.00000 0 0.000000 ++ 2097152.00000 0 0.000000 ++ 4194304.00000 0 0.000000 ++ 8388608.00000 0 0.000000 ++TOO LONG 0 TOO LONG +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; +SET SESSION query_exec_time=0.31; +SELECT 1; @@ -1214,7 +1402,7 @@ +query_response_time_range_base 2 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -1230,7 +1418,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 2 0.200000 ++ 0.125000 0 0.000000 + 0.250000 0 0.000000 + 0.500000 10 3.550000 + 1.000000 1 0.500000 @@ -1260,7 +1448,7 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -1276,7 +1464,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 3 0.300000 ++ 0.125000 0 0.000000 + 0.250000 0 0.000000 + 0.500000 10 3.550000 + 1.000000 1 0.500000 @@ -1309,6 +1497,38 @@ +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=10; +FLUSH QUERY_RESPONSE_TIME; ++SHOW QUERY_RESPONSE_TIME; ++ ++ 0.000001 0 0.000000 ++ 0.000010 0 0.000000 ++ 0.000100 0 0.000000 ++ 0.001000 0 0.000000 ++ 0.010000 0 0.000000 ++ 0.100000 0 0.000000 ++ 1.000000 0 0.000000 ++ 10.000000 0 0.000000 ++ 100.000000 0 0.000000 ++ 1000.000000 0 0.000000 ++ 10000.000000 0 0.000000 ++ 100000.000000 0 0.000000 ++ 1000000.00000 0 0.000000 ++TOO LONG 0 TOO LONG ++SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; ++time count total ++ 0.000001 0 0.000000 ++ 0.000010 0 0.000000 ++ 0.000100 0 0.000000 ++ 0.001000 0 0.000000 ++ 0.010000 0 0.000000 ++ 0.100000 0 0.000000 ++ 1.000000 0 0.000000 ++ 10.000000 0 0.000000 ++ 100.000000 0 0.000000 ++ 1000.000000 0 0.000000 ++ 10000.000000 0 0.000000 ++ 100000.000000 0 0.000000 ++ 1000000.00000 0 0.000000 ++TOO LONG 0 TOO LONG +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; +SET SESSION query_exec_time=0.31; +SELECT 1; @@ -1405,13 +1625,13 @@ +query_response_time_range_base 10 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.000010 0 0.000000 + 0.000100 0 0.000000 + 0.001000 0 0.000000 + 0.010000 0 0.000000 + 0.100000 0 0.000000 -+ 1.000000 13 4.250000 ++ 1.000000 11 4.050000 + 10.000000 11 25.699999 + 100.000000 0 0.000000 + 1000.000000 0 0.000000 @@ -1421,13 +1641,13 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.000010 0 0.000000 + 0.000100 0 0.000000 + 0.001000 0 0.000000 + 0.010000 0 0.000000 + 0.100000 0 0.000000 -+ 1.000000 14 4.350000 ++ 1.000000 11 4.050000 + 10.000000 11 25.699999 + 100.000000 0 0.000000 + 1000.000000 0 0.000000 @@ -1440,6 +1660,44 @@ +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=7; +FLUSH QUERY_RESPONSE_TIME; ++SHOW QUERY_RESPONSE_TIME; ++ ++ 0.000001 0 0.000000 ++ 0.000008 0 0.000000 ++ 0.000059 0 0.000000 ++ 0.000416 0 0.000000 ++ 0.002915 0 0.000000 ++ 0.020408 0 0.000000 ++ 0.142857 0 0.000000 ++ 1.000000 0 0.000000 ++ 7.000000 0 0.000000 ++ 49.000000 0 0.000000 ++ 343.000000 0 0.000000 ++ 2401.000000 0 0.000000 ++ 16807.000000 0 0.000000 ++ 117649.000000 0 0.000000 ++ 823543.000000 0 0.000000 ++ 5764801.00000 0 0.000000 ++TOO LONG 0 TOO LONG ++SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; ++time count total ++ 0.000001 0 0.000000 ++ 0.000008 0 0.000000 ++ 0.000059 0 0.000000 ++ 0.000416 0 0.000000 ++ 0.002915 0 0.000000 ++ 0.020408 0 0.000000 ++ 0.142857 0 0.000000 ++ 1.000000 0 0.000000 ++ 7.000000 0 0.000000 ++ 49.000000 0 0.000000 ++ 343.000000 0 0.000000 ++ 2401.000000 0 0.000000 ++ 16807.000000 0 0.000000 ++ 117649.000000 0 0.000000 ++ 823543.000000 0 0.000000 ++ 5764801.00000 0 0.000000 ++TOO LONG 0 TOO LONG +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; +SET SESSION query_exec_time=0.31; +SELECT 1; @@ -1536,13 +1794,13 @@ +query_response_time_range_base 7 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.000008 0 0.000000 + 0.000059 0 0.000000 + 0.000416 0 0.000000 + 0.002915 0 0.000000 + 0.020408 0 0.000000 -+ 0.142857 2 0.200000 ++ 0.142857 0 0.000000 + 1.000000 11 4.050000 + 7.000000 11 25.699999 + 49.000000 0 0.000000 @@ -1555,13 +1813,13 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.000008 0 0.000000 + 0.000059 0 0.000000 + 0.000416 0 0.000000 + 0.002915 0 0.000000 + 0.020408 0 0.000000 -+ 0.142857 3 0.300000 ++ 0.142857 0 0.000000 + 1.000000 11 4.050000 + 7.000000 11 25.699999 + 49.000000 0 0.000000 @@ -1577,6 +1835,24 @@ +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=156; +FLUSH QUERY_RESPONSE_TIME; ++SHOW QUERY_RESPONSE_TIME; ++ ++ 0.000041 0 0.000000 ++ 0.006410 0 0.000000 ++ 1.000000 0 0.000000 ++ 156.000000 0 0.000000 ++ 24336.000000 0 0.000000 ++ 3796416.00000 0 0.000000 ++TOO LONG 0 TOO LONG ++SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; ++time count total ++ 0.000041 0 0.000000 ++ 0.006410 0 0.000000 ++ 1.000000 0 0.000000 ++ 156.000000 0 0.000000 ++ 24336.000000 0 0.000000 ++ 3796416.00000 0 0.000000 ++TOO LONG 0 TOO LONG +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; +SET SESSION query_exec_time=0.31; +SELECT 1; @@ -1673,18 +1949,18 @@ +query_response_time_range_base 156 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000041 25 0.000000 ++ 0.000041 24 0.000000 + 0.006410 0 0.000000 -+ 1.000000 13 4.250000 ++ 1.000000 11 4.050000 + 156.000000 11 25.699999 + 24336.000000 0 0.000000 + 3796416.00000 0 0.000000 +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000041 25 0.000000 ++ 0.000041 24 0.000000 + 0.006410 0 0.000000 -+ 1.000000 14 4.350000 ++ 1.000000 11 4.050000 + 156.000000 11 25.699999 + 24336.000000 0 0.000000 + 3796416.00000 0 0.000000 @@ -1694,6 +1970,22 @@ +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1000; +FLUSH QUERY_RESPONSE_TIME; ++SHOW QUERY_RESPONSE_TIME; ++ ++ 0.000001 0 0.000000 ++ 0.001000 0 0.000000 ++ 1.000000 0 0.000000 ++ 1000.000000 0 0.000000 ++ 1000000.00000 0 0.000000 ++TOO LONG 0 TOO LONG ++SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; ++time count total ++ 0.000001 0 0.000000 ++ 0.001000 0 0.000000 ++ 1.000000 0 0.000000 ++ 1000.000000 0 0.000000 ++ 1000000.00000 0 0.000000 ++TOO LONG 0 TOO LONG +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; +SET SESSION query_exec_time=0.31; +SELECT 1; @@ -1790,17 +2082,17 @@ +query_response_time_range_base 1000 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.001000 0 0.000000 -+ 1.000000 13 4.250000 ++ 1.000000 11 4.050000 + 1000.000000 11 25.699999 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.001000 0 0.000000 -+ 1.000000 14 4.350000 ++ 1.000000 11 4.050000 + 1000.000000 11 25.699999 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG @@ -1811,6 +2103,22 @@ +Warnings: +Warning 1292 Truncated incorrect query_response_time_range_base value: '1001' +FLUSH QUERY_RESPONSE_TIME; ++SHOW QUERY_RESPONSE_TIME; ++ ++ 0.000001 0 0.000000 ++ 0.001000 0 0.000000 ++ 1.000000 0 0.000000 ++ 1000.000000 0 0.000000 ++ 1000000.00000 0 0.000000 ++TOO LONG 0 TOO LONG ++SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; ++time count total ++ 0.000001 0 0.000000 ++ 0.001000 0 0.000000 ++ 1.000000 0 0.000000 ++ 1000.000000 0 0.000000 ++ 1000000.00000 0 0.000000 ++TOO LONG 0 TOO LONG +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; +SET SESSION query_exec_time=0.31; +SELECT 1; @@ -1907,17 +2215,17 @@ +query_response_time_range_base 1000 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.001000 0 0.000000 -+ 1.000000 13 4.250000 ++ 1.000000 11 4.050000 + 1000.000000 11 25.699999 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 25 0.000000 ++ 0.000001 24 0.000000 + 0.001000 0 0.000000 -+ 1.000000 14 4.350000 ++ 1.000000 11 4.050000 + 1000.000000 11 25.699999 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG @@ -1970,7 +2278,7 @@ +query_response_time_range_base 2 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -1986,7 +2294,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 46 4.600000 ++ 0.125000 44 4.400000 + 0.250000 0 0.000000 + 0.500000 10 3.550000 + 1.000000 1 0.500000 @@ -2016,7 +2324,7 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -2032,7 +2340,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 47 4.700000 ++ 0.125000 44 4.400000 + 0.250000 0 0.000000 + 0.500000 10 3.550000 + 1.000000 1 0.500000 @@ -2094,7 +2402,7 @@ +query_response_time_range_base 2 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -2110,7 +2418,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 46 4.600000 ++ 0.125000 44 4.400000 + 0.250000 0 0.000000 + 0.500000 10 3.550000 + 1.000000 1 0.500000 @@ -2140,7 +2448,7 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.000003 0 0.000000 + 0.000007 0 0.000000 + 0.000015 0 0.000000 @@ -2156,7 +2464,7 @@ + 0.015625 0 0.000000 + 0.031250 0 0.000000 + 0.062500 0 0.000000 -+ 0.125000 47 4.700000 ++ 0.125000 44 4.400000 + 0.250000 0 0.000000 + 0.500000 10 3.550000 + 1.000000 1 0.500000 @@ -2218,13 +2526,13 @@ +query_response_time_range_base 10 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.000010 0 0.000000 + 0.000100 0 0.000000 + 0.001000 0 0.000000 + 0.010000 0 0.000000 + 0.100000 0 0.000000 -+ 1.000000 57 8.650000 ++ 1.000000 55 8.450000 + 10.000000 11 25.699999 + 100.000000 0 0.000000 + 1000.000000 0 0.000000 @@ -2234,13 +2542,13 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.000010 0 0.000000 + 0.000100 0 0.000000 + 0.001000 0 0.000000 + 0.010000 0 0.000000 + 0.100000 0 0.000000 -+ 1.000000 58 8.750000 ++ 1.000000 55 8.450000 + 10.000000 11 25.699999 + 100.000000 0 0.000000 + 1000.000000 0 0.000000 @@ -2282,13 +2590,13 @@ +query_response_time_range_base 7 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.000008 0 0.000000 + 0.000059 0 0.000000 + 0.000416 0 0.000000 + 0.002915 0 0.000000 + 0.020408 0 0.000000 -+ 0.142857 46 4.600000 ++ 0.142857 44 4.400000 + 1.000000 11 4.050000 + 7.000000 11 25.699999 + 49.000000 0 0.000000 @@ -2301,13 +2609,13 @@ +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.000008 0 0.000000 + 0.000059 0 0.000000 + 0.000416 0 0.000000 + 0.002915 0 0.000000 + 0.020408 0 0.000000 -+ 0.142857 47 4.700000 ++ 0.142857 44 4.400000 + 1.000000 11 4.050000 + 7.000000 11 25.699999 + 49.000000 0 0.000000 @@ -2352,18 +2660,18 @@ +query_response_time_range_base 156 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000041 46 0.000000 ++ 0.000041 45 0.000000 + 0.006410 0 0.000000 -+ 1.000000 57 8.650000 ++ 1.000000 55 8.450000 + 156.000000 11 25.699999 + 24336.000000 0 0.000000 + 3796416.00000 0 0.000000 +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000041 46 0.000000 ++ 0.000041 45 0.000000 + 0.006410 0 0.000000 -+ 1.000000 58 8.750000 ++ 1.000000 55 8.450000 + 156.000000 11 25.699999 + 24336.000000 0 0.000000 + 3796416.00000 0 0.000000 @@ -2402,17 +2710,17 @@ +query_response_time_range_base 1000 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.001000 0 0.000000 -+ 1.000000 57 8.650000 ++ 1.000000 55 8.450000 + 1000.000000 11 25.699999 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.001000 0 0.000000 -+ 1.000000 58 8.750000 ++ 1.000000 55 8.450000 + 1000.000000 11 25.699999 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG @@ -2452,17 +2760,17 @@ +query_response_time_range_base 1000 +SHOW QUERY_RESPONSE_TIME; + -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.001000 0 0.000000 -+ 1.000000 57 8.650000 ++ 1.000000 55 8.450000 + 1000.000000 11 25.699999 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; +time count total -+ 0.000001 46 0.000000 ++ 0.000001 45 0.000000 + 0.001000 0 0.000000 -+ 1.000000 58 8.750000 ++ 1.000000 55 8.450000 + 1000.000000 11 25.699999 + 1000000.00000 0 0.000000 +TOO LONG 0 TOO LONG @@ -2667,7 +2975,7 @@ /* We have to initialize the storage engines before CSV logging */ if (ha_init()) { -@@ -6909,6 +6921,11 @@ +@@ -6905,6 +6917,11 @@ #else have_query_cache=SHOW_OPTION_NO; #endif @@ -3099,15 +3407,20 @@ #include "transaction.h" #include "sql_audit.h" #include "sql_prepare.h" -@@ -1507,6 +1508,7 @@ +@@ -1507,6 +1508,12 @@ ulonglong end_utime_of_query= thd->current_utime(); ulonglong query_exec_time= get_query_exec_time(thd, end_utime_of_query); -+ query_response_time_collect(query_exec_time); ++#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION ++ if (opt_query_response_time_stats) ++ { ++ query_response_time_collect(query_exec_time); ++ } ++#endif /* Low long_query_time value most likely means user is debugging stuff and even -@@ -1671,6 +1673,7 @@ +@@ -1671,6 +1678,7 @@ case SCH_CHARSETS: case SCH_ENGINES: case SCH_COLLATIONS: @@ -3149,7 +3462,7 @@ #include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH #include "debug_sync.h" #include "datadict.h" // dd_frm_type() -@@ -7865,6 +7866,14 @@ +@@ -7888,6 +7889,14 @@ */ @@ -3164,7 +3477,7 @@ ST_SCHEMA_TABLE schema_tables[]= { {"CHARACTER_SETS", charsets_fields_info, create_schema_table, -@@ -7918,6 +7927,13 @@ +@@ -7941,6 +7950,13 @@ 1, 9, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, {"ROUTINES", proc_fields_info, create_schema_table, fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0}, @@ -3188,7 +3501,7 @@ %token QUICK %token RANGE_SYM /* SQL-2003-R */ %token READS_SYM /* SQL-2003-R */ -@@ -11080,6 +11081,15 @@ +@@ -11099,6 +11100,15 @@ { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; } @@ -3204,10 +3517,10 @@ | CREATE PROCEDURE_SYM sp_name { LEX *lex= Lex; -@@ -11316,6 +11326,12 @@ - { Lex->type|= REFRESH_STATUS; } - | SLAVE - { Lex->type|= REFRESH_SLAVE; } +@@ -11338,6 +11348,12 @@ + Lex->type|= REFRESH_SLAVE; + Lex->reset_slave_info.all= false; + } + | QUERY_RESPONSE_TIME_SYM + { +#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION @@ -3217,7 +3530,7 @@ | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | DES_KEY_FILE -@@ -12617,6 +12633,7 @@ +@@ -12645,6 +12661,7 @@ | PROXY_SYM {} | QUARTER_SYM {} | QUERY_SYM {} @@ -3267,8 +3580,8 @@ @@ -0,0 +1,2 @@ +Variable_name Value +have_response_time_distribution YES ---- a/include/atomic/x86-gcc.h 2011-05-11 14:54:11.000000000 +0300 -+++ b/include/atomic/x86-gcc.h 2011-07-21 16:20:24.563057000 +0300 +--- a/include/atomic/x86-gcc.h ++++ b/include/atomic/x86-gcc.h @@ -108,27 +108,22 @@ v=tmp; @@ -3308,3 +3621,27 @@ #endif /* +--- a/mysql-test/r/mysqld--help-notwin.result ++++ b/mysql-test/r/mysqld--help-notwin.result +@@ -503,6 +503,12 @@ + Invalidate queries in query cache on LOCK for write + --query-prealloc-size=# + Persistent buffer for query parsing and execution ++ --query-response-time-range-base=# ++ Select base of log for query_response_time ranges. ++ WARNING: variable change affect only after flush ++ --query-response-time-stats ++ Enable or disable query response time statisics ++ collecting + --range-alloc-block-size=# + Allocation block size for storing ranges during + optimization +@@ -936,6 +942,8 @@ + query-cache-type ON + query-cache-wlock-invalidate FALSE + query-prealloc-size 8192 ++query-response-time-range-base 10 ++query-response-time-stats FALSE + range-alloc-block-size 4096 + read-buffer-size 131072 + read-only FALSE diff --git a/show_slave_status_nolock.patch b/show_slave_status_nolock.patch index 9ed13a9..279611c 100644 --- a/show_slave_status_nolock.patch +++ b/show_slave_status_nolock.patch @@ -47,7 +47,7 @@ in "struct show_var_st status_vars[]= {" ... --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc -@@ -335,6 +335,7 @@ +@@ -336,6 +336,7 @@ sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND; @@ -55,7 +55,7 @@ sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]= CF_STATUS_COMMAND; -@@ -2359,12 +2360,16 @@ +@@ -2368,12 +2369,17 @@ mysql_mutex_unlock(&LOCK_active_mi); break; } @@ -66,22 +66,32 @@ if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL)) goto error; - mysql_mutex_lock(&LOCK_active_mi); -+ if(SQLCOM_SHOW_SLAVE_NOLOCK_STAT != lex->sql_command) ++ bool do_lock=SQLCOM_SHOW_SLAVE_NOLOCK_STAT != lex->sql_command; ++ if(do_lock) + { + mysql_mutex_lock(&LOCK_active_mi); + } if (active_mi != NULL) { res = show_master_info(thd, active_mi); -@@ -2375,7 +2380,10 @@ +@@ -2384,7 +2390,19 @@ WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO)); my_ok(thd); } - mysql_mutex_unlock(&LOCK_active_mi); -+ if(SQLCOM_SHOW_SLAVE_NOLOCK_STAT != lex->sql_command) ++ if(do_lock) + { + mysql_mutex_unlock(&LOCK_active_mi); + } ++ DBUG_EXECUTE_IF("after_show_slave_status", ++ { ++ const char act[]= ++ "now " ++ "signal signal.after_show_slave_status"; ++ DBUG_ASSERT(opt_debug_sync_timeout > 0); ++ DBUG_ASSERT(!debug_sync_set_action(current_thd, ++ STRING_WITH_LEN(act))); ++ };); break; } case SQLCOM_SHOW_MASTER_STAT: @@ -95,10 +105,11 @@ %token STDDEV_SAMP_SYM /* SQL-2003-N */ %token STD_SYM %token STOP_SYM -@@ -11086,6 +11087,10 @@ +@@ -11105,6 +11106,11 @@ { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; } ++ /* SHOW SLAVE STATUS NOLOCK */ + | SLAVE STATUS_SYM NOLOCK_SYM + { + Lex->sql_command = SQLCOM_SHOW_SLAVE_NOLOCK_STAT; //SQLCOM_SHOW_SLAVE_NOLOCK_STAT; @@ -107,83 +118,254 @@ { #ifdef HAVE_RESPONSE_TIME_DISTRIBUTION --- /dev/null ++++ b/mysql-test/t/percona_show_slave_status_nolock.test +@@ -0,0 +1,90 @@ ++--source include/master-slave.inc ++--source include/have_debug_sync.inc ++--source include/have_binlog_format_statement.inc ++ ++call mtr.add_suppression("Slave SQL: Request to stop slave SQL Thread received while applying a group that has non-transactional changes"); ++ ++--let $rpl_connection_name=slave_lock ++--let $rpl_server_number=2 ++--source include/rpl_connect.inc ++ ++--let $rpl_connection_name=slave_nolock ++--let $rpl_server_number=2 ++--source include/rpl_connect.inc ++ ++--let $show_statement= SHOW PROCESSLIST ++--let $field= Info ++ ++connection master; ++--echo [master] ++--disable_warnings ++DROP TABLE IF EXISTS t; ++--enable_warnings ++CREATE TABLE t(id INT); ++sync_slave_with_master; ++ ++connection slave; ++--echo [slave] ++SET DEBUG_SYNC='RESET'; ++SET GLOBAL DEBUG="+d,after_mysql_insert,after_show_slave_status"; ++ ++connection master; ++--echo [master] ++INSERT INTO t VALUES(0); ++ ++connection slave; ++--echo [slave] ++--let $condition= 'INSERT INTO t VALUES(0)' ++--source include/wait_show_condition.inc ++ ++--echo check 'SHOW SLAVE STATUS' and 'SHOW SLAVE STATUS NOLOCK' - both should work fine ++--source include/percona_show_slave_status_nolock.inc ++ ++connection master; ++--echo [master] ++INSERT INTO t VALUES(1); ++ ++connection slave; ++--echo [slave] ++--let $condition= 'INSERT INTO t VALUES(1)' ++--source include/wait_show_condition.inc ++ ++--let $rpl_connection_name=slave_stop ++--let $rpl_server_number=2 ++--source include/rpl_connect.inc ++ ++connection slave_stop; ++--echo [slave_stop] ++send STOP SLAVE; ++ ++connection slave; ++--echo [slave] ++--let $condition= 'STOP SLAVE' ++--source include/wait_show_condition.inc ++ ++--echo check 'SHOW SLAVE STATUS' and 'SHOW SLAVE STATUS NOLOCK' - just NOLOCK version should works fine ++--source include/percona_show_slave_status_nolock.inc ++ ++ ++connection slave_stop; ++--echo [slave_stop] ++reap; ++--source include/wait_for_slave_to_stop.inc ++START SLAVE; ++--source include/wait_for_slave_to_start.inc ++ ++connection master; ++--echo [master] ++SET DEBUG_SYNC='RESET'; ++ ++connection slave; ++--echo [slave] ++SET GLOBAL DEBUG=''; ++SET DEBUG_SYNC='RESET'; ++ ++connection master; ++--echo [master] ++DROP TABLE t; ++sync_slave_with_master; ++ ++--source include/rpl_end.inc +--- /dev/null +++ b/mysql-test/r/percona_show_slave_status_nolock.result -@@ -0,0 +1,21 @@ +@@ -0,0 +1,69 @@ +include/master-slave.inc +[connection master] ++call mtr.add_suppression("Slave SQL: Request to stop slave SQL Thread received while applying a group that has non-transactional changes"); ++include/rpl_connect.inc [creating slave_lock] ++include/rpl_connect.inc [creating slave_nolock] ++[master] +DROP TABLE IF EXISTS t; +CREATE TABLE t(id INT); -+INSERT INTO t SELECT SLEEP(10); ++[slave] ++SET DEBUG_SYNC='RESET'; ++SET GLOBAL DEBUG="+d,after_mysql_insert,after_show_slave_status"; ++[master] ++INSERT INTO t VALUES(0); ++[slave] ++check 'SHOW SLAVE STATUS' and 'SHOW SLAVE STATUS NOLOCK' - both should work fine ++ ++[slave_lock] ++SHOW SLAVE STATUS; ++SET DEBUG_SYNC='now WAIT_FOR signal.after_show_slave_status TIMEOUT 1'; ++SIGNAL after SHOW SLAVE STATUS is 'signal.after_show_slave_status' ++[slave] ++SET DEBUG_SYNC='now SIGNAL signal.empty'; ++[slave_nolock] ++SHOW SLAVE STATUS NOLOCK; ++SET DEBUG_SYNC='now WAIT_FOR signal.after_show_slave_status TIMEOUT 1'; ++# should be 'signal.after_show_slave_status' ++SIGNAL after SHOW SLAVE STATUS NOLOCK is 'signal.after_show_slave_status' ++[slave] ++SET DEBUG_SYNC='now SIGNAL signal.continue'; ++[slave] ++SET DEBUG_SYNC='now SIGNAL signal.empty'; ++ ++[master] ++INSERT INTO t VALUES(1); ++[slave] ++include/rpl_connect.inc [creating slave_stop] ++[slave_stop] +STOP SLAVE; -+Warnings: -+Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. -+master count(*) -+master 1 -+slave count(*) -+slave 0 ++[slave] ++check 'SHOW SLAVE STATUS' and 'SHOW SLAVE STATUS NOLOCK' - just NOLOCK version should works fine ++ ++[slave_lock] ++SHOW SLAVE STATUS; ++SET DEBUG_SYNC='now WAIT_FOR signal.after_show_slave_status TIMEOUT 1'; ++SIGNAL after SHOW SLAVE STATUS is 'signal.empty' ++[slave] ++SET DEBUG_SYNC='now SIGNAL signal.empty'; ++[slave_nolock] +SHOW SLAVE STATUS NOLOCK; ++SET DEBUG_SYNC='now WAIT_FOR signal.after_show_slave_status TIMEOUT 1'; ++# should be 'signal.after_show_slave_status' ++SIGNAL after SHOW SLAVE STATUS NOLOCK is 'signal.after_show_slave_status' ++[slave] ++SET DEBUG_SYNC='now SIGNAL signal.continue'; ++[slave] ++SET DEBUG_SYNC='now SIGNAL signal.empty'; ++ ++[slave_stop] +include/wait_for_slave_to_stop.inc +START SLAVE; +include/wait_for_slave_to_start.inc -+slave count(*) -+slave 1 ++[master] ++SET DEBUG_SYNC='RESET'; ++[slave] ++SET GLOBAL DEBUG=''; ++SET DEBUG_SYNC='RESET'; ++[master] +DROP TABLE t; -+STOP SLAVE; -+include/wait_for_slave_to_stop.inc ++include/rpl_end.inc --- /dev/null -+++ b/mysql-test/t/percona_show_slave_status_nolock.test -@@ -0,0 +1,53 @@ -+--source include/master-slave.inc -+--source include/have_binlog_format_statement.inc -+--disable_query_log -+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. Statement:"); -+call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); -+--enable_query_log -+connection master; -+ --disable_warnings -+ DROP TABLE IF EXISTS t; -+ --enable_warnings -+ CREATE TABLE t(id INT); -+ sync_slave_with_master; ++++ b/mysql-test/include/percona_show_slave_status_nolock.inc +@@ -0,0 +1,56 @@ ++--echo ++--disable_result_log ++connection slave_lock; ++--echo [slave_lock] ++send SHOW SLAVE STATUS; + -+connection master; -+ send INSERT INTO t SELECT SLEEP(10); ++connection slave; ++--let $condition= 'SHOW SLAVE STATUS' ++--source include/wait_show_condition.inc ++ ++--disable_warnings ++SET DEBUG_SYNC='now WAIT_FOR signal.after_show_slave_status TIMEOUT 1'; ++--enable_warnings ++ ++--let current=`SELECT SUBSTR(Variable_value FROM 22) FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE Variable_name = 'DEBUG_SYNC'` ++--echo SIGNAL after SHOW SLAVE STATUS is $current + +connection slave; -+ sleep 15; -+ send STOP SLAVE; ++--echo [slave] ++SET DEBUG_SYNC='now SIGNAL signal.empty'; + -+connection master; -+ reap; ++connection slave_nolock; ++--echo [slave_nolock] ++send SHOW SLAVE STATUS NOLOCK; + -+ --disable_query_log -+ select "master",count(*) from t; -+ --enable_query_log ++connection slave; ++--let $condition= 'SHOW SLAVE STATUS NOLOCK' ++--source include/wait_show_condition.inc + -+connection slave1; -+ --disable_query_log -+ select "slave",count(*) from t; -+ --enable_query_log ++--disable_warnings ++SET DEBUG_SYNC='now WAIT_FOR signal.after_show_slave_status TIMEOUT 1'; ++--enable_warnings + -+ --disable_result_log -+ SHOW SLAVE STATUS NOLOCK; -+ --enable_result_log ++--echo # should be 'signal.after_show_slave_status' ++--let current=`SELECT SUBSTR(Variable_value FROM 22) FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE Variable_name = 'DEBUG_SYNC'` ++--echo SIGNAL after SHOW SLAVE STATUS NOLOCK is $current + +connection slave; -+ reap; ++--echo [slave] ++SET DEBUG_SYNC='now SIGNAL signal.continue'; + -+ --source include/wait_for_slave_to_stop.inc -+ START SLAVE; -+ --source include/wait_for_slave_to_start.inc ++connection slave_lock; ++--disable_result_log ++reap; ++--enable_result_log + -+ --disable_query_log -+ select "slave",count(*) from t; -+ --enable_query_log ++connection slave_nolock; ++--disable_result_log ++reap; ++--enable_result_log + -+connection master; -+ DROP TABLE t; -+sync_slave_with_master; -+STOP SLAVE; -+--source include/wait_for_slave_to_stop.inc -+ -\ No newline at end of file ++connection slave; ++--echo [slave] ++SET DEBUG_SYNC='now SIGNAL signal.empty'; ++--enable_result_log ++--echo +--- a/sql/slave.cc ++++ b/sql/slave.cc +@@ -1816,6 +1816,7 @@ + + if (mi->host[0]) + { ++ bool do_lock=SQLCOM_SHOW_SLAVE_NOLOCK_STAT != thd->lex->sql_command; + DBUG_PRINT("info",("host is set: '%s'", mi->host)); + String *packet= &thd->packet; + protocol->prepare_for_resend(); +@@ -1824,9 +1825,15 @@ + slave_running can be accessed without run_lock but not other + non-volotile members like mi->io_thd, which is guarded by the mutex. + */ +- mysql_mutex_lock(&mi->run_lock); ++ if (do_lock) ++ { ++ mysql_mutex_lock(&mi->run_lock); ++ } + protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin); +- mysql_mutex_unlock(&mi->run_lock); ++ if (do_lock) ++ { ++ mysql_mutex_unlock(&mi->run_lock); ++ } + + mysql_mutex_lock(&mi->data_lock); + mysql_mutex_lock(&mi->rli.data_lock); diff --git a/show_temp.patch b/show_temp.patch index 01189cf..d67f056 100644 --- a/show_temp.patch +++ b/show_temp.patch @@ -88,7 +88,7 @@ case SQLCOM_SHOW_TRIGGERS: case SQLCOM_SHOW_TABLE_STATUS: case SQLCOM_SHOW_OPEN_TABLES: -@@ -4846,6 +4852,8 @@ +@@ -4852,6 +4858,8 @@ case SCH_TABLE_NAMES: case SCH_TABLES: @@ -107,7 +107,7 @@ case SQLCOM_SHOW_TRIGGERS: case SQLCOM_SHOW_EVENTS: thd->make_lex_string(&lookup_field_values->db_value, -@@ -3279,6 +3280,231 @@ +@@ -3283,6 +3284,231 @@ return (uint) OPEN_FULL_TABLE; } @@ -339,7 +339,7 @@ /** Try acquire high priority share metadata lock on a table (with -@@ -7023,6 +7249,25 @@ +@@ -7046,6 +7272,25 @@ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -365,7 +365,7 @@ ST_FIELD_INFO columns_fields_info[]= { -@@ -7637,6 +7882,9 @@ +@@ -7660,6 +7905,9 @@ hton_fill_schema_table, 0, 0, -1, -1, 0, 0}, {"GLOBAL_STATUS", variables_fields_info, create_schema_table, fill_status, make_old_format, 0, 0, -1, 0, 0}, @@ -375,7 +375,7 @@ {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table, fill_variables, make_old_format, 0, 0, -1, 0, 0}, {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table, -@@ -7686,6 +7934,9 @@ +@@ -7709,6 +7957,9 @@ get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0}, {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table, fill_schema_table_privileges, 0, 0, -1, -1, 0, 0}, @@ -387,7 +387,7 @@ OPEN_TRIGGER_ONLY|OPTIMIZE_I_S_TABLE}, --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy -@@ -10873,6 +10873,15 @@ +@@ -10892,6 +10892,15 @@ if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES)) MYSQL_YYABORT; } @@ -415,7 +415,7 @@ key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create, --- a/sql/sql_base.cc +++ b/sql/sql_base.cc -@@ -1588,12 +1588,16 @@ +@@ -1651,12 +1651,16 @@ if (!mysql_bin_log.is_open()) { TABLE *tmp_next; @@ -432,7 +432,7 @@ DBUG_RETURN(FALSE); } -@@ -1606,6 +1610,8 @@ +@@ -1669,6 +1673,8 @@ memcpy(buf, stub, stub_len); @@ -441,7 +441,7 @@ /* Insertion sort of temp tables by pseudo_thread_id to build ordered list of sublists of equal pseudo_thread_id -@@ -1727,6 +1733,8 @@ +@@ -1790,6 +1796,8 @@ thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */ thd->temporary_tables=0; @@ -450,7 +450,7 @@ DBUG_RETURN(error); } -@@ -2104,6 +2112,8 @@ +@@ -2167,6 +2175,8 @@ table->s->db.str, table->s->table_name.str, (long) table, table->alias)); @@ -459,7 +459,7 @@ if (table->prev) { table->prev->next= table->next; -@@ -2130,6 +2140,9 @@ +@@ -2193,6 +2203,9 @@ slave_open_temp_tables--; } close_temporary(table, free_share, delete_table); @@ -469,7 +469,7 @@ DBUG_VOID_RETURN; } -@@ -5854,6 +5867,7 @@ +@@ -5931,6 +5944,7 @@ if (add_to_temporary_tables_list) { /* growing temp list at the head */ @@ -477,7 +477,7 @@ tmp_table->next= thd->temporary_tables; if (tmp_table->next) tmp_table->next->prev= tmp_table; -@@ -5861,6 +5875,7 @@ +@@ -5938,6 +5952,7 @@ thd->temporary_tables->prev= 0; if (thd->slave_thread) slave_open_temp_tables++; @@ -487,7 +487,7 @@ DBUG_PRINT("tmptable", ("opened table: '%s'.'%s' 0x%lx", tmp_table->s->db.str, --- a/sql/sql_class.cc +++ b/sql/sql_class.cc -@@ -837,6 +837,8 @@ +@@ -836,6 +836,8 @@ active_vio = 0; #endif mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST); @@ -496,7 +496,7 @@ /* Variables with default values */ proc_info="login"; -@@ -1349,6 +1351,7 @@ +@@ -1348,6 +1350,7 @@ db= NULL; free_root(&transaction.mem_root,MYF(0)); mysql_mutex_destroy(&LOCK_thd_data); diff --git a/slow_extended.patch b/slow_extended.patch index d0ab66d..f1cbd37 100644 --- a/slow_extended.patch +++ b/slow_extended.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp -@@ -185,6 +185,16 @@ +@@ -186,6 +186,16 @@ char *thd_security_context(void* thd, char *buffer, unsigned int length, unsigned int max_query_len); void thd_inc_row_count(void* thd); @@ -26,7 +26,7 @@ unsigned long thd_get_thread_id(const void* thd); --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp -@@ -185,6 +185,16 @@ +@@ -186,6 +186,16 @@ char *thd_security_context(void* thd, char *buffer, unsigned int length, unsigned int max_query_len); void thd_inc_row_count(void* thd); @@ -45,7 +45,7 @@ unsigned long thd_get_thread_id(const void* thd); --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp -@@ -138,6 +138,16 @@ +@@ -139,6 +139,16 @@ char *thd_security_context(void* thd, char *buffer, unsigned int length, unsigned int max_query_len); void thd_inc_row_count(void* thd); @@ -64,7 +64,7 @@ unsigned long thd_get_thread_id(const void* thd); --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h -@@ -536,6 +536,17 @@ +@@ -545,6 +545,17 @@ /* Increments the row counter, see THD::row_count */ void thd_inc_row_count(MYSQL_THD thd); @@ -135,7 +135,7 @@ /* --- a/sql/filesort.cc +++ b/sql/filesort.cc -@@ -195,6 +195,7 @@ +@@ -193,6 +193,7 @@ { status_var_increment(thd->status_var.filesort_scan_count); } @@ -143,15 +143,15 @@ #ifdef CAN_TRUST_RANGE if (select && select->quick && select->quick->records > 0L) { -@@ -260,6 +261,7 @@ - } - else - { +@@ -261,6 +262,7 @@ + /* filesort cannot handle zero-length records during merge. */ + DBUG_ASSERT(param.sort_length != 0); + + thd->query_plan_flags|= QPLAN_FILESORT_DISK; if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer) { my_free(table_sort.buffpek); -@@ -1219,6 +1221,7 @@ +@@ -1209,6 +1211,7 @@ DBUG_ENTER("merge_buffers"); status_var_increment(current_thd->status_var.filesort_merge_passes); @@ -424,10 +424,14 @@ my_bool lower_case_file_system= 0; my_bool opt_large_pages= 0; my_bool opt_super_large_pages= 0; -@@ -5896,10 +5900,10 @@ - "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to " - "the slow log if it is open.", &opt_log_slow_admin_statements, - &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +@@ -5892,14 +5896,10 @@ + "Don't log extra information to update and slow-query logs.", + &opt_short_log_format, &opt_short_log_format, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +- {"log-slow-admin-statements", 0, +- "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to " +- "the slow log if it is open.", &opt_log_slow_admin_statements, +- &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"log-slow-slave-statements", 0, + /*{"log-slow-slave-statements", 0, "Log slow statements executed by slave thread to the slow log if it is open.", @@ -437,7 +441,7 @@ {"log-slow-queries", OPT_SLOW_QUERY_LOG, "Log slow queries to a table or log file. Defaults logging to table " "mysql.slow_log or hostname-slow.log if --log-output=file is used. " -@@ -7288,6 +7292,10 @@ +@@ -7288,6 +7288,10 @@ C_MODE_END @@ -448,7 +452,7 @@ /** Get server options from the command line, and perform related server initializations. -@@ -7437,6 +7445,8 @@ +@@ -7437,6 +7441,8 @@ global_system_variables.long_query_time= (ulonglong) (global_system_variables.long_query_time_double * 1e6); @@ -549,15 +553,16 @@ /** Dumps a text description of a thread, its security context -@@ -912,6 +943,7 @@ - *cond_hdl= NULL; - return FALSE; - } +@@ -926,6 +957,8 @@ + const char* msg, + MYSQL_ERROR ** cond_hdl) + { + last_errno= sql_errno; - - for (Internal_error_handler *error_handler= m_internal_handler; - error_handler; -@@ -3656,6 +3688,12 @@ ++ + if (!m_internal_handler) + { + *cond_hdl= NULL; +@@ -3675,6 +3708,12 @@ first_successful_insert_id_in_prev_stmt; backup->first_successful_insert_id_in_cur_stmt= first_successful_insert_id_in_cur_stmt; @@ -570,7 +575,7 @@ if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) && !is_current_stmt_binlog_format_row()) -@@ -3676,6 +3714,14 @@ +@@ -3695,6 +3734,14 @@ cuted_fields= 0; transaction.savepoints= 0; first_successful_insert_id_in_cur_stmt= 0; @@ -585,7 +590,7 @@ } -@@ -3738,6 +3784,12 @@ +@@ -3757,6 +3804,12 @@ */ examined_row_count+= backup->examined_row_count; cuted_fields+= backup->cuted_fields; @@ -847,7 +852,7 @@ /* Reset warning count for each query that uses tables A better approach would be to reset this for any commands -@@ -5297,6 +5390,21 @@ +@@ -5303,6 +5396,21 @@ thd->rand_used= 0; thd->sent_row_count= thd->examined_row_count= 0; @@ -978,7 +983,7 @@ static bool fix_low_prio_updates(sys_var *self, THD *thd, enum_var_type type) { if (type == OPT_SESSION) -@@ -2898,6 +2921,117 @@ +@@ -2898,6 +2921,123 @@ DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_log_state)); @@ -1053,6 +1058,12 @@ + "Log queries replayed be the slave SQL thread", + GLOBAL_VAR(opt_log_slow_slave_statements), CMD_LINE(OPT_ARG), + DEFAULT(FALSE)); ++static Sys_var_mybool Sys_log_slow_admin_statements( ++ "log_slow_admin_statements", ++ "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements" ++ " to the slow log if it is open.", ++ GLOBAL_VAR(opt_log_slow_admin_statements), CMD_LINE(OPT_ARG), ++ DEFAULT(FALSE)); +static Sys_var_mybool Sys_log_slow_sp_statements( + "log_slow_sp_statements", + "Log slow statements executed by stored procedure to the slow log if it is open.", @@ -2318,7 +2329,7 @@ +DROP TABLE t; --- a/sql/log_event.cc +++ b/sql/log_event.cc -@@ -2380,6 +2380,14 @@ +@@ -2385,6 +2385,14 @@ start+= host.length; } } @@ -2333,7 +2344,7 @@ /* NOTE: When adding new status vars, please don't forget to update the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function -@@ -2866,6 +2874,17 @@ +@@ -2871,6 +2879,17 @@ data_written= master_data_written= uint4korr(pos); pos+= 4; break; @@ -2376,3 +2387,267 @@ + +SET GLOBAL query_exec_time=default; +SET SESSION query_exec_time=default; +--- /dev/null ++++ b/mysql-test/r/percona_log_slow_global_control_default.result +@@ -0,0 +1 @@ ++SET GLOBAL slow_query_log_use_global_control=default; +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_global_control_default.test +@@ -0,0 +1 @@ ++SET GLOBAL slow_query_log_use_global_control=default; +--- /dev/null ++++ b/mysql-test/r/percona_slow_extended_log_error.result +@@ -0,0 +1,9 @@ ++SET long_query_time=0; ++DROP TABLE IF EXISTS t1; ++CREATE TABLE t(a INT); ++[log_start.inc] percona.slow_extended.log_error ++CREATE TABLE t(a INT); ++ERROR 42S01: Table 't' already exists ++[log_stop.inc] percona.slow_extended.log_error ++[log_grep.inc] file: percona.slow_extended.log_error pattern: Last_errno: 1050 ++[log_grep.inc] lines: 1 +--- /dev/null ++++ b/mysql-test/t/percona_slow_extended_log_error.test +@@ -0,0 +1,15 @@ ++--let log_file=percona.slow_extended.log_error ++SET long_query_time=0; ++--disable_warnings ++DROP TABLE IF EXISTS t1; ++--enable_warnings ++CREATE TABLE t(a INT); ++--source include/log_start.inc ++ ++--error ER_TABLE_EXISTS_ERROR ++CREATE TABLE t(a INT); ++ ++--source include/log_stop.inc ++--let grep_pattern = Last_errno: 1050 ++--source include/log_grep.inc ++DROP TABLE t; +--- /dev/null ++++ b/mysql-test/suite/sys_vars/t/log_slow_admin_statements_basic.test +@@ -0,0 +1 @@ ++SELECT @@global.log_slow_admin_statements; +--- /dev/null ++++ b/mysql-test/suite/sys_vars/r/log_slow_admin_statements_basic.result +@@ -0,0 +1,3 @@ ++SELECT @@global.log_slow_admin_statements; ++@@global.log_slow_admin_statements ++0 +--- /dev/null ++++ b/mysql-test/r/percona_log_slow_admin_statements.result +@@ -0,0 +1,35 @@ ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++Variable_name Value ++log_slow_admin_statements OFF ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++VARIABLE_NAME VARIABLE_VALUE ++LOG_SLOW_ADMIN_STATEMENTS OFF ++SET GLOBAL log_slow_admin_statements=true; ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++Variable_name Value ++log_slow_admin_statements ON ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++VARIABLE_NAME VARIABLE_VALUE ++LOG_SLOW_ADMIN_STATEMENTS ON ++SET GLOBAL log_slow_admin_statements=false; ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++Variable_name Value ++log_slow_admin_statements OFF ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++VARIABLE_NAME VARIABLE_VALUE ++LOG_SLOW_ADMIN_STATEMENTS OFF ++SET GLOBAL log_slow_admin_statements=foo; ++ERROR 42000: Variable 'log_slow_admin_statements' can't be set to the value of 'foo' ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++Variable_name Value ++log_slow_admin_statements OFF ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++VARIABLE_NAME VARIABLE_VALUE ++LOG_SLOW_ADMIN_STATEMENTS OFF ++SET GLOBAL log_slow_admin_statements=default; ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++Variable_name Value ++log_slow_admin_statements OFF ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++VARIABLE_NAME VARIABLE_VALUE ++LOG_SLOW_ADMIN_STATEMENTS OFF +--- /dev/null ++++ b/mysql-test/r/percona_log_slow_admin_statements-config_false.result +@@ -0,0 +1,6 @@ ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++Variable_name Value ++log_slow_admin_statements OFF ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++VARIABLE_NAME VARIABLE_VALUE ++LOG_SLOW_ADMIN_STATEMENTS OFF +--- /dev/null ++++ b/mysql-test/r/percona_log_slow_admin_statements-config_foo.result +@@ -0,0 +1,7 @@ ++call mtr.add_suppression("option 'log_slow_admin_statements': boolean value 'foo' wasn't recognized. Set to OFF."); ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++Variable_name Value ++log_slow_admin_statements OFF ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++VARIABLE_NAME VARIABLE_VALUE ++LOG_SLOW_ADMIN_STATEMENTS OFF +--- /dev/null ++++ b/mysql-test/r/percona_log_slow_admin_statements-config_true.result +@@ -0,0 +1,6 @@ ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++Variable_name Value ++log_slow_admin_statements ON ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++VARIABLE_NAME VARIABLE_VALUE ++LOG_SLOW_ADMIN_STATEMENTS ON +--- /dev/null ++++ b/mysql-test/r/percona_log_slow_admin_statements-config.result +@@ -0,0 +1,6 @@ ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++Variable_name Value ++log_slow_admin_statements ON ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++VARIABLE_NAME VARIABLE_VALUE ++LOG_SLOW_ADMIN_STATEMENTS ON +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_admin_statements-config_false.cnf +@@ -0,0 +1,2 @@ ++[mysqld.1] ++log-slow-admin-statements=false +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_admin_statements-config_foo.cnf +@@ -0,0 +1,2 @@ ++[mysqld.1] ++log-slow-admin-statements=foo +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_admin_statements-config_true.cnf +@@ -0,0 +1,2 @@ ++[mysqld.1] ++log-slow-admin-statements=true +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_admin_statements-config.cnf +@@ -0,0 +1,2 @@ ++[mysqld.1] ++log-slow-admin-statements +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_admin_statements.test +@@ -0,0 +1,20 @@ ++# default value ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++# set value to 'true' ++SET GLOBAL log_slow_admin_statements=true; ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++# set value to 'false' ++SET GLOBAL log_slow_admin_statements=false; ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++# set value to 'foo' ++--error ER_WRONG_VALUE_FOR_VAR ++SET GLOBAL log_slow_admin_statements=foo; ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; ++# set value to default ++SET GLOBAL log_slow_admin_statements=default; ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_admin_statements-config_false.test +@@ -0,0 +1,2 @@ ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_admin_statements-config_foo.test +@@ -0,0 +1,3 @@ ++call mtr.add_suppression("option 'log_slow_admin_statements': boolean value 'foo' wasn't recognized. Set to OFF."); ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_admin_statements-config_true.test +@@ -0,0 +1,2 @@ ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; +--- /dev/null ++++ b/mysql-test/t/percona_log_slow_admin_statements-config.test +@@ -0,0 +1,2 @@ ++SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; ++SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; +--- a/mysql-test/r/mysqld--help-notwin.result ++++ b/mysql-test/r/mysqld--help-notwin.result +@@ -250,15 +250,31 @@ + --log-slow-admin-statements + Log slow OPTIMIZE, ANALYZE, ALTER and other + administrative statements to the slow log if it is open. ++ --log-slow-filter=name ++ Log only the queries that followed certain execution ++ plan. Multiple flags allowed in a comma-separated string. ++ [qc_miss, full_scan, full_join, tmp_table, ++ tmp_table_on_disk, filesort, filesort_on_disk] + --log-slow-queries[=name] + Log slow queries to a table or log file. Defaults logging + to table mysql.slow_log or hostname-slow.log if + --log-output=file is used. Must be enabled to activate + other slow log options. Deprecated option, use + --slow-query-log/--slow-query-log-file instead. ++ --log-slow-rate-limit=# ++ Rate limit statement writes to slow log to only those ++ from every (1/log_slow_rate_limit) session. + --log-slow-slave-statements +- Log slow statements executed by slave thread to the slow +- log if it is open. ++ Log queries replayed be the slave SQL thread ++ --log-slow-sp-statements ++ Log slow statements executed by stored procedure to the ++ slow log if it is open. ++ (Defaults to on; use --skip-log-slow-sp-statements to disable.) ++ --log-slow-verbosity=name ++ Choose how verbose the messages to your slow log will be. ++ Multiple flags allowed in a comma-separated string. ++ [microtime, query_plan, innodb, profiling, ++ profiling_use_getrusage] + --log-tc=name Path to transaction coordinator log (used for + transactions that affect more than one storage engine, + when binary log is disabled). +@@ -660,6 +676,18 @@ + Log slow queries to given log file. Defaults logging to + hostname-slow.log. Must be enabled to activate other slow + log options ++ --slow-query-log-timestamp-always ++ Timestamp is printed for all records of the slow log even ++ if they are same time. ++ --slow-query-log-timestamp-precision=name ++ Log slow statements executed by stored procedure to the ++ slow log if it is open. [second, microsecond] ++ --slow-query-log-use-global-control=name ++ Choose flags, wich always use the global variables. ++ Multiple flags allowed in a comma-separated string. ++ [none, log_slow_filter, log_slow_rate_limit, ++ log_slow_verbosity, long_query_time, ++ min_examined_row_limit, all] + --socket=name Socket file to use for connection + --sort-buffer-size=# + Each thread that needs to do a sort allocates a buffer of +@@ -817,7 +845,11 @@ + log-short-format FALSE + log-slave-updates FALSE + log-slow-admin-statements FALSE ++log-slow-filter ++log-slow-rate-limit 1 + log-slow-slave-statements FALSE ++log-slow-sp-statements TRUE ++log-slow-verbosity + log-tc tc.log + log-tc-size 24576 + log-warnings 1 +@@ -933,6 +965,9 @@ + slave-type-conversions + slow-launch-time 2 + slow-query-log FALSE ++slow-query-log-timestamp-always FALSE ++slow-query-log-timestamp-precision second ++slow-query-log-use-global-control + sort-buffer-size 2097152 + sporadic-binlog-dump-fail FALSE + sql-mode diff --git a/sql_no_fcache.patch b/sql_no_fcache.patch index 059ff86..9756337 100644 --- a/sql_no_fcache.patch +++ b/sql_no_fcache.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/client/mysqldump.c +++ b/client/mysqldump.c -@@ -141,6 +141,8 @@ +@@ -143,6 +143,8 @@ static uint opt_protocol= 0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; @@ -16,7 +16,7 @@ /* Dynamic_string wrapper functions. In this file use these wrappers, they will terminate the process if there is -@@ -1494,6 +1496,17 @@ +@@ -1496,6 +1498,17 @@ /* Don't switch charsets for 4.1 and earlier. (bug#34192). */ server_supports_switching_charsets= FALSE; } @@ -34,7 +34,7 @@ /* As we're going to set SQL_MODE, it would be lost on reconnect, so we cannot reconnect. -@@ -3175,7 +3188,12 @@ +@@ -3177,7 +3190,12 @@ /* now build the query string */ @@ -48,7 +48,7 @@ dynstr_append_checked(&query_string, filename); dynstr_append_checked(&query_string, "'"); -@@ -3225,7 +3243,12 @@ +@@ -3227,7 +3245,12 @@ check_io(md_result_file); } @@ -294,7 +294,7 @@ mysqld_exit(0); } -@@ -6557,6 +6666,7 @@ +@@ -6553,6 +6662,7 @@ {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG}, {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH}, {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG}, @@ -314,7 +314,7 @@ lex->leaf_tables_insert= 0; --- a/sql/sql_lex.h +++ b/sql/sql_lex.h -@@ -2298,6 +2298,7 @@ +@@ -2303,6 +2303,7 @@ enum enum_yes_no_unknown tx_chain, tx_release; bool safe_to_cache_query; @@ -378,7 +378,7 @@ %token SQL_SMALL_RESULT %token SQL_SYM /* SQL-2003-R */ %token SQL_THREAD -@@ -7353,6 +7354,10 @@ +@@ -7357,6 +7358,10 @@ Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE; } } diff --git a/subunit.patch b/subunit.patch new file mode 100644 index 0000000..8d03b18 --- /dev/null +++ b/subunit.patch @@ -0,0 +1,199 @@ +=== added file 'mysql-test/lib/Subunit.pm' +--- /dev/null ++++ b/mysql-test/lib/Subunit.pm +@@ -0,0 +1,94 @@ ++# Perl module for parsing and generating the Subunit protocol ++# Copyright (C) 2008-2009 Jelmer Vernooij ++# ++# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause ++# license at the users choice. A copy of both licenses are available in the ++# project source as Apache-2.0 and BSD. You may not use this file except in ++# compliance with one of these two licences. ++# ++# Unless required by applicable law or agreed to in writing, software ++# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT ++# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++# license you chose for the specific language governing permissions and ++# limitations under that license. ++ ++package Subunit; ++use POSIX; ++ ++use vars qw ( $VERSION ); ++ ++$VERSION = '0.0.2'; ++ ++use strict; ++my $SUBUNIT_OUT= 'test_results.subunit'; ++# reset the file ++open(SUBUNITOUT, ">$SUBUNIT_OUT"); ++close(SUBUNITOUT); ++ ++sub subunit_start_test($) ++{ ++ my ($testname) = @_; ++ open(SUBUNITOUT, ">>$SUBUNIT_OUT"); ++ print SUBUNITOUT "test: $testname\n"; ++ close(SUBUNITOUT); ++ return; ++} ++ ++sub subunit_end_test($$;$) ++{ ++ my $name = shift; ++ my $result = shift; ++ my $reason = shift; ++ open(SUBUNITOUT, ">>$SUBUNIT_OUT"); ++ if ($reason) { ++ print SUBUNITOUT "$result: $name [\n"; ++ print SUBUNITOUT "$reason\n"; ++ print SUBUNITOUT "]\n"; ++ } else { ++ print SUBUNITOUT "$result: $name\n"; ++ } ++ close(SUBUNITOUT); ++ return; ++} ++ ++sub subunit_skip_test($;$) ++{ ++ my $name = shift; ++ my $reason = shift; ++ subunit_end_test($name, "skip", $reason); ++} ++ ++sub subunit_fail_test($;$) ++{ ++ my $name = shift; ++ my $reason = shift; ++ subunit_end_test($name, "failure", $reason); ++} ++ ++sub subunit_pass_test($;$) ++{ ++ my $name = shift; ++ my $reason = shift; ++ subunit_end_test($name, "success", $reason); ++} ++ ++sub subunit_xfail_test($;$) ++{ ++ my $name = shift; ++ my $reason = shift; ++ subunit_end_test($name, "xfail", $reason); ++} ++ ++sub report_time($) ++{ ++ my ($time) = @_; ++ my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($time); ++ open(SUBUNITOUT, ">>$SUBUNIT_OUT"); ++ printf SUBUNITOUT "time: %04d-%02d-%02d %02d:%02d:%02dZ\n", $year+1900, $mon, $mday, $hour, $min, $sec; ++ close(SUBUNITOUT); ++ return; ++} ++ ++ ++ ++1; +--- a/mysql-test/lib/mtr_report.pm ++++ b/mysql-test/lib/mtr_report.pm +@@ -27,9 +27,11 @@ + mtr_warning mtr_error mtr_debug mtr_verbose + mtr_verbose_restart mtr_report_test_passed + mtr_report_test_skipped mtr_print ++ mtr_report_test_subunit + mtr_report_test); + + use mtr_match; ++use Subunit; + use My::Platform; + use POSIX qw[ _exit ]; + use IO::Handle qw[ flush ]; +@@ -225,6 +227,68 @@ + } + } + ++sub mtr_report_test_subunit ($) { ++ my ($tinfo)= @_; ++ my $subunit_testname= $tinfo->{name}; ++ $subunit_testname.= " '$tinfo->{combination}'" ++ if defined $tinfo->{combination}; ++ ++ ++ my $comment= $tinfo->{'comment'}; ++ my $logfile= $tinfo->{'logfile'}; ++ my $warnings= $tinfo->{'warnings'}; ++ my $result= $tinfo->{'result'}; ++ my $retry= $tinfo->{'retries'} ? "retry-" : ""; ++ ++ my $test_name_sub = $tinfo->{name}; ++ ++ if ($result eq 'MTR_RES_FAILED'){ ++ ++ my $timest = format_time(); ++ my $fail = "fail"; ++ ++ if ( $warnings ) ++ { ++ Subunit::subunit_start_test($subunit_testname); ++ Subunit::subunit_fail_test($subunit_testname, "Found warnings/errors in server log file!"); ++ return; ++ } ++ my $timeout= $tinfo->{'timeout'}; ++ if ( $timeout ) ++ { ++ Subunit::subunit_start_test($subunit_testname); ++ Subunit::subunit_fail_test($subunit_testname, "Timeout after $timeout seconds\n\n$tinfo->{'comment'}"); ++ return; ++ } ++ Subunit::subunit_start_test($subunit_testname); ++ Subunit::subunit_fail_test($subunit_testname, "Comment: $comment\n\nLogfile:\n$logfile"); ++ } ++ elsif ($result eq 'MTR_RES_SKIPPED') ++ { ++ if ( $tinfo->{'disable'} ) ++ { ++ $comment="DISABLED: $comment"; ++ } ++ # report into to subunit for Jenkins reporting ++ Subunit::subunit_start_test($subunit_testname); ++ Subunit::subunit_skip_test($subunit_testname, $comment); ++ } ++ elsif ($result eq 'MTR_RES_PASSED') ++ { ++ # Show any problems check-testcase found ++ if ( defined $tinfo->{'check'} ) ++ { ++ mtr_report($tinfo->{'check'}); ++ } ++ # report info to subunit for Jenkins reporting ++ # TODO: catch 'check-testcase' output?? ++ Subunit::report_time(time() - $tinfo->{timer}/1000); ++ Subunit::subunit_start_test($subunit_testname); ++ Subunit::report_time(time()); ++ Subunit::subunit_pass_test($subunit_testname); ++ } ++} ++ + + sub mtr_report_stats ($$;$) { + my ($prefix, $tests, $dont_error)= @_; +--- a/mysql-test/mysql-test-run.pl ++++ b/mysql-test/mysql-test-run.pl +@@ -99,6 +99,7 @@ + use mtr_results; + use IO::Socket::INET; + use IO::Select; ++use Subunit; + + require "lib/mtr_process.pl"; + require "lib/mtr_io.pl"; +@@ -629,6 +630,7 @@ + + # Report test status + mtr_report_test($result); ++ mtr_report_test_subunit($result); + + if ( $result->is_failed() ) { + diff --git a/userstat.patch b/userstat.patch index 3cf8211..9567dea 100644 --- a/userstat.patch +++ b/userstat.patch @@ -7,7 +7,7 @@ # should be done or reviewed by the maintainer! --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h -@@ -547,6 +547,9 @@ +@@ -556,6 +556,9 @@ unsigned long thd_log_slow_verbosity(const MYSQL_THD thd); int thd_opt_slow_log(); #define EXTENDED_SLOWLOG @@ -61,7 +61,7 @@ +Rename variable USERSTAT_RUNNING => USERSTAT --- a/sql/handler.cc +++ b/sql/handler.cc -@@ -1244,6 +1244,8 @@ +@@ -1245,6 +1245,8 @@ goto end; } DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE();); @@ -70,7 +70,7 @@ RUN_HOOK(transaction, after_commit, (thd, FALSE)); end: if (rw_trans && mdl_request.ticket) -@@ -1398,6 +1400,8 @@ +@@ -1399,6 +1401,8 @@ /* Always cleanup. Even if nht==0. There may be savepoints. */ if (is_real_trans) thd->transaction.cleanup(); @@ -79,7 +79,7 @@ if (all) thd->transaction_rollback_request= FALSE; -@@ -1802,6 +1806,7 @@ +@@ -1803,6 +1807,7 @@ ha_info->reset(); /* keep it conveniently zero-filled */ } trans->ha_list= sv->ha_list; @@ -87,7 +87,7 @@ DBUG_RETURN(error); } -@@ -2178,6 +2183,8 @@ +@@ -2179,6 +2184,8 @@ dup_ref=ref+ALIGN_SIZE(ref_length); cached_table_flags= table_flags(); } @@ -96,7 +96,7 @@ DBUG_RETURN(error); } -@@ -3631,6 +3638,127 @@ +@@ -3638,6 +3645,127 @@ return; } @@ -603,7 +603,7 @@ delete thd; DBUG_VOID_RETURN; } -@@ -7961,6 +7993,8 @@ +@@ -7957,6 +7989,8 @@ key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi, key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create, key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log, @@ -612,7 +612,7 @@ key_LOCK_gdl, key_LOCK_global_system_variables, key_LOCK_manager, key_LOCK_prepared_stmt_count, -@@ -8000,6 +8034,13 @@ +@@ -7996,6 +8030,13 @@ { &key_LOCK_delayed_insert, "LOCK_delayed_insert", PSI_FLAG_GLOBAL}, { &key_LOCK_delayed_status, "LOCK_delayed_status", PSI_FLAG_GLOBAL}, { &key_LOCK_error_log, "LOCK_error_log", PSI_FLAG_GLOBAL}, @@ -703,7 +703,7 @@ TODO: Replace this with an inline function. --- a/sql/sql_base.cc +++ b/sql/sql_base.cc -@@ -1524,6 +1524,11 @@ +@@ -1587,6 +1587,11 @@ table->mdl_ticket= NULL; mysql_mutex_lock(&thd->LOCK_thd_data); @@ -715,7 +715,7 @@ *table_ptr=table->next; mysql_mutex_unlock(&thd->LOCK_thd_data); -@@ -2162,6 +2167,8 @@ +@@ -2225,6 +2230,8 @@ DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", table->s->db.str, table->s->table_name.str)); @@ -726,7 +726,7 @@ if (delete_table) --- a/sql/sql_class.cc +++ b/sql/sql_class.cc -@@ -850,6 +850,13 @@ +@@ -869,6 +869,13 @@ mysys_var=0; binlog_evt_union.do_union= FALSE; enable_slow_log= 0; @@ -740,7 +740,7 @@ #ifndef DBUG_OFF dbug_sentry=THD_SENTRY_MAGIC; #endif -@@ -1228,6 +1235,7 @@ +@@ -1248,6 +1255,7 @@ variables.option_bits|= OPTION_BIN_LOG; else variables.option_bits&= ~OPTION_BIN_LOG; @@ -748,7 +748,7 @@ #if defined(ENABLED_DEBUG_SYNC) /* Initialize the Debug Sync Facility. See debug_sync.cc. */ -@@ -1235,6 +1243,94 @@ +@@ -1255,6 +1263,94 @@ #endif /* defined(ENABLED_DEBUG_SYNC) */ } @@ -843,7 +843,7 @@ /* Init THD for query processing. -@@ -1989,6 +2085,32 @@ +@@ -2009,6 +2105,32 @@ } #endif @@ -876,7 +876,7 @@ struct Item_change_record: public ilink { -@@ -2165,6 +2287,7 @@ +@@ -2185,6 +2307,7 @@ } thd->sent_row_count++; @@ -884,7 +884,7 @@ if (thd->vio_ok()) DBUG_RETURN(protocol->write()); -@@ -2257,6 +2380,7 @@ +@@ -2277,6 +2400,7 @@ select_export::~select_export() { thd->sent_row_count=row_count; @@ -892,7 +892,7 @@ } -@@ -3280,6 +3404,7 @@ +@@ -3300,6 +3424,7 @@ if (likely(thd != 0)) { /* current_thd==0 when close_connection() calls net_send_error() */ thd->status_var.bytes_sent+= length; @@ -900,7 +900,7 @@ } } -@@ -3287,6 +3412,7 @@ +@@ -3307,6 +3432,7 @@ void thd_increment_bytes_received(ulong length) { current_thd->status_var.bytes_received+= length; @@ -919,7 +919,7 @@ uint32 file_id; // for LOAD DATA INFILE /* remote (peer) port */ uint16 peer_port; -@@ -2105,6 +2107,8 @@ +@@ -2098,6 +2100,8 @@ */ enum_tx_isolation tx_isolation; enum_check_fields count_cuted_fields; @@ -928,7 +928,7 @@ DYNAMIC_ARRAY user_var_events; /* For user variables replication */ MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */ -@@ -2199,6 +2203,49 @@ +@@ -2192,6 +2196,49 @@ */ LOG_INFO* current_linfo; NET* slave_net; // network connection from slave -> m. @@ -978,7 +978,7 @@ /* Used by the sys_var class to store temporary values */ union { -@@ -2279,6 +2326,11 @@ +@@ -2272,6 +2319,11 @@ alloc_root. */ void init_for_queries(); @@ -990,7 +990,7 @@ void change_user(void); void cleanup(void); void cleanup_after_query(); -@@ -2751,6 +2803,15 @@ +@@ -2744,6 +2796,15 @@ } thd_scheduler scheduler; @@ -1006,7 +1006,7 @@ public: inline Internal_error_handler *get_internal_handler() { return m_internal_handler; } -@@ -2951,6 +3012,10 @@ +@@ -2944,6 +3005,10 @@ LEX_STRING invoker_host; }; @@ -1740,7 +1740,7 @@ thd->abort_on_warning= 0; DBUG_RETURN(FALSE); -@@ -3540,6 +3543,7 @@ +@@ -3535,6 +3538,7 @@ thd->first_successful_insert_id_in_prev_stmt : (info.copied ? autoinc_value_of_last_inserted_row : 0)); ::my_ok(thd, row_count, id, buff); @@ -1796,7 +1796,7 @@ /* Commands which always take a long time are logged into the slow log only if opt_log_slow_admin_statements is set. -@@ -1667,6 +1680,13 @@ +@@ -1672,6 +1685,13 @@ thd->profiling.discard_current_query(); #endif break; @@ -1810,7 +1810,7 @@ case SCH_OPEN_TABLES: case SCH_VARIABLES: case SCH_STATUS: -@@ -1824,6 +1844,7 @@ +@@ -1829,6 +1849,7 @@ thd->security_ctx->priv_host)) && check_global_access(thd, SUPER_ACL)) { @@ -1818,7 +1818,7 @@ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); DBUG_RETURN(TRUE); } -@@ -4806,6 +4827,7 @@ +@@ -4827,6 +4848,7 @@ case ACL_INTERNAL_ACCESS_DENIED: if (! no_errors) { @@ -1826,7 +1826,7 @@ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->priv_host, db); } -@@ -4856,6 +4878,7 @@ +@@ -4877,6 +4899,7 @@ DBUG_PRINT("error",("No possible access")); if (!no_errors) { @@ -1834,7 +1834,7 @@ if (thd->password == 2) my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0), sctx->priv_user, -@@ -4972,6 +4995,7 @@ +@@ -4993,6 +5016,7 @@ if (!thd->col_access && check_grant_db(thd, dst_db_name)) { @@ -1842,7 +1842,7 @@ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), thd->security_ctx->priv_user, thd->security_ctx->priv_host, -@@ -5242,6 +5266,7 @@ +@@ -5263,6 +5287,7 @@ if ((thd->security_ctx->master_access & want_access)) return 0; get_privilege_desc(command, sizeof(command), want_access); @@ -1850,7 +1850,7 @@ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); return 1; #else -@@ -5623,6 +5648,32 @@ +@@ -5644,6 +5669,32 @@ lex_start(thd); mysql_reset_thd_for_next_command(thd); @@ -1883,7 +1883,7 @@ if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0) { LEX *lex= thd->lex; -@@ -5691,6 +5742,52 @@ +@@ -5712,6 +5763,52 @@ DBUG_ASSERT(thd->change_list.is_empty()); } @@ -2731,7 +2731,7 @@ /* collect status for all running threads */ -@@ -7689,6 +8005,104 @@ +@@ -7712,6 +8028,104 @@ }; @@ -2836,7 +2836,7 @@ ST_FIELD_INFO processlist_fields_info[]= { {"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE}, -@@ -7878,6 +8292,8 @@ +@@ -7901,6 +8315,8 @@ { {"CHARACTER_SETS", charsets_fields_info, create_schema_table, fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0}, @@ -2845,7 +2845,7 @@ {"COLLATIONS", collation_fields_info, create_schema_table, fill_schema_collation, make_old_format, 0, -1, -1, 0, 0}, {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info, -@@ -7887,6 +8303,8 @@ +@@ -7910,6 +8326,8 @@ OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL}, {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table, fill_schema_column_privileges, 0, 0, -1, -1, 0, 0}, @@ -2854,7 +2854,7 @@ {"ENGINES", engines_fields_info, create_schema_table, fill_schema_engines, make_old_format, 0, -1, -1, 0, 0}, #ifdef HAVE_EVENT_SCHEDULER -@@ -7959,14 +8377,20 @@ +@@ -7982,14 +8400,20 @@ get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0}, {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table, fill_schema_table_privileges, 0, 0, -1, -1, 0, 0}, @@ -2944,7 +2944,7 @@ %token USE_FRM %token USE_SYM %token USING /* SQL-2003-R */ -@@ -11100,6 +11105,41 @@ +@@ -11120,6 +11125,41 @@ MYSQL_YYABORT; #endif // HAVE_RESPONSE_TIME_DISTRIBUTION } @@ -2986,7 +2986,7 @@ | CREATE PROCEDURE_SYM sp_name { LEX *lex= Lex; -@@ -11342,6 +11382,16 @@ +@@ -11365,6 +11405,16 @@ Lex->type|= REFRESH_QUERY_RESPONSE_TIME; #endif // HAVE_RESPONSE_TIME_DISTRIBUTION } @@ -3003,7 +3003,7 @@ | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | DES_KEY_FILE -@@ -12480,6 +12530,7 @@ +@@ -12509,6 +12559,7 @@ | CHAIN_SYM {} | CHANGED {} | CIPHER_SYM {} @@ -3011,7 +3011,7 @@ | CLIENT_SYM {} | CLASS_ORIGIN_SYM {} | COALESCE {} -@@ -12548,6 +12599,7 @@ +@@ -12577,6 +12628,7 @@ | HOSTS_SYM {} | HOUR_SYM {} | IDENTIFIED_SYM {} @@ -3019,7 +3019,7 @@ | IGNORE_SERVER_IDS_SYM {} | INVOKER_SYM {} | IMPORT {} -@@ -12699,6 +12751,7 @@ +@@ -12728,6 +12780,7 @@ | SUSPEND_SYM {} | SWAPS_SYM {} | SWITCHES_SYM {} @@ -3027,7 +3027,7 @@ | TABLE_NAME_SYM {} | TABLES {} | TABLE_CHECKSUM_SYM {} -@@ -12724,6 +12777,7 @@ +@@ -12753,6 +12806,7 @@ | UNKNOWN_SYM {} | UNTIL_SYM {} | USER {} @@ -3459,3 +3459,40 @@ +SET GLOBAL userstat=OFF; +DROP TABLE t1; \ No newline at end of file +--- a/mysql-test/r/mysqld--help-notwin.result ++++ b/mysql-test/r/mysqld--help-notwin.result +@@ -743,6 +743,8 @@ + Define threads usage for handling queries, one of + one-thread-per-connection, no-threads, loaded-dynamically + --thread-stack=# The stack size for each thread ++ --thread-statistics Control TABLE_STATISTICS running, when userstat is ++ enabled + --time-format=name The TIME format (ignored) + --timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are + currently supported) +@@ -768,6 +770,9 @@ + of the underlying table and the query uses a LIMIT clause + (usually get from GUI tools) + -u, --user=name Run mysqld daemon as user. ++ --userstat Control USER_STATISTICS, CLIENT_STATISTICS, ++ THREAD_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS ++ running + -v, --verbose Used with --help option for detailed help. + -V, --version Output version information and exit. + --wait-timeout=# The number of seconds the server waits for activity on a +@@ -1002,6 +1007,7 @@ + thread-cache-size 0 + thread-handling one-thread-per-connection + thread-stack 262144 ++thread-statistics FALSE + time-format %H:%i:%s + timed-mutexes FALSE + tmp-table-size 16777216 +@@ -1009,6 +1015,7 @@ + transaction-isolation REPEATABLE-READ + transaction-prealloc-size 4096 + updatable-views-with-limit YES ++userstat FALSE + verbose TRUE + wait-timeout 28800 + xtradb-admin-command ON diff --git a/valgrind_zlib_suppression.patch b/valgrind_zlib_suppression.patch index bdbb5ba..1504176 100644 --- a/valgrind_zlib_suppression.patch +++ b/valgrind_zlib_suppression.patch @@ -2,7 +2,7 @@ # https://bugs.launchpad.net/percona-server/+bug/794837 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp -@@ -876,3 +876,12 @@ +@@ -876,6 +876,15 @@ fun:buf_buddy_free_low fun:buf_buddy_free } @@ -15,3 +15,6 @@ + fun:compress + fun:my_compress_alloc +} + + # Note the wildcard in the (mangled) function signatures of + # write_keys() and find_all_keys(). -- 2.44.0