]> git.pld-linux.org Git - packages/mysql.git/commitdiff
up to 5.1.70, using percona tarball 5.1.70-rel14.8
authorElan Ruusamäe <glen@delfi.ee>
Fri, 9 Aug 2013 00:20:01 +0000 (03:20 +0300)
committerElan Ruusamäe <glen@delfi.ee>
Fri, 9 Aug 2013 00:20:01 +0000 (03:20 +0300)
79 files changed:
bug45702.patch [deleted file]
bug53761.patch [deleted file]
bug813587.patch [deleted file]
bug860910.patch [deleted file]
disable_query_cache_28249_test_sporadic_failure.patch [deleted file]
innodb_bug47167_test_fix.patch [deleted file]
innodb_fake_changes.patch [deleted file]
innodb_kill_idle_transaction.patch [deleted file]
mysql-acc-pslist.patch [deleted file]
mysql-bug-34192.patch [deleted file]
mysql-bug580324.patch [deleted file]
mysql-bug677407.patch [deleted file]
mysql-bugfix48929.patch [deleted file]
mysql-control_online_alter_index.patch [deleted file]
mysql-error_pad.patch [deleted file]
mysql-fix-bug671764.patch [deleted file]
mysql-i_s_innodb_buffer_pool_pages.patch [deleted file]
mysql-info.patch [deleted file]
mysql-innodb_adjust_defaults.patch [deleted file]
mysql-innodb_admin_command_base.patch [deleted file]
mysql-innodb_buffer_pool_shm.patch [deleted file]
mysql-innodb_bug60788.patch [deleted file]
mysql-innodb_deadlock_count.patch [deleted file]
mysql-innodb_dict_size_limit.patch [deleted file]
mysql-innodb_expand_fast_index_creation.patch [deleted file]
mysql-innodb_expand_import.patch [deleted file]
mysql-innodb_expand_undo_slots.patch [deleted file]
mysql-innodb_extend_slow.patch [deleted file]
mysql-innodb_extra_rseg.patch [deleted file]
mysql-innodb_fast_checksum.patch [deleted file]
mysql-innodb_fast_shutdown.patch [deleted file]
mysql-innodb_files_extend.patch [deleted file]
mysql-innodb_fix_misc.patch [deleted file]
mysql-innodb_io_patches.patch [deleted file]
mysql-innodb_lru_dump_restore.patch [deleted file]
mysql-innodb_opt_lru_count.patch [deleted file]
mysql-innodb_overwrite_relay_log_info.patch [deleted file]
mysql-innodb_pass_corrupt_table.patch [deleted file]
mysql-innodb_purge_thread.patch [deleted file]
mysql-innodb_recovery_patches.patch [deleted file]
mysql-innodb_rw_lock.patch [deleted file]
mysql-innodb_separate_doublewrite.patch [deleted file]
mysql-innodb_show_enhancements.patch [deleted file]
mysql-innodb_show_lock_name.patch [deleted file]
mysql-innodb_show_status.patch [deleted file]
mysql-innodb_show_sys_tables.patch [deleted file]
mysql-innodb_split_buf_pool_mutex.patch [deleted file]
mysql-innodb_stats.patch [deleted file]
mysql-innodb_swap_builtin_plugin.patch [deleted file]
mysql-innodb_thread_concurrency_timer_based.patch [deleted file]
mysql-libs.patch
mysql-log_connection_error.patch [deleted file]
mysql-microsec_process.patch [deleted file]
mysql-microslow.patch [deleted file]
mysql-mysql-syslog.patch [deleted file]
mysql-mysql_dump_ignore_ct.patch [deleted file]
mysql-mysql_remove_eol_carret.patch [deleted file]
mysql-optimizer_fix.patch [deleted file]
mysql-profiling_slow.patch [deleted file]
mysql-query_cache_enhance.patch [deleted file]
mysql-remove_fcntl_excessive_calls.patch [deleted file]
mysql-response-time-distribution.patch [deleted file]
mysql-show_patches.patch [deleted file]
mysql-show_slave_status_nolock.patch [deleted file]
mysql-show_temp_51.patch [deleted file]
mysql-slow_extended.patch [deleted file]
mysql-split_buf_pool_mutex_fixed_optimistic_safe.patch [deleted file]
mysql-sql_no_fcache.patch [deleted file]
mysql-suppress_log_warning_1592.patch [deleted file]
mysql-system-users.patch
mysql-userstat.patch [deleted file]
mysql-userstats.patch [deleted file]
mysql.spec
response_time_distribution.patch [deleted file]
slave_timeout_fix.patch [deleted file]
subunit.patch [deleted file]
utf8_general50_ci.patch [deleted file]
warning_fixes.patch [deleted file]
xtradb_bug317074.patch [deleted file]

diff --git a/bug45702.patch b/bug45702.patch
deleted file mode 100644 (file)
index 9100a73..0000000
+++ /dev/null
@@ -1,725 +0,0 @@
---- a/include/my_sys.h
-+++ b/include/my_sys.h
-@@ -346,8 +346,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;
-@@ -809,23 +809,23 @@
- #define my_init_dynamic_array2(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E CALLER_INFO)
- #define my_init_dynamic_array2_ci(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E ORIG_CALLER_INFO)
- 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
-                                    CALLER_INFO_PROTO);
- /* 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
-                                   CALLER_INFO_PROTO);
- 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
-@@ -44,8 +44,8 @@
- */
- my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
--                            void *init_buffer, uint init_alloc, 
--                            uint alloc_increment CALLER_INFO_PROTO)
-+                            void *init_buffer, ulong init_alloc, 
-+                            ulong alloc_increment CALLER_INFO_PROTO)
- {
-   DBUG_ENTER("init_dynamic_array");
-   if (!alloc_increment)
-@@ -76,8 +76,8 @@
- } 
- my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
--                           uint init_alloc, 
--                           uint alloc_increment CALLER_INFO_PROTO)
-+                           ulong init_alloc,
-+                           ulong alloc_increment CALLER_INFO_PROTO)
- {
-   /* placeholder to preserve ABI */
-   return my_init_dynamic_array_ci(array, element_size, init_alloc, 
-@@ -200,7 +200,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)
-   {
-@@ -232,11 +232,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;
-@@ -277,11 +277,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;
-@@ -324,7 +324,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--;
-@@ -344,7 +344,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
-@@ -372,7 +372,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
-@@ -2435,7 +2435,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/myisamdef.h
-+++ b/storage/myisam/myisamdef.h
-@@ -347,10 +347,10 @@
-   int (*key_write)(struct st_mi_sort_param *, const void *);
-   void (*lock_in_memory)(MI_CHECK *);
-   NEAR int (*write_keys)(struct st_mi_sort_param *, register uchar **,
--                     uint , struct st_buffpek *, IO_CACHE *);
--  NEAR uint (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint);
-+                         ulong, struct st_buffpek *, IO_CACHE *);
-+  NEAR ulong (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint);
-   NEAR 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/storage/myisam/sort.c
-+++ b/storage/myisam/sort.c
-@@ -47,42 +47,42 @@
- /* Functions defined in this file */
--static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info,uint keys,
-+static ha_rows NEAR_F 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 NEAR_F 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 NEAR_F write_key(MI_SORT_PARAM *info, uchar *key,
-                           IO_CACHE *tempfile);
- static int NEAR_F write_index(MI_SORT_PARAM *info,uchar * *sort_keys,
--                              uint count);
--static int NEAR_F merge_many_buff(MI_SORT_PARAM *info,uint keys,
-+                              ulong count);
-+static int NEAR_F 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 NEAR_F read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
--                                  uint sort_length);
--static int NEAR_F merge_buffers(MI_SORT_PARAM *info,uint keys,
-+static ulong NEAR_F read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
-+                                   uint sort_length);
-+static int NEAR_F 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 NEAR_F merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int,
-+static int NEAR_F merge_index(MI_SORT_PARAM *, ulong, uchar **, BUFFPEK *, long,
-                               IO_CACHE *);
- static int flush_ft_buf(MI_SORT_PARAM *info);
- static int NEAR_F write_keys_varlen(MI_SORT_PARAM *info,uchar **sort_keys,
--                                    uint count, BUFFPEK *buffpek,
-+                                    ulong count, BUFFPEK *buffpek,
-                                     IO_CACHE *tempfile);
--static uint NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
-+static ulong NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
-                                          uint sort_length);
- static int NEAR_F 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 NEAR_F 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);
-@@ -103,8 +103,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;
-@@ -138,25 +139,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))))
-@@ -182,7 +183,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))
-@@ -192,7 +193,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
-@@ -256,13 +257,13 @@
- /* Search after all keys and place them in a temp. file */
--static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
-+static ha_rows NEAR_F 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;
-@@ -312,8 +313,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);
-@@ -349,7 +350,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;
-@@ -360,21 +361,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*))+
-@@ -403,7 +404,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;
-@@ -560,7 +561,7 @@
-     }
-     if (sinfo->buffpek.elements)
-     {
--      uint maxbuffer=sinfo->buffpek.elements-1;
-+      ulong maxbuffer=sinfo->buffpek.elements-1;
-       if (!mergebuf)
-       {
-         length=param->sort_buffer_length;
-@@ -583,7 +584,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;
-@@ -648,7 +649,7 @@
-         /* Write all keys in memory to file for later merge */
- static int NEAR_F 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;
-@@ -690,7 +691,7 @@
- static int NEAR_F write_keys_varlen(MI_SORT_PARAM *info,
-                                   register uchar **sort_keys,
--                                    uint count, BUFFPEK *buffpek,
-+                                    ulong count, BUFFPEK *buffpek,
-                                   IO_CACHE *tempfile)
- {
-   uchar **end;
-@@ -736,7 +737,7 @@
- /* Write index */
- static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys,
--                              register uint count)
-+                              register ulong count)
- {
-   DBUG_ENTER("write_index");
-@@ -753,11 +754,11 @@
-         /* Merge buffers to make < MERGEBUFF2 buffers */
--static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
-+static int NEAR_F 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");
-@@ -787,7 +788,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 */
-@@ -816,17 +817,17 @@
-     -1        Error
- */
--static uint NEAR_F read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
--                                  uint sort_length)
-+static ulong NEAR_F 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 (my_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;
-@@ -835,15 +836,15 @@
-   return (count*sort_length);
- } /* read_to_buffer */
--static uint NEAR_F read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
--                                         uint sort_length)
-+static ulong NEAR_F 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;
-@@ -851,11 +852,11 @@
-     {
-       if (my_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 (my_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;
-     }
-@@ -869,9 +870,9 @@
- static int NEAR_F 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++)
-@@ -887,7 +888,7 @@
- static int NEAR_F 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);
- }
-@@ -898,12 +899,13 @@
- */
- static int NEAR_F
--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;
-@@ -913,7 +915,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)
-@@ -921,7 +923,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 */
-@@ -931,9 +933,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);
-   }
-@@ -965,10 +966,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));
-@@ -993,7 +994,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 */
-     }
-@@ -1026,23 +1027,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 NEAR_F
--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
-@@ -11524,7 +11524,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
-@@ -48,6 +48,7 @@
-                 myf MyFlags)
- {
-   size_t readbytes;
-+  size_t total_readbytes= 0;
-   int error= 0;
-   DBUG_ENTER("my_pread");
-   DBUG_PRINT("my",("Fd: %d  Seek: %lu  Buffer: 0x%lx  Count: %u  MyFlags: %d",
-@@ -68,6 +69,9 @@
-     if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count)))
-       my_errno= errno ? errno : -1;
- #endif
-+    if (readbytes > 0)
-+      total_readbytes+= readbytes;
-+
-     if (error || readbytes != Count)
-     {
-       DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d",
-@@ -80,6 +84,24 @@
-         continue;                              /* Interrupted */
-       }
- #endif
-+      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;
-+      }
-       if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
-       {
-       if (readbytes == (size_t) -1)
-@@ -94,7 +116,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 */
diff --git a/bug53761.patch b/bug53761.patch
deleted file mode 100644 (file)
index 5c2e7c9..0000000
+++ /dev/null
@@ -1,472 +0,0 @@
-# name       : bug53761.patch
-# maintainer : Alexey
-#
-# Backport of the fix for MySQL bug #53761 to 5.1
-#
---- a/storage/innodb_plugin/btr/btr0cur.c
-+++ b/storage/innodb_plugin/btr/btr0cur.c
-@@ -3238,6 +3238,7 @@
- {
-       btr_path_t*     slot;
-       rec_t*          rec;
-+      page_t*         page;
-       ut_a(cursor->path_arr);
-@@ -3260,8 +3261,155 @@
-       slot = cursor->path_arr + (root_height - height);
-+      page = page_align(rec);
-+
-       slot->nth_rec = page_rec_get_n_recs_before(rec);
--      slot->n_recs = page_get_n_recs(page_align(rec));
-+      slot->n_recs = page_get_n_recs(page);
-+      slot->page_no = page_get_page_no(page);
-+      slot->page_level = btr_page_get_level_low(page);
-+}
-+
-+/*******************************************************************//**
-+Estimate the number of rows between slot1 and slot2 for any level on a
-+B-tree. This function starts from slot1->page and reads a few pages to
-+the right, counting their records. If we reach slot2->page quickly then
-+we know exactly how many records there are between slot1 and slot2 and
-+we set is_n_rows_exact to TRUE. If we cannot reach slot2->page quickly
-+then we calculate the average number of records in the pages scanned
-+so far and assume that all pages that we did not scan up to slot2->page
-+contain the same number of records, then we multiply that average to
-+the number of pages between slot1->page and slot2->page (which is
-+n_rows_on_prev_level). In this case we set is_n_rows_exact to FALSE.
-+@return       number of rows (exact or estimated) */
-+static
-+ib_int64_t
-+btr_estimate_n_rows_in_range_on_level(
-+/*==================================*/
-+      dict_index_t*   index,                  /*!< in: index */
-+      btr_path_t*     slot1,                  /*!< in: left border */
-+      btr_path_t*     slot2,                  /*!< in: right border */
-+      ib_int64_t      n_rows_on_prev_level,   /*!< in: number of rows
-+                                              on the previous level for the
-+                                              same descend paths; used to
-+                                              determine the numbe of pages
-+                                              on this level */
-+      ibool*          is_n_rows_exact)        /*!< out: TRUE if the returned
-+                                              value is exact i.e. not an
-+                                              estimation */
-+{
-+      ulint           space;
-+      ib_int64_t      n_rows;
-+      ulint           n_pages_read;
-+      ulint           page_no;
-+      ulint           zip_size;
-+      ulint           level;
-+
-+      space = dict_index_get_space(index);
-+
-+      n_rows = 0;
-+      n_pages_read = 0;
-+
-+      /* Assume by default that we will scan all pages between
-+      slot1->page_no and slot2->page_no */
-+      *is_n_rows_exact = TRUE;
-+
-+      /* add records from slot1->page_no which are to the right of
-+      the record which serves as a left border of the range, if any */
-+      if (slot1->nth_rec < slot1->n_recs) {
-+              n_rows += slot1->n_recs - slot1->nth_rec;
-+      }
-+
-+      /* add records from slot2->page_no which are to the left of
-+      the record which servers as a right border of the range, if any */
-+      if (slot2->nth_rec > 1) {
-+              n_rows += slot2->nth_rec - 1;
-+      }
-+
-+      /* count the records in the pages between slot1->page_no and
-+      slot2->page_no (non inclusive), if any */
-+
-+      zip_size = fil_space_get_zip_size(space);
-+
-+      /* Do not read more than this number of pages in order not to hurt
-+      performance with this code which is just an estimation. If we read
-+      this many pages before reaching slot2->page_no then we estimate the
-+      average from the pages scanned so far */
-+      #define N_PAGES_READ_LIMIT      10
-+
-+      page_no = slot1->page_no;
-+      level = slot1->page_level;
-+
-+      do {
-+              mtr_t           mtr;
-+              page_t*         page;
-+              buf_block_t*    block;
-+
-+              mtr_start(&mtr);
-+
-+              /* fetch the page */
-+              block = buf_page_get(space, zip_size, page_no, RW_S_LATCH,
-+                                   &mtr);
-+
-+              page = buf_block_get_frame(block);
-+
-+              /* It is possible that the tree has been reorganized in the
-+              meantime and this is a different page. If this happens the
-+              calculated estimate will be bogus, which is not fatal as
-+              this is only an estimate. We are sure that a page with
-+              page_no exists because InnoDB never frees pages, only
-+              reuses them. */
-+              if (fil_page_get_type(page) != FIL_PAGE_INDEX
-+                  || ut_dulint_cmp(btr_page_get_index_id(page), index->id)
-+                  || btr_page_get_level_low(page) != level) {
-+
-+                      /* The page got reused for something else */
-+                      goto inexact;
-+              }
-+
-+              n_pages_read++;
-+
-+              if (page_no != slot1->page_no) {
-+                      /* Do not count the records on slot1->page_no,
-+                      we already counted them before this loop. */
-+                      n_rows += page_get_n_recs(page);
-+              }
-+
-+              page_no = btr_page_get_next(page, &mtr);
-+
-+              mtr_commit(&mtr);
-+
-+              if (n_pages_read == N_PAGES_READ_LIMIT
-+                  || page_no == FIL_NULL) {
-+                      /* Either we read too many pages or
-+                      we reached the end of the level without passing
-+                      through slot2->page_no, the tree must have changed
-+                      in the meantime */
-+                      goto inexact;
-+              }
-+
-+      } while (page_no != slot2->page_no);
-+
-+      return(n_rows);
-+
-+inexact:
-+
-+      *is_n_rows_exact = FALSE;
-+
-+      /* We did interrupt before reaching slot2->page */
-+
-+      if (n_pages_read > 0) {
-+              /* The number of pages on this level is
-+              n_rows_on_prev_level, multiply it by the
-+              average number of recs per page so far */
-+              n_rows = n_rows_on_prev_level
-+                      * n_rows / n_pages_read;
-+      } else {
-+              /* The tree changed before we could even
-+              start with slot1->page_no */
-+              n_rows = 10;
-+      }
-+
-+      return(n_rows);
- }
- /*******************************************************************//**
-@@ -3286,6 +3434,7 @@
-       ibool           diverged_lot;
-       ulint           divergence_level;
-       ib_int64_t      n_rows;
-+      ibool           is_n_rows_exact;
-       ulint           i;
-       mtr_t           mtr;
-@@ -3328,6 +3477,7 @@
-       /* We have the path information for the range in path1 and path2 */
-       n_rows = 1;
-+      is_n_rows_exact = TRUE;
-       diverged = FALSE;           /* This becomes true when the path is not
-                                   the same any more */
-       diverged_lot = FALSE;       /* This becomes true when the paths are
-@@ -3343,7 +3493,7 @@
-               if (slot1->nth_rec == ULINT_UNDEFINED
-                   || slot2->nth_rec == ULINT_UNDEFINED) {
--                      if (i > divergence_level + 1) {
-+                      if (i > divergence_level + 1 && !is_n_rows_exact) {
-                               /* In trees whose height is > 1 our algorithm
-                               tends to underestimate: multiply the estimate
-                               by 2: */
-@@ -3355,7 +3505,9 @@
-                       to over 1 / 2 of the estimated rows in the whole
-                       table */
--                      if (n_rows > index->table->stat_n_rows / 2) {
-+                      if (n_rows > index->table->stat_n_rows / 2
-+                          && !is_n_rows_exact) {
-+
-                               n_rows = index->table->stat_n_rows / 2;
-                               /* If there are just 0 or 1 rows in the table,
-@@ -3381,10 +3533,15 @@
-                                       divergence_level = i;
-                               }
-                       } else {
--                              /* Maybe the tree has changed between
--                              searches */
--
--                              return(10);
-+                              /* It is possible that
-+                              slot1->nth_rec >= slot2->nth_rec
-+                              if, for example, we have a single page
-+                              tree which contains (inf, 5, 6, supr)
-+                              and we select where x > 20 and x < 30;
-+                              in this case slot1->nth_rec will point
-+                              to the supr record and slot2->nth_rec
-+                              will point to 6 */
-+                              n_rows = 0;
-                       }
-               } else if (diverged && !diverged_lot) {
-@@ -3408,8 +3565,9 @@
-                       }
-               } else if (diverged_lot) {
--                      n_rows = (n_rows * (slot1->n_recs + slot2->n_recs))
--                              / 2;
-+                      n_rows = btr_estimate_n_rows_in_range_on_level(
-+                              index, slot1, slot2, n_rows,
-+                              &is_n_rows_exact);
-               }
-       }
- }
---- a/storage/innodb_plugin/include/btr0cur.h
-+++ b/storage/innodb_plugin/include/btr0cur.h
-@@ -670,6 +670,11 @@
-                               order); value ULINT_UNDEFINED
-                               denotes array end */
-       ulint   n_recs;         /*!< number of records on the page */
-+      ulint   page_no;        /*!< no of the page containing the record */
-+      ulint   page_level;     /*!< level of the page, if later we fetch
-+                              the page under page_no and it is no different
-+                              level then we know that the tree has been
-+                              reorganized */
- };
- #define BTR_PATH_ARRAY_N_SLOTS        250     /*!< size of path array (in slots) */
---- a/mysql-test/suite/innodb_plugin/r/innodb_gis.result
-+++ b/mysql-test/suite/innodb_plugin/r/innodb_gis.result
-@@ -572,7 +572,7 @@
- EXPLAIN 
- SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
- id    select_type     table   type    possible_keys   key     key_len ref     rows    Extra
--1     SIMPLE  t2      ref     p       p       28      const   1       Using where
-+1     SIMPLE  t2      ref     p       p       28      const   2       Using where
- SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
- COUNT(*)
- 2
---- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result
-+++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result
-@@ -889,13 +889,13 @@
- id    1
- select_type   SIMPLE
- table t1
--type  range
-+type  index
- possible_keys bkey
--key   bkey
--key_len       5
-+key   PRIMARY
-+key_len       4
- ref   NULL
--rows  16
--Extra Using where; Using index; Using filesort
-+rows  32
-+Extra Using where
- SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a;
- a     b
- 1     2
-@@ -934,12 +934,12 @@
- id    1
- select_type   SIMPLE
- table t1
--type  range
-+type  index
- possible_keys bkey
- key   bkey
- key_len       5
- ref   NULL
--rows  16
-+rows  32
- Extra Using where; Using index
- SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a;
- a     b
-@@ -989,7 +989,7 @@
- key   bkey
- key_len       5
- ref   const
--rows  8
-+rows  16
- Extra Using where; Using index; Using filesort
- SELECT * FROM t2 WHERE b=1 ORDER BY a;
- a     b       c
-@@ -1018,7 +1018,7 @@
- key   bkey
- key_len       10
- ref   const,const
--rows  8
-+rows  16
- Extra Using where; Using index
- SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a;
- a     b       c
-@@ -1047,7 +1047,7 @@
- key   bkey
- key_len       10
- ref   const,const
--rows  8
-+rows  16
- Extra Using where; Using index
- SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY b,c,a;
- a     b       c
-@@ -1076,7 +1076,7 @@
- key   bkey
- key_len       10
- ref   const,const
--rows  8
-+rows  16
- Extra Using where; Using index
- SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY c,a;
- a     b       c
-@@ -1211,7 +1211,7 @@
- key   b
- key_len       5
- ref   const
--rows  1
-+rows  2
- Extra Using where; Using index
- SELECT * FROM t1 WHERE b=2 ORDER BY a ASC;
- a     b
-@@ -1226,7 +1226,7 @@
- key   b
- key_len       5
- ref   const
--rows  1
-+rows  2
- Extra Using where; Using index
- SELECT * FROM t1 WHERE b=2 ORDER BY a DESC;
- a     b
-@@ -1370,7 +1370,7 @@
- INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
- EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
- id    select_type     table   type    possible_keys   key     key_len ref     rows    Extra
--1     SIMPLE  t1      index   t1_b    PRIMARY 4       NULL    8       Using where
-+1     SIMPLE  t1      range   t1_b    t1_b    5       NULL    8       Using where
- SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
- a     b       c
- 8     1       1
-@@ -1729,7 +1729,7 @@
- FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
- id    select_type     table   type    possible_keys   key     key_len ref     rows    Extra
- 1     PRIMARY <derived2>      system  NULL    NULL    NULL    NULL    1       
--2     DERIVED t1      index   c3,c2   c2      10      NULL    5       
-+2     DERIVED t1      ALL     c3,c2   c3      5               5       Using filesort
- DROP TABLE t1;
- CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
- ENGINE=InnoDB;
-@@ -1743,7 +1743,7 @@
- FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
- id    select_type     table   type    possible_keys   key     key_len ref     rows    Extra
- 1     PRIMARY <derived2>      system  NULL    NULL    NULL    NULL    1       
--2     DERIVED t1      index   c3,c2   c2      18      NULL    5       
-+2     DERIVED t1      ALL     c3,c2   c3      9               5       Using filesort
- DROP TABLE t1;
- CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), 
- KEY (c3), KEY (c2, c3))
-@@ -1758,7 +1758,7 @@
- FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
- id    select_type     table   type    possible_keys   key     key_len ref     rows    Extra
- 1     PRIMARY <derived2>      system  NULL    NULL    NULL    NULL    1       
--2     DERIVED t1      index   c3,c2   c2      14      NULL    5       
-+2     DERIVED t1      ALL     c3,c2   c3      7               5       Using filesort
- DROP TABLE t1;
- End of 5.1 tests
- drop table if exists t1, t2, t3;
-@@ -1834,7 +1834,7 @@
- key   b
- key_len       5
- ref   NULL
--rows  3
-+rows  5
- Extra Using where; Using index
- EXPLAIN SELECT c FROM bar WHERE c>2;;
- id    1
-@@ -2430,7 +2430,7 @@
- WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
- id    select_type     table   type    possible_keys   key     key_len ref     rows    Extra
- 1     PRIMARY NULL    NULL    NULL    NULL    NULL    NULL    NULL    Select tables optimized away
--2     DERIVED t1      index_merge     PRIMARY,idx     idx,PRIMARY     5,4     NULL    3537    Using sort_union(idx,PRIMARY); Using where
-+2     DERIVED t1      index_merge     PRIMARY,idx     idx,PRIMARY     5,4     NULL    1536    Using sort_union(idx,PRIMARY); Using where
- SELECT COUNT(*) FROM
- (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
- WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
---- a/mysql-test/r/index_merge_innodb.result
-+++ b/mysql-test/r/index_merge_innodb.result
-@@ -346,7 +346,7 @@
- FROM t1
- WHERE c = 1 AND b = 1 AND d = 1;
- id    select_type     table   type    possible_keys   key     key_len ref     rows    Extra
--1     SIMPLE  t1      index_merge     c,bd    c,bd    5,10    NULL    1       Using intersect(c,bd); Using where; Using index
-+1     SIMPLE  t1      ref     c,bd    bd      10      const,const     2       Using where
- CREATE TABLE t2 ( a INT )
- SELECT a
- FROM t1
---- a/mysql-test/r/rowid_order_innodb.result
-+++ b/mysql-test/r/rowid_order_innodb.result
-@@ -15,7 +15,7 @@
- (10, 1, 1);
- explain select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
- id    select_type     table   type    possible_keys   key     key_len ref     rows    Extra
--1     SIMPLE  t1      index_merge     key1,key2       key1,key2       5,5     NULL    4       Using sort_union(key1,key2); Using where
-+1     SIMPLE  t1      index_merge     key1,key2       key1,key2       5,5     NULL    5       Using sort_union(key1,key2); Using where
- select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
- pk1   key1    key2
- -100  1       1
---- a/mysql-test/r/type_bit_innodb.result
-+++ b/mysql-test/r/type_bit_innodb.result
-@@ -233,7 +233,7 @@
- 127   403
- explain select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
- id    select_type     table   type    possible_keys   key     key_len ref     rows    Extra
--1     SIMPLE  t1      range   a       a       2       NULL    19      Using where; Using index; Using filesort
-+1     SIMPLE  t1      range   a       a       2       NULL    27      Using where; Using index; Using filesort
- select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
- a+0   b+0
- 44    307
---- a/mysql-test/r/endspace.result
-+++ b/mysql-test/r/endspace.result
-@@ -201,12 +201,12 @@
- text1
- teststring    
- teststring 
--select text1, length(text1) from t1 where text1='teststring' or text1 like 'teststring_%';
-+select text1, length(text1) from t1 where text1='teststring' or text1 like 'teststring_%' order by 1, 2;
- text1 length(text1)
- teststring            11
- teststring    10
- teststring    11
--select text1, length(text1) from t1 where text1='teststring' or text1 >= 'teststring\t';
-+select text1, length(text1) from t1 where text1='teststring' or text1 >= 'teststring\t' order by 1, 2;
- text1 length(text1)
- teststring            11
- teststring    10
---- a/mysql-test/t/endspace.test
-+++ b/mysql-test/t/endspace.test
-@@ -93,8 +93,8 @@
- select * from t1 where text1 like 'teststring_%';
- # The following gives wrong result in InnoDB
--select text1, length(text1) from t1 where text1='teststring' or text1 like 'teststring_%';
--select text1, length(text1) from t1 where text1='teststring' or text1 >= 'teststring\t';
-+select text1, length(text1) from t1 where text1='teststring' or text1 like 'teststring_%' order by 1, 2;
-+select text1, length(text1) from t1 where text1='teststring' or text1 >= 'teststring\t' order by 1, 2;
- select concat('|', text1, '|') from t1 order by text1;
- drop table t1;
diff --git a/bug813587.patch b/bug813587.patch
deleted file mode 100644 (file)
index a33a67b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-# name       : bug813587.patch
-# maintainer : Alexey
-#
-# Fix for LP bug #813587 / MySQL bug #51196 / MySQL bug #61790
-#
-# Clear MySQL connection errors in ha_federated::close(), since they
-# can affect queries on other tables due to table cache eviction.
-#
---- a/storage/federated/ha_federated.cc
-+++ b/storage/federated/ha_federated.cc
-@@ -1641,6 +1641,7 @@
- int ha_federated::close(void)
- {
-+  THD *thd= current_thd;
-   DBUG_ENTER("ha_federated::close");
-   free_result();
-@@ -1651,6 +1652,10 @@
-   mysql_close(mysql);
-   mysql= NULL;
-+  /* Clear possible errors from mysql_close(), see LP bug #813587. */
-+  if (thd)
-+    thd->clear_error();
-+
-   DBUG_RETURN(free_share(share));
- }
diff --git a/bug860910.patch b/bug860910.patch
deleted file mode 100644 (file)
index 2590b62..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-# 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
-@@ -4629,6 +4629,12 @@
-                                  user_var_event->length,
-                                  user_var_event->type,
-                                  user_var_event->charset_number);
-+            /*
-+              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/disable_query_cache_28249_test_sporadic_failure.patch b/disable_query_cache_28249_test_sporadic_failure.patch
deleted file mode 100644 (file)
index e1598a2..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
---- a/mysql-test/t/disabled.def
-+++ b/mysql-test/t/disabled.def
-@@ -12,4 +12,4 @@
- kill                     : Bug#11748945 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
- read_many_rows_innodb    : Bug#11748886 2010-11-15 mattiasj report already exists
- main.log_tables-big      : Bug#11756699 2010-11-15 mattiasj report already exists
--
-+main.query_cache_28249   : http://bugs.mysql.com/bug.php?id=41098
diff --git a/innodb_bug47167_test_fix.patch b/innodb_bug47167_test_fix.patch
deleted file mode 100644 (file)
index 8a6671e..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
---- a/mysql-test/suite/innodb_plugin/r/innodb_bug47167.result
-+++ b/mysql-test/suite/innodb_plugin/r/innodb_bug47167.result
-@@ -1,7 +1,4 @@
- set @old_innodb_file_format_check=@@innodb_file_format_check;
--select @old_innodb_file_format_check;
--@old_innodb_file_format_check
--Antelope
- set global innodb_file_format_check = Barracuda;
- select @@innodb_file_format_check;
- @@innodb_file_format_check
-@@ -11,9 +8,9 @@
- @@innodb_file_format_check
- Barracuda
- set global innodb_file_format_check = @old_innodb_file_format_check;
--select @@innodb_file_format_check;
--@@innodb_file_format_check
--Antelope
-+select @@innodb_file_format_check = @old_innodb_file_format_check;
-+@@innodb_file_format_check = @old_innodb_file_format_check
-+1
- set global innodb_file_format_check = cheetah;
- ERROR HY000: Incorrect arguments to SET
- set global innodb_file_format_check = Bear;
---- a/mysql-test/suite/innodb_plugin/t/innodb_bug47167.test
-+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug47167.test
-@@ -9,9 +9,6 @@
- # 'old_innodb_file_format_check'
- set @old_innodb_file_format_check=@@innodb_file_format_check;
--# @old_innodb_file_format_check shall have the value of 'Antelope'
--select @old_innodb_file_format_check;
--
- # Reset the value in 'innodb_file_format_check' to 'Barracuda'
- set global innodb_file_format_check = Barracuda;
-@@ -27,7 +24,7 @@
- set global innodb_file_format_check = @old_innodb_file_format_check;
- # Check whether 'innodb_file_format_check' get its original value.
--select @@innodb_file_format_check;
-+select @@innodb_file_format_check = @old_innodb_file_format_check;
- # Following are negative tests, all should fail.
- --disable_warnings
diff --git a/innodb_fake_changes.patch b/innodb_fake_changes.patch
deleted file mode 100644 (file)
index 14b33fd..0000000
+++ /dev/null
@@ -1,768 +0,0 @@
-# name       : innodb_fake_changes.patch
-# introduced : 5.1.58
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/btr/btr0cur.c
-+++ b/storage/innodb_plugin/btr/btr0cur.c
-@@ -1046,6 +1046,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 */
-@@ -1177,7 +1182,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);
-@@ -1272,6 +1277,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 */
-@@ -1414,10 +1425,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
-@@ -1483,6 +1494,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))) {
-@@ -1539,6 +1560,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;
-@@ -1837,6 +1863,14 @@
-               return(err);
-       }
-+      if (trx->fake_changes) {
-+              /* skip CHANGE, LOG */
-+              if (UNIV_LIKELY_NULL(heap)) {
-+                      mem_heap_free(heap);
-+              }
-+              return(err); /* == DB_SUCCESS */
-+      }
-+
-       if (block->is_hashed) {
-               /* The function row_upd_changes_ord_field_binary works only
-               if the update vector was built for a clustered index, we must
-@@ -1939,7 +1973,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));
-@@ -2053,6 +2087,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). */
-@@ -2203,9 +2242,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 */
-@@ -2293,6 +2332,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);
-@@ -2331,6 +2373,12 @@
-               ut_ad(flags & BTR_KEEP_POS_FLAG);
-       }
-+      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
-@@ -2686,6 +2734,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);
-@@ -2823,6 +2876,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/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -369,6 +369,12 @@
-   "The value 3 regards innodb_flush_log_at_trx_commit (default).",
-   NULL, NULL, 3, 0, 3, 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,
-@@ -1400,6 +1406,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;
-@@ -2816,6 +2824,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->main_da.reset_diagnostics_area(); /* because debug assertion code complains, if something left */
-+              DBUG_RETURN(HA_ERR_WRONG_COMMAND);
-+      }
-       /* The flag trx->active_trans is set to 1 in
-       1. ::external_lock(),
-@@ -7141,6 +7154,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. */
-@@ -7346,6 +7365,10 @@
-               DBUG_RETURN(HA_ERR_CRASHED);
-       }
-+      if (prebuilt->trx->fake_changes) {
-+              goto fallback;
-+      }
-+
-       /* Truncate the table in InnoDB */
-       error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
-@@ -7406,6 +7429,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);
-@@ -7494,6 +7523,12 @@
-       trx->mysql_thd = NULL;
- #else
-       trx = innobase_trx_allocate(thd);
-+      if (trx->fake_changes) {
-+              my_free(namebuf, MYF(0));
-+              innobase_commit_low(trx);
-+              trx_free_for_mysql(trx);
-+              return; /* ignore */
-+      }
- #endif
-       row_drop_database_for_mysql(namebuf, trx);
-       my_free(namebuf, MYF(0));
-@@ -7601,6 +7636,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);
-@@ -10373,6 +10413,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
-@@ -11905,6 +11949,7 @@
-   MYSQL_SYSVAR(use_purge_thread),
-   MYSQL_SYSVAR(pass_corrupt_table),
-   MYSQL_SYSVAR(lazy_drop_table),
-+  MYSQL_SYSVAR(fake_changes),
-   NULL
- };
---- a/storage/innodb_plugin/handler/handler0alter.cc
-+++ b/storage/innodb_plugin/handler/handler0alter.cc
-@@ -652,6 +652,9 @@
-       /* In case MySQL calls this in the middle of a SELECT query, release
-       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)) {
-@@ -678,6 +681,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
-@@ -964,6 +974,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);
-@@ -1168,6 +1182,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/innodb_plugin/ibuf/ibuf0ibuf.c
-+++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c
-@@ -2613,6 +2613,8 @@
-       ut_a(trx_sys_multiple_tablespace_format);
-+      ut_ad(!(thr_get_trx(thr)->fake_changes));
-+
-       do_merge = FALSE;
-       mutex_enter(&ibuf_mutex);
---- a/storage/innodb_plugin/include/trx0trx.h
-+++ b/storage/innodb_plugin/include/trx0trx.h
-@@ -509,6 +509,7 @@
-                                       150 bytes in the undo log size as then
-                                       we skip XA steps */
-       ulint           flush_log_at_trx_commit_session;
-+      ulint           fake_changes;
-       ulint           flush_log_later;/* In 2PC, we hold the
-                                       prepare_commit mutex across
-                                       both phases. In that case, we
---- a/storage/innodb_plugin/lock/lock0lock.c
-+++ b/storage/innodb_plugin/lock/lock0lock.c
-@@ -3907,6 +3907,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 */
-@@ -5108,6 +5112,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);
-@@ -5276,6 +5285,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);
-@@ -5334,6 +5347,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,
-@@ -5421,6 +5438,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();
-@@ -5498,6 +5519,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/innodb_plugin/que/que0que.c
-+++ b/storage/innodb_plugin/que/que0que.c
-@@ -1418,6 +1418,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/innodb_plugin/row/row0ins.c
-+++ b/storage/innodb_plugin/row/row0ins.c
-@@ -1512,6 +1512,11 @@
-       if (UNIV_LIKELY_NULL(heap)) {
-               mem_heap_free(heap);
-       }
-+
-+      if (trx->fake_changes) {
-+              err = DB_SUCCESS;
-+      }
-+
-       return(err);
- }
-@@ -2014,7 +2019,7 @@
-       }
-       btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
--                                  mode | BTR_INSERT | ignore_sec_unique,
-+                                  thr_get_trx(thr)->fake_changes ? BTR_SEARCH_LEAF : (mode | BTR_INSERT | ignore_sec_unique),
-                                   &cursor, 0, __FILE__, __LINE__, &mtr);
-       if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
-@@ -2074,7 +2079,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);
-               }
-@@ -2162,6 +2167,22 @@
-       mtr_commit(&mtr);
-       if (UNIV_LIKELY_NULL(big_rec)) {
-+
-+              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/innodb_plugin/row/row0mysql.c
-+++ b/storage/innodb_plugin/row/row0mysql.c
-@@ -1189,6 +1189,7 @@
-               prebuilt->table->stat_n_rows--;
-       }
-+      if (!(trx->fake_changes))
-       row_update_statistics_if_needed(prebuilt->table);
-       trx->op_info = "";
-@@ -1449,6 +1450,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);
-       }
-@@ -1667,6 +1669,7 @@
-               srv_n_rows_updated++;
-       }
-+      if (!(trx->fake_changes))
-       row_update_statistics_if_needed(table);
-       return(err);
---- a/storage/innodb_plugin/row/row0upd.c
-+++ b/storage/innodb_plugin/row/row0upd.c
-@@ -1591,8 +1591,9 @@
-       mtr_start(&mtr);
--      found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
--                                     &mtr);
-+      found = row_search_index_entry(index, entry,
-+                                     trx->fake_changes ? BTR_SEARCH_LEAF : BTR_MODIFY_LEAF,
-+                                     &pcur, &mtr);
-       btr_cur = btr_pcur_get_btr_cur(&pcur);
-       rec = btr_cur_get_rec(btr_cur);
-@@ -1822,9 +1823,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
-@@ -1854,7 +1857,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);
-@@ -1982,7 +1985,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)));
-@@ -1990,7 +1994,8 @@
-       err = btr_cur_pessimistic_update(
-               BTR_NO_LOCKING_FLAG | BTR_KEEP_POS_FLAG, btr_cur,
-               &heap, &big_rec, node->update, node->cmpl_info, thr, mtr);
--      if (big_rec) {
-+      /* skip store extern for fake_changes */
-+      if (big_rec && !(thr_get_trx(thr)->fake_changes)) {
-               ulint           offsets_[REC_OFFS_NORMAL_SIZE];
-               rec_t*          rec;
-               rec_offs_init(offsets_);
-@@ -2132,7 +2137,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/innodb_plugin/trx/trx0trx.c
-+++ b/storage/innodb_plugin/trx/trx0trx.c
-@@ -114,6 +114,8 @@
-       trx->flush_log_at_trx_commit_session = 3; /* means to use innodb_flush_log_at_trx_commit value */
-+      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_plugin.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_plugin.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_kill_idle_transaction.patch b/innodb_kill_idle_transaction.patch
deleted file mode 100644 (file)
index 9f7251c..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-# name       : innodb_kill_idle_transaction.patch
-# introduced : 5.1.58
-# 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
-@@ -847,6 +847,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(MYSQL_THD thd);
-+#define EXTENDED_FOR_KILLIDLE
-+
- #ifdef __cplusplus
- }
- #endif
---- a/include/mysql/plugin.h.pp
-+++ b/include/mysql/plugin.h.pp
-@@ -150,3 +150,6 @@
- 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(void* thd);
---- a/sql/sql_class.cc
-+++ b/sql/sql_class.cc
-@@ -470,6 +470,26 @@
-   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(THD* thd)
-+{
-+  pthread_mutex_lock(&thd->LOCK_thd_data);
-+  thd->awake(THD::KILL_CONNECTION);
-+  pthread_mutex_unlock(&thd->LOCK_thd_data);
-+}
- /**
-   Implementation of Drop_table_error_handler::handle_error().
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -2517,6 +2517,10 @@
-       innobase_commit_concurrency_init_default();
-+#ifndef EXTENDED_FOR_KILLIDLE
-+      srv_kill_idle_transaction = 0;
-+#endif
-+
-       /* Since we in this module access directly the fields of a trx
-       struct, and due to different headers and flags it might happen that
-       mutex_t has a different size in this module and in InnoDB
-@@ -11231,6 +11235,48 @@
-       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(
-+/*==============*/
-+      void*   thd)
-+{
-+#ifdef EXTENDED_FOR_KILLIDLE
-+      thd_kill((THD*) thd);
-+#else
-+      return;
-+#endif
-+}
-+
-+
- static SHOW_VAR innodb_status_variables_export[]= {
-   {"Innodb",                   (char*) &show_innodb_vars, SHOW_FUNC},
-   {NullS, NullS, SHOW_LONG}
-@@ -11474,6 +11520,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.",
-@@ -11767,6 +11822,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/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -282,6 +282,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/innodb_plugin/include/trx0trx.h
-+++ b/storage/innodb_plugin/include/trx0trx.h
-@@ -600,6 +600,8 @@
-       ulint           mysql_process_no;/* since in Linux, 'top' reports
-                                       process id's and not thread id's, we
-                                       store the process number too */
-+      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/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -86,6 +86,11 @@
- #include "trx0i_s.h"
- #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
-+/* 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(void* thd);
-+
- /* prototypes for new functions added to ha_innodb.cc */
- ibool innobase_get_slow_log();
-@@ -100,6 +105,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;
-@@ -2557,6 +2565,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; /* as stmt ID */
-+
-+                              start_time = innobase_thd_get_start_time(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(trx->mysql_thd);
-+                                      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/innodb_plugin/trx/trx0trx.c
-+++ b/storage/innodb_plugin/trx/trx0trx.c
-@@ -137,6 +137,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, 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/mysql-acc-pslist.patch b/mysql-acc-pslist.patch
deleted file mode 100644 (file)
index f447f4f..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-diff -r 1a59073d658d mysql-test/r/create.result
---- a/mysql-test/r/create.result       Sat Sep 13 17:31:30 2008 -0700
-+++ b/mysql-test/r/create.result       Sat Sep 13 17:31:40 2008 -0700
-@@ -1720,7 +1720,8 @@
-   `COMMAND` varchar(16) NOT NULL DEFAULT '',
-   `TIME` bigint(7) NOT NULL DEFAULT '0',
-   `STATE` varchar(64) DEFAULT NULL,
--  `INFO` longtext
-+  `INFO` longtext,
-+  `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8
- drop table t1;
- create temporary table t1 like information_schema.processlist;
-@@ -1734,7 +1735,8 @@
-   `COMMAND` varchar(16) NOT NULL DEFAULT '',
-   `TIME` bigint(7) NOT NULL DEFAULT '0',
-   `STATE` varchar(64) DEFAULT NULL,
--  `INFO` longtext
-+  `INFO` longtext,
-+  `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8
- drop table t1;
- create table t1 like information_schema.character_sets;
-diff -r 1a59073d658d sql/sql_show.cc
---- a/sql/sql_show.cc  Sat Sep 13 17:31:30 2008 -0700
-+++ b/sql/sql_show.cc  Sat Sep 13 17:31:40 2008 -0700
-@@ -1803,7 +1803,7 @@
-   TABLE *table= tables->table;
-   CHARSET_INFO *cs= system_charset_info;
-   char *user;
--  time_t now= my_time(0);
-+  ulonglong unow= my_micro_time();
-   DBUG_ENTER("fill_process_list");
-   user= thd->security_ctx->master_access & PROCESS_ACL ?
-@@ -1873,8 +1873,8 @@
-         table->field[4]->store(command_name[tmp->command].str,
-                                command_name[tmp->command].length, cs);
-       /* MYSQL_TIME */
--      table->field[5]->store((longlong)(tmp->start_time ?
--                                      now - tmp->start_time : 0), FALSE);
-+      const ulonglong utime= tmp->start_utime ? unow - tmp->start_utime : 0;
-+      table->field[5]->store(utime / 1000000, TRUE);
-       /* STATE */
- #ifndef EMBEDDED_LIBRARY
-       val= (char*) (tmp->locked ? "Locked" :
-@@ -1896,11 +1896,15 @@
-         table->field[7]->set_notnull();
-       }
-+      /* TIME_MS */
-+      table->field[8]->store((double)(utime / 1000.0));
-+
-       if (schema_table_store_record(thd, table))
-       {
-         VOID(pthread_mutex_unlock(&LOCK_thread_count));
-         DBUG_RETURN(1);
-       }
-+
-     }
-   }
-@@ -5531,7 +5535,7 @@
-     into it two numbers, based on modulus of base-10 numbers.  In the ones
-     position is the number of decimals.  Tens position is unused.  In the
-     hundreds and thousands position is a two-digit decimal number representing
--    length.  Encode this value with  (decimals*100)+length  , where
-+    length.  Encode this value with  (length*100)+decimals  , where
-     0<decimals<10 and 0<=length<100 .
-   @param
-@@ -6539,6 +6543,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},
-+  {"TIME_MS", 100 * (MY_INT64_NUM_DECIMAL_DIGITS + 1) + 3, MYSQL_TYPE_DECIMAL,
-+    0, 0, "Time_ms", SKIP_OPEN_TABLE},
-   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
- };
diff --git a/mysql-bug-34192.patch b/mysql-bug-34192.patch
deleted file mode 100644 (file)
index d6491d4..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-From: Chad&nbsp;MILLERDate: February 1 2008 5:53pm
-Subject: bk commit into 5.0 tree (cmiller:1.2572) BUG#34192
-
-Below is the list of changes that have just been committed into a local
-5.0 repository of cmiller.  When cmiller does a push these changes
-will be propagated to the main repository and, within 24 hours after the
-push, to the public repository.
-For information on how to access the public repository
-see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
-
-ChangeSet@stripped, 2008-02-01 11:53:48-05:00, cmiller@stripped +1 -0
-  Bug#34192: mysqldump from mysql 5.0.51 silently fails on dumping \
-       databases from 4.0 server
-  
-  Contribution from Arkadiusz Miskiewicz.  No CLA required for this size.
-  
-  mysqldump treated a failure to set the results charset as a severe
-  error.  
-  
-  Now, don't try to set the charset for the SHOW CREATE TABLE statement,
-  if the dumper doesn't want SET NAMES or the remote server doesn't 
-  support changing charsets.
-  
-  (The original patch tried to set the charset to binary and back in 
-  any case, and only exited-with-failure if the dumper wanted it and
-  the remote server supported it.)
-
-  client/mysqldump.c@stripped, 2008-02-01 11:53:46-05:00, cmiller@stripped +13 -3
-    Don't set the charset for receiving results if it's not wanted or if
-    the server doesn't support it.
-
-diff -Nrup a/client/mysqldump.c b/client/mysqldump.c
---- a/client/mysqldump.c       2007-12-04 22:07:00 -05:00
-+++ b/client/mysqldump.c       2008-02-01 11:53:46 -05:00
-@@ -1705,10 +1705,20 @@ static uint get_table_structure(char *ta
-       my_snprintf(buff, sizeof(buff), "show create table %s", result_table);
--      if (switch_character_set_results(mysql, "binary") ||
--          mysql_query_with_error_report(mysql, &result, buff) ||
--          switch_character_set_results(mysql, default_charset))
-+      if (opt_set_charset)  /* Was forced to false if server is too old. */
-+      {
-+        if (switch_character_set_results(mysql, "binary") != 0)
-+          DBUG_RETURN(0);
-+      }
-+
-+      if (mysql_query_with_error_report(mysql, &result, buff) != 0)
-         DBUG_RETURN(0);
-+
-+      if (opt_set_charset)  /* Was forced to false if server is too old. */
-+      {
-+        if (switch_character_set_results(mysql, default_charset) != 0)
-+          DBUG_RETURN(0);
-+      }
-       if (path)
-       {
diff --git a/mysql-bug580324.patch b/mysql-bug580324.patch
deleted file mode 100644 (file)
index 3459c76..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-# name       : bug580324.patch
-# introduced : 11 or before
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/sql/sql_base.cc
-+++ b/sql/sql_base.cc
-@@ -233,8 +233,12 @@
- uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list,
-                           bool tmp_table)
- {
--  uint key_length= (uint) (strmov(strmov(key, table_list->db)+1,
--                                  table_list->table_name)-key)+1;
-+  char *db_end= strnmov(key, table_list->db, MAX_DBKEY_LENGTH - 2);
-+  *db_end++= '\0';
-+  char *table_end= strnmov(db_end, table_list->table_name,
-+                           key + MAX_DBKEY_LENGTH - 1 - db_end);
-+  *table_end++= '\0';
-+  uint key_length= (uint) (table_end-key);
-   if (tmp_table)
-   {
-     int4store(key + key_length, thd->server_id);
---- a/sql/sql_parse.cc
-+++ b/sql/sql_parse.cc
-@@ -1344,10 +1344,12 @@
-     break;
- #else
-   {
--    char *fields, *packet_end= packet + packet_length, *arg_end;
-+    char *fields, *packet_end= packet + packet_length, *wildcard;
-     /* Locked closure of all tables */
-     TABLE_LIST table_list;
--    LEX_STRING conv_name;
-+    char db_buff[NAME_LEN+1];
-+    uint32 db_length;
-+    uint dummy_errors;
-     /* used as fields initializator */
-     lex_start(thd);
-@@ -1359,26 +1361,22 @@
-     /*
-       We have name + wildcard in packet, separated by endzero
-     */
--    arg_end= strend(packet);
--    uint arg_length= arg_end - packet;
--    
--    /* Check given table name length. */
--    if (arg_length >= packet_length || arg_length > NAME_LEN)
-+    wildcard= strend(packet);
-+    db_length= wildcard - packet;
-+    wildcard++;
-+    uint query_length= (uint) (packet_end - wildcard); // Don't count end \0
-+    if (db_length > NAME_LEN || query_length > NAME_LEN)
-     {
-       my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-       break;
-     }
--    thd->convert_string(&conv_name, system_charset_info,
--                      packet, arg_length, thd->charset());
--    if (check_table_name(conv_name.str, conv_name.length, FALSE))
--    {
--      /* this is OK due to convert_string() null-terminating the string */
--      my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str);
-+    db_length= copy_and_convert(db_buff, sizeof(db_buff)-1,
-+                                system_charset_info, packet, db_length,
-+                                thd->charset(), &dummy_errors);
-+    db_buff[db_length]= '\0';
-+    table_list.alias= table_list.table_name= db_buff;
-+    if (!(fields= (char *) thd->memdup(wildcard, query_length + 1)))
-       break;
--    }
--
--    table_list.alias= table_list.table_name= conv_name.str;
--    packet= arg_end + 1;
-     if (is_schema_db(table_list.db, table_list.db_length))
-     {
-@@ -1387,9 +1385,6 @@
-         table_list.schema_table= schema_table;
-     }
--    uint query_length= (uint) (packet_end - packet); // Don't count end \0
--    if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
--      break;
-     thd->set_query(fields, query_length);
-     general_log_print(thd, command, "%s %s", table_list.table_name, fields);
-     if (lower_case_table_names)
---- a/strings/ctype-utf8.c
-+++ b/strings/ctype-utf8.c
-@@ -4118,6 +4118,10 @@
- {
-   int code;
-   char hex[]= "0123456789abcdef";
-+
-+  if (s >= e)
-+    return MY_CS_TOOSMALL;
-+
-   if (wc < 128 && filename_safe_char[wc])
-   {
-     *s= (uchar) wc;
diff --git a/mysql-bug677407.patch b/mysql-bug677407.patch
deleted file mode 100644 (file)
index 996e8d8..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-# name       : bug677407
-# introduced : 13
-# maintainer : Alexey
-
-LP bug#677407 / MySQL Bug#48883: Stale data from INNODB_LOCKS table.
-
-The innodb.innodb_information_schema test could fail sporadically due to
-the flawed logic in the INFORMATION_SCHEMA.INNODB_LOCKS caching
-mechanism.
-
-The logic for how to check when to update the table cache for
-INNODB_LOCKS with real data was flawed. This could result in both not
-updating the cache often enough (when the table is queried repeatedly
-with less than 100 milliseconds in-between) resulting in stale data; as
-well as updating too often (when multiple queries against the table
-start at around the same time).
-
-Fixed by updating the "last updated" timestamp in the right place, when
-the cache is updated, not when it is read.
-
-I hereby grant Percona the following BSD license to this patch for
-inclusion in Percona Server:
-
-Copyright (c) 2010, Kristian Nielsen All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in
-      the documentation and/or other materials provided with the
-      distribution.
-    * Neither the name of the author nor the names of its contributors
-      may be used to endorse or promote products derived from this
-      software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
---- a/storage/innodb_plugin/trx/trx0i_s.c
-+++ b/storage/innodb_plugin/trx/trx0i_s.c
-@@ -157,10 +157,6 @@
-       ullint          last_read;      /*!< last time the cache was read;
-                                       measured in microseconds since
-                                       epoch */
--      mutex_t         last_read_mutex;/*!< mutex protecting the
--                                      last_read member - it is updated
--                                      inside a shared lock of the
--                                      rw_lock member */
-       i_s_table_cache_t innodb_trx;   /*!< innodb_trx table */
-       i_s_table_cache_t innodb_locks; /*!< innodb_locks table */
-       i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */
-@@ -1142,13 +1138,6 @@
- {
-       ullint  now;
--      /* Here we read cache->last_read without acquiring its mutex
--      because last_read is only updated when a shared rw lock on the
--      whole cache is being held (see trx_i_s_cache_end_read()) and
--      we are currently holding an exclusive rw lock on the cache.
--      So it is not possible for last_read to be updated while we are
--      reading it. */
--
- #ifdef UNIV_SYNC_DEBUG
-       ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX));
- #endif
-@@ -1246,6 +1235,12 @@
- /*===================================*/
-       trx_i_s_cache_t*        cache)  /*!< in/out: cache */
- {
-+      ullint  now;
-+
-+#ifdef UNIV_SYNC_DEBUG
-+      ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX));
-+#endif
-+
-       if (!can_cache_be_updated(cache)) {
-               return(1);
-@@ -1258,6 +1253,10 @@
-       mutex_exit(&kernel_mutex);
-+      /* update cache last read time */
-+      now = ut_time_us(NULL);
-+      cache->last_read = now;
-+
-       return(0);
- }
-@@ -1288,16 +1287,12 @@
-       release kernel_mutex
-       release trx_i_s_cache_t::rw_lock
-       acquire trx_i_s_cache_t::rw_lock, S
--      acquire trx_i_s_cache_t::last_read_mutex
--      release trx_i_s_cache_t::last_read_mutex
-       release trx_i_s_cache_t::rw_lock */
-       rw_lock_create(&cache->rw_lock, SYNC_TRX_I_S_RWLOCK);
-       cache->last_read = 0;
--      mutex_create(&cache->last_read_mutex, SYNC_TRX_I_S_LAST_READ);
--
-       table_cache_init(&cache->innodb_trx, sizeof(i_s_trx_row_t));
-       table_cache_init(&cache->innodb_locks, sizeof(i_s_locks_row_t));
-       table_cache_init(&cache->innodb_lock_waits,
-@@ -1348,18 +1343,10 @@
- /*===================*/
-       trx_i_s_cache_t*        cache)  /*!< in: cache */
- {
--      ullint  now;
--
- #ifdef UNIV_SYNC_DEBUG
-       ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_SHARED));
- #endif
--      /* update cache last read time */
--      now = ut_time_us(NULL);
--      mutex_enter(&cache->last_read_mutex);
--      cache->last_read = now;
--      mutex_exit(&cache->last_read_mutex);
--
-       rw_lock_s_unlock(&cache->rw_lock);
- }
diff --git a/mysql-bugfix48929.patch b/mysql-bugfix48929.patch
deleted file mode 100644 (file)
index 266ba7b..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-# name       : bugfix48929.patch
-# introduced : 11 or before
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/configure.in
-+++ b/configure.in
-@@ -815,7 +815,7 @@
- AC_HEADER_STDC
- AC_HEADER_SYS_WAIT
- AC_CHECK_HEADERS(fcntl.h fenv.h float.h floatingpoint.h fpu_control.h \
-- ieeefp.h limits.h memory.h pwd.h select.h \
-+ ieeefp.h limits.h memory.h pwd.h select.h poll.h \
-  stdlib.h stddef.h \
-  strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \
-  sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -56,6 +56,10 @@
- #include "sp_rcontext.h"
- #include "sp_cache.h"
-+#ifdef HAVE_POLL_H
-+#include <poll.h>
-+#endif
-+
- #define mysqld_charset &my_charset_latin1
- #ifdef HAVE_purify
-@@ -5137,31 +5141,58 @@
- #ifndef EMBEDDED_LIBRARY
- pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
- {
--  my_socket sock,new_sock;
-+  my_socket UNINIT_VAR(sock),new_sock;
-   uint error_count=0;
--  uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
--  fd_set readFDs,clientFDs;
-   THD *thd;
-   struct sockaddr_in cAddr;
--  int ip_flags=0,socket_flags=0,flags;
-+#if !defined(HAVE_POLL)
-+  int ip_flags= 0;
-+#endif
-+#if defined(HAVE_SYS_UN_H) && !defined(HAVE_POLL)
-+  int socket_flags= 0;
-+#endif
-+  int UNINIT_VAR(flags),retval;
-   st_vio *vio_tmp;
-+#ifdef HAVE_POLL
-+  int socket_count= 0;
-+  struct pollfd fds[2]; // for ip_sock and unix_sock
-+#else
-+  fd_set readFDs,clientFDs;
-+  uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
-+#endif
-+
-   DBUG_ENTER("handle_connections_sockets");
-   LINT_INIT(new_sock);
-   (void) my_pthread_getprio(pthread_self());          // For debugging
-+#ifndef HAVE_POLL
-   FD_ZERO(&clientFDs);
-+#endif
-+
-   if (ip_sock != INVALID_SOCKET)
-   {
-+#ifdef HAVE_POLL
-+    fds[socket_count].fd= ip_sock;
-+    fds[socket_count].events= POLLIN;
-+    socket_count++;
-+#else
-     FD_SET(ip_sock,&clientFDs);
--#ifdef HAVE_FCNTL
-+#endif
-+#if !defined (HAVE_POLL) && defined(HAVE_FCNTL)
-     ip_flags = fcntl(ip_sock, F_GETFL, 0);
- #endif
-   }
- #ifdef HAVE_SYS_UN_H
-+#ifdef HAVE_POLL
-+  fds[socket_count].fd= unix_sock;
-+  fds[socket_count].events= POLLIN;
-+  socket_count++;
-+#else
-   FD_SET(unix_sock,&clientFDs);
--#ifdef HAVE_FCNTL
-+#endif
-+#if defined(HAVE_FCNTL) && defined(HAVE_SYS_UN_H) && !defined(HAVE_POLL)
-   socket_flags=fcntl(unix_sock, F_GETFL, 0);
- #endif
- #endif
-@@ -5170,12 +5201,15 @@
-   MAYBE_BROKEN_SYSCALL;
-   while (!abort_loop)
-   {
--    readFDs=clientFDs;
--#ifdef HPUX10
--    if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0)
--      continue;
-+#ifdef HAVE_POLL
-+    retval= poll(fds, socket_count, -1);
- #else
--    if (select((int) max_used_connection,&readFDs,0,0,0) < 0)
-+    readFDs=clientFDs;
-+
-+    retval= select((int) max_used_connection,&readFDs,0,0,0);
-+#endif
-+
-+    if (retval < 0)
-     {
-       if (socket_errno != SOCKET_EINTR)
-       {
-@@ -5185,7 +5219,7 @@
-       MAYBE_BROKEN_SYSCALL
-       continue;
-     }
--#endif        /* HPUX10 */
-+
-     if (abort_loop)
-     {
-       MAYBE_BROKEN_SYSCALL;
-@@ -5193,6 +5227,21 @@
-     }
-     /* Is this a new connection request ? */
-+#ifdef HAVE_POLL
-+    for (int i= 0; i < socket_count; ++i) 
-+    {
-+      if (fds[i].revents & POLLIN)
-+      {
-+        sock= fds[i].fd;
-+#ifdef HAVE_FCNTL
-+        flags= fcntl(sock, F_GETFL, 0);
-+#else
-+        flags= 0;
-+#endif // HAVE_FCNTL
-+        break;
-+      }
-+    }
-+#else  // HAVE_POLL
- #ifdef HAVE_SYS_UN_H
-     if (FD_ISSET(unix_sock,&readFDs))
-     {
-@@ -5200,11 +5249,12 @@
-       flags= socket_flags;
-     }
-     else
--#endif
-+#endif // HAVE_SYS_UN_H
-     {
-       sock = ip_sock;
-       flags= ip_flags;
-     }
-+#endif // HAVE_POOL
- #if !defined(NO_FCNTL_NONBLOCK)
-     if (!(test_flags & TEST_BLOCKING))
diff --git a/mysql-control_online_alter_index.patch b/mysql-control_online_alter_index.patch
deleted file mode 100644 (file)
index 5a921fb..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-# name       : control_online_alter_index.patch
-# introduced : 12
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/sql/handler.h
-+++ b/sql/handler.h
-@@ -171,6 +171,19 @@
- #define HA_ONLINE_DROP_UNIQUE_INDEX             (1L << 9) /*drop uniq. online*/
- #define HA_ONLINE_ADD_PK_INDEX                  (1L << 10)/*add prim. online*/
- #define HA_ONLINE_DROP_PK_INDEX                 (1L << 11)/*drop prim. online*/
-+
-+#define HA_ONLINE_ALTER_INDEX_MASK    (HA_ONLINE_ADD_INDEX_NO_WRITES \
-+                                              | HA_ONLINE_DROP_INDEX_NO_WRITES \
-+                                              | HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES \
-+                                              | HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES \
-+                                              | HA_ONLINE_ADD_PK_INDEX_NO_WRITES \
-+                                              | HA_ONLINE_DROP_PK_INDEX_NO_WRITES \
-+                                              | HA_ONLINE_ADD_INDEX \
-+                                              | HA_ONLINE_DROP_INDEX \
-+                                              | HA_ONLINE_ADD_UNIQUE_INDEX \
-+                                              | HA_ONLINE_DROP_UNIQUE_INDEX \
-+                                              | HA_ONLINE_ADD_PK_INDEX \
-+                                              | HA_ONLINE_DROP_PK_INDEX)
- /*
-   HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
-   supported at all.
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -5914,6 +5914,7 @@
-   OPT_USERSTAT_RUNNING,
-   OPT_THREAD_STATISTICS,
-   OPT_OPTIMIZER_FIX,
-+  OPT_ONLINE_ALTER_INDEX,
-   OPT_SUPPRESS_LOG_WARNING_1592,
-   OPT_QUERY_CACHE_STRIP_COMMENTS,
-   OPT_USE_GLOBAL_LONG_QUERY_TIME,
-@@ -5946,6 +5947,13 @@
-    "from libc.so",
-    &opt_allow_suspicious_udfs, &opt_allow_suspicious_udfs,
-    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+  {"fast_index_creation",
-+   OPT_ONLINE_ALTER_INDEX,
-+   "If disabled, suppresses online operations for indexes of ALTER TABLE "
-+   "(e.g. fast index creation of InnoDB Plugin) for the session.",
-+   (uchar**) &global_system_variables.online_alter_index,
-+   (uchar**) &global_system_variables.online_alter_index,
-+   0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
-   {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode "
-    "will also set transaction isolation level 'serializable'.", 0, 0, 0,
-    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
---- a/sql/set_var.cc
-+++ b/sql/set_var.cc
-@@ -760,6 +760,11 @@
- sys_engine_condition_pushdown(&vars, "engine_condition_pushdown",
-                             &SV::engine_condition_pushdown);
-+/* Control online operations of ALTER TABLE */
-+static sys_var_thd_bool
-+sys_online_alter_index(&vars, "fast_index_creation",
-+                      &SV::online_alter_index);
-+
- #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
- /* ndb thread specific variable settings */
- static sys_var_thd_ulong
---- a/sql/sql_class.h
-+++ b/sql/sql_class.h
-@@ -383,6 +383,8 @@
-   my_bool ndb_use_transactions;
-   my_bool ndb_index_stat_enable;
-+  my_bool online_alter_index;
-+
-   my_bool old_alter_table;
-   my_bool old_passwords;
---- a/sql/sql_partition.cc
-+++ b/sql/sql_partition.cc
-@@ -4381,7 +4381,12 @@
-         alter_info->no_parts= curr_part_no - new_part_no;
-       }
-     }
--    if (!(flags= table->file->alter_table_flags(alter_info->flags)))
-+    flags= table->file->alter_table_flags(alter_info->flags);
-+    if (!thd->variables.online_alter_index)
-+    {
-+      flags&= ~((uint)HA_ONLINE_ALTER_INDEX_MASK);
-+    }
-+    if (!flags)
-     {
-       my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
-       DBUG_RETURN(1);
---- a/sql/sql_table.cc
-+++ b/sql/sql_table.cc
-@@ -7023,6 +7023,10 @@
-     uint  *idx_end_p;
-     alter_flags= table->file->alter_table_flags(alter_info->flags);
-+    if (!thd->variables.online_alter_index)
-+    {
-+      alter_flags&= ~((ulong)HA_ONLINE_ALTER_INDEX_MASK);
-+    }
-     DBUG_PRINT("info", ("alter_flags: %lu", alter_flags));
-     /* Check dropped indexes. */
-     for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
diff --git a/mysql-error_pad.patch b/mysql-error_pad.patch
deleted file mode 100644 (file)
index 5402dab..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-# name       : error_pad.patch
-# introduced : 12
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/extra/comp_err.c
-+++ b/extra/comp_err.c
-@@ -32,11 +32,12 @@
- #include <assert.h>
- #include <my_dir.h>
--#define MAX_ROWS  1000
-+#define MAX_ROWS  5000
- #define HEADER_LENGTH 32                /* Length of header in errmsg.sys */
- #define DEFAULT_CHARSET_DIR "../sql/share/charsets"
- #define ER_PREFIX "ER_"
- #define WARN_PREFIX "WARN_"
-+#define PADD_PREFIX "PADD_"
- static char *OUTFILE= (char*) "errmsg.sys";
- static char *HEADERFILE= (char*) "mysqld_error.h";
- static char *NAMEFILE= (char*) "mysqld_ername.h";
-@@ -91,6 +92,7 @@
-   const char *sql_code1;              /* sql state */
-   const char *sql_code2;              /* ODBC state */
-   struct errors *next_error;            /* Pointer to next error */
-+  my_bool is_padding;                   /* If true - padd this er_name while er_code != d_code*/
-   DYNAMIC_ARRAY msg;                    /* All language texts for this error */
- };
-@@ -129,6 +131,7 @@
- static struct languages *parse_charset_string(char *str);
-+static struct errors *parse_padd_string(char *ptr, int er_count);
- static struct errors *parse_error_string(char *ptr, int er_count);
- static struct message *parse_message_string(struct message *new_message,
-                                           char *str);
-@@ -231,6 +234,11 @@
-   for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error)
-   {
-+    if (tmp_error->is_padding)
-+    {
-+      er_last= tmp_error->d_code;
-+      continue;
-+    }
-     /*
-        generating mysqld_error.h
-        fprintf() will automatically add \r on windows
-@@ -320,12 +328,29 @@
-               "language\n", tmp_error->er_name, tmp_lang->lang_short_name);
-       goto err;
-       }
--      if (copy_rows(to, tmp->text, row_nr, start_pos))
-+      if (tmp_error->is_padding)
-       {
--      fprintf(stderr, "Failed to copy rows to %s\n", outfile);
--      goto err;
-+        int padd_to= tmp_error->d_code;
-+        char* padd_message= tmp->text;
-+        while ((int) row_nr + er_offset < padd_to)
-+        {
-+          if (copy_rows(to, padd_message,row_nr,start_pos))
-+          {
-+            fprintf(stderr, "Failed to copy rows to %s\n", outfile);
-+            goto err;
-+          }
-+          row_nr++;
-+        }
-+      }
-+      else
-+      {
-+        if (copy_rows(to, tmp->text, row_nr, start_pos))
-+        {
-+          fprintf(stderr, "Failed to copy rows to %s\n", outfile);
-+          goto err;
-+        }
-+        row_nr++;
-       }
--      row_nr++;
-     }
-     /* continue with header of the errmsg.sys file */
-@@ -476,14 +501,26 @@
-       DBUG_RETURN(0);
-       continue;
-     }
--    if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX))
-+    if (is_prefix(str, ER_PREFIX) || is_prefix(str, WARN_PREFIX) || is_prefix(str, PADD_PREFIX))
-     {
--      if (!(current_error= parse_error_string(str, rcount)))
-+      if (is_prefix(str, PADD_PREFIX))
-       {
--      fprintf(stderr, "Failed to parse the error name string\n");
--      DBUG_RETURN(0);
-+        if (!(current_error= parse_padd_string(str, rcount)))
-+        {
-+          fprintf(stderr, "Failed to parse the error padd string\n");
-+          DBUG_RETURN(0);
-+        }
-+        rcount= current_error->d_code - er_offset;  /* Count number of unique errors */
-+      }
-+      else
-+      {
-+        if (!(current_error= parse_error_string(str, rcount)))
-+        {
-+          fprintf(stderr, "Failed to parse the error name string\n");
-+          DBUG_RETURN(0);
-+        }
-+        rcount++;                         /* Count number of unique errors */
-       }
--      rcount++;                         /* Count number of unique errors */
-       /* add error to the list */
-       *tail_error= current_error;
-@@ -824,78 +861,122 @@
-   DBUG_RETURN(new_message);
- }
-+static struct errors* create_new_error(my_bool is_padding, char *er_name, int d_code, const char *sql_code1, const char *sql_code2)
-+{
-+  struct errors *new_error;
-+  DBUG_ENTER("create_new_error");
-+  /* create a new element */
-+  new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME));
-+  if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0))
-+    DBUG_RETURN(0);                           /* OOM: Fatal error */
-+  new_error->is_padding= is_padding;
-+  DBUG_PRINT("info", ("is_padding: %s", (is_padding ? "true" : "false")));
-+  new_error->er_name= er_name;
-+  DBUG_PRINT("info", ("er_name: %s", er_name));
-+  new_error->d_code= d_code;
-+  DBUG_PRINT("info", ("d_code: %d", d_code));
-+  new_error->sql_code1= sql_code1;
-+  DBUG_PRINT("info", ("sql_code1: %s", sql_code1));
-+  new_error->sql_code2= sql_code2;
-+  DBUG_PRINT("info", ("sql_code2: %s", sql_code2));
-+  DBUG_RETURN(new_error);
-+}
- /*
--  Parsing the string with error name and codes; returns the pointer to
-+  Parsing the string with padd syntax (name + error to pad); returns the pointer to
-   the errors struct
- */
--static struct errors *parse_error_string(char *str, int er_count)
-+static struct errors *parse_padd_string(char* str, int er_count)
- {
--  struct errors *new_error;
-+  char *er_name;
-+  uint d_code;
-+  char *start;
-   DBUG_ENTER("parse_error_string");
-   DBUG_PRINT("enter", ("str: %s", str));
--  /* create a new element */
--  new_error= (struct errors *) my_malloc(sizeof(*new_error), MYF(MY_WME));
-+  start= str;
-+  str= skip_delimiters(str);
--  if (my_init_dynamic_array(&new_error->msg, sizeof(struct message), 0, 0))
-+  /* getting the error name */
-+
-+  if (!(er_name= get_word(&str)))
-     DBUG_RETURN(0);                           /* OOM: Fatal error */
--  /* getting the error name */
-   str= skip_delimiters(str);
--  if (!(new_error->er_name= get_word(&str)))
-+  if (!(d_code= parse_error_offset(start)))
-+  {
-+    fprintf(stderr, "Failed to parse the error padd string '%s' '%s' (d_code doesn't parse)!\n",er_name,str);
-+    DBUG_RETURN(0);
-+  }
-+  if (d_code < (uint) er_offset + er_count)
-+  {
-+    fprintf(stderr, "Error to padding less current error number!\n");
-+    DBUG_RETURN(0);
-+  }
-+  DBUG_RETURN(create_new_error(TRUE,er_name,d_code,empty_string,empty_string));
-+}
-+
-+/*
-+  Parsing the string with error name and codes; returns the pointer to
-+  the errors struct
-+*/
-+
-+static struct errors *parse_error_string(char *str, int er_count)
-+{
-+  char *er_name;
-+  int d_code;
-+  const char *sql_code1= empty_string;
-+  const char *sql_code2= empty_string;
-+  DBUG_ENTER("parse_error_string");
-+  DBUG_PRINT("enter", ("str: %s", str));
-+
-+  str= skip_delimiters(str);
-+
-+  /* getting the error name */
-+
-+  if (!(er_name= get_word(&str)))
-     DBUG_RETURN(0);                           /* OOM: Fatal error */
--  DBUG_PRINT("info", ("er_name: %s", new_error->er_name));
-   str= skip_delimiters(str);
-   /* getting the code1 */
--
--  new_error->d_code= er_offset + er_count;
--  DBUG_PRINT("info", ("d_code: %d", new_error->d_code));
-+  d_code= er_offset + er_count;
-   str= skip_delimiters(str);
-   /* if we reached EOL => no more codes, but this can happen */
-   if (!*str)
-   {
--    new_error->sql_code1= empty_string;
--    new_error->sql_code2= empty_string;
-     DBUG_PRINT("info", ("str: %s", str));
--    DBUG_RETURN(new_error);
-+    goto complete_create;
-   }
--
-   /* getting the sql_code 1 */
--
--  if (!(new_error->sql_code1= get_word(&str)))
-+  if (!(sql_code1= get_word(&str)))
-     DBUG_RETURN(0);                           /* OOM: Fatal error */
--  DBUG_PRINT("info", ("sql_code1: %s", new_error->sql_code1));
-   str= skip_delimiters(str);
-   /* if we reached EOL => no more codes, but this can happen */
-   if (!*str)
-   {
--    new_error->sql_code2= empty_string;
-     DBUG_PRINT("info", ("str: %s", str));
--    DBUG_RETURN(new_error);
-+    goto complete_create;
-   }
--
-   /* getting the sql_code 2 */
--  if (!(new_error->sql_code2= get_word(&str)))
-+  if (!(sql_code2= get_word(&str)))
-     DBUG_RETURN(0);                           /* OOM: Fatal error */
--  DBUG_PRINT("info", ("sql_code2: %s", new_error->sql_code2));
-   str= skip_delimiters(str);
-+
-   if (*str)
-   {
-     fprintf(stderr, "The error line did not end with sql/odbc code!");
-     DBUG_RETURN(0);
-   }
--
--  DBUG_RETURN(new_error);
-+complete_create:
-+  DBUG_RETURN(create_new_error(FALSE,er_name,d_code,sql_code1,sql_code2));
- }
diff --git a/mysql-fix-bug671764.patch b/mysql-fix-bug671764.patch
deleted file mode 100644 (file)
index bda76b2..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# name       : fix-bug671764.patch
-# introduced : 12
-# maintainer : Alexander
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/configure.in
-+++ b/configure.in
-@@ -2772,7 +2772,7 @@
-     MAN_DROP="$MAN_DROP embedded"
-     grep -v 'embedded' $MANLISTFIL > $TMPLISTFIL ; mv -f $TMPLISTFIL $MANLISTFIL
-   fi
--  if test X"$with_plugin_innobase" != Xyes
-+  if test X"$with_plugin_innodb_plugin" != Xyes
-   then
-     MAN_DROP="$MAN_DROP innodb"
-     grep -v 'inno' $MANLISTFIL > $TMPLISTFIL ; mv -f $TMPLISTFIL $MANLISTFIL
-@@ -2851,7 +2851,7 @@
- fi
- # "innochecksum" is not in the "innobase/" subdirectory, but should be switched
--AM_CONDITIONAL([BUILD_INNODB_TOOLS], [test X"$with_plugin_innobase" = Xyes])
-+AM_CONDITIONAL([BUILD_INNODB_TOOLS], [test X"$with_plugin_innodb_plugin" = Xyes])
- # IMPORTANT - do not modify LIBS past this line - this hack is the only way
- # I know to add the static NSS magic if we have static NSS libraries with
diff --git a/mysql-i_s_innodb_buffer_pool_pages.patch b/mysql-i_s_innodb_buffer_pool_pages.patch
deleted file mode 100644 (file)
index 857053d..0000000
+++ /dev/null
@@ -1,791 +0,0 @@
-# name       : i_s_innodb_buffer_pool_pages.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -269,14 +269,6 @@
- UNIV_INTERN ibool             buf_debug_prints = FALSE;
- #endif /* UNIV_DEBUG */
--/** A chunk of buffers.  The buffer pool is allocated in chunks. */
--struct buf_chunk_struct{
--      ulint           mem_size;       /*!< allocated size of the chunk */
--      ulint           size;           /*!< size of frames[] and blocks[] */
--      void*           mem;            /*!< pointer to the memory area which
--                                      was allocated for the frames */
--      buf_block_t*    blocks;         /*!< array of buffer control blocks */
--};
- #endif /* !UNIV_HOTBACKUP */
- /********************************************************************//**
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -11248,6 +11248,9 @@
-   innobase_system_variables, /* system variables */
-   NULL /* reserved */
- },
-+i_s_innodb_buffer_pool_pages,
-+i_s_innodb_buffer_pool_pages_index,
-+i_s_innodb_buffer_pool_pages_blob,
- i_s_innodb_trx,
- i_s_innodb_locks,
- i_s_innodb_lock_waits,
---- a/storage/innodb_plugin/handler/i_s.cc
-+++ b/storage/innodb_plugin/handler/i_s.cc
-@@ -42,6 +42,7 @@
- #include "buf0buf.h" /* for buf_pool and PAGE_ZIP_MIN_SIZE */
- #include "ha_prototypes.h" /* for innobase_convert_name() */
- #include "srv0start.h" /* for srv_was_started */
-+#include "btr0btr.h" /* for btr_page_get_index_id */
- }
- static const char plugin_author[] = "Innobase Oy";
-@@ -380,6 +381,705 @@
- };
-+static ST_FIELD_INFO  i_s_innodb_buffer_pool_pages_fields_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "page_type"),
-+       STRUCT_FLD(field_length,       64),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_MAYBE_NULL),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "space_id"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "page_no"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "lru_position"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "fix_count"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "flush_type"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      END_OF_ST_FIELD_INFO
-+};
-+
-+static ST_FIELD_INFO  i_s_innodb_buffer_pool_pages_index_fields_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "index_id"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "space_id"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "page_no"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "n_recs"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "data_size"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "hashed"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "access_time"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "modified"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "dirty"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "old"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "lru_position"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "fix_count"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "flush_type"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      END_OF_ST_FIELD_INFO
-+};
-+
-+static ST_FIELD_INFO  i_s_innodb_buffer_pool_pages_blob_fields_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "space_id"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "page_no"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "compressed"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "part_len"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "next_page_no"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "lru_position"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "fix_count"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "flush_type"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      END_OF_ST_FIELD_INFO
-+};
-+
-+/***********************************************************************
-+Fill the dynamic table information_schema.innodb_buffer_pool_pages. */
-+static
-+int
-+i_s_innodb_buffer_pool_pages_fill(
-+/*================*/
-+                              /* out: 0 on success, 1 on failure */
-+      THD*            thd,    /* in: thread */
-+      TABLE_LIST*     tables, /* in/out: tables to fill */
-+      COND*           cond)   /* in: condition (ignored) */
-+{
-+      TABLE*  table   = (TABLE *) tables->table;
-+      int     status  = 0;
-+
-+  ulint               n_chunks, n_blocks;
-+
-+      buf_chunk_t*    chunk;
-+
-+      DBUG_ENTER("i_s_innodb_buffer_pool_pages_fill");
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+
-+              DBUG_RETURN(0);
-+      }
-+
-+      RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
-+
-+      buf_pool_mutex_enter();
-+      
-+      chunk = buf_pool->chunks;
-+  
-+      for (n_chunks = buf_pool->n_chunks; n_chunks--; chunk++) {
-+              buf_block_t*    block           = chunk->blocks;
-+
-+    for (n_blocks     = chunk->size; n_blocks--; block++) {
-+      const buf_frame_t* frame = block->frame;
-+  
-+      char page_type[64];
-+
-+      switch(fil_page_get_type(frame))
-+      {
-+      case FIL_PAGE_INDEX:
-+        strcpy(page_type, "index");
-+        break;
-+      case FIL_PAGE_UNDO_LOG:
-+        strcpy(page_type, "undo_log");
-+        break;
-+      case FIL_PAGE_INODE:
-+        strcpy(page_type, "inode");
-+        break;
-+      case FIL_PAGE_IBUF_FREE_LIST:
-+        strcpy(page_type, "ibuf_free_list");
-+        break;
-+      case FIL_PAGE_TYPE_ALLOCATED:
-+        strcpy(page_type, "allocated");
-+        break;
-+      case FIL_PAGE_IBUF_BITMAP:
-+        strcpy(page_type, "bitmap");
-+        break;
-+      case FIL_PAGE_TYPE_SYS:
-+        strcpy(page_type, "sys");
-+        break;
-+      case FIL_PAGE_TYPE_TRX_SYS:
-+        strcpy(page_type, "trx_sys");
-+        break;
-+      case FIL_PAGE_TYPE_FSP_HDR:
-+        strcpy(page_type, "fsp_hdr");
-+        break;
-+      case FIL_PAGE_TYPE_XDES:
-+        strcpy(page_type, "xdes");
-+        break;
-+      case FIL_PAGE_TYPE_BLOB:
-+        strcpy(page_type, "blob");
-+        break;
-+      case FIL_PAGE_TYPE_ZBLOB:
-+        strcpy(page_type, "zblob");
-+        break;
-+      case FIL_PAGE_TYPE_ZBLOB2:
-+        strcpy(page_type, "zblob2");
-+        break;
-+      default:
-+        sprintf(page_type, "unknown (type=%li)", fil_page_get_type(frame));
-+      }
-+      
-+      field_store_string(table->field[0], page_type);
-+      table->field[1]->store(block->page.space);
-+      table->field[2]->store(block->page.offset);
-+      table->field[3]->store(0);
-+      table->field[4]->store(block->page.buf_fix_count);
-+      table->field[5]->store(block->page.flush_type);
-+
-+      if (schema_table_store_record(thd, table)) {
-+        status = 1;
-+        break;
-+      }
-+      
-+    }      
-+      }
-+
-+      buf_pool_mutex_exit();
-+
-+      DBUG_RETURN(status);
-+}
-+
-+/***********************************************************************
-+Fill the dynamic table information_schema.innodb_buffer_pool_pages_index. */
-+static
-+int
-+i_s_innodb_buffer_pool_pages_index_fill(
-+/*================*/
-+                              /* out: 0 on success, 1 on failure */
-+      THD*            thd,    /* in: thread */
-+      TABLE_LIST*     tables, /* in/out: tables to fill */
-+      COND*           cond)   /* in: condition (ignored) */
-+{
-+      TABLE*  table   = (TABLE *) tables->table;
-+      int     status  = 0;
-+
-+  ulint               n_chunks, n_blocks;
-+  dulint              index_id;
-+
-+      buf_chunk_t*    chunk;
-+
-+      DBUG_ENTER("i_s_innodb_buffer_pool_pages_index_fill");
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+
-+              DBUG_RETURN(0);
-+      }
-+
-+      RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
-+
-+      buf_pool_mutex_enter();
-+      
-+      chunk = buf_pool->chunks;
-+  
-+      for (n_chunks = buf_pool->n_chunks; n_chunks--; chunk++) {
-+              buf_block_t*    block           = chunk->blocks;
-+
-+              for (n_blocks   = chunk->size; n_blocks--; block++) {
-+                      const buf_frame_t* frame = block->frame;
-+  
-+      if (fil_page_get_type(frame) == FIL_PAGE_INDEX) {
-+        index_id = btr_page_get_index_id(frame);
-+        table->field[0]->store(ut_conv_dulint_to_longlong(index_id));
-+        table->field[1]->store(block->page.space);
-+        table->field[2]->store(block->page.offset);
-+        table->field[3]->store(page_get_n_recs(frame));
-+        table->field[4]->store(page_get_data_size(frame));
-+        table->field[5]->store(block->is_hashed);
-+        table->field[6]->store(block->page.access_time);
-+        table->field[7]->store(block->page.newest_modification != 0);
-+        table->field[8]->store(block->page.oldest_modification != 0);
-+        table->field[9]->store(block->page.old);
-+        table->field[10]->store(0);
-+        table->field[11]->store(block->page.buf_fix_count);
-+        table->field[12]->store(block->page.flush_type);
-+          
-+        if (schema_table_store_record(thd, table)) {
-+          status = 1;
-+          break;
-+        }
-+      }      
-+    }
-+      }
-+
-+      buf_pool_mutex_exit();
-+
-+      DBUG_RETURN(status);
-+}
-+
-+/***********************************************************************
-+Fill the dynamic table information_schema.innodb_buffer_pool_pages_index. */
-+static
-+int
-+i_s_innodb_buffer_pool_pages_blob_fill(
-+/*================*/
-+                              /* out: 0 on success, 1 on failure */
-+      THD*            thd,    /* in: thread */
-+      TABLE_LIST*     tables, /* in/out: tables to fill */
-+      COND*           cond)   /* in: condition (ignored) */
-+{
-+      TABLE*  table   = (TABLE *) tables->table;
-+      int     status  = 0;
-+
-+  ulint               n_chunks, n_blocks;
-+      buf_chunk_t*    chunk;
-+      page_zip_des_t* block_page_zip;
-+
-+      ulint           part_len;
-+      ulint           next_page_no;
-+
-+      DBUG_ENTER("i_s_innodb_buffer_pool_pages_blob_fill");
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+
-+              DBUG_RETURN(0);
-+      }
-+
-+      RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
-+
-+      buf_pool_mutex_enter();
-+      
-+      chunk = buf_pool->chunks;
-+    
-+      for (n_chunks = buf_pool->n_chunks; n_chunks--; chunk++) {
-+              buf_block_t*    block           = chunk->blocks;
-+    block_page_zip = buf_block_get_page_zip(block);
-+
-+    for (n_blocks     = chunk->size; n_blocks--; block++) {
-+      const buf_frame_t* frame = block->frame;
-+
-+      if (fil_page_get_type(frame) == FIL_PAGE_TYPE_BLOB) {
-+
-+        if (UNIV_LIKELY_NULL(block_page_zip)) {
-+          part_len = 0; /* hmm, can't figure it out */
-+  
-+          next_page_no = mach_read_from_4(
-+            buf_block_get_frame(block)
-+            + FIL_PAGE_NEXT);        
-+        } else {
-+          part_len = mach_read_from_4(
-+            buf_block_get_frame(block)
-+            + FIL_PAGE_DATA
-+            + 0 /*BTR_BLOB_HDR_PART_LEN*/);
-+  
-+          next_page_no = mach_read_from_4(
-+            buf_block_get_frame(block)
-+            + FIL_PAGE_DATA
-+            + 4 /*BTR_BLOB_HDR_NEXT_PAGE_NO*/);
-+        }
-+
-+        table->field[0]->store(block->page.space);
-+        table->field[1]->store(block->page.offset);
-+        table->field[2]->store(block_page_zip != NULL);
-+        table->field[3]->store(part_len);
-+
-+        if(next_page_no == FIL_NULL)
-+        {
-+          table->field[4]->store(0);
-+        } else {
-+          table->field[4]->store(block->page.offset);
-+        }
-+
-+        table->field[5]->store(0);
-+        table->field[6]->store(block->page.buf_fix_count);
-+        table->field[7]->store(block->page.flush_type);
-+  
-+        if (schema_table_store_record(thd, table)) {
-+          status = 1;
-+          break;
-+        }
-+
-+      }
-+    }      
-+      }
-+
-+      buf_pool_mutex_exit();
-+
-+      DBUG_RETURN(status);
-+}
-+
-+/***********************************************************************
-+Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
-+static
-+int
-+i_s_innodb_buffer_pool_pages_init(
-+/*=========*/
-+                      /* out: 0 on success */
-+      void*   p)      /* in/out: table schema object */
-+{
-+      DBUG_ENTER("i_s_innodb_buffer_pool_pages_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_buffer_pool_pages_fields_info;
-+      schema->fill_table = i_s_innodb_buffer_pool_pages_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+/***********************************************************************
-+Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
-+static
-+int
-+i_s_innodb_buffer_pool_pages_index_init(
-+/*=========*/
-+                      /* out: 0 on success */
-+      void*   p)      /* in/out: table schema object */
-+{
-+      DBUG_ENTER("i_s_innodb_buffer_pool_pages_index_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_buffer_pool_pages_index_fields_info;
-+      schema->fill_table = i_s_innodb_buffer_pool_pages_index_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+/***********************************************************************
-+Bind the dynamic table information_schema.innodb_buffer_pool_pages. */
-+static
-+int
-+i_s_innodb_buffer_pool_pages_blob_init(
-+/*=========*/
-+                      /* out: 0 on success */
-+      void*   p)      /* in/out: table schema object */
-+{
-+      DBUG_ENTER("i_s_innodb_buffer_pool_pages_blob_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_buffer_pool_pages_blob_fields_info;
-+      schema->fill_table = i_s_innodb_buffer_pool_pages_blob_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+
-+UNIV_INTERN struct st_mysql_plugin    i_s_innodb_buffer_pool_pages =
-+{
-+      /* the plugin type (a MYSQL_XXX_PLUGIN value) */
-+      /* int */
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+
-+      /* pointer to type-specific plugin descriptor */
-+      /* void* */
-+      STRUCT_FLD(info, &i_s_info),
-+
-+      /* plugin name */
-+      /* const char* */
-+      STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"),
-+
-+      /* plugin author (for SHOW PLUGINS) */
-+      /* const char* */
-+      STRUCT_FLD(author, "Percona"),
-+
-+      /* general descriptive text (for SHOW PLUGINS) */
-+      /* const char* */
-+      STRUCT_FLD(descr, "InnoDB buffer pool pages"),
-+
-+      /* the plugin license (PLUGIN_LICENSE_XXX) */
-+      /* int */
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+
-+      /* the function to invoke when plugin is loaded */
-+      /* int (*)(void*); */
-+      STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init),
-+
-+      /* the function to invoke when plugin is unloaded */
-+      /* int (*)(void*); */
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+
-+      /* plugin version (for SHOW PLUGINS) */
-+      /* unsigned int */
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+
-+      /* struct st_mysql_show_var* */
-+      STRUCT_FLD(status_vars, NULL),
-+
-+      /* struct st_mysql_sys_var** */
-+      STRUCT_FLD(system_vars, NULL),
-+
-+      /* reserved for dependency checking */
-+      /* void* */
-+      STRUCT_FLD(__reserved1, NULL)
-+};
-+
-+UNIV_INTERN struct st_mysql_plugin    i_s_innodb_buffer_pool_pages_index =
-+{
-+      /* the plugin type (a MYSQL_XXX_PLUGIN value) */
-+      /* int */
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+
-+      /* pointer to type-specific plugin descriptor */
-+      /* void* */
-+      STRUCT_FLD(info, &i_s_info),
-+
-+      /* plugin name */
-+      /* const char* */
-+      STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"),
-+
-+      /* plugin author (for SHOW PLUGINS) */
-+      /* const char* */
-+      STRUCT_FLD(author, "Percona"),
-+
-+      /* general descriptive text (for SHOW PLUGINS) */
-+      /* const char* */
-+      STRUCT_FLD(descr, "InnoDB buffer pool index pages"),
-+
-+      /* the plugin license (PLUGIN_LICENSE_XXX) */
-+      /* int */
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+
-+      /* the function to invoke when plugin is loaded */
-+      /* int (*)(void*); */
-+      STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init),
-+
-+      /* the function to invoke when plugin is unloaded */
-+      /* int (*)(void*); */
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+
-+      /* plugin version (for SHOW PLUGINS) */
-+      /* unsigned int */
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+
-+      /* struct st_mysql_show_var* */
-+      STRUCT_FLD(status_vars, NULL),
-+
-+      /* struct st_mysql_sys_var** */
-+      STRUCT_FLD(system_vars, NULL),
-+
-+      /* reserved for dependency checking */
-+      /* void* */
-+      STRUCT_FLD(__reserved1, NULL)
-+};
-+
-+UNIV_INTERN struct st_mysql_plugin    i_s_innodb_buffer_pool_pages_blob =
-+{
-+      /* the plugin type (a MYSQL_XXX_PLUGIN value) */
-+      /* int */
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+
-+      /* pointer to type-specific plugin descriptor */
-+      /* void* */
-+      STRUCT_FLD(info, &i_s_info),
-+
-+      /* plugin name */
-+      /* const char* */
-+      STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"),
-+
-+      /* plugin author (for SHOW PLUGINS) */
-+      /* const char* */
-+      STRUCT_FLD(author, "Percona"),
-+
-+      /* general descriptive text (for SHOW PLUGINS) */
-+      /* const char* */
-+      STRUCT_FLD(descr, "InnoDB buffer pool blob pages"),
-+
-+      /* the plugin license (PLUGIN_LICENSE_XXX) */
-+      /* int */
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+
-+      /* the function to invoke when plugin is loaded */
-+      /* int (*)(void*); */
-+      STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init),
-+
-+      /* the function to invoke when plugin is unloaded */
-+      /* int (*)(void*); */
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+
-+      /* plugin version (for SHOW PLUGINS) */
-+      /* unsigned int */
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+
-+      /* struct st_mysql_show_var* */
-+      STRUCT_FLD(status_vars, NULL),
-+
-+      /* struct st_mysql_sys_var** */
-+      STRUCT_FLD(system_vars, NULL),
-+
-+      /* reserved for dependency checking */
-+      /* void* */
-+      STRUCT_FLD(__reserved1, NULL)
-+};
-+
-+
- /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
- static ST_FIELD_INFO  innodb_trx_fields_info[] =
- {
---- a/storage/innodb_plugin/handler/i_s.h
-+++ b/storage/innodb_plugin/handler/i_s.h
-@@ -26,6 +26,9 @@
- #ifndef i_s_h
- #define i_s_h
-+extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages;
-+extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index;
-+extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob;
- extern struct st_mysql_plugin i_s_innodb_trx;
- extern struct st_mysql_plugin i_s_innodb_locks;
- extern struct st_mysql_plugin i_s_innodb_lock_waits;
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -27,5 +27,6 @@
- {"innodb_show_status","Improvements to SHOW INNODB STATUS","Memory information and lock info fixes","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_io","Improvements to InnoDB IO","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_opt_lru_count","Fix of buffer_pool mutex","Decreases contention on buffer_pool mutex on LRU operations","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/buf0buf.h
-+++ b/storage/innodb_plugin/include/buf0buf.h
-@@ -1334,6 +1334,15 @@
- #define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
- /* @} */
-+/** A chunk of buffers.  The buffer pool is allocated in chunks. */
-+struct buf_chunk_struct{
-+      ulint           mem_size;       /*!< allocated size of the chunk */
-+      ulint           size;           /*!< size of frames[] and blocks[] */
-+      void*           mem;            /*!< pointer to the memory area which
-+                                      was allocated for the frames */
-+      buf_block_t*    blocks;         /*!< array of buffer control blocks */
-+};
-+
- /** @brief The buffer pool statistics structure. */
- struct buf_pool_stat_struct{
-       ulint   n_page_gets;    /*!< number of page gets performed;
diff --git a/mysql-info.patch b/mysql-info.patch
deleted file mode 100644 (file)
index 179f823..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
---- mysql-4.1.12/Docs/mysql.info~      2005-05-16 08:05:46.000000000 +0300
-+++ mysql-4.1.12/Docs/mysql.info       2005-05-16 08:06:36.000000000 +0300
-@@ -1,8 +1,9 @@
- This is mysql.info, produced by makeinfo version 4.7 from manual.texi.
--START-INFO-DIR-ENTRY
--* mysql: (mysql).               MySQL documentation.
--END-INFO-DIR-ENTRY
-+@dircategory Data bases:
-+@direntry
-+* mysql: (mysql).                     MySQL documentation
-+@end direntry
\1f
- File: mysql.info,  Node: Top,  Next: Introduction,  Prev: (dir),  Up: (dir)
diff --git a/mysql-innodb_adjust_defaults.patch b/mysql-innodb_adjust_defaults.patch
deleted file mode 100644 (file)
index fef2378..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-# name       : innodb_adjust_defaults.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -11290,7 +11290,7 @@
- static MYSQL_SYSVAR_ULONG(use_purge_thread, srv_use_purge_thread,
-   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-   "Number of purge devoted threads. #### over 1 is EXPERIMENTAL ####",
--  NULL, NULL, 0, 0, UNIV_MAX_PARALLELISM, 0);
-+  NULL, NULL, 1, 0, UNIV_MAX_PARALLELISM, 0);
- static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
-   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-@@ -11390,7 +11390,7 @@
- static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
-   PLUGIN_VAR_NOCMDARG,
-   "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
--  NULL, NULL, TRUE);
-+  NULL, NULL, FALSE);
- static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
-   PLUGIN_VAR_RQCMDARG,
-@@ -11628,7 +11628,7 @@
- static MYSQL_SYSVAR_ULONG(ibuf_active_contract, srv_ibuf_active_contract,
-   PLUGIN_VAR_RQCMDARG,
-   "Enable/Disable active_contract of insert buffer. 0:disable 1:enable",
--  NULL, NULL, 0, 0, 1, 0);
-+  NULL, NULL, 1, 0, 1, 0);
- static MYSQL_SYSVAR_ULONG(ibuf_accel_rate, srv_ibuf_accel_rate,
-   PLUGIN_VAR_RQCMDARG,
-@@ -11708,8 +11708,8 @@
- };
- static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
-   PLUGIN_VAR_RQCMDARG,
--  "Enable/Disable flushing along modified age. ([none], reflex, estimate, keep_average)",
--  NULL, innodb_adaptive_checkpoint_update, 0, &adaptive_checkpoint_typelib);
-+  "Enable/Disable flushing along modified age. (none, reflex, [estimate], keep_average)",
-+  NULL, innodb_adaptive_checkpoint_update, 2, &adaptive_checkpoint_typelib);
- static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_enable_unsafe_group_commit,
-   PLUGIN_VAR_RQCMDARG,
diff --git a/mysql-innodb_admin_command_base.patch b/mysql-innodb_admin_command_base.patch
deleted file mode 100644 (file)
index 7e8bdae..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-# name       : innodb_admin_command_base.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -11530,6 +11530,7 @@
- i_s_innodb_cmp_reset,
- i_s_innodb_cmpmem,
- i_s_innodb_cmpmem_reset,
-+i_s_innodb_admin_command,
- i_s_innodb_patches
- mysql_declare_plugin_end;
---- a/storage/innodb_plugin/handler/i_s.cc
-+++ b/storage/innodb_plugin/handler/i_s.cc
-@@ -2602,3 +2602,139 @@
-       /* void* */
-       STRUCT_FLD(__reserved1, NULL)
- };
-+
-+/***********************************************************************
-+*/
-+static ST_FIELD_INFO  i_s_innodb_admin_command_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "result_message"),
-+       STRUCT_FLD(field_length,       1024),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      END_OF_ST_FIELD_INFO
-+};
-+
-+#ifndef INNODB_COMPATIBILITY_HOOKS
-+#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS
-+#endif
-+
-+extern "C" {
-+char **thd_query(MYSQL_THD thd);
-+}
-+
-+static
-+int
-+i_s_innodb_admin_command_fill(
-+/*==========================*/
-+      THD*            thd,
-+      TABLE_LIST*     tables,
-+      COND*           cond)
-+{
-+      TABLE*  i_s_table       = (TABLE *) tables->table;
-+      char**  query_str;
-+      char*   ptr;
-+      char    quote   = '\0';
-+      const char*     command_head = "XTRA_";
-+
-+      DBUG_ENTER("i_s_innodb_admin_command_fill");
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+              DBUG_RETURN(0);
-+      }
-+
-+      if(thd_sql_command(thd) != SQLCOM_SELECT) {
-+              field_store_string(i_s_table->field[0],
-+                      "SELECT command is only accepted.");
-+              goto end_func;
-+      }
-+
-+      query_str = thd_query(thd);
-+      ptr = *query_str;
-+      
-+      for (; *ptr; ptr++) {
-+              if (*ptr == quote) {
-+                      quote = '\0';
-+              } else if (quote) {
-+              } else if (*ptr == '`' || *ptr == '"') {
-+                      quote = *ptr;
-+              } else {
-+                      long    i;
-+                      for (i = 0; command_head[i]; i++) {
-+                              if (toupper((int)(unsigned char)(ptr[i]))
-+                                  != toupper((int)(unsigned char)
-+                                    (command_head[i]))) {
-+                                      goto nomatch;
-+                              }
-+                      }
-+                      break;
-+nomatch:
-+                      ;
-+              }
-+      }
-+
-+      if (!*ptr) {
-+              field_store_string(i_s_table->field[0],
-+                      "No XTRA_* command in the SQL statement."
-+                      " Please add /*!XTRA_xxxx*/ to the SQL.");
-+              goto end_func;
-+      }
-+
-+      if (!strncasecmp("XTRA_HELLO", ptr, 10)) {
-+              /* This is example command XTRA_HELLO */
-+
-+              ut_print_timestamp(stderr);
-+              fprintf(stderr, " InnoDB: administration command test for XtraDB"
-+                              " 'XTRA_HELLO' was detected.\n");
-+
-+              field_store_string(i_s_table->field[0],
-+                      "Hello!");
-+              goto end_func;
-+      }
-+
-+      field_store_string(i_s_table->field[0],
-+              "Undefined XTRA_* command.");
-+      goto end_func;
-+
-+end_func:
-+      if (schema_table_store_record(thd, i_s_table)) {
-+              DBUG_RETURN(1);
-+      } else {
-+              DBUG_RETURN(0);
-+      }
-+}
-+
-+static
-+int
-+i_s_innodb_admin_command_init(
-+/*==========================*/
-+      void*   p)
-+{
-+      DBUG_ENTER("i_s_innodb_admin_command_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_admin_command_info;
-+      schema->fill_table = i_s_innodb_admin_command_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+UNIV_INTERN struct st_mysql_plugin    i_s_innodb_admin_command =
-+{
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+      STRUCT_FLD(info, &i_s_info),
-+      STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"),
-+      STRUCT_FLD(author, "Percona"),
-+      STRUCT_FLD(descr, "XtraDB specific command acceptor"),
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+      STRUCT_FLD(init, i_s_innodb_admin_command_init),
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+      STRUCT_FLD(status_vars, NULL),
-+      STRUCT_FLD(system_vars, NULL),
-+      STRUCT_FLD(__reserved1, NULL)
-+};
---- a/storage/innodb_plugin/handler/i_s.h
-+++ b/storage/innodb_plugin/handler/i_s.h
-@@ -38,5 +38,6 @@
- extern struct st_mysql_plugin i_s_innodb_cmpmem_reset;
- extern struct st_mysql_plugin i_s_innodb_patches;
- extern struct st_mysql_plugin i_s_innodb_rseg;
-+extern struct st_mysql_plugin i_s_innodb_admin_command;
- #endif /* i_s_h */
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -37,5 +37,6 @@
- {"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- /dev/null
-+++ b/mysql-test/r/percona_xtradb_admin_command.result
-@@ -0,0 +1,6 @@
-+select * from information_schema.XTRADB_ADMIN_COMMAND;
-+result_message
-+No XTRA_* command in the SQL statement. Please add /*!XTRA_xxxx*/ to the SQL.
-+select * from information_schema.XTRADB_ADMIN_COMMAND /*!XTRA_HELLO*/;
-+result_message
-+Hello!
---- /dev/null
-+++ b/mysql-test/t/percona_xtradb_admin_command.test
-@@ -0,0 +1,3 @@
-+--source include/have_innodb.inc
-+select * from information_schema.XTRADB_ADMIN_COMMAND;
-+select * from information_schema.XTRADB_ADMIN_COMMAND /*!XTRA_HELLO*/;
diff --git a/mysql-innodb_buffer_pool_shm.patch b/mysql-innodb_buffer_pool_shm.patch
deleted file mode 100644 (file)
index e57fd18..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-# name       : innodb_buffer_pool_shm.patch
-# introduced : 12
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -773,10 +773,12 @@
-       buf_block_t*    block;
-       byte*           frame;
-       ulint           i;
-+      ulint           size_target;
-       /* Round down to a multiple of page size,
-       although it already should be. */
-       mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE);
-+      size_target = (mem_size / UNIV_PAGE_SIZE) - 1;
-       /* 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);
-@@ -814,6 +816,10 @@
-               chunk->size = size;
-       }
-+      if (chunk->size > size_target) {
-+              chunk->size = size_target;
-+      }
-+
-       /* Init block structs and assign frames for them. Then we
-       assign the frames to the first blocks (we already mapped the
-       memory above). */
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -198,6 +198,8 @@
- static my_bool        innobase_create_status_file             = FALSE;
- static my_bool        innobase_stats_on_metadata              = TRUE;
- static my_bool        innobase_use_sys_stats_table            = FALSE;
-+static my_bool        innobase_buffer_pool_shm_checksum       = TRUE;
-+static uint   innobase_buffer_pool_shm_key            = 0;
- static char*  internal_innobase_data_file_path        = NULL;
-@@ -2472,6 +2474,12 @@
-       srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
-+      if (innobase_buffer_pool_shm_key) {
-+              fprintf(stderr,
-+                      "InnoDB: Warning: innodb_buffer_pool_shm_key is deprecated function.\n"
-+                      "InnoDB:          innodb_buffer_pool_shm_key was ignored.\n");
-+      }
-+
-       srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
-       srv_n_file_io_threads = (ulint) innobase_file_io_threads;
-@@ -11556,6 +11564,16 @@
-   "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
-   NULL, NULL, 128*1024*1024L, 32*1024*1024L, LONGLONG_MAX, 1024*1024L);
-+static MYSQL_SYSVAR_UINT(buffer_pool_shm_key, innobase_buffer_pool_shm_key,
-+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-+  "[Deprecated option] no effect",
-+  NULL, NULL, 0, 0, INT_MAX32, 0);
-+
-+static MYSQL_SYSVAR_BOOL(buffer_pool_shm_checksum, innobase_buffer_pool_shm_checksum,
-+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-+  "[Deprecated option] no effect",
-+  NULL, NULL, TRUE);
-+
- static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
-   PLUGIN_VAR_RQCMDARG,
-   "Helps in performance tuning in heavily concurrent environments.",
-@@ -11864,6 +11882,8 @@
-   MYSQL_SYSVAR(additional_mem_pool_size),
-   MYSQL_SYSVAR(autoextend_increment),
-   MYSQL_SYSVAR(buffer_pool_size),
-+  MYSQL_SYSVAR(buffer_pool_shm_key),
-+  MYSQL_SYSVAR(buffer_pool_shm_checksum),
-   MYSQL_SYSVAR(checksums),
-   MYSQL_SYSVAR(fast_checksum),
-   MYSQL_SYSVAR(commit_concurrency),
---- /dev/null
-+++ b/mysql-test/r/percona_innodb_buffer_pool_shm.result
-@@ -0,0 +1,4 @@
-+show variables like 'innodb_buffer_pool_shm%';
-+Variable_name Value
-+innodb_buffer_pool_shm_checksum       ON
-+innodb_buffer_pool_shm_key    123456
---- /dev/null
-+++ b/mysql-test/t/percona_innodb_buffer_pool_shm-master.opt
-@@ -0,0 +1,2 @@
-+--innodb_buffer_pool_shm_key=123456
-+--innodb=FORCE
---- /dev/null
-+++ b/mysql-test/t/percona_innodb_buffer_pool_shm.test
-@@ -0,0 +1,3 @@
-+--source include/have_innodb.inc
-+show variables like 'innodb_buffer_pool_shm%';
-+
diff --git a/mysql-innodb_bug60788.patch b/mysql-innodb_bug60788.patch
deleted file mode 100644 (file)
index f5a7610..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-# name       : innodb_bug60788.patch
-# maintainer : Alexey
-#
-# Fix for MySQL bug #60788: InnoDB crashes with an assertion failure when 
-#                           receiving a signal on pwrite()
-#
-# Changes InnoDB IO code so that fsync(), pread() and pwrite() are restarted
-# when interrupted by a signal.
-#
---- a/storage/innodb_plugin/os/os0file.c
-+++ b/storage/innodb_plugin/os/os0file.c
-@@ -1988,6 +1988,9 @@
-                       failures++;
-                       retry = TRUE;
-+              } else if (ret == -1 && errno == EINTR) {
-+                      /* Handle signal interruptions correctly */
-+                      retry = TRUE;
-               } else {
-                       retry = FALSE;
-@@ -2120,6 +2123,7 @@
-       off_t   offs;
- #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
-       ssize_t n_bytes;
-+      ssize_t n_read;
- #endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
-       ulint           sec;
-       ulint           ms;
-@@ -2160,7 +2164,18 @@
-       os_n_pending_reads++;
-       os_mutex_exit(os_file_count_mutex);
--      n_bytes = pread(file, buf, (ssize_t)n, offs);
-+      /* Handle signal interruptions correctly */
-+      for (n_bytes = 0; n_bytes < (ssize_t) n; ) {
-+              n_read = pread(file, buf, (ssize_t)n, offs);
-+              if (n_read > 0) {
-+                      n_bytes += n_read;
-+                      offs += n_read;
-+              } else if (n_read == -1 && errno == EINTR) {
-+                      continue;
-+              } else {
-+                      break;
-+              }
-+      }
-       os_mutex_enter(os_file_count_mutex);
-       os_file_n_pending_preads--;
-@@ -2179,6 +2194,7 @@
-       {
-               off_t   ret_offset;
-               ssize_t ret;
-+              ssize_t n_read;
- #ifndef UNIV_HOTBACKUP
-               ulint   i;
- #endif /* !UNIV_HOTBACKUP */
-@@ -2199,7 +2215,17 @@
-               if (ret_offset < 0) {
-                       ret = -1;
-               } else {
--                      ret = read(file, buf, (ssize_t)n);
-+                      /* Handle signal interruptions correctly */
-+                      for (ret = 0; ret < (ssize_t) n; ) {
-+                              n_read = read(file, buf, (ssize_t)n);
-+                              if (n_read > 0) {
-+                                      ret += n_read;
-+                              } else if (n_read == -1 && errno == EINTR) {
-+                                      continue;
-+                              } else {
-+                                      break;
-+                              }
-+                      }
-               }
- #ifndef UNIV_HOTBACKUP
-@@ -2238,6 +2264,7 @@
-                               offset */
- {
-       ssize_t ret;
-+      ssize_t n_written;
-       off_t   offs;
-       ut_a((offset & 0xFFFFFFFFUL) == offset);
-@@ -2265,7 +2292,18 @@
-       os_n_pending_writes++;
-       os_mutex_exit(os_file_count_mutex);
--      ret = pwrite(file, buf, (ssize_t)n, offs);
-+      /* Handle signal interruptions correctly */
-+      for (ret = 0; ret < (ssize_t) n; ) {
-+              n_written = pwrite(file, buf, (ssize_t)n, offs);
-+              if (n_written > 0) {
-+                      ret += n_written;
-+                      offs += n_written;
-+              } else if (n_written == -1 && errno == EINTR) {
-+                      continue;
-+              } else {
-+                      break;
-+              }
-+      }
-       os_mutex_enter(os_file_count_mutex);
-       os_file_n_pending_pwrites--;
-@@ -2312,7 +2350,17 @@
-                       goto func_exit;
-               }
--              ret = write(file, buf, (ssize_t)n);
-+              /* Handle signal interruptions correctly */
-+              for (ret = 0; ret < (ssize_t) n; ) {
-+                      n_written = write(file, buf, (ssize_t)n);
-+                      if (n_written > 0) {
-+                              ret += n_written;
-+                      } else if (n_written == -1 && errno == EINTR) {
-+                              continue;
-+                      } else {
-+                              break;
-+                      }
-+              }
- # ifdef UNIV_DO_FLUSH
-               if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC
diff --git a/mysql-innodb_deadlock_count.patch b/mysql-innodb_deadlock_count.patch
deleted file mode 100644 (file)
index 4c31dca..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-# name       : innodb_deadlock_count.patch
-# introduced : 11 or before
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -576,6 +576,8 @@
-   (char*) &export_vars.innodb_data_written,             SHOW_LONG},
-   {"dblwr_pages_written",
-   (char*) &export_vars.innodb_dblwr_pages_written,      SHOW_LONG},
-+  {"deadlocks",
-+  (char*) &export_vars.innodb_deadlocks,                  SHOW_LONG}, 
-   {"dblwr_writes",
-   (char*) &export_vars.innodb_dblwr_writes,             SHOW_LONG},
-   {"dict_tables",
---- a/storage/innodb_plugin/include/lock0lock.h
-+++ b/storage/innodb_plugin/include/lock0lock.h
-@@ -43,6 +43,7 @@
- #endif /* UNIV_DEBUG */
- /* Buffer for storing information about the most recent deadlock error */
- extern FILE*  lock_latest_err_file;
-+extern ulint    srv_n_lock_deadlock_count;
- /*********************************************************************//**
- Gets the size of a lock struct.
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -695,6 +695,7 @@
-       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_deadlocks;                 /* ??? */
-       ulint innodb_dblwr_pages_written;       /*!< srv_dblwr_pages_written */
-       ulint innodb_dblwr_writes;              /*!< srv_dblwr_writes */
-       ibool innodb_have_atomic_builtins;      /*!< HAVE_ATOMIC_BUILTINS */
---- a/storage/innodb_plugin/lock/lock0lock.c
-+++ b/storage/innodb_plugin/lock/lock0lock.c
-@@ -3330,6 +3330,7 @@
-               break;
-       case LOCK_VICTIM_IS_START:
-+              srv_n_lock_deadlock_count++;
-               fputs("*** WE ROLL BACK TRANSACTION (2)\n",
-                     lock_latest_err_file);
-               break;
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -458,7 +458,7 @@
- static ulint  srv_n_rows_updated_old          = 0;
- static ulint  srv_n_rows_deleted_old          = 0;
- static ulint  srv_n_rows_read_old             = 0;
--
-+UNIV_INTERN ulint               srv_n_lock_deadlock_count       = 0;
- 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;
-@@ -2171,6 +2171,8 @@
-               = UT_LIST_GET_LEN(buf_pool->flush_list);
-       export_vars.innodb_buffer_pool_pages_free
-               = UT_LIST_GET_LEN(buf_pool->free);
-+      export_vars.innodb_deadlocks
-+              = srv_n_lock_deadlock_count;
- #ifdef UNIV_DEBUG
-       export_vars.innodb_buffer_pool_pages_latched
-               = buf_get_latched_pages_number();
---- /dev/null
-+++ b/mysql-test/r/percona_innodb_deadlock_count.result
-@@ -0,0 +1,28 @@
-+# Establish connection con1 (user=root)
-+# Establish connection con2 (user=root)
-+# Establish connection con3 (user=root)
-+# Drop test table
-+drop table if exists t;
-+# Create test table
-+create table t(a INT PRIMARY KEY, b INT) engine=InnoDB;
-+# Insert two rows to test table
-+insert into t values(2,1);
-+insert into t values(1,2);
-+# Switch to connection con1
-+BEGIN;
-+SELECT b FROM t WHERE a=1 FOR UPDATE;
-+# Switch to connection con2
-+BEGIN;
-+SELECT b FROM t WHERE a=2 FOR UPDATE;
-+# Switch to connection con1
-+SELECT b FROM t WHERE a=2 FOR UPDATE;
-+# Switch to connection con2
-+SELECT b FROM t WHERE a=1 FOR UPDATE;
-+# Switch to connection con1
-+ROLLBACK;
-+# Switch to connection con2
-+ROLLBACK;
-+# Switch to connection con3
-+Deadlocks: 1
-+# Drop test table
-+drop table t;
---- /dev/null
-+++ b/mysql-test/t/percona_innodb_deadlock_count.test
-@@ -0,0 +1,61 @@
-+--source include/have_innodb.inc
-+--echo # Establish connection con1 (user=root)
-+connect (con1,localhost,root,,);
-+--echo # Establish connection con2 (user=root)
-+connect (con2,localhost,root,,);
-+--echo # Establish connection con3 (user=root)
-+connect (con3,localhost,root,,);
-+--echo # Drop test table
-+--disable_warnings
-+drop table if exists t;
-+--enable_warnings
-+
-+--echo # Create test table
-+create table t(a INT PRIMARY KEY, b INT) engine=InnoDB;
-+--echo # Insert two rows to test table
-+insert into t values(2,1);
-+insert into t values(1,2);
-+
-+#--echo # Save current deadlock count
-+let $current = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_deadlocks'`;
-+
-+--disable_result_log
-+
-+--echo # Switch to connection con1
-+connection con1;
-+BEGIN; SELECT b FROM t WHERE a=1 FOR UPDATE;
-+
-+--echo # Switch to connection con2
-+connection con2;
-+BEGIN; SELECT b FROM t WHERE a=2 FOR UPDATE;
-+
-+--echo # Switch to connection con1
-+connection con1;
-+SEND SELECT b FROM t WHERE a=2 FOR UPDATE;
-+
-+--echo # Switch to connection con2
-+connection con2;
-+SEND SELECT b FROM t WHERE a=1 FOR UPDATE;
-+
-+--echo # Switch to connection con1
-+connection con1;
-+--error 0, ER_LOCK_DEADLOCK
-+reap;
-+ROLLBACK;
-+
-+--echo # Switch to connection con2
-+connection con2;
-+--error 0, ER_LOCK_DEADLOCK
-+reap;
-+ROLLBACK;
-+
-+--echo # Switch to connection con3
-+connection con3;
-+let $result = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_deadlocks'`;
-+
-+--enable_result_log
-+
-+let $diff = `SELECT $result - $current`;
-+echo Deadlocks: $diff;
-+--echo # Drop test table
-+drop table t;
diff --git a/mysql-innodb_dict_size_limit.patch b/mysql-innodb_dict_size_limit.patch
deleted file mode 100644 (file)
index c7c2d45..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-# name       : innodb_dict_size_limit.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/btr/btr0sea.c
-+++ b/storage/innodb_plugin/btr/btr0sea.c
-@@ -1173,6 +1173,173 @@
-       mem_free(folds);
- }
-+/************************************************************************
-+Drops a page hash index based on index */
-+UNIV_INTERN
-+void
-+btr_search_drop_page_hash_index_on_index(
-+/*=====================================*/
-+      dict_index_t*   index)          /* in: record descriptor */
-+{
-+
-+      hash_table_t*   table;
-+      buf_block_t*    block;
-+      ulint           n_fields;
-+      ulint           n_bytes;
-+      const page_t*           page;
-+      const rec_t*            rec;
-+      ulint           fold;
-+      ulint           prev_fold;
-+      dulint                  index_id;
-+      ulint           n_cached;
-+      ulint           n_recs;
-+      ulint*          folds;
-+      ulint           i;
-+      mem_heap_t*     heap    = NULL;
-+      ulint*          offsets;
-+      ibool           released_search_latch;
-+
-+      rw_lock_s_lock(&btr_search_latch);
-+
-+      table = btr_search_sys->hash_index;
-+
-+      do {
-+              buf_chunk_t*    chunks  = buf_pool->chunks;
-+              buf_chunk_t*    chunk   = chunks + buf_pool->n_chunks;
-+
-+              released_search_latch = FALSE;
-+
-+              while (--chunk >= chunks) {
-+                      block   = chunk->blocks;
-+                      i       = chunk->size;
-+
-+retry:
-+                      for (; i--; block++) {
-+                              if (buf_block_get_state(block)
-+                                  != BUF_BLOCK_FILE_PAGE
-+                                  || block->index != index
-+                                  || !block->is_hashed) {
-+                                      continue;
-+                              }
-+
-+                              page = block->frame;
-+
-+                              /* from btr_search_drop_page_hash_index() */
-+                              n_fields = block->curr_n_fields;
-+                              n_bytes = block->curr_n_bytes;
-+
-+
-+                              /* keeping latch order */
-+                              rw_lock_s_unlock(&btr_search_latch);
-+                              released_search_latch = TRUE;
-+                              rw_lock_x_lock(&block->lock);
-+
-+
-+                              ut_a(n_fields + n_bytes > 0);
-+
-+                              n_recs = page_get_n_recs(page);
-+
-+                              /* Calculate and cache fold values into an array for fast deletion
-+                              from the hash index */
-+
-+                              folds = mem_alloc(n_recs * sizeof(ulint));
-+
-+                              n_cached = 0;
-+
-+                              rec = page_get_infimum_rec(page);
-+                              rec = page_rec_get_next_low(rec, page_is_comp(page));
-+
-+                              index_id = btr_page_get_index_id(page);
-+      
-+                              ut_a(0 == ut_dulint_cmp(index_id, index->id));
-+
-+                              prev_fold = 0;
-+
-+                              offsets = NULL;
-+
-+                              while (!page_rec_is_supremum(rec)) {
-+                                      offsets = rec_get_offsets(rec, index, offsets,
-+                                                              n_fields + (n_bytes > 0), &heap);
-+                                      ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
-+                                      fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
-+
-+                                      if (fold == prev_fold && prev_fold != 0) {
-+
-+                                              goto next_rec;
-+                                      }
-+
-+                                      /* Remove all hash nodes pointing to this page from the
-+                                      hash chain */
-+
-+                                      folds[n_cached] = fold;
-+                                      n_cached++;
-+next_rec:
-+                                      rec = page_rec_get_next_low(rec, page_rec_is_comp(rec));
-+                                      prev_fold = fold;
-+                              }
-+
-+                              if (UNIV_LIKELY_NULL(heap)) {
-+                                      mem_heap_empty(heap);
-+                              }
-+
-+                              rw_lock_x_lock(&btr_search_latch);
-+
-+                              if (UNIV_UNLIKELY(!block->is_hashed)) {
-+                                      goto cleanup;
-+                              }
-+
-+                              ut_a(block->index == index);
-+
-+                              if (UNIV_UNLIKELY(block->curr_n_fields != n_fields)
-+                                  || UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) {
-+                                      rw_lock_x_unlock(&btr_search_latch);
-+                                      rw_lock_x_unlock(&block->lock);
-+
-+                                      mem_free(folds);
-+
-+                                      rw_lock_s_lock(&btr_search_latch);
-+                                      goto retry;
-+                              }
-+
-+                              for (i = 0; i < n_cached; i++) {
-+
-+                                      ha_remove_all_nodes_to_page(table, folds[i], page);
-+                              }
-+
-+                              ut_a(index->search_info->ref_count > 0);
-+                              index->search_info->ref_count--;
-+
-+                              block->is_hashed = FALSE;
-+                              block->index = NULL;
-+
-+cleanup:      
-+#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-+                              if (UNIV_UNLIKELY(block->n_pointers)) {
-+                                      /* Corruption */
-+                                      ut_print_timestamp(stderr);
-+                                      fprintf(stderr,
-+"  InnoDB: Corruption of adaptive hash index. After dropping\n"
-+"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n",
-+                                              index->name, (ulong) block->n_pointers);
-+                              }
-+#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-+                              rw_lock_x_unlock(&btr_search_latch);
-+                              rw_lock_x_unlock(&block->lock);
-+
-+                              mem_free(folds);
-+
-+                              rw_lock_s_lock(&btr_search_latch);
-+                      }
-+              }
-+      } while (released_search_latch);
-+
-+      rw_lock_s_unlock(&btr_search_latch);
-+
-+      if (UNIV_LIKELY_NULL(heap)) {
-+              mem_heap_free(heap);
-+      }
-+}
-+
- /********************************************************************//**
- Drops a page hash index when a page is freed from a fseg to the file system.
- Drops possible hash index if the page happens to be in the buffer pool. */
---- a/storage/innodb_plugin/dict/dict0boot.c
-+++ b/storage/innodb_plugin/dict/dict0boot.c
-@@ -283,6 +283,7 @@
-       system tables */
-       /*-------------------------*/
-       table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
-       dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
-@@ -335,6 +336,7 @@
-       /*-------------------------*/
-       table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
-       dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
-@@ -367,6 +369,7 @@
-       /*-------------------------*/
-       table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
-       dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
-@@ -412,6 +415,7 @@
-       /*-------------------------*/
-       table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
-       dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
---- a/storage/innodb_plugin/dict/dict0crea.c
-+++ b/storage/innodb_plugin/dict/dict0crea.c
-@@ -1211,6 +1211,9 @@
-               /* Foreign constraint system tables have already been
-               created, and they are ok */
-+              table1->n_mysql_handles_opened = 1; /* for pin */
-+              table2->n_mysql_handles_opened = 1; /* for pin */
-+
-               mutex_exit(&(dict_sys->mutex));
-               return(DB_SUCCESS);
-@@ -1292,6 +1295,11 @@
-       trx_commit_for_mysql(trx);
-+      table1 = dict_table_get_low("SYS_FOREIGN");
-+      table2 = dict_table_get_low("SYS_FOREIGN_COLS");
-+      table1->n_mysql_handles_opened = 1; /* for pin */
-+      table2->n_mysql_handles_opened = 1; /* for pin */
-+
-       row_mysql_unlock_data_dictionary(trx);
-       trx_free_for_mysql(trx);
---- a/storage/innodb_plugin/dict/dict0dict.c
-+++ b/storage/innodb_plugin/dict/dict0dict.c
-@@ -613,6 +613,8 @@
-       table = dict_table_get_on_id_low(table_id);
-+      dict_table_LRU_trim(table);
-+
-       mutex_exit(&(dict_sys->mutex));
-       return(table);
-@@ -728,6 +730,8 @@
-               table->n_mysql_handles_opened++;
-       }
-+      dict_table_LRU_trim(table);
-+
-       mutex_exit(&(dict_sys->mutex));
-       if (table != NULL) {
-@@ -1241,6 +1245,64 @@
-       dict_mem_table_free(table);
- }
-+/**************************************************************************
-+Frees tables from the end of table_LRU if the dictionary cache occupies
-+too much space. */
-+UNIV_INTERN
-+void
-+dict_table_LRU_trim(
-+/*================*/
-+      dict_table_t*   self)
-+{
-+      dict_table_t*   table;
-+      dict_table_t*   prev_table;
-+      dict_foreign_t* foreign;
-+      ulint           n_removed;
-+      ulint           n_have_parent;
-+      ulint           cached_foreign_tables;
-+
-+#ifdef UNIV_SYNC_DEBUG
-+      ut_ad(mutex_own(&(dict_sys->mutex)));
-+#endif /* UNIV_SYNC_DEBUG */
-+
-+retry:
-+      n_removed = n_have_parent = 0;
-+      table = UT_LIST_GET_LAST(dict_sys->table_LRU);
-+
-+      while ( srv_dict_size_limit && table
-+              && ((dict_sys->table_hash->n_cells
-+                   + dict_sys->table_id_hash->n_cells) * sizeof(hash_cell_t)
-+                  + dict_sys->size) > srv_dict_size_limit ) {
-+              prev_table = UT_LIST_GET_PREV(table_LRU, table);
-+
-+              if (table == self || table->n_mysql_handles_opened)
-+                      goto next_loop;
-+
-+              cached_foreign_tables = 0;
-+              foreign = UT_LIST_GET_FIRST(table->foreign_list);
-+              while (foreign != NULL) {
-+                      if (foreign->referenced_table)
-+                              cached_foreign_tables++;
-+                      foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
-+              }
-+
-+              if (cached_foreign_tables == 0) {
-+                      dict_table_remove_from_cache(table);
-+                      n_removed++;
-+              } else {
-+                      n_have_parent++;
-+              }
-+next_loop:
-+              table = prev_table;
-+      }
-+
-+      if ( srv_dict_size_limit && n_have_parent && n_removed
-+              && ((dict_sys->table_hash->n_cells
-+                   + dict_sys->table_id_hash->n_cells) * sizeof(hash_cell_t)
-+                  + dict_sys->size) > srv_dict_size_limit )
-+              goto retry;
-+}
-+
- /****************************************************************//**
- If the given column name is reserved for InnoDB system columns, return
- TRUE.
-@@ -1709,6 +1771,11 @@
-       ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
-       ut_ad(mutex_own(&(dict_sys->mutex)));
-+      /* remove all entry of the index from adaptive hash index,
-+      because removing from adaptive hash index needs dict_index */
-+      if (btr_search_enabled && srv_dict_size_limit)
-+              btr_search_drop_page_hash_index_on_index(index);
-+
-       /* We always create search info whether or not adaptive
-       hash index is enabled or not. */
-       info = index->search_info;
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -562,6 +562,8 @@
-   (char*) &export_vars.innodb_dblwr_pages_written,      SHOW_LONG},
-   {"dblwr_writes",
-   (char*) &export_vars.innodb_dblwr_writes,             SHOW_LONG},
-+  {"dict_tables",
-+  (char*) &export_vars.innodb_dict_tables,              SHOW_LONG},
-   {"have_atomic_builtins",
-   (char*) &export_vars.innodb_have_atomic_builtins,     SHOW_BOOL},
-   {"log_waits",
-@@ -11381,6 +11383,11 @@
-   "Number of extra user rollback segments when create new database.",
-   NULL, NULL, 0, 0, 126, 0);
-+static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Limit the allocated memory for dictionary cache. (0: unlimited)",
-+  NULL, NULL, 0, 0, LONG_MAX, 0);
-+
- static struct st_mysql_sys_var* innobase_system_variables[]= {
-   MYSQL_SYSVAR(additional_mem_pool_size),
-   MYSQL_SYSVAR(autoextend_increment),
-@@ -11449,6 +11456,7 @@
-   MYSQL_SYSVAR(flush_log_at_trx_commit_session),
-   MYSQL_SYSVAR(enable_unsafe_group_commit),
-   MYSQL_SYSVAR(extra_rsegments),
-+  MYSQL_SYSVAR(dict_size_limit),
-   MYSQL_SYSVAR(use_sys_malloc),
-   MYSQL_SYSVAR(change_buffering),
- #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -32,5 +32,6 @@
- {"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
- {"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
-+{"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c
-+++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c
-@@ -514,6 +514,7 @@
-       /* Use old-style record format for the insert buffer. */
-       table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-       dict_mem_table_add_col(table, heap, "DUMMY_COLUMN", DATA_BINARY, 0, 0);
---- a/storage/innodb_plugin/include/btr0sea.h
-+++ b/storage/innodb_plugin/include/btr0sea.h
-@@ -140,6 +140,13 @@
-                               s- or x-latched, or an index page
-                               for which we know that
-                               block->buf_fix_count == 0 */
-+/************************************************************************
-+Drops a page hash index based on index */
-+UNIV_INTERN
-+void
-+btr_search_drop_page_hash_index_on_index(
-+/*=====================================*/
-+      dict_index_t*   index);         /* in: record descriptor */
- /********************************************************************//**
- Drops a page hash index when a page is freed from a fseg to the file system.
- Drops possible hash index if the page happens to be in the buffer pool. */
---- a/storage/innodb_plugin/include/dict0dict.h
-+++ b/storage/innodb_plugin/include/dict0dict.h
-@@ -1131,6 +1131,12 @@
- /*====================================*/
-       dict_table_t*   table,  /*!< in: table */
-       const char*     name);  /*!< in: name of the index to find */
-+
-+UNIV_INTERN
-+void
-+dict_table_LRU_trim(
-+/*================*/
-+      dict_table_t*   self);
- /* Buffers for storing detailed information about the latest foreign key
- and unique key errors */
- extern FILE*  dict_foreign_err_file;
---- a/storage/innodb_plugin/include/dict0dict.ic
-+++ b/storage/innodb_plugin/include/dict0dict.ic
-@@ -786,6 +786,13 @@
-       HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold,
-                   dict_table_t*, table, ut_ad(table->cached),
-                   !strcmp(table->name, table_name));
-+
-+      /* make young in table_LRU */
-+      if (table) {
-+              UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
-+              UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
-+      }
-+
-       return(table);
- }
-@@ -839,6 +846,12 @@
-               table = dict_load_table_on_id(table_id);
-       }
-+      /* make young in table_LRU */
-+      if (table) {
-+              UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
-+              UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
-+      }
-+
-       ut_ad(!table || table->cached);
-       /* TODO: should get the type information from MySQL */
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -220,7 +220,7 @@
- extern ulint  srv_adaptive_checkpoint;
- extern ulint  srv_extra_rsegments;
--
-+extern ulint  srv_dict_size_limit;
- /*-------------------------------------------*/
- extern ulint  srv_n_rows_inserted;
-@@ -626,6 +626,7 @@
-       ulint innodb_data_writes;               /*!< I/O write requests */
-       ulint innodb_data_written;              /*!< Data bytes written */
-       ulint innodb_data_reads;                /*!< I/O read requests */
-+      ulint innodb_dict_tables;
-       ulint innodb_buffer_pool_pages_total;   /*!< Buffer pool size */
-       ulint innodb_buffer_pool_pages_data;    /*!< Data pages */
-       ulint innodb_buffer_pool_pages_dirty;   /*!< Dirty data pages */
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -393,6 +393,7 @@
- UNIV_INTERN ulint     srv_adaptive_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
- UNIV_INTERN ulint     srv_extra_rsegments = 0; /* extra rseg for users */
-+UNIV_INTERN ulint     srv_dict_size_limit = 0;
- /*-------------------------------------------*/
- UNIV_INTERN ulong     srv_n_spin_wait_rounds  = 30;
- UNIV_INTERN ulong     srv_n_free_tickets_to_enter = 500;
-@@ -2093,6 +2094,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;
-+      export_vars.innodb_dict_tables= (dict_sys ? UT_LIST_GET_LEN(dict_sys->table_LRU) : 0);
-       export_vars.innodb_buffer_pool_read_requests = buf_pool->stat.n_page_gets;
-       export_vars.innodb_buffer_pool_write_requests
-               = srv_buf_pool_write_requests;
diff --git a/mysql-innodb_expand_fast_index_creation.patch b/mysql-innodb_expand_fast_index_creation.patch
deleted file mode 100644 (file)
index 15e5437..0000000
+++ /dev/null
@@ -1,1434 +0,0 @@
-# name       : innodb_expand_fast_index_creation.patch
-# maintainer : Alexey
-#
-# Expands the applicability of InnoDB fast index creation to mysqldump,
-# ALTER TABLE and OPTIMIZE TABLE.
-#
-#
---- a/client/client_priv.h
-+++ b/client/client_priv.h
-@@ -99,5 +99,6 @@
-   OPT_FIRST_SLAVE,
-   OPT_ALL,
-   OPT_NO_REMOVE_EOL_CARRET,
-+  OPT_INNODB_OPTIMIZE_KEYS,
-   OPT_MAX_CLIENT_OPTION
- };
---- a/client/mysqldump.c
-+++ b/client/mysqldump.c
-@@ -47,6 +47,7 @@
- #include <m_ctype.h>
- #include <hash.h>
- #include <stdarg.h>
-+#include <my_list.h>
- #include "client_priv.h"
- #include "mysql.h"
-@@ -138,6 +139,8 @@
- static my_bool server_supports_sql_no_fcache= FALSE;
-+static my_bool opt_innodb_optimize_keys= FALSE;
-+
- /*
- Dynamic_string wrapper functions. In this file use these
- wrappers, they will terminate the process if there is
-@@ -183,6 +186,8 @@
- HASH ignore_table;
-+LIST *skipped_keys_list;
-+
- static struct my_option my_long_options[] =
- {
-   {"all", OPT_ALL, "Deprecated. Use --create-options instead.",
-@@ -329,6 +334,11 @@
-    "be specified with both database and table names, e.g., "
-    "--ignore-table=database.table.",
-    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+  {"innodb-optimize-keys", OPT_INNODB_OPTIMIZE_KEYS,
-+   "Use InnoDB fast index creation by creating secondary indexes after "
-+   "dumping the data.",
-+   &opt_innodb_optimize_keys, &opt_innodb_optimize_keys, 0, GET_BOOL, NO_ARG,
-+   0, 0, 0, 0, 0, 0},
-   {"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},
-@@ -2249,6 +2259,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] == '`' &&
-+      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"
-+    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, my_bool has_pk)
-+{
-+  char *ptr, *strend;
-+  char *last_comma = NULL;
-+  HASH ignored_columns;
-+  my_bool pk_processed= FALSE;
-+
-+  if (hash_init(&ignored_columns, charset_info, 16, 0, 0,
-+                (hash_get_key) get_table_key,
-+                (hash_free_key) free_table_ent, 0))
-+    exit(EX_EOM);
-+
-+  strend= create_str + strlen(create_str);
-+
-+  ptr= create_str;
-+  while (*ptr)
-+  {
-+    char *tmp, *orig_ptr, c;
-+    my_bool UNINIT_VAR(is_unique);
-+
-+    orig_ptr= ptr;
-+    /* Skip leading whitespace */
-+    while (*ptr && my_isspace(charset_info, *ptr))
-+      ptr++;
-+
-+    /* 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 (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;
-+
-+      /* Remove the trailing comma */
-+      if (*end == ',')
-+        end--;
-+      data= my_strndup(ptr, end - ptr + 1, MYF(MY_FAE));
-+      skipped_keys_list= list_cons(data, skipped_keys_list);
-+
-+      memmove(orig_ptr, tmp + 1, strend - tmp);
-+      ptr= orig_ptr;
-+      strend-= tmp + 1 - ptr;
-+
-+      /* Remove the comma on the previos line */
-+      if (last_comma != NULL)
-+      {
-+        *last_comma= ' ';
-+      }
-+    }
-+    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;
-+    }
-+  }
-+
-+  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.
-@@ -2285,6 +2478,7 @@
-   int        len;
-   MYSQL_RES  *result;
-   MYSQL_ROW  row;
-+  my_bool    UNINIT_VAR(has_pk);
-   DBUG_ENTER("get_table_structure");
-   DBUG_PRINT("enter", ("db: %s  table: %s", db, table));
-@@ -2326,6 +2520,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);
-@@ -2489,6 +2686,9 @@
-       row= mysql_fetch_row(result);
-+      if (opt_innodb_optimize_keys && !strcmp(table_type, "InnoDB"))
-+        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"
-@@ -3581,6 +3781,27 @@
-       goto err;
-     }
-+    /* Perform delayed secondary index creation for --innodb-optimize-keys */
-+    if (skipped_keys_list)
-+    {
-+      uint keys;
-+      skipped_keys_list= list_reverse(skipped_keys_list);
-+      fprintf(md_result_file, "ALTER TABLE %s ", opt_quoted_table);
-+      for (keys= list_length(skipped_keys_list); keys > 0; keys--)
-+      {
-+        LIST *node= skipped_keys_list;
-+        char *def= node->data;
-+
-+        fprintf(md_result_file, "ADD %s%s", def, (keys > 1) ? ", " : ";\n");
-+
-+        skipped_keys_list= list_delete(skipped_keys_list, node);
-+        my_free(def, MYF(0));
-+        my_free(node, MYF(0));
-+      }
-+
-+      DBUG_ASSERT(skipped_keys_list == NULL);
-+    }
-+
-     /* Moved enable keys to before unlock per bug 15977 */
-     if (opt_disable_keys)
-     {
---- /dev/null
-+++ b/mysql-test/r/percona_mysqldump_innodb_optimize_keys.result
-@@ -0,0 +1,367 @@
-+#
-+# Test the --innodb-optimize-keys option.
-+#
-+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, KEY(b)) ENGINE=MyISAM;
-+######################################
-+
-+/*!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,
-+  `b` int(11) DEFAULT NULL,
-+  PRIMARY KEY (`a`),
-+  KEY `b` (`b`)
-+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-+/*!40101 SET character_set_client = @saved_cs_client */;
-+
-+LOCK TABLES `t1` WRITE;
-+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
-+/*!40000 ALTER TABLE `t1` 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;
-+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
-+INSERT INTO t2 VALUES (0), (1), (2);
-+CREATE TABLE t1 (
-+id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-+a INT, b VARCHAR(255), c DECIMAL(10,3),
-+KEY (b),
-+UNIQUE KEY uniq(c,a),
-+FOREIGN KEY (a) REFERENCES t2(a) ON DELETE CASCADE
-+) ENGINE=InnoDB;
-+INSERT INTO t1(a,b,c) VALUES (0, "0", 0.0), (1, "1", 1.1), (2, "2", 2.2);
-+######################################
-+
-+/*!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,
-+  `a` int(11) DEFAULT NULL,
-+  `b` varchar(255) DEFAULT NULL,
-+  `c` decimal(10,3) DEFAULT NULL,
-+  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`);
-+/*!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,
-+  PRIMARY KEY (`a`)
-+) 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 (0),(1),(2);
-+/*!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 (
-+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;
---- a/mysql-test/suite/innodb_plugin/t/innodb.test
-+++ b/mysql-test/suite/innodb_plugin/t/innodb.test
-@@ -15,6 +15,12 @@
- -- source include/have_innodb_plugin.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
---- /dev/null
-+++ b/mysql-test/t/percona_mysqldump_innodb_optimize_keys.test
-@@ -0,0 +1,187 @@
-+# Embedded server doesn't support external clients
-+--source include/not_embedded.inc
-+
-+# Fast index creation is only available in InnoDB plugin
-+--source include/have_innodb_plugin.inc
-+
-+# Save the initial number of concurrent sessions
-+--source include/count_sessions.inc
-+
-+--echo #
-+--echo # Test the --innodb-optimize-keys option.
-+--echo #
-+
-+--let $file=$MYSQLTEST_VARDIR/tmp/t1.sql
-+
-+# First test that the option has no effect on non-InnoDB tables
-+
-+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, KEY(b)) ENGINE=MyISAM;
-+
-+--exec $MYSQL_DUMP --skip-comments --innodb-optimize-keys test t1 >$file
-+
-+--echo ######################################
-+--cat_file $file
-+--echo ######################################
-+
-+--remove_file $file
-+
-+DROP TABLE t1;
-+
-+# 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);
-+
-+CREATE TABLE t1 (
-+  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-+  a INT, b VARCHAR(255), c DECIMAL(10,3),
-+  KEY (b),
-+  UNIQUE KEY uniq(c,a),
-+  FOREIGN KEY (a) REFERENCES t2(a) ON DELETE CASCADE
-+) ENGINE=InnoDB;
-+
-+INSERT INTO t1(a,b,c) VALUES (0, "0", 0.0), (1, "1", 1.1), (2, "2", 2.2);
-+
-+--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 #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
-@@ -1497,6 +1497,9 @@
-   alter_list(rhs.alter_list, mem_root),
-   key_list(rhs.key_list, mem_root),
-   create_list(rhs.create_list, mem_root),
-+  delayed_key_list(rhs.delayed_key_list, mem_root),
-+  delayed_key_info(rhs.delayed_key_info),
-+  delayed_key_count(rhs.delayed_key_count),
-   flags(rhs.flags),
-   keys_onoff(rhs.keys_onoff),
-   tablespace_op(rhs.tablespace_op),
-@@ -1519,6 +1522,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);
-+  list_copy_and_replace_each_value(delayed_key_list, mem_root);
-   /* partition_names are not deeply copied currently */
- }
---- a/sql/sql_lex.h
-+++ b/sql/sql_lex.h
-@@ -904,6 +904,9 @@
-   List<Alter_column>            alter_list;
-   List<Key>                     key_list;
-   List<Create_field>            create_list;
-+  List<Key>                     delayed_key_list;
-+  KEY                           *delayed_key_info;
-+  uint                          delayed_key_count;
-   uint                          flags;
-   enum enum_enable_or_disable   keys_onoff;
-   enum tablespace_op_type       tablespace_op;
-@@ -915,6 +918,8 @@
-   Alter_info() :
-+    delayed_key_info(NULL),
-+    delayed_key_count(0),
-     flags(0),
-     keys_onoff(LEAVE_AS_IS),
-     tablespace_op(NO_TABLESPACE_OP),
-@@ -930,6 +935,9 @@
-     alter_list.empty();
-     key_list.empty();
-     create_list.empty();
-+    delayed_key_list.empty();
-+    delayed_key_info= NULL;
-+    delayed_key_count= 0;
-     flags= 0;
-     keys_onoff= LEAVE_AS_IS;
-     tablespace_op= NO_TABLESPACE_OP;
---- a/sql/sql_table.cc
-+++ b/sql/sql_table.cc
-@@ -3016,6 +3016,14 @@
-   if (!*key_info_buffer || ! key_part_info)
-     DBUG_RETURN(TRUE);                                // Out of memory
-+  List_iterator<Key> delayed_key_iterator(alter_info->delayed_key_list);
-+  alter_info->delayed_key_count= 0;
-+  if (alter_info->delayed_key_list.elements > 0)
-+  {
-+    alter_info->delayed_key_info= (KEY *) sql_calloc(sizeof(KEY) *
-+                                                     (*key_count));
-+  }
-+
-   key_iterator.rewind();
-   key_number=0;
-   for (; (key=key_iterator++) ; key_number++)
-@@ -3394,8 +3402,26 @@
-       my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
-       DBUG_RETURN(TRUE);
-     }
-+
-+    if (alter_info->delayed_key_list.elements > 0)
-+    {
-+      Key *delayed_key;
-+
-+      delayed_key_iterator.rewind();
-+      while ((delayed_key= delayed_key_iterator++))
-+      {
-+        if (delayed_key == key)
-+        {
-+         alter_info->delayed_key_info[alter_info->delayed_key_count++]=
-+           *key_info;
-+         break;
-+        }
-+      }
-+    }
-+
-     key_info++;
-   }
-+
-   if (!unique_key && !primary_key &&
-       (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
-   {
-@@ -6094,6 +6120,10 @@
-   List<Create_field> new_create_list;
-   /* New key definitions are added here */
-   List<Key> new_key_list;
-+  /* List with secondary keys which should be created after copying the data */
-+  List<Key> delayed_key_list;
-+  /* Foreign key list returned by handler::get_foreign_key_list() */
-+  List<FOREIGN_KEY_INFO> f_key_list;
-   List_iterator<Alter_drop> drop_it(alter_info->drop_list);
-   List_iterator<Create_field> def_it(alter_info->create_list);
-   List_iterator<Alter_column> alter_it(alter_info->alter_list);
-@@ -6106,6 +6136,7 @@
-   uint used_fields= create_info->used_fields;
-   KEY *key_info=table->key_info;
-   bool rc= TRUE;
-+  bool skip_secondary;
-   DBUG_ENTER("mysql_prepare_alter_table");
-@@ -6133,6 +6164,7 @@
-     char *tablespace= static_cast<char *>(thd->alloc(FN_LEN + 1));
-     /*
-        Regular alter table of disk stored table (no tablespace/storage change)
-+
-        Copy tablespace name
-     */
-     if (tablespace &&
-@@ -6300,7 +6332,26 @@
-   /*
-     Collect all keys which isn't in drop list. Add only those
-     for which some fields exists.
--  */
-+
-+    We also store secondary keys in delayed_key_list to make use of
-+    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;
-+    - there are no foreign keys. This can be optimized later to exclude only
-+      those keys which are a part of foreign key constraints. Currently we
-+      simply disable this optimization for all keys if there are any foreign
-+      key constraints in the table.
-+  */
-+
-+  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++)
-   {
-@@ -6403,6 +6454,8 @@
-                    test(key_info->flags & HA_GENERATED_KEY),
-                    key_parts);
-       new_key_list.push_back(key);
-+      if (skip_secondary && key_type == Key::MULTIPLE)
-+        delayed_key_list.push_back(key);
-     }
-   }
-   {
-@@ -6410,7 +6463,21 @@
-     while ((key=key_it++))                    // Add new keys
-     {
-       if (key->type != Key::FOREIGN_KEY)
--        new_key_list.push_back(key);
-+      {
-+          new_key_list.push_back(key);
-+        if (skip_secondary && key->type == Key::MULTIPLE)
-+          delayed_key_list.push_back(key);
-+      }
-+      else if (skip_secondary)
-+      {
-+        /*
-+          We are adding a foreign key so disable the secondary keys
-+          optimization.
-+        */
-+        skip_secondary= FALSE;
-+        delayed_key_list.empty();
-+      }
-+
-       if (key->name &&
-         !my_strcasecmp(system_charset_info,key->name,primary_key_name))
-       {
-@@ -6459,12 +6526,100 @@
-   rc= FALSE;
-   alter_info->create_list.swap(new_create_list);
-   alter_info->key_list.swap(new_key_list);
-+  alter_info->delayed_key_list.swap(delayed_key_list);
- err:
-   DBUG_RETURN(rc);
- }
- /*
-+  Temporarily remove secondary keys previously stored in
-+  alter_info->delayed_key_info.
-+*/
-+static int
-+remove_secondary_keys(THD *thd, TABLE *table, Alter_info *alter_info)
-+{
-+  uint *key_numbers;
-+  uint key_counter= 0;
-+  uint i;
-+  int error;
-+  DBUG_ENTER("remove_secondary_keys");
-+  DBUG_ASSERT(alter_info->delayed_key_count > 0);
-+
-+  key_numbers= (uint *) thd->alloc(sizeof(uint) *
-+                                   alter_info->delayed_key_count);
-+  for (i= 0; i < alter_info->delayed_key_count; i++)
-+  {
-+    KEY *key= alter_info->delayed_key_info + i;
-+    uint j;
-+
-+    for (j= 0; j < table->s->keys; j++)
-+    {
-+      if (!strcmp(table->key_info[j].name, key->name))
-+      {
-+        key_numbers[key_counter++]= j;
-+        break;
-+      }
-+    }
-+  }
-+
-+  DBUG_ASSERT(key_counter == alter_info->delayed_key_count);
-+
-+  if ((error= table->file->prepare_drop_index(table, key_numbers,
-+                                              key_counter)) ||
-+      (error= table->file->final_drop_index(table)))
-+  {
-+    table->file->print_error(error, MYF(0));
-+  }
-+
-+  DBUG_RETURN(error);
-+}
-+
-+/*
-+  Restore secondary keys previously removed in remove_secondary_keys.
-+*/
-+
-+static int
-+restore_secondary_keys(THD *thd, TABLE *table, Alter_info *alter_info)
-+{
-+  uint i;
-+  int error;
-+  DBUG_ENTER("restore_secondary_keys");
-+  DBUG_ASSERT(alter_info->delayed_key_count > 0);
-+
-+  thd_proc_info(thd, "restoring secondary keys");
-+
-+  /* Fix the key parts */
-+  for (i= 0; i < alter_info->delayed_key_count; i++)
-+  {
-+    KEY *key = alter_info->delayed_key_info + i;
-+    KEY_PART_INFO *key_part;
-+    KEY_PART_INFO *part_end;
-+
-+    part_end= key->key_part + key->key_parts;
-+    for (key_part= key->key_part; key_part < part_end; key_part++)
-+      key_part->field= table->field[key_part->fieldnr];
-+  }
-+
-+  if ((error= table->file->add_index(table, alter_info->delayed_key_info,
-+                                     alter_info->delayed_key_count)))
-+  {
-+    /*
-+      Exchange the key_info for the error message. If we exchange
-+      key number by key name in the message later, we need correct info.
-+    */
-+    KEY *save_key_info= table->key_info;
-+    table->key_info= alter_info->delayed_key_info;
-+    table->file->print_error(error, MYF(0));
-+    table->key_info= save_key_info;
-+
-+    DBUG_RETURN(error);
-+  }
-+
-+  DBUG_RETURN(0);
-+}
-+
-+/*
-   Alter table
-   SYNOPSIS
-@@ -7248,6 +7403,12 @@
-   else
-     create_info->data_file_name=create_info->index_file_name=0;
-+  /*
-+    Postpone secondary index creation for InnoDB tables if the data has to be
-+    copied.
-+    TODO: is there a better way to check for InnoDB?
-+  */
-+
-   DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock");
-   /*
-     Create a table with a temporary name.
-@@ -7304,15 +7465,33 @@
-   */
-   if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
-   {
-+    /*
-+      Check if we can temporarily remove secondary indexes from the table
-+      before copying the data and recreate them later to utilize InnoDB fast
-+      index creation.
-+      TODO: is there a better way to check for InnoDB?
-+    */
-+    bool optimize_keys= (alter_info->delayed_key_count > 0) &&
-+      !my_strcasecmp(system_charset_info,
-+                     new_table->file->table_type(), "InnoDB");
-     /* We don't want update TIMESTAMP fields during ALTER TABLE. */
-     new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-     new_table->next_number_field=new_table->found_next_number_field;
-+
-+    if (optimize_keys)
-+    {
-+      /* ignore the error */
-+      error= remove_secondary_keys(thd, new_table, alter_info);
-+    }
-+
-     thd_proc_info(thd, "copy to tmp table");
-     error= copy_data_between_tables(table, new_table,
-                                     alter_info->create_list, ignore,
-                                     order_num, order, &copied, &deleted,
-                                     alter_info->keys_onoff,
-                                     alter_info->error_if_not_empty);
-+    if (!error && optimize_keys)
-+      error= restore_secondary_keys(thd, new_table, alter_info);
-   }
-   else
-   {
---- /dev/null
-+++ b/mysql-test/r/percona_innodb_expand_fast_index_creation.result
-@@ -0,0 +1,67 @@
-+SELECT @@expand_fast_index_creation;
-+@@expand_fast_index_creation
-+0
-+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,46 @@
-+--source include/have_innodb.inc
-+
-+SELECT @@expand_fast_index_creation;
-+
-+########################################################################
-+# 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/innodb_plugin/row/row0merge.c
-+++ b/storage/innodb_plugin/row/row0merge.c
-@@ -56,6 +56,7 @@
- #include "log0log.h"
- #include "ut0sort.h"
- #include "handler0alter.h"
-+#include "ha_prototypes.h"
- #ifdef UNIV_DEBUG
- /** Set these in order ot enable debug printout. */
-@@ -2630,6 +2631,9 @@
-               }
-       }
-+      if (trx->mysql_thd && thd_expand_fast_index_creation(trx->mysql_thd))
-+              dict_update_statistics(new_table, FALSE, TRUE);
-+
- func_exit:
-       close(tmpfd);
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -6061,7 +6061,8 @@
-   OPT_IGNORE_BUILTIN_INNODB,
-   OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
-   OPT_DEFAULT_CHARACTER_SET_OLD,
--  OPT_MAX_LONG_DATA_SIZE
-+  OPT_MAX_LONG_DATA_SIZE,
-+  OPT_EXPAND_FAST_INDEX_CREATION
- };
-@@ -6297,6 +6298,13 @@
- each time the SQL thread starts.",
-    &opt_init_slave, &opt_init_slave, 0, GET_STR_ALLOC,
-    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+  {"expand-fast-index-creation", OPT_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",
-+   &global_system_variables.expand_fast_index_creation,
-+   &max_system_variables.expand_fast_index_creation,
-+   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, NULL},
-   {"language", 'L',
-    "Client error messages in given language. May be given as a full path.",
-    &language_ptr, &language_ptr, 0, GET_STR, REQUIRED_ARG,
---- a/sql/set_var.cc
-+++ b/sql/set_var.cc
-@@ -1056,6 +1056,9 @@
-                                                      SHOW_LONGLONG,
-                                                      get_myisam_mmap_size);
-+static sys_var_thd_bool
-+sys_expand_fast_index_creation(&vars,
-+  "expand_fast_index_creation", &SV::expand_fast_index_creation);
- bool sys_var::check(THD *thd, set_var *var)
- {
---- a/sql/sql_class.h
-+++ b/sql/sql_class.h
-@@ -425,6 +425,8 @@
-   ulong      innodb_lock_que_wait_timer;
-   ulong      innodb_innodb_que_wait_timer;
-   ulong      innodb_page_access;
-+
-+  my_bool expand_fast_index_creation;
- };
---- a/storage/innodb_plugin/include/ha_prototypes.h
-+++ b/storage/innodb_plugin/include/ha_prototypes.h
-@@ -276,4 +276,14 @@
- /*================================*/
-       void*   thd);
-+/******************************************************************//**
-+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
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -770,6 +770,19 @@
-       return(THDVAR((THD*) thd, flush_log_at_trx_commit_session));
- }
-+/******************************************************************//**
-+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 */
diff --git a/mysql-innodb_expand_import.patch b/mysql-innodb_expand_import.patch
deleted file mode 100644 (file)
index c5b06e3..0000000
+++ /dev/null
@@ -1,1072 +0,0 @@
-# name       : innodb_expand_import.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/btr/btr0btr.c
-+++ b/storage/innodb_plugin/btr/btr0btr.c
-@@ -837,7 +837,7 @@
- /**************************************************************//**
- Creates a new index page (not the root, and also not
- used in page reorganization).  @see btr_page_empty(). */
--static
-+UNIV_INTERN
- void
- btr_page_create(
- /*============*/
-@@ -1704,7 +1704,7 @@
- #ifndef UNIV_HOTBACKUP
- /*************************************************************//**
- Empties an index page.  @see btr_page_create(). */
--static
-+UNIV_INTERN
- void
- btr_page_empty(
- /*===========*/
-@@ -2266,7 +2266,7 @@
- /**************************************************************//**
- Attaches the halves of an index page on the appropriate level in an
- index tree. */
--static
-+UNIV_INTERN
- void
- btr_attach_half_pages(
- /*==================*/
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -40,6 +40,14 @@
- #include "dict0dict.h"
- #include "page0page.h"
- #include "page0zip.h"
-+#include "trx0trx.h"
-+#include "trx0sys.h"
-+#include "pars0pars.h"
-+#include "row0mysql.h"
-+#include "row0row.h"
-+#include "que0que.h"
-+#include "btr0btr.h"
-+#include "btr0sea.h"
- #ifndef UNIV_HOTBACKUP
- # include "buf0lru.h"
- # include "ibuf0ibuf.h"
-@@ -2984,6 +2992,84 @@
- }
- /********************************************************************//**
-+Checks if a page is corrupt. (for offline page)
-+*/
-+static
-+ibool
-+fil_page_buf_page_is_corrupted_offline(
-+/*===================================*/
-+      const byte*     page,           /*!< in: a database page */
-+      ulint           zip_size)       /*!< in: size of compressed page;
-+                                      0 for uncompressed pages */
-+{
-+      ulint           checksum_field;
-+      ulint           old_checksum_field;
-+
-+      if (!zip_size
-+          && memcmp(page + FIL_PAGE_LSN + 4,
-+                    page + UNIV_PAGE_SIZE
-+                    - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) {
-+              return(TRUE);
-+      }
-+
-+      checksum_field = mach_read_from_4(page
-+                                        + FIL_PAGE_SPACE_OR_CHKSUM);
-+
-+      if (zip_size) {
-+              return(checksum_field != BUF_NO_CHECKSUM_MAGIC
-+                     && checksum_field
-+                     != page_zip_calc_checksum(page, zip_size));
-+      }
-+
-+      old_checksum_field = mach_read_from_4(
-+              page + UNIV_PAGE_SIZE
-+              - FIL_PAGE_END_LSN_OLD_CHKSUM);
-+
-+      if (old_checksum_field != mach_read_from_4(page
-+                                                 + FIL_PAGE_LSN)
-+          && old_checksum_field != BUF_NO_CHECKSUM_MAGIC
-+          && old_checksum_field
-+          != buf_calc_page_old_checksum(page)) {
-+              return(TRUE);
-+      }
-+
-+      if (checksum_field != 0
-+          && checksum_field != BUF_NO_CHECKSUM_MAGIC
-+          && checksum_field
-+          != buf_calc_page_new_checksum(page)) {
-+              return(TRUE);
-+      }
-+
-+      return(FALSE);
-+}
-+
-+/********************************************************************//**
-+*/
-+static
-+void
-+fil_page_buf_page_store_checksum(
-+/*=============================*/
-+      byte*   page,
-+      ulint   zip_size)
-+{
-+      if (!zip_size) {
-+              mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
-+                              srv_use_checksums
-+                              ? buf_calc_page_new_checksum(page)
-+                                              : BUF_NO_CHECKSUM_MAGIC);
-+              mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
-+                              srv_use_checksums
-+                              ? buf_calc_page_old_checksum(page)
-+                                              : BUF_NO_CHECKSUM_MAGIC);
-+      } else {
-+              mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
-+                              srv_use_checksums
-+                              ? page_zip_calc_checksum(page, zip_size)
-+                              : BUF_NO_CHECKSUM_MAGIC);
-+      }
-+}
-+
-+/********************************************************************//**
- Tries to open a single-table tablespace and optionally checks the space id is
- right in it. If does not succeed, prints an error message to the .err log. This
- function is used to open a tablespace when we start up mysqld, and also in
-@@ -3029,7 +3115,7 @@
-       ut_a(!(flags & (~0UL << DICT_TF_BITS)));
-       file = os_file_create_simple_no_error_handling(
--              filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
-+              filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
-       if (!success) {
-               /* The following call prints an error message */
-               os_file_get_last_error(TRUE);
-@@ -3076,6 +3162,445 @@
-       space_id = fsp_header_get_space_id(page);
-       space_flags = fsp_header_get_flags(page);
-+      if (srv_expand_import) {
-+
-+              ibool           file_is_corrupt = FALSE;
-+              byte*           buf3;
-+              byte*           descr_page;
-+              ibool           descr_is_corrupt = FALSE;
-+              dulint          old_id[31];
-+              dulint          new_id[31];
-+              ulint           root_page[31];
-+              ulint           n_index;
-+              os_file_t       info_file = -1;
-+              char*           info_file_path;
-+              ulint   i;
-+              int             len;
-+              ib_uint64_t     current_lsn;
-+              ulint           size_low, size_high, size, free_limit;
-+              ib_int64_t      size_bytes, free_limit_bytes;
-+              dict_table_t*   table;
-+              dict_index_t*   index;
-+              fil_system_t*   system;
-+              fil_node_t*     node = NULL;
-+              fil_space_t*    space;
-+              ulint           zip_size;
-+
-+              buf3 = ut_malloc(2 * UNIV_PAGE_SIZE);
-+              descr_page = ut_align(buf3, UNIV_PAGE_SIZE);
-+
-+              current_lsn = log_get_lsn();
-+
-+              /* check the header page's consistency */
-+              if (buf_page_is_corrupted(page,
-+                                        dict_table_flags_to_zip_size(space_flags))) {
-+                      fprintf(stderr, "InnoDB: page 0 of %s seems corrupt.\n", filepath);
-+                      file_is_corrupt = TRUE;
-+                      descr_is_corrupt = TRUE;
-+              }
-+
-+              /* store as first descr page */
-+              memcpy(descr_page, page, UNIV_PAGE_SIZE);
-+
-+              zip_size = dict_table_flags_to_zip_size(flags);
-+              ut_a(zip_size == dict_table_flags_to_zip_size(space_flags));
-+
-+              /* get free limit (page number) of the table space */
-+/* these should be same to the definition in fsp0fsp.c */
-+#define FSP_HEADER_OFFSET     FIL_PAGE_DATA
-+#define       FSP_FREE_LIMIT          12
-+              free_limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT + page);
-+              free_limit_bytes = (ib_int64_t)free_limit * (ib_int64_t)(zip_size ? zip_size : UNIV_PAGE_SIZE);
-+
-+              /* overwrite fsp header */
-+              fsp_header_init_fields(page, id, flags);
-+              mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
-+              space_id = id;
-+              space_flags = flags;
-+              if (mach_read_ull(page + FIL_PAGE_FILE_FLUSH_LSN) > current_lsn)
-+                      mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
-+
-+              fil_page_buf_page_store_checksum(page, zip_size);
-+
-+              success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE);
-+
-+              /* get file size */
-+              os_file_get_size(file, &size_low, &size_high);
-+              size_bytes = (((ib_int64_t)size_high) << 32)
-+                              + (ib_int64_t)size_low;
-+
-+              if (size_bytes < free_limit_bytes) {
-+                      free_limit_bytes = size_bytes;
-+                      if (size_bytes >= (ib_int64_t) (FSP_EXTENT_SIZE * (zip_size ? zip_size : UNIV_PAGE_SIZE))) {
-+                              fprintf(stderr, "InnoDB: free limit of %s is larger than its real size.\n", filepath);
-+                              file_is_corrupt = TRUE;
-+                      }
-+              }
-+
-+              /* get cruster index information */
-+              table = dict_table_get_low(name);
-+              index = dict_table_get_first_index(table);
-+              ut_a(index->page==3);
-+
-+              /* read metadata from .exp file */
-+              n_index = 0;
-+              memset(old_id, 0, sizeof(old_id));
-+              memset(new_id, 0, sizeof(new_id));
-+              memset(root_page, 0, sizeof(root_page));
-+
-+              info_file_path = fil_make_ibd_name(name, FALSE);
-+              len = strlen(info_file_path);
-+              info_file_path[len - 3] = 'e';
-+              info_file_path[len - 2] = 'x';
-+              info_file_path[len - 1] = 'p';
-+
-+              info_file = os_file_create_simple_no_error_handling(
-+                              info_file_path, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
-+              if (!success) {
-+                      fprintf(stderr, "InnoDB: cannot open %s\n", info_file_path);
-+                      file_is_corrupt = TRUE;
-+                      goto skip_info;
-+              }
-+              success = os_file_read(info_file, page, 0, 0, UNIV_PAGE_SIZE);
-+              if (!success) {
-+                      fprintf(stderr, "InnoDB: cannot read %s\n", info_file_path);
-+                      file_is_corrupt = TRUE;
-+                      goto skip_info;
-+              }
-+              if (mach_read_from_4(page) != 0x78706f72UL
-+                  || mach_read_from_4(page + 4) != 0x74696e66UL) {
-+                      fprintf(stderr, "InnoDB: %s seems not to be a correct .exp file\n", info_file_path);
-+                      file_is_corrupt = TRUE;
-+                      goto skip_info;
-+              }
-+
-+              fprintf(stderr, "InnoDB: import: extended import of %s is started.\n", name);
-+
-+              n_index = mach_read_from_4(page + 8);
-+              fprintf(stderr, "InnoDB: import: %lu indexes are detected.\n", (ulong)n_index);
-+              for (i = 0; i < n_index; i++) {
-+                      new_id[i] =
-+                              dict_table_get_index_on_name(table,
-+                                              (char*)(page + (i + 1) * 512 + 12))->id;
-+                      old_id[i] = mach_read_from_8(page + (i + 1) * 512);
-+                      root_page[i] = mach_read_from_4(page + (i + 1) * 512 + 8);
-+              }
-+
-+skip_info:
-+              if (info_file != -1)
-+                      os_file_close(info_file);
-+
-+              /*
-+              if (size_bytes >= 1024 * 1024) {
-+                      size_bytes = ut_2pow_round(size_bytes, 1024 * 1024);
-+              }
-+              */
-+
-+              if (zip_size) {
-+                      fprintf(stderr, "InnoDB: Warning: importing compressed table is still EXPERIMENTAL, currently.\n");
-+              }
-+
-+              {
-+                      mem_heap_t*     heap = NULL;
-+                      ulint           offsets_[REC_OFFS_NORMAL_SIZE];
-+                      ulint*          offsets = offsets_;
-+                      ib_int64_t      offset;
-+
-+                      size = (ulint) (size_bytes / (zip_size ? zip_size : UNIV_PAGE_SIZE));
-+                      /* over write space id of all pages */
-+                      rec_offs_init(offsets_);
-+
-+                      fprintf(stderr, "InnoDB: Progress in %%:");
-+
-+                      for (offset = 0; offset < free_limit_bytes;
-+                           offset += zip_size ? zip_size : UNIV_PAGE_SIZE) {
-+                              ibool           page_is_corrupt;
-+
-+                              success = os_file_read(file, page,
-+                                                      (ulint)(offset & 0xFFFFFFFFUL),
-+                                                      (ulint)(offset >> 32),
-+                                                      zip_size ? zip_size : UNIV_PAGE_SIZE);
-+
-+                              page_is_corrupt = FALSE;
-+
-+                              /* check consistency */
-+                              if (fil_page_buf_page_is_corrupted_offline(page, zip_size)) {
-+                                      page_is_corrupt = TRUE;
-+                              }
-+
-+                              if (mach_read_from_4(page + FIL_PAGE_OFFSET)
-+                                  != offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)) {
-+
-+                                      page_is_corrupt = TRUE;
-+                              }
-+
-+                              /* if it is free page, inconsistency is acceptable */
-+                              if (!offset) {
-+                                      /* header page*/
-+                                      /* it should be overwritten already */
-+                                      ut_a(!page_is_corrupt);
-+
-+                              } else if (!((offset / (zip_size ? zip_size : UNIV_PAGE_SIZE))
-+                                           % (zip_size ? zip_size : UNIV_PAGE_SIZE))) {
-+                                      /* descr page (not header) */
-+                                      if (page_is_corrupt) {
-+                                              file_is_corrupt = TRUE;
-+                                              descr_is_corrupt = TRUE;
-+                                      } else {
-+
-+                                              descr_is_corrupt = FALSE;
-+                                      }
-+
-+                                      /* store as descr page */
-+                                      memcpy(descr_page, page, (zip_size ? zip_size : UNIV_PAGE_SIZE));
-+
-+                              } else if (descr_is_corrupt) {
-+                                      /* unknown state of the page */
-+                                      if (page_is_corrupt) {
-+                                              file_is_corrupt = TRUE;
-+                                      }
-+
-+                              } else {
-+                                      /* check free page or not */
-+                                      /* These definitions should be same to fsp0fsp.c */
-+#define       FSP_HEADER_SIZE         (32 + 5 * FLST_BASE_NODE_SIZE)
-+
-+#define       XDES_BITMAP             (FLST_NODE_SIZE + 12)
-+#define       XDES_BITS_PER_PAGE      2
-+#define       XDES_FREE_BIT           0
-+#define       XDES_SIZE                                                       \
-+      (XDES_BITMAP + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE))
-+#define       XDES_ARR_OFFSET         (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
-+
-+                                      /*descr = descr_page + XDES_ARR_OFFSET + XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset)*/
-+                                      /*xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)*/
-+                                      byte*   descr;
-+                                      ulint   index;
-+                                      ulint   byte_index;
-+                                      ulint   bit_index;
-+
-+                                      descr = descr_page + XDES_ARR_OFFSET
-+                                              + XDES_SIZE * (ut_2pow_remainder(
-+                                                      (offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)),
-+                                                      (zip_size ? zip_size : UNIV_PAGE_SIZE)) / FSP_EXTENT_SIZE);
-+
-+                                      index = XDES_FREE_BIT
-+                                              + XDES_BITS_PER_PAGE * ((offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)) % FSP_EXTENT_SIZE);
-+                                      byte_index = index / 8;
-+                                      bit_index = index % 8;
-+
-+                                      if (ut_bit_get_nth(mach_read_from_1(descr + XDES_BITMAP + byte_index), bit_index)) {
-+                                              /* free page */
-+                                              if (page_is_corrupt) {
-+                                                      goto skip_write;
-+                                              }
-+                                      } else {
-+                                              /* not free */
-+                                              if (page_is_corrupt) {
-+                                                      file_is_corrupt = TRUE;
-+                                              }
-+                                      }
-+                              }
-+
-+                              if (page_is_corrupt) {
-+                                      fprintf(stderr, " [errp:%lld]", offset / (zip_size ? zip_size : UNIV_PAGE_SIZE));
-+
-+                                      /* cannot treat corrupt page */
-+                                      goto skip_write;
-+                              }
-+
-+                              if (mach_read_from_4(page + FIL_PAGE_OFFSET) || !offset) {
-+                                      mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
-+
-+                                      for (i = 0; i < n_index; i++) {
-+                                              if (offset / (zip_size ? zip_size : UNIV_PAGE_SIZE) == root_page[i]) {
-+                                                      if (fil_page_get_type(page) != FIL_PAGE_INDEX) {
-+                                                              file_is_corrupt = TRUE;
-+                                                              fprintf(stderr, " [etyp:%lld]",
-+                                                                      offset / (zip_size ? zip_size : UNIV_PAGE_SIZE));
-+                                                              goto skip_write;
-+                                                      }
-+                                                      /* this is index root page */
-+                                                      mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
-+                                                                                      + FSEG_HDR_SPACE, id);
-+                                                      mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
-+                                                                                      + FSEG_HDR_SPACE, id);
-+                                                      break;
-+                                              }
-+                                      }
-+
-+                                      if (fil_page_get_type(page) == FIL_PAGE_INDEX) {
-+                                              dulint tmp = mach_read_from_8(page + (PAGE_HEADER + PAGE_INDEX_ID));
-+
-+                                              for (i = 0; i < n_index; i++) {
-+                                                      if (ut_dulint_cmp(old_id[i], tmp) == 0) {
-+                                                              mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), new_id[i]);
-+                                                              break;
-+                                                      }
-+                                              }
-+
-+                                              if (!zip_size && mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0
-+                                                  && ut_dulint_cmp(old_id[0], tmp) == 0) {
-+                                                      /* leaf page of cluster index, reset trx_id of records */
-+                                                      rec_t*  rec;
-+                                                      rec_t*  supremum;
-+                                                      ulint   n_recs;
-+
-+                                                      supremum = page_get_supremum_rec(page);
-+                                                      rec = page_rec_get_next(page_get_infimum_rec(page));
-+                                                      n_recs = page_get_n_recs(page);
-+
-+                                                      while (rec && rec != supremum && n_recs > 0) {
-+                                                              ulint   n_fields;
-+                                                              ulint   i;
-+                                                              ulint   offset = index->trx_id_offset;
-+                                                              offsets = rec_get_offsets(rec, index, offsets,
-+                                                                              ULINT_UNDEFINED, &heap);
-+                                                              n_fields = rec_offs_n_fields(offsets);
-+                                                              if (!offset) {
-+                                                                      offset = row_get_trx_id_offset(index, offsets);
-+                                                              }
-+                                                              trx_write_trx_id(rec + offset, ut_dulint_create(0, 1));
-+
-+                                                              for (i = 0; i < n_fields; i++) {
-+                                                                      if (rec_offs_nth_extern(offsets, i)) {
-+                                                                              ulint   local_len;
-+                                                                              byte*   data;
-+
-+                                                                              data = rec_get_nth_field(rec, offsets, i, &local_len);
-+
-+                                                                              local_len -= BTR_EXTERN_FIELD_REF_SIZE;
-+
-+                                                                              mach_write_to_4(data + local_len + BTR_EXTERN_SPACE_ID, id);
-+                                                                      }
-+                                                              }
-+
-+                                                              rec = page_rec_get_next(rec);
-+                                                              n_recs--;
-+                                                      }
-+                                              } else if (mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0
-+                                                         && ut_dulint_cmp(old_id[0], tmp) != 0) {
-+                                                      mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), ut_dulint_create(0, 1));
-+                                              }
-+                                      }
-+
-+                                      if (mach_read_ull(page + FIL_PAGE_LSN) > current_lsn) {
-+                                              mach_write_ull(page + FIL_PAGE_LSN, current_lsn);
-+                                              if (!zip_size) {
-+                                                      mach_write_ull(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
-+                                                                      current_lsn);
-+                                              }
-+                                      }
-+
-+                                      fil_page_buf_page_store_checksum(page, zip_size);
-+
-+                                      success = os_file_write(filepath, file, page,
-+                                                              (ulint)(offset & 0xFFFFFFFFUL),
-+                                                              (ulint)(offset >> 32),
-+                                                              zip_size ? zip_size : UNIV_PAGE_SIZE);
-+                              }
-+
-+skip_write:
-+                              if (free_limit_bytes
-+                                  && ((ib_int64_t)((offset + (zip_size ? zip_size : UNIV_PAGE_SIZE)) * 100) / free_limit_bytes)
-+                                      != ((offset * 100) / free_limit_bytes)) {
-+                                      fprintf(stderr, " %lu",
-+                                              (ulong)((ib_int64_t)((offset + (zip_size ? zip_size : UNIV_PAGE_SIZE)) * 100) / free_limit_bytes));
-+                              }
-+                      }
-+
-+                      fprintf(stderr, " done.\n");
-+
-+                      /* update SYS_INDEXES set root page */
-+                      index = dict_table_get_first_index(table);
-+                      while (index) {
-+                              for (i = 0; i < n_index; i++) {
-+                                      if (ut_dulint_cmp(new_id[i], index->id) == 0) {
-+                                              break;
-+                                      }
-+                              }
-+
-+                              if (i != n_index
-+                                  && root_page[i] != index->page) {
-+                                      /* must update */
-+                                      ulint   error;
-+                                      trx_t*  trx;
-+                                      pars_info_t*    info = NULL;
-+
-+                                      trx = trx_allocate_for_mysql();
-+                                      trx->op_info = "extended import";
-+
-+                                      info = pars_info_create();
-+
-+                                      pars_info_add_dulint_literal(info, "indexid", new_id[i]);
-+                                      pars_info_add_int4_literal(info, "new_page", (lint) root_page[i]);
-+
-+                                      error = que_eval_sql(info,
-+                                              "PROCEDURE UPDATE_INDEX_PAGE () IS\n"
-+                                              "BEGIN\n"
-+                                              "UPDATE SYS_INDEXES"
-+                                              " SET PAGE_NO = :new_page"
-+                                              " WHERE ID = :indexid;\n"
-+                                              "COMMIT WORK;\n"
-+                                              "END;\n",
-+                                              FALSE, trx);
-+
-+                                      if (error != DB_SUCCESS) {
-+                                              fprintf(stderr, "InnoDB: failed to update SYS_INDEXES\n");
-+                                      }
-+
-+                                      trx_commit_for_mysql(trx);
-+
-+                                      trx_free_for_mysql(trx);
-+
-+                                      index->page = root_page[i];
-+                              }
-+
-+                              index = dict_table_get_next_index(index);
-+                      }
-+                      if (UNIV_LIKELY_NULL(heap)) {
-+                              mem_heap_free(heap);
-+                      }
-+              }
-+              /* .exp file should be removed */
-+              success = os_file_delete(info_file_path);
-+              if (!success) {
-+                      success = os_file_delete_if_exists(info_file_path);
-+              }
-+              mem_free(info_file_path);
-+
-+              system  = fil_system;
-+              mutex_enter(&(system->mutex));
-+              space = fil_space_get_by_id(id);
-+              if (space)
-+                      node = UT_LIST_GET_FIRST(space->chain);
-+              if (node && node->size < size) {
-+                      space->size += (size - node->size);
-+                      node->size = size;
-+              }
-+              mutex_exit(&(system->mutex));
-+
-+              ut_free(buf3);
-+
-+              if (file_is_corrupt) {
-+                      ut_print_timestamp(stderr);
-+                      fputs("  InnoDB: Error: file ",
-+                            stderr);
-+                      ut_print_filename(stderr, filepath);
-+                      fprintf(stderr, " seems to be corrupt.\n"
-+                              "InnoDB: anyway, all not corrupt pages were tried to be converted to salvage.\n"
-+                              "InnoDB: ##### CAUTION #####\n"
-+                              "InnoDB: ## The .ibd must cause to crash InnoDB, though re-import would seem to be succeeded.\n"
-+                              "InnoDB: ## If you don't have knowledge about salvaging data from .ibd, you should not use the file.\n"
-+                              "InnoDB: ###################\n");
-+                      success = FALSE;
-+
-+                      ut_free(buf2);
-+
-+                      goto func_exit;
-+              }
-+      }
-+
-       ut_free(buf2);
-       if (UNIV_UNLIKELY(space_id != id
-@@ -3117,6 +3642,269 @@
-       os_file_close(file);
-       mem_free(filepath);
-+      if (srv_expand_import && dict_table_flags_to_zip_size(flags)) {
-+              ulint           page_no;
-+              ulint           zip_size;
-+              ulint           height;
-+              rec_t*          node_ptr;
-+              dict_table_t*   table;
-+              dict_index_t*   index;
-+              buf_block_t*    block;
-+              page_t*         page;
-+              page_zip_des_t* page_zip;
-+              mtr_t           mtr;
-+
-+              mem_heap_t*     heap            = NULL;
-+              ulint           offsets_[REC_OFFS_NORMAL_SIZE];
-+              ulint*          offsets         = offsets_;
-+
-+              rec_offs_init(offsets_);
-+
-+              zip_size = dict_table_flags_to_zip_size(flags);
-+
-+              table = dict_table_get_low(name);
-+              index = dict_table_get_first_index(table);
-+              page_no = dict_index_get_page(index);
-+              ut_a(page_no == 3);
-+
-+              fprintf(stderr, "InnoDB: It is compressed .ibd file. need to convert additionaly on buffer pool.\n");
-+
-+              /* down to leaf */
-+              mtr_start(&mtr);
-+              mtr_set_log_mode(&mtr, MTR_LOG_NONE);
-+
-+              height = ULINT_UNDEFINED;
-+
-+              for (;;) {
-+                      block = buf_page_get(space_id, zip_size, page_no,
-+                                           RW_NO_LATCH, &mtr);
-+                      page = buf_block_get_frame(block);
-+
-+                      block->check_index_page_at_flush = TRUE;
-+
-+                      if (height == ULINT_UNDEFINED) {
-+                              height = btr_page_get_level(page, &mtr);
-+                      }
-+
-+                      if (height == 0) {
-+                              break;
-+                      }
-+
-+                      node_ptr = page_rec_get_next(page_get_infimum_rec(page));
-+
-+                      height--;
-+
-+                      offsets = rec_get_offsets(node_ptr, index, offsets, ULINT_UNDEFINED, &heap);
-+                      page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
-+              }
-+
-+              mtr_commit(&mtr);
-+
-+              fprintf(stderr, "InnoDB: pages needs split are ...");
-+
-+              /* scan reaf pages */
-+              while (page_no != FIL_NULL) {
-+                      rec_t*  rec;
-+                      rec_t*  supremum;
-+                      ulint   n_recs;
-+
-+                      mtr_start(&mtr);
-+
-+                      block = buf_page_get(space_id, zip_size, page_no,
-+                                           RW_X_LATCH, &mtr);
-+                      page = buf_block_get_frame(block);
-+                      page_zip = buf_block_get_page_zip(block);
-+
-+                      if (!page_zip) {
-+                              /*something wrong*/
-+                              fprintf(stderr, "InnoDB: Something wrong with reading page %lu.\n", page_no);
-+convert_err_exit:
-+                              mtr_commit(&mtr);
-+                              mutex_enter(&fil_system->mutex);
-+                              fil_space_free(space_id, FALSE);
-+                              mutex_exit(&fil_system->mutex);
-+                              success = FALSE;
-+                              goto convert_exit;
-+                      }
-+
-+                      supremum = page_get_supremum_rec(page);
-+                      rec = page_rec_get_next(page_get_infimum_rec(page));
-+                      n_recs = page_get_n_recs(page);
-+
-+                      /* illegal operation as InnoDB online system. so not logged */
-+                      while (rec && rec != supremum && n_recs > 0) {
-+                              ulint   n_fields;
-+                              ulint   i;
-+                              ulint   offset = index->trx_id_offset;
-+
-+                              offsets = rec_get_offsets(rec, index, offsets,
-+                                              ULINT_UNDEFINED, &heap);
-+                              n_fields = rec_offs_n_fields(offsets);
-+                              if (!offset) {
-+                                      offset = row_get_trx_id_offset(index, offsets);
-+                              }
-+                              trx_write_trx_id(rec + offset, ut_dulint_create(0, 1));
-+
-+                              for (i = 0; i < n_fields; i++) {
-+                                      if (rec_offs_nth_extern(offsets, i)) {
-+                                              ulint   local_len;
-+                                              byte*   data;
-+
-+                                              data = rec_get_nth_field(rec, offsets, i, &local_len);
-+
-+                                              local_len -= BTR_EXTERN_FIELD_REF_SIZE;
-+
-+                                              mach_write_to_4(data + local_len + BTR_EXTERN_SPACE_ID, id);
-+                                      }
-+                              }
-+
-+                              rec = page_rec_get_next(rec);
-+                              n_recs--;
-+                      }
-+
-+                      /* dummy logged update for along with modified page path */
-+                      if (ut_dulint_cmp(index->id, btr_page_get_index_id(page)) != 0) {
-+                              /* this should be adjusted already */
-+                              fprintf(stderr, "InnoDB: The page %lu seems to be converted wrong.\n", page_no);
-+                              goto convert_err_exit;
-+                      }
-+                      btr_page_set_index_id(page, page_zip, index->id, &mtr);
-+
-+                      /* confirm whether fits to the page size or not */
-+                      if (!page_zip_compress(page_zip, page, index, &mtr)
-+                          && !btr_page_reorganize(block, index, &mtr)) {
-+                              buf_block_t*    new_block;
-+                              page_t*         new_page;
-+                              page_zip_des_t* new_page_zip;
-+                              rec_t*          split_rec;
-+                              ulint           n_uniq;
-+
-+                              /* split page is needed */
-+                              fprintf(stderr, " %lu", page_no);
-+
-+                              mtr_x_lock(dict_index_get_lock(index), &mtr);
-+
-+                              n_uniq = dict_index_get_n_unique_in_tree(index);
-+
-+                              if(page_get_n_recs(page) < 2) {
-+                                      /* no way to make smaller */
-+                                      fprintf(stderr, "InnoDB: The page %lu cannot be store to the page size.\n", page_no);
-+                                      goto convert_err_exit;
-+                              }
-+
-+                              if (UNIV_UNLIKELY(page_no == dict_index_get_page(index))) {
-+                                      ulint           new_page_no;
-+                                      dtuple_t*       node_ptr;
-+                                      ulint           level;
-+                                      rec_t*          node_ptr_rec;
-+                                      page_cur_t      page_cursor;
-+
-+                                      /* it is root page, need to raise before split */
-+
-+                                      level = btr_page_get_level(page, &mtr);
-+
-+                                      new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, &mtr);
-+                                      new_page = buf_block_get_frame(new_block);
-+                                      new_page_zip = buf_block_get_page_zip(new_block);
-+                                      btr_page_create(new_block, new_page_zip, index, level, &mtr);
-+
-+                                      btr_page_set_next(new_page, new_page_zip, FIL_NULL, &mtr);
-+                                      btr_page_set_prev(new_page, new_page_zip, FIL_NULL, &mtr);
-+
-+                                      page_zip_copy_recs(new_page_zip, new_page,
-+                                                         page_zip, page, index, &mtr);
-+                                      btr_search_move_or_delete_hash_entries(new_block, block, index);
-+
-+                                      rec = page_rec_get_next(page_get_infimum_rec(new_page));
-+                                      new_page_no = buf_block_get_page_no(new_block);
-+
-+                                      node_ptr = dict_index_build_node_ptr(index, rec, new_page_no, heap,
-+                                                                           level);
-+                                      dtuple_set_info_bits(node_ptr,
-+                                                           dtuple_get_info_bits(node_ptr)
-+                                                           | REC_INFO_MIN_REC_FLAG);
-+                                      btr_page_empty(block, page_zip, index, level + 1, &mtr);
-+
-+                                      btr_page_set_next(page, page_zip, FIL_NULL, &mtr);
-+                                      btr_page_set_prev(page, page_zip, FIL_NULL, &mtr);
-+
-+                                      page_cur_set_before_first(block, &page_cursor);
-+
-+                                      node_ptr_rec = page_cur_tuple_insert(&page_cursor, node_ptr,
-+                                                                           index, 0, &mtr);
-+                                      ut_a(node_ptr_rec);
-+
-+                                      if (!btr_page_reorganize(block, index, &mtr)) {
-+                                              fprintf(stderr, "InnoDB: failed to store the page %lu.\n", page_no);
-+                                              goto convert_err_exit;
-+                                      }
-+
-+                                      /* move to the raised page */
-+                                      page_no = new_page_no;
-+                                      block = new_block;
-+                                      page = new_page;
-+                                      page_zip = new_page_zip;
-+
-+                                      fprintf(stderr, "(raise_to:%lu)", page_no);
-+                              }
-+
-+                              split_rec = page_get_middle_rec(page);
-+
-+                              new_block = btr_page_alloc(index, page_no + 1, FSP_UP,
-+                                                         btr_page_get_level(page, &mtr), &mtr);
-+                              new_page = buf_block_get_frame(new_block);
-+                              new_page_zip = buf_block_get_page_zip(new_block);
-+                              btr_page_create(new_block, new_page_zip, index,
-+                                              btr_page_get_level(page, &mtr), &mtr);
-+
-+                              offsets = rec_get_offsets(split_rec, index, offsets, n_uniq, &heap);
-+
-+                              btr_attach_half_pages(index, block,
-+                                                    split_rec, new_block, FSP_UP, &mtr);
-+
-+                              page_zip_copy_recs(new_page_zip, new_page,
-+                                                 page_zip, page, index, &mtr);
-+                              page_delete_rec_list_start(split_rec - page + new_page,
-+                                                         new_block, index, &mtr);
-+                              btr_search_move_or_delete_hash_entries(new_block, block, index);
-+                              page_delete_rec_list_end(split_rec, block, index,
-+                                                       ULINT_UNDEFINED, ULINT_UNDEFINED, &mtr);
-+
-+                              fprintf(stderr, "(new:%lu)", buf_block_get_page_no(new_block));
-+
-+                              /* Are they needed? */
-+                              if (!btr_page_reorganize(block, index, &mtr)) {
-+                                      fprintf(stderr, "InnoDB: failed to store the page %lu.\n", page_no);
-+                                      goto convert_err_exit;
-+                              }
-+                              if (!btr_page_reorganize(new_block, index, &mtr)) {
-+                                      fprintf(stderr, "InnoDB: failed to store the page %lu.\n", buf_block_get_page_no(new_block));
-+                                      goto convert_err_exit;
-+                              }
-+                      }
-+
-+                      page_no = btr_page_get_next(page, &mtr);
-+
-+                      mtr_commit(&mtr);
-+
-+                      if (heap) {
-+                              mem_heap_empty(heap);
-+                      }
-+              }
-+
-+              fprintf(stderr, "...done.\nInnoDB: waiting the flush batch of the additional conversion.\n");
-+
-+              /* should wait for the not-logged changes are all flushed */
-+              buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX, mtr.end_lsn + 1);
-+              buf_flush_wait_batch_end(BUF_FLUSH_LIST);
-+
-+              fprintf(stderr, "InnoDB: done.\n");
-+convert_exit:
-+              if (UNIV_LIKELY_NULL(heap)) {
-+                      mem_heap_free(heap);
-+              }
-+      }
-+
-       return(success);
- }
- #endif /* !UNIV_HOTBACKUP */
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -7102,6 +7102,14 @@
-               err = row_discard_tablespace_for_mysql(dict_table->name, trx);
-       } else {
-               err = row_import_tablespace_for_mysql(dict_table->name, trx);
-+
-+              /* in expanded import mode re-initialize auto_increment again */
-+              if ((err == DB_SUCCESS) && srv_expand_import &&
-+                  (table->found_next_number_field != NULL)) {
-+                      dict_table_autoinc_lock(dict_table);
-+                      innobase_initialize_autoinc();
-+                      dict_table_autoinc_unlock(dict_table);
-+              }
-       }
-       err = convert_error_code_to_mysql(err, dict_table->flags, NULL);
-@@ -11378,6 +11386,11 @@
-   "Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.",
-   NULL, NULL, 0, 0, 1, 0);
-+static MYSQL_SYSVAR_ULONG(expand_import, srv_expand_import,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Enable/Disable converting automatically *.ibd files when import tablespace.",
-+  NULL, NULL, 0, 0, 1, 0);
-+
- static MYSQL_SYSVAR_ULONG(extra_rsegments, srv_extra_rsegments,
-   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-   "Number of extra user rollback segments when create new database.",
-@@ -11455,6 +11468,7 @@
-   MYSQL_SYSVAR(adaptive_checkpoint),
-   MYSQL_SYSVAR(flush_log_at_trx_commit_session),
-   MYSQL_SYSVAR(enable_unsafe_group_commit),
-+  MYSQL_SYSVAR(expand_import),
-   MYSQL_SYSVAR(extra_rsegments),
-   MYSQL_SYSVAR(dict_size_limit),
-   MYSQL_SYSVAR(use_sys_malloc),
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -32,6 +32,7 @@
- {"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
- {"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
-+{"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
---- a/storage/innodb_plugin/include/btr0btr.h
-+++ b/storage/innodb_plugin/include/btr0btr.h
-@@ -208,6 +208,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))
-+/**************************************************************//**
-+Sets the index id field of a page. */
-+UNIV_INLINE
-+void
-+btr_page_set_index_id(
-+/*==================*/
-+      page_t*         page,   /*!< in: page to be created */
-+      page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
-+                              part will be updated, or NULL */
-+      dulint          id,     /*!< in: index id */
-+      mtr_t*          mtr);   /*!< in: mtr */
- #endif /* !UNIV_HOTBACKUP */
- /**************************************************************//**
- Gets the index id field of a page.
-@@ -245,6 +256,17 @@
-       const page_t*   page,   /*!< in: index page */
-       mtr_t*          mtr);   /*!< in: mini-transaction handle */
- /********************************************************//**
-+Sets the next index page field. */
-+UNIV_INLINE
-+void
-+btr_page_set_next(
-+/*==============*/
-+      page_t*         page,   /*!< in: index page */
-+      page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
-+                              part will be updated, or NULL */
-+      ulint           next,   /*!< in: next page number */
-+      mtr_t*          mtr);   /*!< in: mini-transaction handle */
-+/********************************************************//**
- Gets the previous index page number.
- @return       prev page number */
- UNIV_INLINE
-@@ -253,6 +275,17 @@
- /*==============*/
-       const page_t*   page,   /*!< in: index page */
-       mtr_t*          mtr);   /*!< in: mini-transaction handle */
-+/********************************************************//**
-+Sets the previous index page field. */
-+UNIV_INLINE
-+void
-+btr_page_set_prev(
-+/*==============*/
-+      page_t*         page,   /*!< in: index page */
-+      page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
-+                              part will be updated, or NULL */
-+      ulint           prev,   /*!< in: previous page number */
-+      mtr_t*          mtr);   /*!< in: mini-transaction handle */
- /*************************************************************//**
- 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.
-@@ -298,6 +331,18 @@
- /*===========================*/
-       const rec_t*    rec,    /*!< in: node pointer record */
-       const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
-+/**************************************************************//**
-+Creates a new index page (not the root, and also not
-+used in page reorganization).  @see btr_page_empty(). */
-+UNIV_INTERN
-+void
-+btr_page_create(
-+/*============*/
-+      buf_block_t*    block,  /*!< in/out: page to be created */
-+      page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
-+      dict_index_t*   index,  /*!< in: index */
-+      ulint           level,  /*!< in: the B-tree level of the page */
-+      mtr_t*          mtr);   /*!< in: mtr */
- /************************************************************//**
- Creates the root node for a new index tree.
- @return       page number of the created root, FIL_NULL if did not succeed */
-@@ -368,6 +413,17 @@
-       dict_index_t*   index,  /*!< in: record descriptor */
-       mtr_t*          mtr);   /*!< in: mtr */
- /*************************************************************//**
-+Empties an index page.  @see btr_page_create(). */
-+UNIV_INTERN
-+void
-+btr_page_empty(
-+/*===========*/
-+      buf_block_t*    block,  /*!< in: page to be emptied */
-+      page_zip_des_t* page_zip,/*!< out: compressed page, or NULL */
-+      dict_index_t*   index,  /*!< in: index of the page */
-+      ulint           level,  /*!< in: the B-tree level of the page */
-+      mtr_t*          mtr);   /*!< in: mtr */
-+/*************************************************************//**
- Decides if the page should be split at the convergence point of
- inserts converging to left.
- @return       TRUE if split recommended */
-@@ -426,6 +482,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 */
-+/**************************************************************//**
-+Attaches the halves of an index page on the appropriate level in an
-+index tree. */
-+UNIV_INTERN
-+void
-+btr_attach_half_pages(
-+/*==================*/
-+      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
-+                                      half page */
-+      buf_block_t*    new_block,      /*!< in/out: the new half page */
-+      ulint           direction,      /*!< in: FSP_UP or FSP_DOWN */
-+      mtr_t*          mtr);           /*!< in: mtr */
- /****************************************************************//**
- Sets a record as the predefined minimum record. */
- UNIV_INTERN
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -219,6 +219,8 @@
- extern ulint  srv_read_ahead;
- extern ulint  srv_adaptive_checkpoint;
-+extern ulint  srv_expand_import;
-+
- extern ulint  srv_extra_rsegments;
- extern ulint  srv_dict_size_limit;
- /*-------------------------------------------*/
---- a/storage/innodb_plugin/row/row0mysql.c
-+++ b/storage/innodb_plugin/row/row0mysql.c
-@@ -2520,6 +2520,11 @@
-       current_lsn = log_get_lsn();
-+      /* Enlarge the fatal lock wait timeout during import. */
-+      mutex_enter(&kernel_mutex);
-+      srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
-+      mutex_exit(&kernel_mutex);
-+
-       /* 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
-@@ -2631,6 +2636,11 @@
-       trx->op_info = "";
-+      /* Restore the fatal semaphore wait timeout */
-+      mutex_enter(&kernel_mutex);
-+      srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
-+      mutex_exit(&kernel_mutex);
-+
-       return((int) err);
- }
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -392,6 +392,8 @@
- UNIV_INTERN ulint     srv_read_ahead = 3; /* 1: random  2: linear  3: Both */
- UNIV_INTERN ulint     srv_adaptive_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
-+UNIV_INTERN ulint     srv_expand_import = 0; /* 0:disable 1:enable */
-+
- UNIV_INTERN ulint     srv_extra_rsegments = 0; /* extra rseg for users */
- UNIV_INTERN ulint     srv_dict_size_limit = 0;
- /*-------------------------------------------*/
diff --git a/mysql-innodb_expand_undo_slots.patch b/mysql-innodb_expand_undo_slots.patch
deleted file mode 100644 (file)
index 3483c74..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-# name       : innodb_expand_undo_slots.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -165,6 +165,7 @@
- #endif /* UNIV_LOG_ARCHIVE */
- static my_bool        innobase_use_doublewrite                = TRUE;
- static my_bool        innobase_use_checksums                  = TRUE;
-+static my_bool        innobase_extra_undoslots                = FALSE;
- static my_bool        innobase_locks_unsafe_for_binlog        = FALSE;
- static my_bool        innobase_rollback_on_timeout            = FALSE;
- static my_bool        innobase_create_status_file             = FALSE;
-@@ -2124,6 +2125,8 @@
-               goto error;
-       }
-+      srv_extra_undoslots = (ibool) innobase_extra_undoslots;
-+
-       /* -------------- Log files ---------------------------*/
-       /* The default dir for log files is the datadir of MySQL */
-@@ -10771,6 +10774,13 @@
-   "The common part for InnoDB table spaces.",
-   NULL, NULL, NULL);
-+static MYSQL_SYSVAR_BOOL(extra_undoslots, innobase_extra_undoslots,
-+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-+  "Enable to use about 4000 undo slots instead of default 1024. "
-+  "#### Attention: Once you enable this parameter, "
-+  "don't use the datafile for normal mysqld or ibbackup! ####",
-+  NULL, NULL, FALSE);
-+
- static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
-   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-   "Enable InnoDB doublewrite buffer (enabled by default). "
-@@ -11168,6 +11178,7 @@
-   MYSQL_SYSVAR(data_file_path),
-   MYSQL_SYSVAR(data_home_dir),
-   MYSQL_SYSVAR(doublewrite),
-+  MYSQL_SYSVAR(extra_undoslots),
-   MYSQL_SYSVAR(fast_shutdown),
-   MYSQL_SYSVAR(file_io_threads),
-   MYSQL_SYSVAR(read_io_threads),
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -28,5 +28,6 @@
- {"innodb_io","Improvements to InnoDB IO","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_opt_lru_count","Fix of buffer_pool mutex","Decreases contention on buffer_pool mutex on LRU operations","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -112,6 +112,8 @@
- extern ulint* srv_data_file_sizes;
- extern ulint* srv_data_file_is_raw_partition;
-+extern ibool  srv_extra_undoslots;
-+
- extern ibool  srv_auto_extend_last_data_file;
- extern ulint  srv_last_file_size_max;
- extern char** srv_log_group_home_dirs;
---- a/storage/innodb_plugin/include/trx0rseg.h
-+++ b/storage/innodb_plugin/include/trx0rseg.h
-@@ -123,8 +123,11 @@
-       trx_rseg_t*     rseg);          /* in, own: instance to free */
-+/* Real max value may be 4076 in usual. But reserve 4 slot for safety or etc... */
-+#define TRX_RSEG_N_EXTRA_SLOTS        (((UNIV_PAGE_SIZE - (FIL_PAGE_DATA + FIL_PAGE_DATA_END + TRX_RSEG_UNDO_SLOTS)) / TRX_RSEG_SLOT_SIZE) - 4)
-+
- /* Number of undo log slots in a rollback segment file copy */
--#define TRX_RSEG_N_SLOTS      (UNIV_PAGE_SIZE / 16)
-+#define TRX_RSEG_N_SLOTS      (srv_extra_undoslots ? TRX_RSEG_N_EXTRA_SLOTS : (UNIV_PAGE_SIZE / 16))
- /* Maximum number of transactions supported by a single rollback segment */
- #define TRX_RSEG_MAX_N_TRXS   (TRX_RSEG_N_SLOTS / 2)
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -142,6 +142,8 @@
- /* size in database pages */
- UNIV_INTERN ulint*    srv_data_file_sizes = NULL;
-+UNIV_INTERN ibool     srv_extra_undoslots = FALSE;
-+
- /* if TRUE, then we auto-extend the last data file */
- UNIV_INTERN ibool     srv_auto_extend_last_data_file  = FALSE;
- /* if != 0, this tells the max size auto-extending may increase the
---- a/storage/innodb_plugin/trx/trx0undo.c
-+++ b/storage/innodb_plugin/trx/trx0undo.c
-@@ -1396,9 +1396,47 @@
-       rseg_header = trx_rsegf_get_new(rseg->space, rseg->zip_size,
-                                       rseg->page_no, &mtr);
-+      if (!srv_extra_undoslots) {
-+              /* uses direct call for avoid "Assertion failure" */
-+              //page_no = trx_rsegf_get_nth_undo(rseg_header, TRX_RSEG_N_EXTRA_SLOTS - 1, &mtr);
-+              page_no = mtr_read_ulint(rseg_header + TRX_RSEG_UNDO_SLOTS
-+                                       + (TRX_RSEG_N_EXTRA_SLOTS - 1) * TRX_RSEG_SLOT_SIZE,
-+                                       MLOG_4BYTES, &mtr);
-+              if (page_no != 0) {
-+                      /* check extended slots are not used */
-+                      for (i = TRX_RSEG_N_SLOTS; i < TRX_RSEG_N_EXTRA_SLOTS; i++) {
-+                              /* uses direct call for avoid "Assertion failure" */
-+                              page_no = mtr_read_ulint(rseg_header + TRX_RSEG_UNDO_SLOTS
-+                                                       + i * TRX_RSEG_SLOT_SIZE,
-+                                                       MLOG_4BYTES, &mtr);
-+                              if (page_no != 0 && page_no != FIL_NULL) {
-+                                      srv_extra_undoslots = TRUE;
-+                                      fprintf(stderr,
-+"InnoDB: Error: innodb_extra_undoslots option is disabled, but it was enabled before.\n"
-+"InnoDB: The datafile is not normal for mysqld and disabled innodb_extra_undoslots.\n"
-+"InnoDB: Enable innodb_extra_undoslots if it was enabled before, and\n"
-+"InnoDB: ### don't use this datafile with other mysqld or ibbackup! ###\n"
-+"InnoDB: Cannot continue operation for the safety. Calling exit(1).\n");
-+                                      exit(1);
-+                              }
-+                      }
-+                      fprintf(stderr,
-+"InnoDB: Warning: innodb_extra_undoslots option is disabled, but it was  enabled before.\n"
-+"InnoDB: But extended undo slots seem not used, so continue operation.\n");
-+              }
-+      }
-+
-       for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
-               page_no = trx_rsegf_get_nth_undo(rseg_header, i, &mtr);
-+              /* If it was not initialized when the datafile created,
-+              page_no will be 0 for the extended slots after that */
-+
-+              if (page_no == 0) {
-+                      page_no = FIL_NULL;
-+                      trx_rsegf_set_nth_undo(rseg_header, i, page_no, &mtr);
-+              }
-+
-               /* In forced recovery: try to avoid operations which look
-               at database pages; undo logs are rapidly changing data, and
-               the probability that they are in an inconsistent state is
diff --git a/mysql-innodb_extend_slow.patch b/mysql-innodb_extend_slow.patch
deleted file mode 100644 (file)
index 903d977..0000000
+++ /dev/null
@@ -1,976 +0,0 @@
-# name       : innodb_extend_slow.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -51,6 +51,40 @@
- #include "dict0dict.h"
- #include "log0recv.h"
- #include "page0zip.h"
-+#include "trx0trx.h"
-+
-+/* prototypes for new functions added to ha_innodb.cc */
-+trx_t* innobase_get_trx();
-+
-+inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
-+{
-+      ulint           block_hash;
-+      ulint           block_hash_byte;
-+      byte            block_hash_offset;
-+
-+      ut_ad(block);
-+
-+      if (!innobase_get_slow_log() || !trx || !trx->take_stats)
-+              return;
-+
-+      if (!trx->distinct_page_access_hash) {
-+              trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
-+              memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
-+      }
-+
-+      block_hash = ut_hash_ulint((block->page.space << 20) + block->page.space +
-+                                      block->page.offset, DPAH_SIZE << 3);
-+      block_hash_byte = block_hash >> 3;
-+      block_hash_offset = (byte) block_hash & 0x07;
-+      if (block_hash_byte >= DPAH_SIZE)
-+              fprintf(stderr, "!!! block_hash_byte = %lu  block_hash_offset = %d !!!\n", block_hash_byte, block_hash_offset);
-+      if (block_hash_offset > 7)
-+              fprintf(stderr, "!!! block_hash_byte = %lu  block_hash_offset = %d !!!\n", block_hash_byte, block_hash_offset);
-+      if ((trx->distinct_page_access_hash[block_hash_byte] & ((byte) 0x01 << block_hash_offset)) == 0)
-+              trx->distinct_page_access++;
-+      trx->distinct_page_access_hash[block_hash_byte] |= (byte) 0x01 << block_hash_offset;
-+      return;
-+}
- /*
-               IMPLEMENTATION OF THE BUFFER POOL
-@@ -1343,10 +1377,18 @@
-       mutex_t*        block_mutex;
-       ibool           must_read;
-       unsigned        access_time;
-+      trx_t*          trx = NULL;
-+      ulint           sec;
-+      ulint           ms;
-+      ib_uint64_t     start_time;
-+      ib_uint64_t     finish_time;
- #ifndef UNIV_LOG_DEBUG
-       ut_ad(!ibuf_inside());
- #endif
-+      if (innobase_get_slow_log()) {
-+              trx = innobase_get_trx();
-+      }
-       buf_pool->stat.n_page_gets++;
-       for (;;) {
-@@ -1363,7 +1405,7 @@
-               //buf_pool_mutex_exit();
-               rw_lock_s_unlock(&page_hash_latch);
--              buf_read_page(space, zip_size, offset);
-+              buf_read_page(space, zip_size, offset, trx);
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-               ut_a(++buf_dbg_counter % 37 || buf_validate());
-@@ -1457,6 +1499,13 @@
-               /* Let us wait until the read operation
-               completes */
-+              if (innobase_get_slow_log() && trx && trx->take_stats)
-+              {
-+                      ut_usectime(&sec, &ms);
-+                      start_time = (ib_uint64_t)sec * 1000000 + ms;
-+              } else {
-+                      start_time = 0;
-+              }
-               for (;;) {
-                       enum buf_io_fix io_fix;
-@@ -1471,6 +1520,12 @@
-                               break;
-                       }
-               }
-+              if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
-+              {
-+                      ut_usectime(&sec, &ms);
-+                      finish_time = (ib_uint64_t)sec * 1000000 + ms;
-+                      trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
-+              }
-       }
- #ifdef UNIV_IBUF_COUNT_DEBUG
-@@ -1730,6 +1785,11 @@
-       ibool           must_read;
-       ulint           retries = 0;
-       mutex_t*        block_mutex = NULL;
-+      trx_t*          trx = NULL;
-+      ulint           sec;
-+      ulint           ms;
-+      ib_uint64_t     start_time;
-+      ib_uint64_t     finish_time;
-       ut_ad(mtr);
-       ut_ad(mtr->state == MTR_ACTIVE);
-@@ -1754,6 +1814,9 @@
- #ifndef UNIV_LOG_DEBUG
-       ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
- #endif
-+      if (innobase_get_slow_log()) {
-+              trx = innobase_get_trx();
-+      }
-       buf_pool->stat.n_page_gets++;
- loop:
-       block = guess;
-@@ -1803,7 +1866,7 @@
-                       return(NULL);
-               }
--              if (buf_read_page(space, zip_size, offset)) {
-+              if (buf_read_page(space, zip_size, offset, trx)) {
-                       retries = 0;
-               } else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
-                       ++retries;
-@@ -2092,6 +2155,13 @@
-                       /* Let us wait until the read operation
-                       completes */
-+                      if (innobase_get_slow_log() && trx && trx->take_stats)
-+                      {
-+                              ut_usectime(&sec, &ms);
-+                              start_time = (ib_uint64_t)sec * 1000000 + ms;
-+                      } else {
-+                              start_time = 0;
-+                      }
-                       for (;;) {
-                               enum buf_io_fix io_fix;
-@@ -2106,6 +2176,12 @@
-                                       break;
-                               }
-                       }
-+                      if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
-+                      {
-+                              ut_usectime(&sec, &ms);
-+                              finish_time = (ib_uint64_t)sec * 1000000 + ms;
-+                              trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
-+                      }
-               }
-               fix_type = MTR_MEMO_BUF_FIX;
-@@ -2131,13 +2207,17 @@
-               /* In the case of a first access, try to apply linear
-               read-ahead */
--              buf_read_ahead_linear(space, zip_size, offset);
-+              buf_read_ahead_linear(space, zip_size, offset, trx);
-       }
- #ifdef UNIV_IBUF_COUNT_DEBUG
-       ut_a(ibuf_count_get(buf_block_get_space(block),
-                           buf_block_get_page_no(block)) == 0);
- #endif
-+      if (innobase_get_slow_log()) {
-+              _increment_page_get_statistics(block, trx);
-+      }
-+
-       return(block);
- }
-@@ -2160,6 +2240,7 @@
-       unsigned        access_time;
-       ibool           success;
-       ulint           fix_type;
-+      trx_t*          trx = NULL;
-       ut_ad(block);
-       ut_ad(mtr);
-@@ -2237,13 +2318,17 @@
- #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
-       ut_a(block->page.file_page_was_freed == FALSE);
- #endif
-+      if (innobase_get_slow_log()) {
-+              trx = innobase_get_trx();
-+      }
-+
-       if (UNIV_UNLIKELY(!access_time)) {
-               /* In the case of a first access, try to apply linear
-               read-ahead */
-               buf_read_ahead_linear(buf_block_get_space(block),
-                                     buf_block_get_zip_size(block),
--                                    buf_block_get_page_no(block));
-+                                    buf_block_get_page_no(block), trx);
-       }
- #ifdef UNIV_IBUF_COUNT_DEBUG
-@@ -2252,6 +2337,9 @@
- #endif
-       buf_pool->stat.n_page_gets++;
-+      if (innobase_get_slow_log()) {
-+              _increment_page_get_statistics(block, trx);
-+      }
-       return(TRUE);
- }
-@@ -2273,6 +2361,7 @@
- {
-       ibool           success;
-       ulint           fix_type;
-+      trx_t*          trx = NULL;
-       ut_ad(mtr);
-       ut_ad(mtr->state == MTR_ACTIVE);
-@@ -2357,6 +2446,11 @@
- #endif
-       buf_pool->stat.n_page_gets++;
-+      if (innobase_get_slow_log()) {
-+              trx = innobase_get_trx();
-+              _increment_page_get_statistics(block, trx);
-+      }
-+
-       return(TRUE);
- }
---- a/storage/innodb_plugin/buf/buf0rea.c
-+++ b/storage/innodb_plugin/buf/buf0rea.c
-@@ -83,7 +83,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 */
--      ulint   offset) /*!< in: page number */
-+      ulint   offset, /*!< in: page number */
-+      trx_t*  trx)
- {
-       buf_page_t*     bpage;
-       ulint           wake_later;
-@@ -184,15 +185,15 @@
-       ut_ad(buf_page_in_file(bpage));
-       if (zip_size) {
--              *err = fil_io(OS_FILE_READ | wake_later,
-+              *err = _fil_io(OS_FILE_READ | wake_later,
-                             sync, space, zip_size, offset, 0, zip_size,
--                            bpage->zip.data, bpage);
-+                            bpage->zip.data, bpage, trx);
-       } else {
-               ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
--              *err = fil_io(OS_FILE_READ | wake_later,
-+              *err = _fil_io(OS_FILE_READ | wake_later,
-                             sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
--                            ((buf_block_t*) bpage)->frame, bpage);
-+                            ((buf_block_t*) bpage)->frame, bpage, trx);
-       }
-       ut_a(*err == DB_SUCCESS);
-@@ -224,8 +225,9 @@
- /*==================*/
-       ulint   space,  /*!< in: space id */
-       ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
--      ulint   offset) /*!< in: page number of a page which the current thread
-+      ulint   offset, /*!< in: page number of a page which the current thread
-                       wants to access */
-+      trx_t*  trx)
- {
-       ib_int64_t      tablespace_version;
-       ulint           recent_blocks   = 0;
-@@ -332,7 +334,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,
-@@ -382,13 +384,14 @@
- /*==========*/
-       ulint   space,  /*!< in: space id */
-       ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
--      ulint   offset) /*!< in: page number */
-+      ulint   offset, /*!< in: page number */
-+      trx_t*  trx)
- {
-       ib_int64_t      tablespace_version;
-       ulint           count;
-       ulint           err;
--      count = buf_read_ahead_random(space, zip_size, offset);
-+      count = buf_read_ahead_random(space, zip_size, offset, trx);
-       srv_buf_pool_reads += count;
-       tablespace_version = fil_space_get_version(space);
-@@ -398,7 +401,7 @@
-       count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
-                                 zip_size, FALSE,
--                                tablespace_version, offset);
-+                                tablespace_version, offset, trx);
-       srv_buf_pool_reads += count;
-       if (err == DB_TABLESPACE_DELETED) {
-               ut_print_timestamp(stderr);
-@@ -449,8 +452,9 @@
- /*==================*/
-       ulint   space,  /*!< in: space id */
-       ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
--      ulint   offset) /*!< in: page number of a page; NOTE: the current thread
-+      ulint   offset, /*!< in: page number of a page; NOTE: the current thread
-                       must want access to this page (see NOTE 3 above) */
-+      trx_t*  trx)
- {
-       ib_int64_t      tablespace_version;
-       buf_page_t*     bpage;
-@@ -673,7 +677,7 @@
-                       count += buf_read_page_low(
-                               &err, FALSE,
-                               ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
--                              space, zip_size, FALSE, tablespace_version, i);
-+                              space, zip_size, FALSE, tablespace_version, i, trx);
-                       if (err == DB_TABLESPACE_DELETED) {
-                               ut_print_timestamp(stderr);
-                               fprintf(stderr,
-@@ -763,7 +767,7 @@
-               buf_read_page_low(&err, sync && (i + 1 == n_stored),
-                                 BUF_READ_ANY_PAGE, space_ids[i],
-                                 zip_size, TRUE, space_versions[i],
--                                page_nos[i]);
-+                                page_nos[i], NULL);
-               if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) {
- tablespace_deleted:
-@@ -904,12 +908,12 @@
-               if ((i + 1 == n_stored) && sync) {
-                       buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
-                                         zip_size, TRUE, tablespace_version,
--                                        page_nos[i]);
-+                                        page_nos[i], NULL);
-               } else {
-                       buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
-                                         | OS_AIO_SIMULATED_WAKE_LATER,
-                                         space, zip_size, TRUE,
--                                        tablespace_version, page_nos[i]);
-+                                        tablespace_version, page_nos[i], NULL);
-               }
-       }
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -4697,7 +4697,7 @@
-                                node->name, node->handle, buf,
-                                offset_low, offset_high,
-                                page_size * n_pages,
--                               NULL, NULL);
-+                               NULL, NULL, NULL);
- #endif
-               if (success) {
-                       node->size += n_pages;
-@@ -5024,7 +5024,7 @@
- i/o on a tablespace which does not exist */
- UNIV_INTERN
- ulint
--fil_io(
-+_fil_io(
- /*===*/
-       ulint   type,           /*!< in: OS_FILE_READ or OS_FILE_WRITE,
-                               ORed to OS_FILE_LOG, if a log i/o
-@@ -5049,8 +5049,9 @@
-       void*   buf,            /*!< in/out: buffer where to store read data
-                               or from where to write; in aio this must be
-                               appropriately aligned */
--      void*   message)        /*!< in: message for aio handler if non-sync
-+      void*   message,        /*!< in: message for aio handler if non-sync
-                               aio used, else ignored */
-+      trx_t*  trx)
- {
-       ulint           mode;
-       fil_space_t*    space;
-@@ -5220,7 +5221,7 @@
- #else
-       /* Queue the aio request */
-       ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
--                   offset_low, offset_high, len, node, message);
-+                   offset_low, offset_high, len, node, message, trx);
- #endif
-       ut_a(ret);
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -1392,6 +1392,16 @@
-       trx->check_unique_secondary = !thd_test_options(
-               thd, OPTION_RELAXED_UNIQUE_CHECKS);
-+#ifdef EXTENDED_SLOWLOG
-+      if (thd_log_slow_verbosity(thd) & SLOG_V_INNODB) {
-+              trx->take_stats = TRUE;
-+      } else {
-+              trx->take_stats = FALSE;
-+      }
-+#else
-+      trx->take_stats = FALSE;
-+#endif
-+
-       DBUG_VOID_RETURN;
- }
-@@ -1447,6 +1457,32 @@
- }
-+/*************************************************************************
-+Gets current trx. */
-+extern "C"
-+trx_t*
-+innobase_get_trx()
-+{
-+      THD *thd=current_thd;
-+      if (likely(thd != 0)) {
-+              trx_t*& trx = thd_to_trx(thd);
-+              return(trx);
-+      } else {
-+              return(NULL);
-+      }
-+}
-+
-+extern "C"
-+ibool
-+innobase_get_slow_log()
-+{
-+#ifdef EXTENDED_SLOWLOG
-+      return((ibool) thd_opt_slow_log());
-+#else
-+      return(FALSE);
-+#endif
-+}
-+
- /*********************************************************************//**
- Construct ha_innobase handler. */
- UNIV_INTERN
-@@ -8965,6 +9001,25 @@
-       statement has ended */
-       if (trx->n_mysql_tables_in_use == 0) {
-+#ifdef EXTENDED_SLOWLOG
-+              increment_thd_innodb_stats(thd,
-+                                      (unsigned long long) ut_conv_dulint_to_longlong(trx->id),
-+                                      trx->io_reads,
-+                                      trx->io_read,
-+                                      trx->io_reads_wait_timer,
-+                                      trx->lock_que_wait_timer,
-+                                      trx->innodb_que_wait_timer,
-+                                      trx->distinct_page_access);
-+
-+              trx->io_reads = 0;
-+              trx->io_read = 0;
-+              trx->io_reads_wait_timer = 0;
-+              trx->lock_que_wait_timer = 0;
-+              trx->innodb_que_wait_timer = 0;
-+              trx->distinct_page_access = 0;
-+              if (trx->distinct_page_access_hash)
-+                      memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
-+#endif
-               trx->mysql_n_tables_locked = 0;
-               prebuilt->used_in_HANDLER = FALSE;
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -39,5 +39,6 @@
- {"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/buf0rea.h
-+++ b/storage/innodb_plugin/include/buf0rea.h
-@@ -27,6 +27,7 @@
- #define buf0rea_h
- #include "univ.i"
-+#include "trx0types.h"
- #include "buf0types.h"
- /********************************************************************//**
-@@ -41,7 +42,8 @@
- /*==========*/
-       ulint   space,  /*!< in: space id */
-       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 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.
-@@ -72,8 +74,9 @@
- /*==================*/
-       ulint   space,  /*!< in: space id */
-       ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
--      ulint   offset);/*!< in: page number of a page; NOTE: the current thread
-+      ulint   offset, /*!< in: page number of a page; NOTE: the current thread
-                       must want access to this page (see NOTE 3 above) */
-+      trx_t*  trx);
- /********************************************************************//**
- Issues read requests for pages which the ibuf module wants to read in, in
- order to contract the insert buffer tree. Technically, this function is like
---- a/storage/innodb_plugin/include/fil0fil.h
-+++ b/storage/innodb_plugin/include/fil0fil.h
-@@ -610,9 +610,12 @@
- Reads or writes data. This operation is asynchronous (aio).
- @return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
- i/o on a tablespace which does not exist */
-+#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message) \
-+      _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, NULL)
-+
- UNIV_INTERN
- ulint
--fil_io(
-+_fil_io(
- /*===*/
-       ulint   type,           /*!< in: OS_FILE_READ or OS_FILE_WRITE,
-                               ORed to OS_FILE_LOG, if a log i/o
-@@ -637,8 +640,9 @@
-       void*   buf,            /*!< in/out: buffer where to store read data
-                               or from where to write; in aio this must be
-                               appropriately aligned */
--      void*   message);       /*!< in: message for aio handler if non-sync
-+      void*   message,        /*!< in: message for aio handler if non-sync
-                               aio used, else ignored */
-+      trx_t*  trx);
- /**********************************************************************//**
- Waits for an aio operation to complete. This function is used to write the
- handler for completed requests. The aio array of pending requests is divided
---- a/storage/innodb_plugin/include/os0file.h
-+++ b/storage/innodb_plugin/include/os0file.h
-@@ -36,6 +36,7 @@
- #define os0file_h
- #include "univ.i"
-+#include "trx0types.h"
- #ifndef __WIN__
- #include <dirent.h>
-@@ -483,9 +484,12 @@
- /*******************************************************************//**
- Requests a synchronous read operation.
- @return       TRUE if request was successful, FALSE if fail */
-+#define os_file_read(file, buf, offset, offset_high, n)         \
-+              _os_file_read(file, buf, offset, offset_high, n, NULL)
-+
- UNIV_INTERN
- ibool
--os_file_read(
-+_os_file_read(
- /*=========*/
-       os_file_t       file,   /*!< in: handle to a file */
-       void*           buf,    /*!< in: buffer where to read */
-@@ -493,7 +497,8 @@
-                               offset where to read */
-       ulint           offset_high,/*!< in: most significant 32 bits of
-                               offset */
--      ulint           n);     /*!< in: number of bytes to read */
-+      ulint           n,      /*!< in: number of bytes to read */
-+      trx_t*          trx);
- /*******************************************************************//**
- Rewind file to its start, read at most size - 1 bytes from it to str, and
- NUL-terminate str. All errors are silently ignored. This function is
-@@ -647,10 +652,11 @@
-                               (can be used to identify a completed
-                               aio operation); ignored if mode is
-                               OS_AIO_SYNC */
--      void*           message2);/*!< in: message for the aio handler
-+      void*           message2,/*!< in: message for the aio handler
-                               (can be used to identify a completed
-                               aio operation); ignored if mode is
-                               OS_AIO_SYNC */
-+      trx_t*          trx);
- /************************************************************************//**
- Wakes up all async i/o threads so that they know to exit themselves in
- shutdown. */
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -62,6 +62,9 @@
- #define SRV_AUTO_EXTEND_INCREMENT     \
-       (srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
-+/* prototypes for new functions added to ha_innodb.cc */
-+ibool innobase_get_slow_log();
-+
- /* This is set to TRUE if the MySQL user has set it in MySQL */
- extern ibool  srv_lower_case_table_names;
---- a/storage/innodb_plugin/include/trx0trx.h
-+++ b/storage/innodb_plugin/include/trx0trx.h
-@@ -749,6 +749,17 @@
-       /*------------------------------*/
-       char detailed_error[256];       /*!< detailed error message for last
-                                       error, or empty. */
-+      /*------------------------------*/
-+      ulint           io_reads;
-+      ib_uint64_t     io_read;
-+      ulint           io_reads_wait_timer;
-+      ib_uint64_t     lock_que_wait_ustarted;
-+      ulint           lock_que_wait_timer;
-+      ulint           innodb_que_wait_timer;
-+      ulint           distinct_page_access;
-+#define       DPAH_SIZE       8192
-+      byte*           distinct_page_access_hash;
-+      ibool           take_stats;
- };
- #define TRX_MAX_N_THREADS     32      /* maximum number of
---- a/storage/innodb_plugin/lock/lock0lock.c
-+++ b/storage/innodb_plugin/lock/lock0lock.c
-@@ -1757,6 +1757,8 @@
- {
-       lock_t* lock;
-       trx_t*  trx;
-+      ulint   sec;
-+      ulint   ms;
-       ut_ad(mutex_own(&kernel_mutex));
-@@ -1815,6 +1817,10 @@
-       trx->que_state = TRX_QUE_LOCK_WAIT;
-       trx->was_chosen_as_deadlock_victim = FALSE;
-       trx->wait_started = time(NULL);
-+      if (innobase_get_slow_log() && trx->take_stats) {
-+              ut_usectime(&sec, &ms);
-+              trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
-+      }
-       ut_a(que_thr_stop(thr));
-@@ -3767,6 +3773,8 @@
- {
-       lock_t* lock;
-       trx_t*  trx;
-+      ulint   sec;
-+      ulint   ms;
-       ut_ad(mutex_own(&kernel_mutex));
-@@ -3822,6 +3830,10 @@
-               return(DB_SUCCESS);
-       }
-+      if (innobase_get_slow_log() && trx->take_stats) {
-+              ut_usectime(&sec, &ms);
-+              trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
-+      }
-       trx->que_state = TRX_QUE_LOCK_WAIT;
-       trx->was_chosen_as_deadlock_victim = FALSE;
-       trx->wait_started = time(NULL);
---- a/storage/innodb_plugin/os/os0file.c
-+++ b/storage/innodb_plugin/os/os0file.c
-@@ -38,6 +38,8 @@
- #include "srv0start.h"
- #include "fil0fil.h"
- #include "buf0buf.h"
-+#include "trx0sys.h"
-+#include "trx0trx.h"
- #include "log0recv.h"
- #ifndef UNIV_HOTBACKUP
- # include "os0sync.h"
-@@ -2098,22 +2100,30 @@
- /*******************************************************************//**
- Does a synchronous read operation in Posix.
- @return       number of bytes read, -1 if error */
-+#define os_file_pread(file, buf, n, offset, offset_high)        \
-+              _os_file_pread(file, buf, n, offset, offset_high, NULL);
-+
- static
- ssize_t
--os_file_pread(
-+_os_file_pread(
- /*==========*/
-       os_file_t       file,   /*!< in: handle to a file */
-       void*           buf,    /*!< in: buffer where to read */
-       ulint           n,      /*!< in: number of bytes to read */
-       ulint           offset, /*!< in: least significant 32 bits of file
-                               offset from where to read */
--      ulint           offset_high) /*!< in: most significant 32 bits of
-+      ulint           offset_high, /*!< in: most significant 32 bits of
-                               offset */
-+      trx_t*          trx)
- {
-       off_t   offs;
- #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
-       ssize_t n_bytes;
- #endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
-+      ulint           sec;
-+      ulint           ms;
-+      ib_uint64_t     start_time;
-+      ib_uint64_t     finish_time;
-       ut_a((offset & 0xFFFFFFFFUL) == offset);
-@@ -2134,6 +2144,15 @@
-       os_n_file_reads++;
-+      if (innobase_get_slow_log() && trx && trx->take_stats)
-+      {
-+              trx->io_reads++;
-+              trx->io_read += n;
-+              ut_usectime(&sec, &ms);
-+              start_time = (ib_uint64_t)sec * 1000000 + ms;
-+      } else {
-+              start_time = 0;
-+      }
- #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
-       os_mutex_enter(os_file_count_mutex);
-       os_file_n_pending_preads++;
-@@ -2147,6 +2166,13 @@
-       os_n_pending_reads--;
-       os_mutex_exit(os_file_count_mutex);
-+      if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
-+      {
-+              ut_usectime(&sec, &ms);
-+              finish_time = (ib_uint64_t)sec * 1000000 + ms;
-+              trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
-+      }
-+
-       return(n_bytes);
- #else
-       {
-@@ -2183,6 +2209,13 @@
-               os_n_pending_reads--;
-               os_mutex_exit(os_file_count_mutex);
-+              if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
-+              {
-+                      ut_usectime(&sec, &ms);
-+                      finish_time = (ib_uint64_t)sec * 1000000 + ms;
-+                      trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
-+              }
-+
-               return(ret);
-       }
- #endif
-@@ -2313,7 +2346,7 @@
- @return       TRUE if request was successful, FALSE if fail */
- UNIV_INTERN
- ibool
--os_file_read(
-+_os_file_read(
- /*=========*/
-       os_file_t       file,   /*!< in: handle to a file */
-       void*           buf,    /*!< in: buffer where to read */
-@@ -2321,7 +2354,8 @@
-                               offset where to read */
-       ulint           offset_high, /*!< in: most significant 32 bits of
-                               offset */
--      ulint           n)      /*!< in: number of bytes to read */
-+      ulint           n,      /*!< in: number of bytes to read */
-+      trx_t*          trx)
- {
- #ifdef __WIN__
-       BOOL            ret;
-@@ -2396,7 +2430,7 @@
-       os_bytes_read_since_printout += n;
- try_again:
--      ret = os_file_pread(file, buf, n, offset, offset_high);
-+      ret = _os_file_pread(file, buf, n, offset, offset_high, trx);
-       if ((ulint)ret == n) {
-@@ -3653,10 +3687,11 @@
-                               (can be used to identify a completed
-                               aio operation); ignored if mode is
-                               OS_AIO_SYNC */
--      void*           message2)/*!< in: message for the aio handler
-+      void*           message2,/*!< in: message for the aio handler
-                               (can be used to identify a completed
-                               aio operation); ignored if mode is
-                               OS_AIO_SYNC */
-+      trx_t*          trx)
- {
-       os_aio_array_t* array;
-       os_aio_slot_t*  slot;
-@@ -3698,8 +3733,8 @@
-               wait in the Windows case. */
-               if (type == OS_FILE_READ) {
--                      return(os_file_read(file, buf, offset,
--                                          offset_high, n));
-+                      return(_os_file_read(file, buf, offset,
-+                                          offset_high, n, trx));
-               }
-               ut_a(type == OS_FILE_WRITE);
-@@ -3732,6 +3767,11 @@
-               ut_error;
-       }
-+      if (trx && type == OS_FILE_READ)
-+      {
-+              trx->io_reads++;
-+              trx->io_read += n;
-+      }
-       slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
-                                        name, buf, offset, offset_high, n);
-       if (type == OS_FILE_READ) {
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -86,6 +86,9 @@
- #include "trx0i_s.h"
- #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
-+/* prototypes for new functions added to ha_innodb.cc */
-+ibool innobase_get_slow_log();
-+
- /* This is set to TRUE if the MySQL user has set it in MySQL; currently
- affects only FOREIGN KEY definition parsing */
- UNIV_INTERN ibool     srv_lower_case_table_names      = FALSE;
-@@ -1158,6 +1161,10 @@
-       ibool                   has_slept = FALSE;
-       srv_conc_slot_t*        slot      = NULL;
-       ulint                   i;
-+      ib_uint64_t             start_time = 0L;
-+      ib_uint64_t             finish_time = 0L;
-+      ulint                   sec;
-+      ulint                   ms;
-       if (trx->mysql_thd != NULL
-           && thd_is_replication_slave_thread(trx->mysql_thd)) {
-@@ -1234,6 +1241,7 @@
-               switches. */
-               if (SRV_THREAD_SLEEP_DELAY > 0) {
-                       os_thread_sleep(SRV_THREAD_SLEEP_DELAY);
-+                      trx->innodb_que_wait_timer += SRV_THREAD_SLEEP_DELAY;
-               }
-               trx->op_info = "";
-@@ -1289,12 +1297,25 @@
-       /* Go to wait for the event; when a thread leaves InnoDB it will
-       release this thread */
-+      if (innobase_get_slow_log() && trx->take_stats) {
-+              ut_usectime(&sec, &ms);
-+              start_time = (ib_uint64_t)sec * 1000000 + ms;
-+      } else {
-+              start_time = 0;
-+      }
-+
-       trx->op_info = "waiting in InnoDB queue";
-       os_event_wait(slot->event);
-       trx->op_info = "";
-+      if (innobase_get_slow_log() && trx->take_stats && start_time) {
-+              ut_usectime(&sec, &ms);
-+              finish_time = (ib_uint64_t)sec * 1000000 + ms;
-+              trx->innodb_que_wait_timer += (ulint)(finish_time - start_time);
-+      }
-+
-       os_fast_mutex_lock(&srv_conc_mutex);
-       srv_conc_n_waiting_threads--;
---- a/storage/innodb_plugin/trx/trx0trx.c
-+++ b/storage/innodb_plugin/trx/trx0trx.c
-@@ -182,6 +182,15 @@
-       trx->global_read_view = NULL;
-       trx->read_view = NULL;
-+      trx->io_reads = 0;
-+      trx->io_read = 0;
-+      trx->io_reads_wait_timer = 0;
-+      trx->lock_que_wait_timer = 0;
-+      trx->innodb_que_wait_timer = 0;
-+      trx->distinct_page_access = 0;
-+      trx->distinct_page_access_hash = NULL;
-+      trx->take_stats = FALSE;
-+
-       /* Set X/Open XA transaction identification to NULL */
-       memset(&trx->xid, 0, sizeof(trx->xid));
-       trx->xid.formatID = -1;
-@@ -219,6 +228,11 @@
-       trx->mysql_process_no = os_proc_get_number();
-+      if (innobase_get_slow_log() && trx->take_stats) {
-+              trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
-+              memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
-+      }
-+
-       return(trx);
- }
-@@ -404,6 +418,12 @@
- /*===============*/
-       trx_t*  trx)    /*!< in, own: trx object */
- {
-+      if (trx->distinct_page_access_hash)
-+      {
-+              mem_free(trx->distinct_page_access_hash);
-+              trx->distinct_page_access_hash= NULL;
-+      }
-+
-       mutex_enter(&kernel_mutex);
-       UT_LIST_REMOVE(mysql_trx_list, trx_sys->mysql_trx_list, trx);
-@@ -425,6 +445,12 @@
- /*====================*/
-       trx_t*  trx)    /*!< in, own: trx object */
- {
-+      if (trx->distinct_page_access_hash)
-+      {
-+              mem_free(trx->distinct_page_access_hash);
-+              trx->distinct_page_access_hash= NULL;
-+      }
-+
-       mutex_enter(&kernel_mutex);
-       trx_free(trx);
-@@ -1157,6 +1183,9 @@
-       trx_t*  trx)    /*!< in: transaction */
- {
-       que_thr_t*      thr;
-+      ulint           sec;
-+      ulint           ms;
-+      ib_uint64_t     now;
-       ut_ad(mutex_own(&kernel_mutex));
-       ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
-@@ -1171,6 +1200,11 @@
-               thr = UT_LIST_GET_FIRST(trx->wait_thrs);
-       }
-+      if (innobase_get_slow_log() && trx->take_stats) {
-+              ut_usectime(&sec, &ms);
-+              now = (ib_uint64_t)sec * 1000000 + ms;
-+              trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
-+      }
-       trx->que_state = TRX_QUE_RUNNING;
- }
-@@ -1184,6 +1218,9 @@
-       trx_t*  trx)    /*!< in: transaction in the TRX_QUE_LOCK_WAIT state */
- {
-       que_thr_t*      thr;
-+      ulint           sec;
-+      ulint           ms;
-+      ib_uint64_t     now;
-       ut_ad(mutex_own(&kernel_mutex));
-       ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
-@@ -1198,6 +1235,11 @@
-               thr = UT_LIST_GET_FIRST(trx->wait_thrs);
-       }
-+      if (innobase_get_slow_log() && trx->take_stats) {
-+              ut_usectime(&sec, &ms);
-+              now = (ib_uint64_t)sec * 1000000 + ms;
-+              trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
-+      }
-       trx->que_state = TRX_QUE_RUNNING;
- }
diff --git a/mysql-innodb_extra_rseg.patch b/mysql-innodb_extra_rseg.patch
deleted file mode 100644 (file)
index 8607b15..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-# name       : innodb_extra_rseg.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -11168,6 +11168,11 @@
-   "Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.",
-   NULL, NULL, 0, 0, 1, 0);
-+static MYSQL_SYSVAR_ULONG(extra_rsegments, srv_extra_rsegments,
-+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-+  "Number of extra user rollback segments when create new database.",
-+  NULL, NULL, 0, 0, 126, 0);
-+
- static struct st_mysql_sys_var* innobase_system_variables[]= {
-   MYSQL_SYSVAR(additional_mem_pool_size),
-   MYSQL_SYSVAR(autoextend_increment),
-@@ -11233,6 +11238,7 @@
-   MYSQL_SYSVAR(adaptive_checkpoint),
-   MYSQL_SYSVAR(flush_log_at_trx_commit_session),
-   MYSQL_SYSVAR(enable_unsafe_group_commit),
-+  MYSQL_SYSVAR(extra_rsegments),
-   MYSQL_SYSVAR(use_sys_malloc),
-   MYSQL_SYSVAR(change_buffering),
- #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
-@@ -11259,6 +11265,7 @@
-   innobase_system_variables, /* system variables */
-   NULL /* reserved */
- },
-+i_s_innodb_rseg,
- i_s_innodb_buffer_pool_pages,
- i_s_innodb_buffer_pool_pages_index,
- i_s_innodb_buffer_pool_pages_blob,
---- a/storage/innodb_plugin/handler/i_s.cc
-+++ b/storage/innodb_plugin/handler/i_s.cc
-@@ -43,6 +43,8 @@
- #include "ha_prototypes.h" /* for innobase_convert_name() */
- #include "srv0start.h" /* for srv_was_started */
- #include "btr0btr.h" /* for btr_page_get_index_id */
-+#include "trx0rseg.h" /* for trx_rseg_struct */
-+#include "trx0sys.h" /* for trx_sys */
- }
- static const char plugin_author[] = "Innobase Oy";
-@@ -2435,3 +2437,166 @@
-       DBUG_RETURN(0);
- }
-+
-+/***********************************************************************
-+*/
-+static ST_FIELD_INFO  i_s_innodb_rseg_fields_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "rseg_id"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "space_id"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "zip_size"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "page_no"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "max_size"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "curr_size"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      END_OF_ST_FIELD_INFO
-+};
-+
-+static
-+int
-+i_s_innodb_rseg_fill(
-+/*=================*/
-+      THD*            thd,    /* in: thread */
-+      TABLE_LIST*     tables, /* in/out: tables to fill */
-+      COND*           cond)   /* in: condition (ignored) */
-+{
-+      TABLE*  table   = (TABLE *) tables->table;
-+      int     status  = 0;
-+      trx_rseg_t*     rseg;
-+
-+      DBUG_ENTER("i_s_innodb_rseg_fill");
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+
-+              DBUG_RETURN(0);
-+      }
-+
-+      RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
-+
-+      rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
-+
-+      while (rseg) {
-+              table->field[0]->store(rseg->id);
-+              table->field[1]->store(rseg->space);
-+              table->field[2]->store(rseg->zip_size);
-+              table->field[3]->store(rseg->page_no);
-+              table->field[4]->store(rseg->max_size);
-+              table->field[5]->store(rseg->curr_size);
-+
-+              if (schema_table_store_record(thd, table)) {
-+                      status = 1;
-+                      break;
-+              }
-+
-+              rseg = UT_LIST_GET_NEXT(rseg_list, rseg);
-+      }
-+
-+      DBUG_RETURN(status);
-+}
-+
-+static
-+int
-+i_s_innodb_rseg_init(
-+/*=================*/
-+                      /* out: 0 on success */
-+      void*   p)      /* in/out: table schema object */
-+{
-+      DBUG_ENTER("i_s_innodb_rseg_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_rseg_fields_info;
-+      schema->fill_table = i_s_innodb_rseg_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+UNIV_INTERN struct st_mysql_plugin    i_s_innodb_rseg =
-+{
-+      /* the plugin type (a MYSQL_XXX_PLUGIN value) */
-+      /* int */
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+
-+      /* pointer to type-specific plugin descriptor */
-+      /* void* */
-+      STRUCT_FLD(info, &i_s_info),
-+
-+      /* plugin name */
-+      /* const char* */
-+      STRUCT_FLD(name, "INNODB_RSEG"),
-+
-+      /* plugin author (for SHOW PLUGINS) */
-+      /* const char* */
-+      STRUCT_FLD(author, "Percona"),
-+
-+      /* general descriptive text (for SHOW PLUGINS) */
-+      /* const char* */
-+      STRUCT_FLD(descr, "InnoDB rollback segment information"),
-+
-+      /* the plugin license (PLUGIN_LICENSE_XXX) */
-+      /* int */
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+
-+      /* the function to invoke when plugin is loaded */
-+      /* int (*)(void*); */
-+      STRUCT_FLD(init, i_s_innodb_rseg_init),
-+
-+      /* the function to invoke when plugin is unloaded */
-+      /* int (*)(void*); */
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+
-+      /* plugin version (for SHOW PLUGINS) */
-+      /* unsigned int */
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+
-+      /* struct st_mysql_show_var* */
-+      STRUCT_FLD(status_vars, NULL),
-+
-+      /* struct st_mysql_sys_var** */
-+      STRUCT_FLD(system_vars, NULL),
-+
-+      /* reserved for dependency checking */
-+      /* void* */
-+      STRUCT_FLD(__reserved1, NULL)
-+};
---- a/storage/innodb_plugin/handler/i_s.h
-+++ b/storage/innodb_plugin/handler/i_s.h
-@@ -37,5 +37,6 @@
- extern struct st_mysql_plugin i_s_innodb_cmpmem;
- extern struct st_mysql_plugin i_s_innodb_cmpmem_reset;
- extern struct st_mysql_plugin i_s_innodb_patches;
-+extern struct st_mysql_plugin i_s_innodb_rseg;
- #endif /* i_s_h */
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -29,5 +29,6 @@
- {"innodb_opt_lru_count","Fix of buffer_pool mutex","Decreases contention on buffer_pool mutex on LRU operations","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -217,6 +217,8 @@
- extern ulint  srv_read_ahead;
- extern ulint  srv_adaptive_checkpoint;
-+extern ulint  srv_extra_rsegments;
-+
- /*-------------------------------------------*/
- extern ulint  srv_n_rows_inserted;
---- a/storage/innodb_plugin/include/trx0rseg.h
-+++ b/storage/innodb_plugin/include/trx0rseg.h
-@@ -114,6 +114,17 @@
- /*=========================*/
-       trx_sysf_t*     sys_header,     /*!< in: trx system header */
-       mtr_t*          mtr);           /*!< in: mtr */
-+/****************************************************************//**
-+Creates a new rollback segment to the database.
-+@return       the created segment object, NULL if fail */
-+UNIV_INTERN
-+trx_rseg_t*
-+trx_rseg_create(
-+/*============*/
-+      ulint   space,          /*!< in: space id */
-+      ulint   max_size,       /*!< in: max size in pages */
-+      ulint*  id,             /*!< out: rseg id */
-+      mtr_t*  mtr);           /*!< in: mtr */
- /***************************************************************************
- Free's an instance of the rollback segment in memory. */
- UNIV_INTERN
---- a/storage/innodb_plugin/include/trx0sys.h
-+++ b/storage/innodb_plugin/include/trx0sys.h
-@@ -134,6 +134,13 @@
- void
- trx_sys_create(void);
- /*================*/
-+/*********************************************************************
-+Create extra rollback segments when create_new_db */
-+UNIV_INTERN
-+void
-+trx_sys_create_extra_rseg(
-+/*======================*/
-+      ulint   num);   /* in: number of extra user rollback segments */
- /****************************************************************//**
- Looks for a free slot for a rollback segment in the trx system file copy.
- @return       slot index or ULINT_UNDEFINED if not found */
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -390,6 +390,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_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
-+
-+UNIV_INTERN ulint     srv_extra_rsegments = 0; /* extra rseg for users */
- /*-------------------------------------------*/
- UNIV_INTERN ulong     srv_n_spin_wait_rounds  = 30;
- UNIV_INTERN ulong     srv_n_free_tickets_to_enter = 500;
---- a/storage/innodb_plugin/srv/srv0start.c
-+++ b/storage/innodb_plugin/srv/srv0start.c
-@@ -1533,6 +1533,14 @@
-               dict_create();
-               srv_startup_is_before_trx_rollback_phase = FALSE;
-+              if (trx_doublewrite == NULL) {
-+                      /* Create the doublewrite buffer here to avoid assertion error
-+                         about page_no of doublewrite_buf */
-+                      trx_sys_create_doublewrite_buf();
-+              }
-+
-+              if (srv_extra_rsegments)
-+                      trx_sys_create_extra_rseg(srv_extra_rsegments);
- #ifdef UNIV_LOG_ARCHIVE
-       } else if (srv_archive_recovery) {
-               fprintf(stderr,
---- a/storage/innodb_plugin/trx/trx0rseg.c
-+++ b/storage/innodb_plugin/trx/trx0rseg.c
-@@ -286,3 +286,39 @@
-               }
-       }
- }
-+
-+/****************************************************************//**
-+Creates a new rollback segment to the database.
-+@return       the created segment object, NULL if fail */
-+UNIV_INTERN
-+trx_rseg_t*
-+trx_rseg_create(
-+/*============*/
-+      ulint   space,          /*!< in: space id */
-+      ulint   max_size,       /*!< in: max size in pages */
-+      ulint*  id,             /*!< out: rseg id */
-+      mtr_t*  mtr)            /*!< in: mtr */
-+{
-+      ulint           flags;
-+      ulint           zip_size;
-+      ulint           page_no;
-+      trx_rseg_t*     rseg;
-+
-+      mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
-+      zip_size = dict_table_flags_to_zip_size(flags);
-+      mutex_enter(&kernel_mutex);
-+
-+      page_no = trx_rseg_header_create(space, zip_size, max_size, id, mtr);
-+
-+      if (page_no == FIL_NULL) {
-+
-+              mutex_exit(&kernel_mutex);
-+              return(NULL);
-+      }
-+
-+      rseg = trx_rseg_mem_create(*id, space, zip_size, page_no, mtr);
-+
-+      mutex_exit(&kernel_mutex);
-+
-+      return(rseg);
-+}
---- a/storage/innodb_plugin/trx/trx0sys.c
-+++ b/storage/innodb_plugin/trx/trx0sys.c
-@@ -1045,6 +1045,31 @@
-       trx_sys_init_at_db_start();
- }
-+/*********************************************************************
-+Create extra rollback segments when create_new_db */
-+UNIV_INTERN
-+void
-+trx_sys_create_extra_rseg(
-+/*======================*/
-+      ulint   num)    /* in: number of extra user rollback segments */
-+{
-+      mtr_t   mtr;
-+      ulint   slot_no;
-+      ulint   i;
-+
-+      /* Craete extra rollback segments */
-+      mtr_start(&mtr);
-+      for (i = 1; i < num + 1; i++) {
-+              if(!trx_rseg_create(TRX_SYS_SPACE, ULINT_MAX, &slot_no, &mtr)) {
-+                      fprintf(stderr,
-+"InnoDB: Warning: Failed to create extra rollback segments.\n");
-+                      break;
-+              }
-+              ut_a(slot_no == i);
-+      }
-+      mtr_commit(&mtr);
-+}
-+
- /*****************************************************************//**
- Update the file format tag.
- @return       always TRUE */
diff --git a/mysql-innodb_fast_checksum.patch b/mysql-innodb_fast_checksum.patch
deleted file mode 100644 (file)
index 8e29419..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-# name       : innodb_fast_checksum.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -343,6 +343,27 @@
-       return(checksum);
- }
-+UNIV_INTERN
-+ulint
-+buf_calc_page_new_checksum_32(
-+/*==========================*/
-+      const byte*     page)   /*!< in: buffer page */
-+{
-+      ulint checksum;
-+
-+      checksum = ut_fold_binary(page + FIL_PAGE_OFFSET,
-+                                FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
-+              + ut_fold_binary(page + FIL_PAGE_DATA,
-+                               FIL_PAGE_DATA_ALIGN_32 - FIL_PAGE_DATA)
-+              + ut_fold_binary_32(page + FIL_PAGE_DATA_ALIGN_32,
-+                                  UNIV_PAGE_SIZE - FIL_PAGE_DATA_ALIGN_32
-+                                  - FIL_PAGE_END_LSN_OLD_CHKSUM);
-+
-+      checksum = checksum & 0xFFFFFFFFUL;
-+
-+      return(checksum);
-+}
-+
- /********************************************************************//**
- 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
-@@ -457,9 +478,21 @@
-               /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
-               (always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */
--              if (checksum_field != 0
-+              if (!srv_fast_checksum
-+                  && checksum_field != 0
-+                  && checksum_field != BUF_NO_CHECKSUM_MAGIC
-+                  && checksum_field
-+                  != buf_calc_page_new_checksum(read_buf)) {
-+
-+                      return(TRUE);
-+              }
-+
-+              if (srv_fast_checksum
-+                  && checksum_field != 0
-                   && checksum_field != BUF_NO_CHECKSUM_MAGIC
-                   && checksum_field
-+                  != buf_calc_page_new_checksum_32(read_buf)
-+                  && checksum_field
-                   != buf_calc_page_new_checksum(read_buf)) {
-                       return(TRUE);
-@@ -483,6 +516,7 @@
-       dict_index_t*   index;
- #endif /* !UNIV_HOTBACKUP */
-       ulint           checksum;
-+      ulint           checksum_32;
-       ulint           old_checksum;
-       ulint           size    = zip_size;
-@@ -569,12 +603,14 @@
-       checksum = srv_use_checksums
-               ? buf_calc_page_new_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
-+      checksum_32 = srv_use_checksums
-+              ? buf_calc_page_new_checksum_32(read_buf) : BUF_NO_CHECKSUM_MAGIC;
-       old_checksum = srv_use_checksums
-               ? buf_calc_page_old_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
-       ut_print_timestamp(stderr);
-       fprintf(stderr,
--              "  InnoDB: Page checksum %lu, prior-to-4.0.14-form"
-+              "  InnoDB: Page checksum %lu (32bit_calc: %lu), prior-to-4.0.14-form"
-               " checksum %lu\n"
-               "InnoDB: stored checksum %lu, prior-to-4.0.14-form"
-               " stored checksum %lu\n"
-@@ -583,7 +619,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",
--              (ulong) checksum, (ulong) old_checksum,
-+              (ulong) checksum, (ulong) checksum_32, (ulong) old_checksum,
-               (ulong) mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
-               (ulong) mach_read_from_4(read_buf + UNIV_PAGE_SIZE
-                                        - FIL_PAGE_END_LSN_OLD_CHKSUM),
---- a/storage/innodb_plugin/buf/buf0flu.c
-+++ b/storage/innodb_plugin/buf/buf0flu.c
-@@ -959,7 +959,9 @@
-       mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
-                       srv_use_checksums
--                      ? buf_calc_page_new_checksum(page)
-+                      ? (!srv_fast_checksum
-+                         ? buf_calc_page_new_checksum(page)
-+                         : buf_calc_page_new_checksum_32(page))
-                       : BUF_NO_CHECKSUM_MAGIC);
-       /* We overwrite the first 4 bytes of the end lsn field to store
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -3046,13 +3046,24 @@
-               return(TRUE);
-       }
--      if (checksum_field != 0
-+      if (!srv_fast_checksum
-+          && checksum_field != 0
-           && checksum_field != BUF_NO_CHECKSUM_MAGIC
-           && checksum_field
-           != buf_calc_page_new_checksum(page)) {
-               return(TRUE);
-       }
-+      if (srv_fast_checksum
-+          && checksum_field != 0
-+          && checksum_field != BUF_NO_CHECKSUM_MAGIC
-+          && checksum_field
-+          != buf_calc_page_new_checksum_32(page)
-+          && checksum_field
-+          != buf_calc_page_new_checksum(page)) {
-+              return(TRUE);
-+      }
-+
-       return(FALSE);
- }
-@@ -3068,7 +3079,9 @@
-       if (!zip_size) {
-               mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
-                               srv_use_checksums
--                              ? buf_calc_page_new_checksum(page)
-+                              ? (!srv_fast_checksum
-+                                 ? buf_calc_page_new_checksum(page)
-+                                 : buf_calc_page_new_checksum_32(page))
-                                               : BUF_NO_CHECKSUM_MAGIC);
-               mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
-                               srv_use_checksums
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -185,6 +185,7 @@
- #endif /* UNIV_LOG_ARCHIVE */
- static my_bool        innobase_use_doublewrite                = TRUE;
- static my_bool        innobase_use_checksums                  = TRUE;
-+static my_bool        innobase_fast_checksum                  = FALSE;
- static my_bool        innobase_extra_undoslots                = FALSE;
- static my_bool        innobase_fast_recovery                  = FALSE;
- static my_bool        innobase_recovery_stats                 = TRUE;
-@@ -2417,6 +2418,7 @@
-       srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
-       srv_use_checksums = (ibool) innobase_use_checksums;
-+      srv_fast_checksum = (ibool) innobase_fast_checksum;
-       srv_blocking_lru_restore = (ibool) innobase_blocking_lru_restore;
-@@ -11185,6 +11187,15 @@
-   "Disable with --skip-innodb-checksums.",
-   NULL, NULL, TRUE);
-+static MYSQL_SYSVAR_BOOL(fast_checksum, innobase_fast_checksum,
-+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-+  "Change the algorithm of checksum for the whole of datapage to 4-bytes word based. "
-+  "The original checksum is checked after the new one. It may be slow for reading page"
-+  " which has orginal checksum. Overwrite the page or recreate the InnoDB database, "
-+  "if you want the entire benefit for performance at once. "
-+  "#### Attention: The checksum is not compatible for normal or disabled version! ####",
-+  NULL, NULL, FALSE);
-+
- static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
-   PLUGIN_VAR_READONLY,
-   "The common part for InnoDB table spaces.",
-@@ -11676,6 +11687,7 @@
-   MYSQL_SYSVAR(autoextend_increment),
-   MYSQL_SYSVAR(buffer_pool_size),
-   MYSQL_SYSVAR(checksums),
-+  MYSQL_SYSVAR(fast_checksum),
-   MYSQL_SYSVAR(commit_concurrency),
-   MYSQL_SYSVAR(concurrency_tickets),
-   MYSQL_SYSVAR(data_file_path),
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -44,5 +44,6 @@
- {"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_separate_doublewrite","Add option 'innodb_doublewrite_file' to separate doublewrite dedicated tablespace","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/buf0buf.h
-+++ b/storage/innodb_plugin/include/buf0buf.h
-@@ -525,6 +525,11 @@
- buf_calc_page_new_checksum(
- /*=======================*/
-       const byte*     page);  /*!< in: buffer page */
-+UNIV_INTERN
-+ulint
-+buf_calc_page_new_checksum_32(
-+/*==========================*/
-+      const byte*     page);  /*!< in: buffer page */
- /********************************************************************//**
- 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
---- a/storage/innodb_plugin/include/fil0fil.h
-+++ b/storage/innodb_plugin/include/fil0fil.h
-@@ -117,6 +117,7 @@
- #define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID  34 /*!< starting from 4.1.x this
-                                       contains the space id of the page */
- #define FIL_PAGE_DATA         38      /*!< start of the data on the page */
-+#define FIL_PAGE_DATA_ALIGN_32        40
- /* @} */
- /** File page trailer @{ */
- #define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /*!< the low 4 bytes of this are used
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -213,6 +213,7 @@
- extern ibool  srv_use_doublewrite_buf;
- extern ibool  srv_use_checksums;
-+extern ibool  srv_fast_checksum;
- extern ibool  srv_set_thread_priorities;
- extern int    srv_query_thread_priority;
---- a/storage/innodb_plugin/include/ut0rnd.h
-+++ b/storage/innodb_plugin/include/ut0rnd.h
-@@ -124,6 +124,13 @@
-       const byte*     str,    /*!< in: string of bytes */
-       ulint           len)    /*!< in: length */
-       __attribute__((pure));
-+UNIV_INLINE
-+ulint
-+ut_fold_binary_32(
-+/*==============*/
-+      const byte*     str,    /*!< in: string of bytes */
-+      ulint           len)    /*!< in: length */
-+      __attribute__((pure));
- /***********************************************************//**
- Looks for a prime number slightly greater than the given argument.
- The prime is chosen so that it is not near any power of 2.
---- a/storage/innodb_plugin/include/ut0rnd.ic
-+++ b/storage/innodb_plugin/include/ut0rnd.ic
-@@ -226,3 +226,28 @@
-       return(fold);
- }
-+
-+UNIV_INLINE
-+ulint
-+ut_fold_binary_32(
-+/*==============*/
-+      const byte*     str,    /*!< in: string of bytes */
-+      ulint           len)    /*!< in: length */
-+{
-+      const ib_uint32_t*      str_end = (const ib_uint32_t*) (str + len);
-+      const ib_uint32_t*      str_32 = (const ib_uint32_t*) str;
-+      ulint                   fold = 0;
-+
-+      ut_ad(str);
-+      /* This function is only for word-aligned data */
-+      ut_ad(len % 4 == 0);
-+      ut_ad((ulint)str % 4 == 0);
-+
-+      while (str_32 < str_end) {
-+              fold = ut_fold_ulint_pair(fold, (ulint)(*str_32));
-+
-+              str_32++;
-+      }
-+
-+      return(fold);
-+}
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -392,6 +392,7 @@
- UNIV_INTERN ibool     srv_use_doublewrite_buf = TRUE;
- UNIV_INTERN ibool     srv_use_checksums = TRUE;
-+UNIV_INTERN ibool     srv_fast_checksum = FALSE;
- UNIV_INTERN ibool     srv_set_thread_priorities = TRUE;
- UNIV_INTERN int       srv_query_thread_priority = 0;
diff --git a/mysql-innodb_fast_shutdown.patch b/mysql-innodb_fast_shutdown.patch
deleted file mode 100644 (file)
index 6f9cfc8..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-# name       : innodb_fast_shutdown
-# introduced : 13
-# maintainer : Alexey
-#
-# Shutting down XtraDB takes uninterruptible sleep()s up to 10
-# seconds, even when there is no actual work to do during shutdown.
-#
-# This patch removes most such delays during shutdown, as found using
-# PMP. This makes standard test run very close in speed to with
-# --loose-innodb-fast-shutdown=2, and greatly speeds up running the test
-# suite.
-#
-# The patch also implements os_event_wait_time() for POSIX systems.
---- /dev/null
-+++ b/COPYING.innodb_fast_shutdown
-@@ -0,0 +1,10 @@
-+Copyright (c) 2010, Kristian Nielsen
-+All rights reserved.
-+
-+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-+
-+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-+    * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-+
-+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---- a/storage/innodb_plugin/include/os0sync.h
-+++ b/storage/innodb_plugin/include/os0sync.h
-@@ -189,14 +189,14 @@
- /**********************************************************//**
- Waits for an event object until it is in the signaled state or
--a timeout is exceeded. In Unix the timeout is always infinite.
-+a timeout is exceeded.
- @return       0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
- UNIV_INTERN
- ulint
- os_event_wait_time(
- /*===============*/
-       os_event_t      event,  /*!< in: event to wait */
--      ulint           time);  /*!< in: timeout in microseconds, or
-+      ulint           wtime); /*!< in: timeout in microseconds, or
-                               OS_SYNC_INFINITE_TIME */
- #ifdef __WIN__
- /**********************************************************//**
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -57,6 +57,9 @@
- thread starts running */
- extern os_event_t     srv_lock_timeout_thread_event;
-+/* This event is set at shutdown to wakeup threads from sleep */
-+extern os_event_t     srv_shutdown_event;
-+
- /* If the last data file is auto-extended, we add this many pages to it
- at a time */
- #define SRV_AUTO_EXTEND_INCREMENT     \
---- a/storage/innodb_plugin/log/log0log.c
-+++ b/storage/innodb_plugin/log/log0log.c
-@@ -3103,6 +3103,7 @@
-       algorithm only works if the server is idle at shutdown */
-       srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
-+      os_event_set(srv_shutdown_event);
- loop:
-       os_thread_sleep(100000);
---- a/storage/innodb_plugin/os/os0sync.c
-+++ b/storage/innodb_plugin/os/os0sync.c
-@@ -31,6 +31,9 @@
- #ifdef __WIN__
- #include <windows.h>
-+#else
-+#include <sys/time.h>
-+#include <time.h>
- #endif
- #include "ut0mem.h"
-@@ -407,14 +410,14 @@
- /**********************************************************//**
- Waits for an event object until it is in the signaled state or
--a timeout is exceeded. In Unix the timeout is always infinite.
-+a timeout is exceeded.
- @return       0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
- UNIV_INTERN
- ulint
- os_event_wait_time(
- /*===============*/
-       os_event_t      event,  /*!< in: event to wait */
--      ulint           time)   /*!< in: timeout in microseconds, or
-+      ulint           wtime)  /*!< in: timeout in microseconds, or
-                               OS_SYNC_INFINITE_TIME */
- {
- #ifdef __WIN__
-@@ -422,8 +425,8 @@
-       ut_a(event);
--      if (time != OS_SYNC_INFINITE_TIME) {
--              err = WaitForSingleObject(event->handle, (DWORD) time / 1000);
-+      if (wtime != OS_SYNC_INFINITE_TIME) {
-+              err = WaitForSingleObject(event->handle, (DWORD) wtime / 1000);
-       } else {
-               err = WaitForSingleObject(event->handle, INFINITE);
-       }
-@@ -439,13 +442,47 @@
-               return(1000000); /* dummy value to eliminate compiler warn. */
-       }
- #else
--      UT_NOT_USED(time);
-+      int             err;
-+      int             ret = 0;
-+      ulint           tmp;
-+      ib_int64_t      old_count;
-+      struct timeval  tv_start;
-+      struct timespec timeout;
-+
-+      if (wtime == OS_SYNC_INFINITE_TIME) {
-+              os_event_wait(event);
-+              return 0;
-+      }
-+
-+      /* Compute the absolute point in time at which to time out. */
-+      gettimeofday(&tv_start, NULL);
-+      tmp = tv_start.tv_usec + wtime;
-+      timeout.tv_sec = tv_start.tv_sec + (tmp / 1000000);
-+      timeout.tv_nsec = (tmp % 1000000) * 1000;
-+
-+      os_fast_mutex_lock(&(event->os_mutex));
-+      old_count = event->signal_count;
--      /* In Posix this is just an ordinary, infinite wait */
-+      for (;;) {
-+              if (event->is_set == TRUE || event->signal_count != old_count)
-+                      break;
-+
-+              err = pthread_cond_timedwait(&(event->cond_var),
-+                                           &(event->os_mutex), &timeout);
-+              if (err == ETIMEDOUT) {
-+                      ret = OS_SYNC_TIME_EXCEEDED;
-+                      break;
-+              }
-+      }
--      os_event_wait(event);
-+      os_fast_mutex_unlock(&(event->os_mutex));
-+
-+      if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
-+
-+              os_thread_exit(NULL);
-+      }
--      return(0);
-+      return ret;
- #endif
- }
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -722,6 +722,8 @@
- UNIV_INTERN os_event_t        srv_lock_timeout_thread_event;
-+UNIV_INTERN os_event_t        srv_shutdown_event;
-+
- UNIV_INTERN srv_sys_t*        srv_sys = NULL;
- /* padding to prevent other memory update hotspots from residing on
-@@ -1027,6 +1029,7 @@
-       }
-       srv_lock_timeout_thread_event = os_event_create(NULL);
-+      srv_shutdown_event = os_event_create(NULL);
-       for (i = 0; i < SRV_MASTER + 1; i++) {
-               srv_n_threads_active[i] = 0;
-@@ -2256,7 +2259,7 @@
-       /* Wake up every 5 seconds to see if we need to print
-       monitor information. */
--      os_thread_sleep(5000000);
-+      os_event_wait_time(srv_shutdown_event, 5000000);
-       current_time = time(NULL);
-@@ -2398,7 +2401,7 @@
-       /* When someone is waiting for a lock, we wake up every second
-       and check if a timeout has passed for a lock wait */
--      os_thread_sleep(1000000);
-+      os_event_wait_time(srv_shutdown_event, 1000000);
-       srv_lock_timeout_active = TRUE;
-@@ -2602,7 +2605,7 @@
-       fflush(stderr);
--      os_thread_sleep(1000000);
-+      os_event_wait_time(srv_shutdown_event, 1000000);
-       if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
-@@ -2648,7 +2651,7 @@
-       last_dump_time = time(NULL);
- loop:
--      os_thread_sleep(5000000);
-+      os_event_wait_time(srv_shutdown_event, 5000000);
-       if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
-               goto exit_func;
-@@ -2831,7 +2834,7 @@
-               if (!skip_sleep) {
-               if (next_itr_time > cur_time) {
--                      os_thread_sleep(ut_min(1000000, (next_itr_time - cur_time) * 1000));
-+                      os_event_wait_time(srv_shutdown_event, ut_min(1000000, (next_itr_time - cur_time) * 1000));
-                       srv_main_sleeps++;
-                       /*
-@@ -3538,9 +3541,10 @@
-               mutex_exit(&kernel_mutex);
-               sleep_ms = 10;
-+              os_event_reset(srv_shutdown_event);
-       }
--      os_thread_sleep( sleep_ms * 1000 );
-+      os_event_wait_time(srv_shutdown_event, sleep_ms * 1000);
-       history_len = trx_sys->rseg_history_len;
-       if (history_len > 1000)
diff --git a/mysql-innodb_files_extend.patch b/mysql-innodb_files_extend.patch
deleted file mode 100644 (file)
index 69c22b0..0000000
+++ /dev/null
@@ -1,576 +0,0 @@
-# name       : innodb_files_extend.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0buddy.c
-+++ b/storage/innodb_plugin/buf/buf0buddy.c
-@@ -43,7 +43,7 @@
- #endif /* UNIV_DEBUG */
- /** Statistics of the buddy system, indexed by block size.
- Protected by buf_pool_mutex. */
--UNIV_INTERN buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES + 1];
-+UNIV_INTERN buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES_MAX + 1];
- /** Validate a given zip_free list. */
- #define BUF_BUDDY_LIST_VALIDATE(i)                            \
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -692,7 +692,7 @@
-               ut_a(space->purpose != FIL_LOG);
-               ut_a(!trx_sys_sys_space(space->id));
--              if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
-+              if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * (lint)UNIV_PAGE_SIZE) {
-                       fprintf(stderr,
-                               "InnoDB: Error: the size of single-table"
-                               " tablespace file %s\n"
-@@ -4101,7 +4101,7 @@
-       size = (((ib_int64_t)size_high) << 32) + (ib_int64_t)size_low;
- #ifndef UNIV_HOTBACKUP
--      if (size < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
-+      if (size < FIL_IBD_FILE_INITIAL_SIZE * (lint)UNIV_PAGE_SIZE) {
-               fprintf(stderr,
-                       "InnoDB: Error: the size of single-table tablespace"
-                       " file %s\n"
-@@ -4121,7 +4121,7 @@
-       /* Align the memory for file i/o if we might have O_DIRECT set */
-       page = ut_align(buf2, UNIV_PAGE_SIZE);
--      if (size >= FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
-+      if (size >= FIL_IBD_FILE_INITIAL_SIZE * (lint)UNIV_PAGE_SIZE) {
-               success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
-               /* We have to read the tablespace id from the file */
-@@ -5099,9 +5099,9 @@
-       ut_ad(ut_is_2pow(zip_size));
-       ut_ad(buf);
-       ut_ad(len > 0);
--#if (1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE
--# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
--#endif
-+//#if (1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE
-+//# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
-+//#endif
-       ut_ad(fil_validate());
- #ifndef UNIV_HOTBACKUP
- # ifndef UNIV_LOG_DEBUG
---- a/storage/innodb_plugin/fsp/fsp0fsp.c
-+++ b/storage/innodb_plugin/fsp/fsp0fsp.c
-@@ -657,16 +657,18 @@
-                               0 for uncompressed pages */
-       ulint   offset)         /*!< in: page offset */
- {
--#ifndef DOXYGEN /* Doxygen gets confused of these */
--# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
--              + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
--#  error
--# endif
--# if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
--              + (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
--#  error
--# endif
--#endif /* !DOXYGEN */
-+//#ifndef DOXYGEN /* Doxygen gets confused of these */
-+//# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET
-+//            + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
-+//#  error
-+//# endif
-+//# if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET
-+//            + (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
-+//#  error
-+//# endif
-+//#endif /* !DOXYGEN */
-+      ut_a(UNIV_PAGE_SIZE > XDES_ARR_OFFSET + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE);
-+      ut_a(PAGE_ZIP_MIN_SIZE > XDES_ARR_OFFSET + (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE);
-       ut_ad(ut_is_2pow(zip_size));
-       if (!zip_size) {
-@@ -1465,12 +1467,12 @@
-                                                          mtr);
-               xdes_init(descr, mtr);
--#if UNIV_PAGE_SIZE % FSP_EXTENT_SIZE
--# error "UNIV_PAGE_SIZE % FSP_EXTENT_SIZE != 0"
--#endif
--#if PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE
--# error "PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE != 0"
--#endif
-+//#if UNIV_PAGE_SIZE % FSP_EXTENT_SIZE
-+//# error "UNIV_PAGE_SIZE % FSP_EXTENT_SIZE != 0"
-+//#endif
-+//#if PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE
-+//# error "PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE != 0"
-+//#endif
-               if (UNIV_UNLIKELY(init_xdes)) {
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -151,6 +151,9 @@
- static ulong innobase_read_io_threads;
- static ulong innobase_write_io_threads;
-+static ulong innobase_page_size;
-+static ulong innobase_log_block_size;
-+
- static my_bool innobase_thread_concurrency_timer_based;
- static long long innobase_buffer_pool_size, innobase_log_file_size;
-@@ -2107,6 +2110,62 @@
-       }
- #endif /* UNIV_DEBUG */
-+      srv_page_size = 0;
-+      srv_page_size_shift = 0;
-+
-+      if (innobase_page_size != (1 << 14)) {
-+              uint n_shift;
-+
-+              fprintf(stderr,
-+                      "InnoDB: Warning: innodb_page_size has been changed from default value 16384. (###EXPERIMENTAL### operation)\n");
-+              for (n_shift = 12; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
-+                      if (innobase_page_size == ((ulong)1 << n_shift)) {
-+                              srv_page_size_shift = n_shift;
-+                              srv_page_size = (1 << srv_page_size_shift);
-+                              fprintf(stderr,
-+                                      "InnoDB: The universal page size of the database is set to %lu.\n",
-+                                      srv_page_size);
-+                              break;
-+                      }
-+              }
-+      } else {
-+              srv_page_size_shift = 14;
-+              srv_page_size = (1 << srv_page_size_shift);
-+      }
-+
-+      if (!srv_page_size_shift) {
-+              fprintf(stderr,
-+                      "InnoDB: Error: %lu is not valid value for innodb_page_size.\n",
-+                      innobase_page_size);
-+              goto error;
-+      }
-+
-+      srv_log_block_size = 0;
-+      if (innobase_log_block_size != (1 << 9)) { /*!=512*/
-+              uint    n_shift;
-+
-+              fprintf(stderr,
-+                      "InnoDB: Warning: innodb_log_block_size has been changed from default value 512. (###EXPERIMENTAL### operation)\n");
-+              for (n_shift = 9; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
-+                      if (innobase_log_block_size == ((ulong)1 << n_shift)) {
-+                              srv_log_block_size = (1 << n_shift);
-+                              fprintf(stderr,
-+                                      "InnoDB: The log block size is set to %lu.\n",
-+                                      srv_log_block_size);
-+                              break;
-+                      }
-+              }
-+      } else {
-+              srv_log_block_size = 512;
-+      }
-+
-+      if (!srv_log_block_size) {
-+              fprintf(stderr,
-+                      "InnoDB: Error: %lu is not valid value for innodb_log_block_size.\n",
-+                      innobase_log_block_size);
-+              goto error;
-+      }
-+
- #ifndef MYSQL_SERVER
-       innodb_overwrite_relay_log_info = FALSE;
- #endif
-@@ -6994,9 +7053,9 @@
-                               | DICT_TF_COMPACT
-                               | DICT_TF_FORMAT_ZIP
-                               << DICT_TF_FORMAT_SHIFT;
--#if DICT_TF_ZSSIZE_MAX < 1
--# error "DICT_TF_ZSSIZE_MAX < 1"
--#endif
-+//#if DICT_TF_ZSSIZE_MAX < 1
-+//# error "DICT_TF_ZSSIZE_MAX < 1"
-+//#endif
-               }
-       }
-@@ -11196,6 +11255,16 @@
-   "#### Attention: The checksum is not compatible for normal or disabled version! ####",
-   NULL, NULL, FALSE);
-+static MYSQL_SYSVAR_ULONG(page_size, innobase_page_size,
-+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-+  "###EXPERIMENTAL###: The universal page size of the database. Changing for created database is not supported. Use on your own risk!",
-+  NULL, NULL, (1 << 14), (1 << 12), (1 << UNIV_PAGE_SIZE_SHIFT_MAX), 0);
-+
-+static MYSQL_SYSVAR_ULONG(log_block_size, innobase_log_block_size,
-+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-+  "###EXPERIMENTAL###: The log block size of the transaction log file. Changing for created log file is not supported. Use on your own risk!",
-+  NULL, NULL, (1 << 9)/*512*/, (1 << 9)/*512*/, (1 << UNIV_PAGE_SIZE_SHIFT_MAX), 0);
-+
- static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
-   PLUGIN_VAR_READONLY,
-   "The common part for InnoDB table spaces.",
-@@ -11683,6 +11752,8 @@
-   NULL, NULL, 0, 0, 2, 0);
- static struct st_mysql_sys_var* innobase_system_variables[]= {
-+  MYSQL_SYSVAR(page_size),
-+  MYSQL_SYSVAR(log_block_size),
-   MYSQL_SYSVAR(additional_mem_pool_size),
-   MYSQL_SYSVAR(autoextend_increment),
-   MYSQL_SYSVAR(buffer_pool_size),
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -45,5 +45,6 @@
- {"innodb_separate_doublewrite","Add option 'innodb_doublewrite_file' to separate doublewrite dedicated tablespace","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/buf0buddy.h
-+++ b/storage/innodb_plugin/include/buf0buddy.h
-@@ -78,7 +78,7 @@
- /** Statistics of the buddy system, indexed by block size.
- Protected by buf_pool_mutex. */
--extern buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES + 1];
-+extern buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES_MAX + 1];
- #ifndef UNIV_NONINL
- # include "buf0buddy.ic"
---- a/storage/innodb_plugin/include/buf0buf.h
-+++ b/storage/innodb_plugin/include/buf0buf.h
-@@ -1503,11 +1503,11 @@
-       UT_LIST_BASE_NODE_T(buf_page_t) zip_clean;
-                                       /*!< unmodified compressed pages */
- #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
--      UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES];
-+      UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES_MAX];
-                                       /*!< buddy free lists */
--#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
--# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE"
--#endif
-+//#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
-+//# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE"
-+//#endif
- #if BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE
- # error "BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE"
- #endif
---- a/storage/innodb_plugin/include/buf0types.h
-+++ b/storage/innodb_plugin/include/buf0types.h
-@@ -65,12 +65,13 @@
- #define BUF_BUDDY_LOW         (1 << BUF_BUDDY_LOW_SHIFT)
- #define BUF_BUDDY_SIZES               (UNIV_PAGE_SIZE_SHIFT - BUF_BUDDY_LOW_SHIFT)
-+#define BUF_BUDDY_SIZES_MAX   (UNIV_PAGE_SIZE_SHIFT_MAX - BUF_BUDDY_LOW_SHIFT)
-                                       /*!< number of buddy sizes */
- /** twice the maximum block size of the buddy system;
- the underlying memory is aligned by this amount:
- this must be equal to UNIV_PAGE_SIZE */
--#define BUF_BUDDY_HIGH        (BUF_BUDDY_LOW << BUF_BUDDY_SIZES)
-+#define BUF_BUDDY_HIGH        ((ulint)BUF_BUDDY_LOW << BUF_BUDDY_SIZES)
- /* @} */
- #endif
---- a/storage/innodb_plugin/include/fsp0types.h
-+++ b/storage/innodb_plugin/include/fsp0types.h
-@@ -42,7 +42,7 @@
- /* @} */
- /** File space extent size (one megabyte) in pages */
--#define       FSP_EXTENT_SIZE         (1 << (20 - UNIV_PAGE_SIZE_SHIFT))
-+#define       FSP_EXTENT_SIZE         ((ulint)1 << (20 - UNIV_PAGE_SIZE_SHIFT))
- /** On a page of any file segment, data may be put starting from this
- offset */
---- a/storage/innodb_plugin/include/log0log.h
-+++ b/storage/innodb_plugin/include/log0log.h
-@@ -672,6 +672,9 @@
-                                       when mysqld is first time started
-                                       on the restored database, it can
-                                       print helpful info for the user */
-+#define LOG_FILE_OS_FILE_LOG_BLOCK_SIZE 64
-+                                      /* extend to record log_block_size
-+                                      of XtraDB. 0 means default 512 */
- #define       LOG_FILE_ARCH_COMPLETED OS_FILE_LOG_BLOCK_SIZE
-                                       /* this 4-byte field is TRUE when
-                                       the writing of an archived log file
---- a/storage/innodb_plugin/include/mtr0log.ic
-+++ b/storage/innodb_plugin/include/mtr0log.ic
-@@ -203,7 +203,7 @@
-       system tablespace */
-       if ((space == TRX_SYS_SPACE
-            || (srv_doublewrite_file && space == TRX_DOUBLEWRITE_SPACE))
--          && offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
-+          && offset >= (ulint)FSP_EXTENT_SIZE && offset < 3 * (ulint)FSP_EXTENT_SIZE) {
-               if (trx_doublewrite_buf_is_being_created) {
-                       /* Do nothing: we only come to this branch in an
-                       InnoDB database creation. We do not redo log
---- a/storage/innodb_plugin/include/os0file.h
-+++ b/storage/innodb_plugin/include/os0file.h
-@@ -107,7 +107,7 @@
- if this fails for a log block, then it is equivalent to a media failure in the
- log. */
--#define OS_FILE_LOG_BLOCK_SIZE                512
-+#define OS_FILE_LOG_BLOCK_SIZE                srv_log_block_size
- /** Options for file_create @{ */
- #define       OS_FILE_OPEN                    51
-@@ -188,6 +188,8 @@
- extern ulint  os_n_file_writes;
- extern ulint  os_n_fsyncs;
-+extern ulint  srv_log_block_size;
-+
- /* File types for directory entry data type */
- enum os_file_type_enum{
---- a/storage/innodb_plugin/include/page0types.h
-+++ b/storage/innodb_plugin/include/page0types.h
-@@ -56,8 +56,9 @@
- /** Number of supported compressed page sizes */
- #define PAGE_ZIP_NUM_SSIZE (UNIV_PAGE_SIZE_SHIFT - PAGE_ZIP_MIN_SIZE_SHIFT + 2)
--#if PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)
--# error "PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)"
-+#define PAGE_ZIP_NUM_SSIZE_MAX (UNIV_PAGE_SIZE_SHIFT_MAX - PAGE_ZIP_MIN_SIZE_SHIFT + 2)
-+#if PAGE_ZIP_NUM_SSIZE_MAX > (1 << PAGE_ZIP_SSIZE_BITS)
-+# error "PAGE_ZIP_NUM_SSIZE_MAX > (1 << PAGE_ZIP_SSIZE_BITS)"
- #endif
- /** Compressed page descriptor */
-@@ -98,7 +99,7 @@
- typedef struct page_zip_stat_struct page_zip_stat_t;
- /** Statistics on compression, indexed by page_zip_des_struct::ssize - 1 */
--extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
-+extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE_MAX - 1];
- /**********************************************************************//**
- Write the "deleted" flag of a record on a compressed page.  The flag must
---- a/storage/innodb_plugin/include/trx0sys.h
-+++ b/storage/innodb_plugin/include/trx0sys.h
-@@ -526,9 +526,9 @@
- /** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
- #define TRX_SYS_MYSQL_LOG_MAGIC_N     873422344
--#if UNIV_PAGE_SIZE < 4096
--# error "UNIV_PAGE_SIZE < 4096"
--#endif
-+//#if UNIV_PAGE_SIZE < 4096
-+//# error "UNIV_PAGE_SIZE < 4096"
-+//#endif
- /** The offset of the MySQL replication info in the trx system header;
- this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
- #define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
---- a/storage/innodb_plugin/include/univ.i
-+++ b/storage/innodb_plugin/include/univ.i
-@@ -285,9 +285,13 @@
- */
- /* The 2-logarithm of UNIV_PAGE_SIZE: */
--#define UNIV_PAGE_SIZE_SHIFT  14
-+/* #define UNIV_PAGE_SIZE_SHIFT       14 */
-+#define UNIV_PAGE_SIZE_SHIFT_MAX      14
-+#define UNIV_PAGE_SIZE_SHIFT  srv_page_size_shift
- /* The universal page size of the database */
--#define UNIV_PAGE_SIZE                (1 << UNIV_PAGE_SIZE_SHIFT)
-+/* #define UNIV_PAGE_SIZE             (1 << UNIV_PAGE_SIZE_SHIFT) */
-+#define UNIV_PAGE_SIZE                srv_page_size
-+#define UNIV_PAGE_SIZE_MAX    (1 << UNIV_PAGE_SIZE_SHIFT_MAX)
- /* Maximum number of parallel threads in a parallelized operation */
- #define UNIV_MAX_PARALLELISM  32
-@@ -401,7 +405,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. */
--#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE)
-+#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE_MAX)
- /* Some macros to improve branch prediction and reduce cache misses */
- #if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
-@@ -504,4 +508,6 @@
-       UNIV_MEM_ALLOC(addr, size);                     \
- } while (0)
-+extern ulint  srv_page_size_shift;
-+extern ulint  srv_page_size;
- #endif
---- a/storage/innodb_plugin/log/log0log.c
-+++ b/storage/innodb_plugin/log/log0log.c
-@@ -591,7 +591,9 @@
-       offset = (gr_lsn_size_offset + difference) % group_size;
-+      if (sizeof(ulint) == 4) {
-       ut_a(offset < (((ib_int64_t) 1) << 32)); /* offset must be < 4 GB */
-+      }
-       /* fprintf(stderr,
-       "Offset is %lu gr_lsn_offset is %lu difference is %lu\n",
-@@ -1182,6 +1184,9 @@
-       /* Wipe over possible label of ibbackup --restore */
-       memcpy(buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, "    ", 4);
-+      mach_write_to_4(buf + LOG_FILE_OS_FILE_LOG_BLOCK_SIZE,
-+                      srv_log_block_size);
-+
-       dest_offset = nth_file * group->file_size;
- #ifdef UNIV_DEBUG
-@@ -1775,9 +1780,7 @@
-       ulint           i;
-       ut_ad(mutex_own(&(log_sys->mutex)));
--#if LOG_CHECKPOINT_SIZE > OS_FILE_LOG_BLOCK_SIZE
--# error "LOG_CHECKPOINT_SIZE > OS_FILE_LOG_BLOCK_SIZE"
--#endif
-+      ut_a(LOG_CHECKPOINT_SIZE <= OS_FILE_LOG_BLOCK_SIZE);
-       buf = group->checkpoint_buf;
-@@ -1791,6 +1794,7 @@
-       mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, log_sys->buf_size);
- #ifdef UNIV_LOG_ARCHIVE
-+#error "UNIV_LOG_ARCHIVE could not be enabled"
-       if (log_sys->archiving_state == LOG_ARCH_OFF) {
-               archived_lsn = IB_ULONGLONG_MAX;
-       } else {
-@@ -1804,7 +1808,9 @@
-       mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
- #else /* UNIV_LOG_ARCHIVE */
--      mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
-+      mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN,
-+                      (ib_uint64_t)log_group_calc_lsn_offset(
-+                              log_sys->next_checkpoint_lsn, group));
- #endif /* UNIV_LOG_ARCHIVE */
-       for (i = 0; i < LOG_MAX_N_GROUPS; i++) {
---- a/storage/innodb_plugin/log/log0recv.c
-+++ b/storage/innodb_plugin/log/log0recv.c
-@@ -702,8 +702,22 @@
-                       group->lsn = mach_read_ull(
-                               buf + LOG_CHECKPOINT_LSN);
-+
-+#ifdef UNIV_LOG_ARCHIVE
-+#error "UNIV_LOG_ARCHIVE could not be enabled"
-+#endif
-+                      {
-+                      ib_uint64_t tmp_lsn_offset = mach_read_ull(
-+                                      buf + LOG_CHECKPOINT_ARCHIVED_LSN);
-+                              if (sizeof(ulint) != 4
-+                                  && tmp_lsn_offset != IB_ULONGLONG_MAX) {
-+                                      group->lsn_offset = (ulint) tmp_lsn_offset;
-+                              } else {
-                       group->lsn_offset = mach_read_from_4(
-                               buf + LOG_CHECKPOINT_OFFSET);
-+                              }
-+                      }
-+
-                       checkpoint_no = mach_read_ull(
-                               buf + LOG_CHECKPOINT_NO);
-@@ -2942,6 +2956,7 @@
-       log_group_t*    max_cp_group;
-       log_group_t*    up_to_date_group;
-       ulint           max_cp_field;
-+      ulint           log_hdr_log_block_size;
-       ib_uint64_t     checkpoint_lsn;
-       ib_uint64_t     checkpoint_no;
-       ib_uint64_t     old_scanned_lsn;
-@@ -3043,6 +3058,20 @@
-                      log_hdr_buf, max_cp_group);
-       }
-+      log_hdr_log_block_size
-+              = mach_read_from_4(log_hdr_buf + LOG_FILE_OS_FILE_LOG_BLOCK_SIZE);
-+      if (log_hdr_log_block_size == 0) {
-+              /* 0 means default value */
-+              log_hdr_log_block_size = 512;
-+      }
-+      if (log_hdr_log_block_size != srv_log_block_size) {
-+              fprintf(stderr,
-+                      "InnoDB: Error: The block size of ib_logfile (%lu) "
-+                      "is not equal to innodb_log_block_size.\n",
-+                      log_hdr_log_block_size);
-+              return(DB_ERROR);
-+      }
-+
- #ifdef UNIV_LOG_ARCHIVE
-       group = UT_LIST_GET_FIRST(log_sys->log_groups);
---- a/storage/innodb_plugin/page/page0zip.c
-+++ b/storage/innodb_plugin/page/page0zip.c
-@@ -49,7 +49,7 @@
- #ifndef UNIV_HOTBACKUP
- /** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
--UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
-+UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE_MAX - 1];
- #endif /* !UNIV_HOTBACKUP */
- /* Please refer to ../include/page0zip.ic for a description of the
---- a/storage/innodb_plugin/row/row0merge.c
-+++ b/storage/innodb_plugin/row/row0merge.c
-@@ -92,7 +92,7 @@
- row_merge_block_t.  Thus, it must be able to hold one merge record,
- whose maximum size is the same as the minimum size of
- row_merge_block_t. */
--typedef byte  mrec_buf_t[UNIV_PAGE_SIZE];
-+typedef byte  mrec_buf_t[UNIV_PAGE_SIZE_MAX];
- /** @brief Merge record in row_merge_block_t.
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -219,6 +219,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;
-+
-+/* The log block size */
-+UNIV_INTERN ulint     srv_log_block_size      = 0;
-+
- /* User settable value of the number of pages that must be present
- in the buffer cache and accessed sequentially for InnoDB to trigger a
- readahead request. */
---- a/storage/innodb_plugin/srv/srv0start.c
-+++ b/storage/innodb_plugin/srv/srv0start.c
-@@ -1513,10 +1513,12 @@
-       }
- #endif /* UNIV_LOG_ARCHIVE */
--      if (srv_n_log_files * srv_log_file_size >= 262144) {
-+      if (sizeof(ulint) == 4
-+          && srv_n_log_files * srv_log_file_size
-+             >= ((ulint)1 << (32 - UNIV_PAGE_SIZE_SHIFT))) {
-               fprintf(stderr,
-                       "InnoDB: Error: combined size of log files"
--                      " must be < 4 GB\n");
-+                      " must be < 4 GB on 32-bit systems\n");
-               return(DB_ERROR);
-       }
-@@ -1525,7 +1527,7 @@
-       for (i = 0; i < srv_n_data_files; i++) {
- #ifndef __WIN__
--              if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= 262144) {
-+              if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= ((ulint)1 << (32 - UNIV_PAGE_SIZE_SHIFT))) {
-                       fprintf(stderr,
-                               "InnoDB: Error: file size must be < 4 GB"
-                               " with this MySQL binary\n"
diff --git a/mysql-innodb_fix_misc.patch b/mysql-innodb_fix_misc.patch
deleted file mode 100644 (file)
index 719d4b9..0000000
+++ /dev/null
@@ -1,859 +0,0 @@
-# name       : innodb_fix_misc.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-# Bug fix for
-# http://bugs.mysql.com/56433 (always: because good for all users, and safe)
-# and http://bugs.mysql.com/51325 (optional: innodb_lazy_drop_table)
-# were added. They may be removed in the future when will be fixed officially.
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -1454,6 +1454,27 @@
- #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-       }
-+      if (UNIV_UNLIKELY(bpage->space_was_being_deleted)) {
-+              /* This page is obsoleted, should discard and retry */
-+              rw_lock_s_unlock(&page_hash_latch);
-+
-+              mutex_enter(&LRU_list_mutex);
-+              block_mutex = buf_page_get_mutex_enter(bpage);
-+
-+              if (UNIV_UNLIKELY(!block_mutex)) {
-+                      mutex_exit(&LRU_list_mutex);
-+                      goto lookup;
-+              }
-+
-+              buf_LRU_free_block(bpage, TRUE, TRUE);
-+
-+              mutex_exit(&LRU_list_mutex);
-+              mutex_exit(block_mutex);
-+              block_mutex = NULL;
-+
-+              goto lookup;
-+      }
-+
-       if (UNIV_UNLIKELY(!bpage->zip.data)) {
-               /* There is no compressed page. */
- err_exit:
-@@ -1897,6 +1918,27 @@
-               rw_lock_s_lock(&page_hash_latch);
-               block = (buf_block_t*) buf_page_hash_get(space, offset);
-               if (block) {
-+                      if (UNIV_UNLIKELY(block->page.space_was_being_deleted)) {
-+                              /* This page is obsoleted, should discard and retry */
-+                              rw_lock_s_unlock(&page_hash_latch);
-+
-+                              mutex_enter(&LRU_list_mutex);
-+                              block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
-+
-+                              if (UNIV_UNLIKELY(!block_mutex)) {
-+                                      mutex_exit(&LRU_list_mutex);
-+                                      goto loop;
-+                              }
-+
-+                              buf_LRU_free_block((buf_page_t*)block, TRUE, TRUE);
-+
-+                              mutex_exit(&LRU_list_mutex);
-+                              mutex_exit(block_mutex);
-+                              block_mutex = NULL;
-+
-+                              goto loop;
-+                      }
-+
-                       block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
-                       ut_a(block_mutex);
-               }
-@@ -2713,6 +2755,7 @@
- {
-       buf_block_t*    block;
-       buf_page_t*     bpage;
-+      buf_page_t*     bpage_in_bp;
-       mtr_t           mtr;
-       ibool           lru     = FALSE;
-       void*           data;
-@@ -2748,11 +2791,29 @@
-               ut_ad(block);
-       }
-+retry:
-       //buf_pool_mutex_enter();
-       mutex_enter(&LRU_list_mutex);
-       rw_lock_x_lock(&page_hash_latch);
--      if (buf_page_hash_get(space, offset)) {
-+      bpage_in_bp = buf_page_hash_get(space, offset);
-+
-+      if (UNIV_UNLIKELY(bpage_in_bp && bpage_in_bp->space_was_being_deleted)) {
-+              mutex_t*        block_mutex = buf_page_get_mutex_enter(bpage_in_bp);
-+
-+              /* This page is obsoleted, should discard and retry */
-+              rw_lock_x_unlock(&page_hash_latch);
-+              ut_a(block_mutex);
-+
-+              buf_LRU_free_block(bpage_in_bp, TRUE, TRUE);
-+
-+              mutex_exit(&LRU_list_mutex);
-+              mutex_exit(block_mutex);
-+
-+              goto retry;
-+      }
-+
-+      if (bpage_in_bp) {
-               /* The page is already in the buffer pool. */
- err_exit:
-               if (block) {
-@@ -2864,6 +2925,7 @@
-               bpage->state    = BUF_BLOCK_ZIP_PAGE;
-               bpage->space    = space;
-               bpage->offset   = offset;
-+              bpage->space_was_being_deleted = FALSE;
- #ifdef UNIV_DEBUG
-               bpage->in_page_hash = FALSE;
-@@ -2936,12 +2998,28 @@
-       free_block = buf_LRU_get_free_block();
-+retry:
-       //buf_pool_mutex_enter();
-       mutex_enter(&LRU_list_mutex);
-       rw_lock_x_lock(&page_hash_latch);
-       block = (buf_block_t*) buf_page_hash_get(space, offset);
-+      if (UNIV_UNLIKELY(block && block->page.space_was_being_deleted)) {
-+              mutex_t*        block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
-+
-+              /* This page is obsoleted, should discard and retry */
-+              rw_lock_x_unlock(&page_hash_latch);
-+              ut_a(block_mutex);
-+
-+              buf_LRU_free_block((buf_page_t*)block, TRUE, TRUE);
-+
-+              mutex_exit(&LRU_list_mutex);
-+              mutex_exit(block_mutex);
-+
-+              goto retry;
-+      }
-+
-       if (block && buf_page_in_file(&block->page)) {
- #ifdef UNIV_IBUF_COUNT_DEBUG
-               ut_a(ibuf_count_get(space, offset) == 0);
---- a/storage/innodb_plugin/buf/buf0flu.c
-+++ b/storage/innodb_plugin/buf/buf0flu.c
-@@ -367,7 +367,7 @@
-       if (UNIV_LIKELY(bpage->in_LRU_list && buf_page_in_file(bpage))) {
--              return(bpage->oldest_modification == 0
-+              return((bpage->oldest_modification == 0 || bpage->space_was_being_deleted)
-                      && buf_page_get_io_fix(bpage) == BUF_IO_NONE
-                      && bpage->buf_fix_count == 0);
-       }
-@@ -406,6 +406,13 @@
-           && buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
-               ut_ad(bpage->in_flush_list);
-+              if (bpage->space_was_being_deleted) {
-+                      /* should be removed from flush_list here */
-+                      /* because buf_flush_try_neighbors() cannot flush without fil_space_get_size(space) */
-+                      buf_flush_remove(bpage);
-+                      return(FALSE);
-+              }
-+
-               if (flush_type != BUF_FLUSH_LRU) {
-                       return(TRUE);
---- a/storage/innodb_plugin/buf/buf0lru.c
-+++ b/storage/innodb_plugin/buf/buf0lru.c
-@@ -505,6 +505,55 @@
-       }
- }
-+/******************************************************************//**
-+*/
-+UNIV_INTERN
-+void
-+buf_LRU_mark_space_was_deleted(
-+/*===========================*/
-+      ulint   id)     /*!< in: space id */
-+{
-+      buf_page_t*     bpage;
-+      buf_chunk_t*    chunk;
-+      ulint           i, j;
-+
-+      mutex_enter(&LRU_list_mutex);
-+
-+      bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-+
-+      while (bpage != NULL) {
-+              if (buf_page_get_space(bpage) == id) {
-+                      bpage->space_was_being_deleted = TRUE;
-+              }
-+              bpage = UT_LIST_GET_NEXT(LRU, bpage);
-+      }
-+
-+      mutex_exit(&LRU_list_mutex);
-+
-+      rw_lock_s_lock(&btr_search_latch);
-+      chunk = buf_pool->chunks;
-+      for (i = buf_pool->n_chunks; i--; chunk++) {
-+              buf_block_t*    block   = chunk->blocks;
-+              for (j = chunk->size; j--; block++) {
-+                      if (buf_block_get_state(block)
-+                          != BUF_BLOCK_FILE_PAGE
-+                          || !block->is_hashed
-+                          || buf_page_get_space(&block->page) != id) {
-+                              continue;
-+                      }
-+
-+                      rw_lock_s_unlock(&btr_search_latch);
-+
-+                      rw_lock_x_lock(&block->lock);
-+                      btr_search_drop_page_hash_index(block);
-+                      rw_lock_x_unlock(&block->lock);
-+
-+                      rw_lock_s_lock(&btr_search_latch);
-+              }
-+      }
-+      rw_lock_s_unlock(&btr_search_latch);
-+}
-+
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- /********************************************************************//**
- Insert a compressed block into buf_pool->zip_clean in the LRU order. */
-@@ -1417,6 +1466,10 @@
-               return(FALSE);
-       }
-+      if (bpage->space_was_being_deleted && bpage->oldest_modification != 0) {
-+              buf_flush_remove(bpage);
-+      }
-+
- #ifdef UNIV_IBUF_COUNT_DEBUG
-       ut_a(ibuf_count_get(bpage->space, bpage->offset) == 0);
- #endif /* UNIV_IBUF_COUNT_DEBUG */
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -244,6 +244,7 @@
- struct fil_system_struct {
- #ifndef UNIV_HOTBACKUP
-       mutex_t         mutex;          /*!< The mutex protecting the cache */
-+      mutex_t         file_extend_mutex;
- #endif /* !UNIV_HOTBACKUP */
-       hash_table_t*   spaces;         /*!< The hash table of spaces in the
-                                       system; they are hashed on the space
-@@ -818,7 +819,7 @@
-       ut_ad(node && system);
-       ut_ad(mutex_own(&(system->mutex)));
-       ut_a(node->open);
--      ut_a(node->n_pending == 0);
-+      ut_a(node->n_pending == 0 || node->space->is_being_deleted);
-       ut_a(node->n_pending_flushes == 0);
-       ut_a(node->modification_counter == node->flush_counter);
-@@ -831,7 +832,7 @@
-       ut_a(system->n_open > 0);
-       system->n_open--;
--      if (node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) {
-+      if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) {
-               ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
-               /* The node is in the LRU list, remove it */
-@@ -1030,7 +1031,7 @@
-       ut_ad(node && system && space);
-       ut_ad(mutex_own(&(system->mutex)));
-       ut_a(node->magic_n == FIL_NODE_MAGIC_N);
--      ut_a(node->n_pending == 0);
-+      ut_a(node->n_pending == 0 || space->is_being_deleted);
-       if (node->open) {
-               /* We fool the assertion in fil_node_close_file() to think
-@@ -1551,6 +1552,7 @@
-       fil_system = mem_zalloc(sizeof(fil_system_t));
-       mutex_create(&fil_system->mutex, SYNC_ANY_LATCH);
-+      mutex_create(&fil_system->file_extend_mutex, SYNC_OUTER_ANY_LATCH);
-       fil_system->spaces = hash_create(hash_size);
-       fil_system->name_hash = hash_create(hash_size);
-@@ -2297,7 +2299,11 @@
-       completely and permanently. The flag is_being_deleted also prevents
-       fil_flush() from being applied to this tablespace. */
-+      if (srv_lazy_drop_table) {
-+              buf_LRU_mark_space_was_deleted(id);
-+      } else {
-       buf_LRU_invalidate_tablespace(id);
-+      }
- #endif
-       /* printf("Deleting tablespace %s id %lu\n", space->name, id); */
-@@ -4671,6 +4677,10 @@
-       ulint           page_size;
-       ibool           success         = TRUE;
-+      /* file_extend_mutex is for http://bugs.mysql.com/56433 */
-+      /* to protect from the other fil_extend_space_to_desired_size() */
-+      /* during temprary releasing &fil_system->mutex */
-+      mutex_enter(&fil_system->file_extend_mutex);
-       fil_mutex_enter_and_prepare_for_io(space_id);
-       space = fil_space_get_by_id(space_id);
-@@ -4682,6 +4692,7 @@
-               *actual_size = space->size;
-               mutex_exit(&fil_system->mutex);
-+              mutex_exit(&fil_system->file_extend_mutex);
-               return(TRUE);
-       }
-@@ -4714,6 +4725,8 @@
-               offset_low  = ((start_page_no - file_start_page_no)
-                              % (4096 * ((1024 * 1024) / page_size)))
-                       * page_size;
-+
-+              mutex_exit(&fil_system->mutex);
- #ifdef UNIV_HOTBACKUP
-               success = os_file_write(node->name, node->handle, buf,
-                                       offset_low, offset_high,
-@@ -4723,8 +4736,10 @@
-                                node->name, node->handle, buf,
-                                offset_low, offset_high,
-                                page_size * n_pages,
--                               NULL, NULL, NULL);
-+                               NULL, NULL, space_id, NULL);
- #endif
-+              mutex_enter(&fil_system->mutex);
-+
-               if (success) {
-                       node->size += n_pages;
-                       space->size += n_pages;
-@@ -4770,6 +4785,7 @@
-       printf("Extended %s to %lu, actual size %lu pages\n", space->name,
-       size_after_extend, *actual_size); */
-       mutex_exit(&fil_system->mutex);
-+      mutex_exit(&fil_system->file_extend_mutex);
-       fil_flush(space_id, TRUE);
-@@ -5134,6 +5150,22 @@
-               srv_data_written+= len;
-       }
-+      /* if the table space was already deleted, space might not exist already. */
-+      if (message
-+          && space_id < SRV_LOG_SPACE_FIRST_ID
-+          && ((buf_page_t*)message)->space_was_being_deleted) {
-+
-+              if (mode == OS_AIO_NORMAL) {
-+                      buf_page_io_complete(message);
-+                      return(DB_SUCCESS); /*fake*/
-+              }
-+              if (type == OS_FILE_READ) {
-+                      return(DB_TABLESPACE_DELETED);
-+              } else {
-+                      return(DB_SUCCESS); /*fake*/
-+              }
-+      }
-+
-       /* Reserve the fil_system mutex and make sure that we can open at
-       least one file while holding it, if the file is not already open */
-@@ -5275,10 +5307,24 @@
- #else
-       /* Queue the aio request */
-       ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
--                   offset_low, offset_high, len, node, message, trx);
-+                   offset_low, offset_high, len, node, message, space_id, trx);
- #endif
-       } /**/
-+      /* if the table space was already deleted, space might not exist already. */
-+      if (message
-+          && space_id < SRV_LOG_SPACE_FIRST_ID
-+          && ((buf_page_t*)message)->space_was_being_deleted) {
-+
-+              if (mode == OS_AIO_SYNC) {
-+                      if (type == OS_FILE_READ) {
-+                              return(DB_TABLESPACE_DELETED);
-+                      } else {
-+                              return(DB_SUCCESS); /*fake*/
-+                      }
-+              }
-+      }
-+
-       ut_a(ret);
-       if (mode == OS_AIO_SYNC) {
-@@ -5378,6 +5424,7 @@
-       fil_node_t*     fil_node;
-       void*           message;
-       ulint           type;
-+      ulint           space_id = 0;
-       ut_ad(fil_validate());
-@@ -5385,7 +5432,7 @@
-               srv_set_io_thread_op_info(segment, "native aio handle");
- #ifdef WIN_ASYNC_IO
-               ret = os_aio_windows_handle(segment, 0, &fil_node,
--                                          &message, &type);
-+                                          &message, &type, &space_id);
- #else
-               ret = 0; /* Eliminate compiler warning */
-               ut_error;
-@@ -5394,7 +5441,22 @@
-               srv_set_io_thread_op_info(segment, "simulated aio handle");
-               ret = os_aio_simulated_handle(segment, &fil_node,
--                                            &message, &type);
-+                                            &message, &type, &space_id);
-+      }
-+
-+      /* if the table space was already deleted, fil_node might not exist already. */
-+      if (message
-+          && space_id < SRV_LOG_SPACE_FIRST_ID
-+          && ((buf_page_t*)message)->space_was_being_deleted) {
-+
-+              /* intended not to be uncompress read page */
-+              ut_a(buf_page_get_io_fix(message) == BUF_IO_WRITE
-+                   || !buf_page_get_zip_size(message)
-+                   || buf_page_get_state(message) != BUF_BLOCK_FILE_PAGE);
-+
-+              srv_set_io_thread_op_info(segment, "complete io for buf page");
-+              buf_page_io_complete(message);
-+              return;
-       }
-       ut_a(ret);
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -11751,6 +11751,12 @@
-   "except for the deletion.",
-   NULL, NULL, 0, 0, 2, 0);
-+static MYSQL_SYSVAR_ULONG(lazy_drop_table, srv_lazy_drop_table,
-+  PLUGIN_VAR_RQCMDARG,
-+  "At deleting tablespace, only miminum needed processes at the time are done. "
-+  "e.g. for http://bugs.mysql.com/51325",
-+  NULL, NULL, 0, 0, 1, 0);
-+
- static struct st_mysql_sys_var* innobase_system_variables[]= {
-   MYSQL_SYSVAR(page_size),
-   MYSQL_SYSVAR(log_block_size),
-@@ -11842,6 +11848,7 @@
-   MYSQL_SYSVAR(blocking_lru_restore),
-   MYSQL_SYSVAR(use_purge_thread),
-   MYSQL_SYSVAR(pass_corrupt_table),
-+  MYSQL_SYSVAR(lazy_drop_table),
-   NULL
- };
-@@ -11851,7 +11858,7 @@
-   &innobase_storage_engine,
-   innobase_hton_name,
-   "Innobase Oy",
--  "Supports transactions, row-level locking, and foreign keys",
-+  "Percona-XtraDB, Supports transactions, row-level locking, and foreign keys",
-   PLUGIN_LICENSE_GPL,
-   innobase_init, /* Plugin Init */
-   NULL, /* Plugin Deinit */
---- a/storage/innodb_plugin/include/buf0buf.h
-+++ b/storage/innodb_plugin/include/buf0buf.h
-@@ -1203,6 +1203,7 @@
-                                       0 if the block was never accessed
-                                       in the buffer pool */
-       /* @} */
-+      ibool           space_was_being_deleted;
-       ibool           is_corrupt;
- # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
-       ibool           file_page_was_freed;
---- a/storage/innodb_plugin/include/buf0buf.ic
-+++ b/storage/innodb_plugin/include/buf0buf.ic
-@@ -400,6 +400,7 @@
-       buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
-       block->page.space = space;
-       block->page.offset = page_no;
-+      block->page.space_was_being_deleted = FALSE;
- }
- /*********************************************************************//**
---- a/storage/innodb_plugin/include/buf0lru.h
-+++ b/storage/innodb_plugin/include/buf0lru.h
-@@ -72,6 +72,13 @@
- buf_LRU_invalidate_tablespace(
- /*==========================*/
-       ulint   id);    /*!< in: space id */
-+/******************************************************************//**
-+*/
-+UNIV_INTERN
-+void
-+buf_LRU_mark_space_was_deleted(
-+/*===========================*/
-+      ulint   id);    /*!< in: space id */
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- /********************************************************************//**
- Insert a compressed block into buf_pool->zip_clean in the LRU order. */
---- a/storage/innodb_plugin/include/os0file.h
-+++ b/storage/innodb_plugin/include/os0file.h
-@@ -658,6 +658,7 @@
-                               (can be used to identify a completed
-                               aio operation); ignored if mode is
-                               OS_AIO_SYNC */
-+      ulint           space_id,
-       trx_t*          trx);
- /************************************************************************//**
- Wakes up all async i/o threads so that they know to exit themselves in
-@@ -718,7 +719,8 @@
-                               parameters are valid and can be used to
-                               restart the operation, for example */
-       void**  message2,
--      ulint*  type);          /*!< out: OS_FILE_WRITE or ..._READ */
-+      ulint*  type,           /*!< out: OS_FILE_WRITE or ..._READ */
-+      ulint*  space_id);
- #endif
- /**********************************************************************//**
-@@ -740,7 +742,8 @@
-                               parameters are valid and can be used to
-                               restart the operation, for example */
-       void**  message2,
--      ulint*  type);          /*!< out: OS_FILE_WRITE or ..._READ */
-+      ulint*  type,           /*!< out: OS_FILE_WRITE or ..._READ */
-+      ulint*  space_id);
- /**********************************************************************//**
- Validates the consistency of the aio system.
- @return       TRUE if ok */
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -237,6 +237,8 @@
- extern ulint  srv_extra_rsegments;
- extern ulint  srv_dict_size_limit;
-+
-+extern ulint  srv_lazy_drop_table;
- /*-------------------------------------------*/
- extern ulint  srv_n_rows_inserted;
---- a/storage/innodb_plugin/include/sync0sync.h
-+++ b/storage/innodb_plugin/include/sync0sync.h
-@@ -498,6 +498,7 @@
- #define       SYNC_BUF_POOL           150
- #define SYNC_BUF_FLUSH_LIST   149
- #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
---- a/storage/innodb_plugin/include/univ.i
-+++ b/storage/innodb_plugin/include/univ.i
-@@ -47,6 +47,11 @@
- #define INNODB_VERSION_MINOR  0
- #define INNODB_VERSION_BUGFIX 17
-+#ifndef PERCONA_INNODB_VERSION
-+#define PERCONA_INNODB_VERSION 12.5
-+#endif
-+
-+
- /* 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:
-@@ -57,13 +62,15 @@
-       (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
- /* auxiliary macros to help creating the version as string */
--#define __INNODB_VERSION(a, b, c)     (#a "." #b "." #c)
--#define _INNODB_VERSION(a, b, c)      __INNODB_VERSION(a, b, c)
-+#define __INNODB_VERSION(a, b, c, d)   (#a "." #b "." #c "-" #d)
-+#define _INNODB_VERSION(a, b, c, d)    __INNODB_VERSION(a, b, c, d)
-+
- #define INNODB_VERSION_STR                    \
-       _INNODB_VERSION(INNODB_VERSION_MAJOR,   \
-                       INNODB_VERSION_MINOR,   \
--                      INNODB_VERSION_BUGFIX)
-+                      INNODB_VERSION_BUGFIX,  \
-+                      PERCONA_INNODB_VERSION)
- #define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/"
---- a/storage/innodb_plugin/os/os0file.c
-+++ b/storage/innodb_plugin/os/os0file.c
-@@ -142,6 +142,7 @@
- //                                    made and only the slot message
- //                                    needs to be passed to the caller
- //                                    of os_aio_simulated_handle */
-+      ulint           space_id;
-       fil_node_t*     message1;       /*!< message which is given by the */
-       void*           message2;       /*!< the requester of an aio operation
-                                       and which can be used to identify
-@@ -3401,7 +3402,8 @@
-                               offset */
-       ulint           offset_high, /*!< in: most significant 32 bits of
-                               offset */
--      ulint           len)    /*!< in: length of the block to read or write */
-+      ulint           len,    /*!< in: length of the block to read or write */
-+      ulint           space_id)
- {
-       os_aio_slot_t*  slot;
-       ulint           i;
-@@ -3483,6 +3485,7 @@
-       slot->offset_high = offset_high;
- //    slot->io_already_done = FALSE;
-       slot->status = OS_AIO_NOT_ISSUED;
-+      slot->space_id = space_id;
- #ifdef WIN_ASYNC_IO
-       control = &(slot->control);
-@@ -3691,6 +3694,7 @@
-                               (can be used to identify a completed
-                               aio operation); ignored if mode is
-                               OS_AIO_SYNC */
-+      ulint           space_id,
-       trx_t*          trx)
- {
-       os_aio_array_t* array;
-@@ -3773,7 +3777,7 @@
-               trx->io_read += n;
-       }
-       slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
--                                       name, buf, offset, offset_high, n);
-+                                       name, buf, offset, offset_high, n, space_id);
-       if (type == OS_FILE_READ) {
-               if (os_aio_use_native_aio) {
- #ifdef WIN_ASYNC_IO
-@@ -3883,7 +3887,8 @@
-                               parameters are valid and can be used to
-                               restart the operation, for example */
-       void**  message2,
--      ulint*  type)           /*!< out: OS_FILE_WRITE or ..._READ */
-+      ulint*  type,           /*!< out: OS_FILE_WRITE or ..._READ */
-+      ulint*  space_id)
- {
-       ulint           orig_seg        = segment;
-       os_aio_array_t* array;
-@@ -3937,6 +3942,7 @@
-       *message2 = slot->message2;
-       *type = slot->type;
-+      *space_id = slot->space_id;
-       if (ret && len == slot->len) {
-               ret_val = TRUE;
-@@ -4020,7 +4026,8 @@
-                               parameters are valid and can be used to
-                               restart the operation, for example */
-       void**  message2,
--      ulint*  type)           /*!< out: OS_FILE_WRITE or ..._READ */
-+      ulint*  type,           /*!< out: OS_FILE_WRITE or ..._READ */
-+      ulint*  space_id)
- {
-       os_aio_array_t* array;
-       ulint           segment;
-@@ -4311,6 +4318,7 @@
-       *message2 = slot->message2;
-       *type = slot->type;
-+      *space_id = slot->space_id;
-       os_mutex_exit(array->mutex);
---- a/storage/innodb_plugin/row/row0mysql.c
-+++ b/storage/innodb_plugin/row/row0mysql.c
-@@ -51,6 +51,7 @@
- #include "btr0sea.h"
- #include "fil0fil.h"
- #include "ibuf0ibuf.h"
-+#include "ha_prototypes.h"
- /** Provide optional 4.x backwards compatibility for 5.0 and above */
- UNIV_INTERN ibool     row_rollback_on_timeout = FALSE;
-@@ -1135,6 +1136,13 @@
-       thr = que_fork_get_first_thr(prebuilt->ins_graph);
-+      if (!prebuilt->mysql_has_locked) {
-+              fprintf(stderr, "InnoDB: Error: row_insert_for_mysql is called without ha_innobase::external_lock()\n");
-+              if (trx->mysql_thd != NULL) {
-+                      innobase_mysql_print_thd(stderr, trx->mysql_thd, 600);
-+              }
-+      }
-+
-       if (prebuilt->sql_stat_start) {
-               node->state = INS_NODE_SET_IX_LOCK;
-               prebuilt->sql_stat_start = FALSE;
-@@ -2547,10 +2555,29 @@
-                       err = DB_ERROR;
-               } else {
-+                      dict_index_t*   index;
-+
-                       /* Set the flag which tells that now it is legal to
-                       IMPORT a tablespace for this table */
-                       table->tablespace_discarded = TRUE;
-                       table->ibd_file_missing = TRUE;
-+
-+                      /* check adaptive hash entries */
-+                      index = dict_table_get_first_index(table);
-+                      while (index) {
-+                              ulint ref_count = btr_search_info_get_ref_count(index->search_info);
-+                              if (ref_count) {
-+                                      fprintf(stderr, "InnoDB: Warning:"
-+                                              " hash index ref_count (%lu) is not zero"
-+                                              " after fil_discard_tablespace().\n"
-+                                              "index: \"%s\""
-+                                              " table: \"%s\"\n",
-+                                              ref_count,
-+                                              index->name,
-+                                              table->name);
-+                              }
-+                              index = dict_table_get_next_index(index);
-+                      }
-               }
-       }
-@@ -2902,6 +2929,19 @@
-                       table->space = space;
-                       index = dict_table_get_first_index(table);
-                       do {
-+                              ulint ref_count = btr_search_info_get_ref_count(index->search_info);
-+                              /* check adaptive hash entries */
-+                              if (ref_count) {
-+                                      fprintf(stderr, "InnoDB: Warning:"
-+                                              " hash index ref_count (%lu) is not zero"
-+                                              " after fil_discard_tablespace().\n"
-+                                              "index: \"%s\""
-+                                              " table: \"%s\"\n",
-+                                              ref_count,
-+                                              index->name,
-+                                              table->name);
-+                              }
-+
-                               index->space = space;
-                               index = dict_table_get_next_index(index);
-                       } while (index);
---- a/storage/innodb_plugin/row/row0sel.c
-+++ b/storage/innodb_plugin/row/row0sel.c
-@@ -3414,6 +3414,7 @@
-       ulint           offsets_[REC_OFFS_NORMAL_SIZE];
-       ulint*          offsets                         = offsets_;
-       ibool           table_lock_waited               = FALSE;
-+      ibool           problematic_use = FALSE;
-       rec_offs_init(offsets_);
-@@ -3780,6 +3781,15 @@
-       /* Do some start-of-statement preparations */
-+      if (!prebuilt->mysql_has_locked) {
-+              fprintf(stderr, "InnoDB: Error: row_search_for_mysql() is called without ha_innobase::external_lock()\n");
-+              if (trx->mysql_thd != NULL) {
-+                      innobase_mysql_print_thd(stderr, trx->mysql_thd, 600);
-+              }
-+              problematic_use = TRUE;
-+      }
-+retry_check:
-+      
-       if (!prebuilt->sql_stat_start) {
-               /* No need to set an intention lock or assign a read view */
-@@ -3790,6 +3800,14 @@
-                             " perform a consistent read\n"
-                             "InnoDB: but the read view is not assigned!\n",
-                             stderr);
-+                      if (problematic_use) {
-+                              fprintf(stderr, "InnoDB: It may be caused by calling "
-+                                              "without ha_innobase::external_lock()\n"
-+                                              "InnoDB: For the first-aid, avoiding the crash. "
-+                                              "But it should be fixed ASAP.\n");
-+                              prebuilt->sql_stat_start = TRUE;
-+                              goto retry_check;
-+                      }
-                       trx_print(stderr, trx, 600);
-                       fputc('\n', stderr);
-                       ut_error;
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -424,6 +424,8 @@
- UNIV_INTERN ulint     srv_extra_rsegments = 0; /* extra rseg for users */
- UNIV_INTERN ulint     srv_dict_size_limit = 0;
-+
-+UNIV_INTERN ulint     srv_lazy_drop_table = 0;
- /*-------------------------------------------*/
- UNIV_INTERN ulong     srv_n_spin_wait_rounds  = 30;
- UNIV_INTERN ulong     srv_n_free_tickets_to_enter = 500;
---- a/storage/innodb_plugin/srv/srv0start.c
-+++ b/storage/innodb_plugin/srv/srv0start.c
-@@ -2018,7 +2018,7 @@
-       if (srv_print_verbose_log) {
-               ut_print_timestamp(stderr);
-               fprintf(stderr,
--                      " InnoDB Plugin %s started; "
-+                      " Percona XtraDB (http://www.percona.com) %s started; "
-                       "log sequence number %llu\n",
-                       INNODB_VERSION_STR, srv_start_lsn);
-       }
---- a/storage/innodb_plugin/sync/sync0sync.c
-+++ b/storage/innodb_plugin/sync/sync0sync.c
-@@ -1166,6 +1166,7 @@
-       case SYNC_LOG:
-       case SYNC_THR_LOCAL:
-       case SYNC_ANY_LATCH:
-+      case SYNC_OUTER_ANY_LATCH:
-       case SYNC_TRX_SYS_HEADER:
-       case SYNC_FILE_FORMAT_TAG:
-       case SYNC_DOUBLEWRITE:
---- a/storage/innodb_plugin/trx/trx0purge.c
-+++ b/storage/innodb_plugin/trx/trx0purge.c
-@@ -1144,8 +1144,7 @@
-       /* If we cannot advance the 'purge view' because of an old
-       'consistent read view', then the DML statements cannot be delayed.
-       Also, srv_max_purge_lag <= 0 means 'infinity'. */
--      if (srv_max_purge_lag > 0
--          && !UT_LIST_GET_LAST(trx_sys->view_list)) {
-+      if (srv_max_purge_lag > 0) {
-               float   ratio = (float) trx_sys->rseg_history_len
-                       / srv_max_purge_lag;
-               if (ratio > ULINT_MAX / 10000) {
---- /dev/null
-+++ b/mysql-test/r/innodb_fix_misc_bug51325.result
-@@ -0,0 +1,13 @@
-+DROP TABLE IF EXISTS t1;
-+SET GLOBAL innodb_file_per_table=ON;
-+SHOW VARIABLES LIKE 'innodb_lazy_drop_table';
-+Variable_name Value
-+innodb_lazy_drop_table        0
-+SET GLOBAL innodb_lazy_drop_table=1;
-+SHOW VARIABLES LIKE 'innodb_lazy_drop_table';
-+Variable_name Value
-+innodb_lazy_drop_table        1
-+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-+DROP TABLE t1;
-+SET GLOBAL innodb_lazy_drop_table=default;
-+SET GLOBAL innodb_file_per_table=default;
---- /dev/null
-+++ b/mysql-test/t/innodb_fix_misc_bug51325.test
-@@ -0,0 +1,13 @@
-+# Test for 'innodb_lazy_drop_table' variable
-+--source include/have_innodb.inc
-+--disable_warnings
-+DROP TABLE IF EXISTS t1; 
-+--enable_warnings
-+SET GLOBAL innodb_file_per_table=ON;
-+SHOW VARIABLES LIKE 'innodb_lazy_drop_table';
-+SET GLOBAL innodb_lazy_drop_table=1;
-+SHOW VARIABLES LIKE 'innodb_lazy_drop_table';
-+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
-+DROP TABLE t1;
-+SET GLOBAL innodb_lazy_drop_table=default;
-+SET GLOBAL innodb_file_per_table=default;
diff --git a/mysql-innodb_io_patches.patch b/mysql-innodb_io_patches.patch
deleted file mode 100644 (file)
index 427fdde..0000000
+++ /dev/null
@@ -1,1764 +0,0 @@
-# name       : innodb_io_patches.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0flu.c
-+++ b/storage/innodb_plugin/buf/buf0flu.c
-@@ -743,7 +743,7 @@
- flush:
-       /* Now flush the doublewrite buffer data to disk */
--      fil_flush(TRX_SYS_SPACE);
-+      fil_flush(TRX_SYS_SPACE, FALSE);
-       /* We know that the writes have been flushed to disk now
-       and in recovery we will find them in the doublewrite buffer
-@@ -1240,8 +1240,9 @@
- /*====================*/
-       ulint           space,          /*!< in: space id */
-       ulint           offset,         /*!< in: page offset */
--      enum buf_flush  flush_type)     /*!< in: BUF_FLUSH_LRU or
-+      enum buf_flush  flush_type,     /*!< in: BUF_FLUSH_LRU or
-                                       BUF_FLUSH_LIST */
-+      ulint           flush_neighbors)
- {
-       buf_page_t*     bpage;
-       ulint           low, high;
-@@ -1250,7 +1251,7 @@
-       ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
--      if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
-+      if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN || !flush_neighbors) {
-               /* If there is little space, it is better not to flush any
-               block except from the end of the LRU list */
-@@ -1422,7 +1423,7 @@
-                               /* Try to flush also all the neighbors */
-                               page_count += buf_flush_try_neighbors(
--                                      space, offset, flush_type);
-+                                      space, offset, flush_type, srv_flush_neighbor_pages);
-                               buf_pool_mutex_enter();
-                               goto flush_next;
---- a/storage/innodb_plugin/buf/buf0rea.c
-+++ b/storage/innodb_plugin/buf/buf0rea.c
-@@ -424,6 +424,10 @@
-               = BUF_READ_AHEAD_LINEAR_AREA;
-       ulint           threshold;
-+      if (!(srv_read_ahead & 2)) {
-+              return(0);
-+      }
-+
-       if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
-               /* No read-ahead to avoid thread deadlocks */
-               return(0);
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -2554,7 +2554,7 @@
-               os_thread_sleep(20000);
--              fil_flush(id);
-+              fil_flush(id, TRUE);
-               goto retry;
-@@ -2767,7 +2767,7 @@
-               goto error_exit;
-       }
--      ret = os_file_flush(file);
-+      ret = os_file_flush(file, TRUE);
-       if (!ret) {
-               fputs("InnoDB: Error: file flush of tablespace ", stderr);
-@@ -2952,7 +2952,7 @@
-               }
-       }
--      success = os_file_flush(file);
-+      success = os_file_flush(file, TRUE);
-       if (!success) {
-               goto func_exit;
-@@ -2974,7 +2974,7 @@
-               goto func_exit;
-       }
--      success = os_file_flush(file);
-+      success = os_file_flush(file, TRUE);
- func_exit:
-       os_file_close(file);
-       ut_free(buf2);
-@@ -3955,7 +3955,7 @@
-       size_after_extend, *actual_size); */
-       mutex_exit(&fil_system->mutex);
--      fil_flush(space_id);
-+      fil_flush(space_id, TRUE);
-       return(success);
- }
-@@ -4521,8 +4521,9 @@
- void
- fil_flush(
- /*======*/
--      ulint   space_id)       /*!< in: file space id (this can be a group of
-+      ulint   space_id,       /*!< in: file space id (this can be a group of
-                               log files or a tablespace of the database) */
-+      ibool   metadata)
- {
-       fil_space_t*    space;
-       fil_node_t*     node;
-@@ -4593,7 +4594,7 @@
-                       /* fprintf(stderr, "Flushing to file %s\n",
-                       node->name); */
--                      os_file_flush(file);
-+                      os_file_flush(file, metadata);
-                       mutex_enter(&fil_system->mutex);
-@@ -4676,7 +4677,7 @@
-       a non-existing space id. */
-       for (i = 0; i < n_space_ids; i++) {
--              fil_flush(space_ids[i]);
-+              fil_flush(space_ids[i], TRUE);
-       }
-       mem_free(space_ids);
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -332,6 +332,12 @@
-   "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
-   NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
-+static MYSQL_THDVAR_ULONG(flush_log_at_trx_commit_session, PLUGIN_VAR_RQCMDARG,
-+  "Control innodb_flush_log_at_trx_commit for each sessions. "
-+  "The value 0~2 are same meanings to innodb_flush_log_at_trx_commit. "
-+  "The value 3 regards innodb_flush_log_at_trx_commit (default).",
-+  NULL, NULL, 3, 0, 3, 0);
-+
- static handler *innobase_create_handler(handlerton *hton,
-                                         TABLE_SHARE *table,
-@@ -710,6 +716,17 @@
-       return(THDVAR((THD*) thd, lock_wait_timeout));
- }
-+/******************************************************************//**
-+*/
-+extern "C" UNIV_INTERN
-+ulong
-+thd_flush_log_at_trx_commit_session(
-+/*================================*/
-+      void*   thd)
-+{
-+      return(THDVAR((THD*) thd, flush_log_at_trx_commit_session));
-+}
-+
- /********************************************************************//**
- Obtain the InnoDB transaction of a MySQL thread.
- @return       reference to transaction pointer */
-@@ -2234,6 +2251,9 @@
-       srv_n_read_io_threads = (ulint) innobase_read_io_threads;
-       srv_n_write_io_threads = (ulint) innobase_write_io_threads;
-+      srv_read_ahead &= 3;
-+      srv_adaptive_checkpoint %= 4;
-+
-       srv_force_recovery = (ulint) innobase_force_recovery;
-       srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
-@@ -9916,6 +9936,10 @@
-       if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
-           (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
-       {
-+              if (srv_enable_unsafe_group_commit && !THDVAR(thd, support_xa)) {
-+                      /* choose group commit rather than binlog order */
-+                      return(error);
-+              }
-               /* For ibbackup to work the order of transactions in binlog
-               and InnoDB must be the same. Consider the situation
-@@ -10891,7 +10915,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.",
--  NULL, NULL, 128*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
-+  NULL, NULL, 128*1024*1024L, 32*1024*1024L, LONGLONG_MAX, 1024*1024L);
- static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
-   PLUGIN_VAR_RQCMDARG,
-@@ -11038,6 +11062,102 @@
-   "trigger a readahead.",
-   NULL, NULL, 56, 0, 64, 0);
-+static MYSQL_SYSVAR_LONGLONG(ibuf_max_size, srv_ibuf_max_size,
-+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-+  "The maximum size of the insert buffer. (in bytes)",
-+  NULL, NULL, LONGLONG_MAX, 0, LONGLONG_MAX, 0);
-+
-+static MYSQL_SYSVAR_ULONG(ibuf_active_contract, srv_ibuf_active_contract,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Enable/Disable active_contract of insert buffer. 0:disable 1:enable",
-+  NULL, NULL, 0, 0, 1, 0);
-+
-+static MYSQL_SYSVAR_ULONG(ibuf_accel_rate, srv_ibuf_accel_rate,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Tunes amount of insert buffer processing of background, in addition to innodb_io_capacity. (in percentage)",
-+  NULL, NULL, 100, 100, 999999999, 0);
-+
-+static MYSQL_SYSVAR_ULONG(checkpoint_age_target, srv_checkpoint_age_target,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Control soft limit of checkpoint age. (0 : not control)",
-+  NULL, NULL, 0, 0, ~0UL, 0);
-+
-+static MYSQL_SYSVAR_ULONG(flush_neighbor_pages, srv_flush_neighbor_pages,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Enable/Disable flushing also neighbor pages. 0:disable 1:enable",
-+  NULL, NULL, 1, 0, 1, 0);
-+
-+static
-+void
-+innodb_read_ahead_update(
-+  THD* thd,
-+  struct st_mysql_sys_var*     var,
-+  void*        var_ptr,
-+  const void*  save)
-+{
-+  *(long *)var_ptr= (*(long *)save) & 3;
-+}
-+const char *read_ahead_names[]=
-+{
-+  "none", /* 0 */
-+  "random",
-+  "linear",
-+  "both", /* 3 */
-+  /* For compatibility of the older patch */
-+  "0", /* 4 ("none" + 4) */
-+  "1",
-+  "2",
-+  "3", /* 7 ("both" + 4) */
-+  NullS
-+};
-+TYPELIB read_ahead_typelib=
-+{
-+  array_elements(read_ahead_names) - 1, "read_ahead_typelib",
-+  read_ahead_names, NULL
-+};
-+static MYSQL_SYSVAR_ENUM(read_ahead, srv_read_ahead,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Control read ahead activity (none, random, [linear], both). [from 1.0.5: random read ahead is ignored]",
-+  NULL, innodb_read_ahead_update, 2, &read_ahead_typelib);
-+
-+static
-+void
-+innodb_adaptive_checkpoint_update(
-+  THD* thd,
-+  struct st_mysql_sys_var*     var,
-+  void*        var_ptr,
-+  const void*  save)
-+{
-+  *(long *)var_ptr= (*(long *)save) % 4;
-+}
-+const char *adaptive_checkpoint_names[]=
-+{
-+  "none", /* 0 */
-+  "reflex", /* 1 */
-+  "estimate", /* 2 */
-+  "keep_average", /* 3 */
-+  /* For compatibility of the older patch */
-+  "0", /* 4 ("none" + 3) */
-+  "1", /* 5 ("reflex" + 3) */
-+  "2", /* 6 ("estimate" + 3) */
-+  "3", /* 7 ("keep_average" + 4) */
-+  NullS
-+};
-+TYPELIB adaptive_checkpoint_typelib=
-+{
-+  array_elements(adaptive_checkpoint_names) - 1, "adaptive_checkpoint_typelib",
-+  adaptive_checkpoint_names, NULL
-+};
-+static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Enable/Disable flushing along modified age. ([none], reflex, estimate, keep_average)",
-+  NULL, innodb_adaptive_checkpoint_update, 0, &adaptive_checkpoint_typelib);
-+
-+static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_enable_unsafe_group_commit,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.",
-+  NULL, NULL, 0, 0, 1, 0);
-+
- static struct st_mysql_sys_var* innobase_system_variables[]= {
-   MYSQL_SYSVAR(additional_mem_pool_size),
-   MYSQL_SYSVAR(autoextend_increment),
-@@ -11093,6 +11213,15 @@
-   MYSQL_SYSVAR(show_verbose_locks),
-   MYSQL_SYSVAR(show_locks_held),
-   MYSQL_SYSVAR(version),
-+  MYSQL_SYSVAR(ibuf_max_size),
-+  MYSQL_SYSVAR(ibuf_active_contract),
-+  MYSQL_SYSVAR(ibuf_accel_rate),
-+  MYSQL_SYSVAR(checkpoint_age_target),
-+  MYSQL_SYSVAR(flush_neighbor_pages),
-+  MYSQL_SYSVAR(read_ahead),
-+  MYSQL_SYSVAR(adaptive_checkpoint),
-+  MYSQL_SYSVAR(flush_log_at_trx_commit_session),
-+  MYSQL_SYSVAR(enable_unsafe_group_commit),
-   MYSQL_SYSVAR(use_sys_malloc),
-   MYSQL_SYSVAR(change_buffering),
- #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -25,5 +25,6 @@
- }innodb_enhancements[] = {
- {"xtradb_show_enhancements","I_S.XTRADB_ENHANCEMENTS","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_show_status","Improvements to SHOW INNODB STATUS","Memory information and lock info fixes","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_io","Improvements to InnoDB IO","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c
-+++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c
-@@ -464,8 +464,10 @@
-       grow in size, as the references on the upper levels of the tree can
-       change */
--      ibuf->max_size = buf_pool_get_curr_size() / UNIV_PAGE_SIZE
--              / IBUF_POOL_SIZE_PER_MAX_SIZE;
-+      ibuf->max_size = ut_min( buf_pool_get_curr_size() / UNIV_PAGE_SIZE
-+              / IBUF_POOL_SIZE_PER_MAX_SIZE, (ulint) srv_ibuf_max_size / UNIV_PAGE_SIZE);
-+
-+      srv_ibuf_max_size = (long long) ibuf->max_size * UNIV_PAGE_SIZE;
-       mutex_create(&ibuf_pessimistic_insert_mutex,
-                    SYNC_IBUF_PESS_INSERT_MUTEX);
-@@ -2306,11 +2308,13 @@
-       mutex_enter(&ibuf_mutex);
-+      if (!srv_ibuf_active_contract) {
-       if (ibuf->size < ibuf->max_size + IBUF_CONTRACT_ON_INSERT_NON_SYNC) {
-               mutex_exit(&ibuf_mutex);
-               return;
-       }
-+      }
-       sync = FALSE;
---- a/storage/innodb_plugin/include/buf0rea.h
-+++ b/storage/innodb_plugin/include/buf0rea.h
-@@ -124,8 +124,7 @@
- /** The size in pages of the area which the read-ahead algorithms read if
- invoked */
--#define       BUF_READ_AHEAD_AREA                                     \
--      ut_min(64, ut_2_power_up(buf_pool->curr_size / 32))
-+#define       BUF_READ_AHEAD_AREA             64
- /** @name Modes used in read-ahead @{ */
- /** read only pages belonging to the insert buffer tree */
---- a/storage/innodb_plugin/include/fil0fil.h
-+++ b/storage/innodb_plugin/include/fil0fil.h
-@@ -657,8 +657,9 @@
- void
- fil_flush(
- /*======*/
--      ulint   space_id);      /*!< in: file space id (this can be a group of
-+      ulint   space_id,       /*!< in: file space id (this can be a group of
-                               log files or a tablespace of the database) */
-+      ibool   metadata);
- /**********************************************************************//**
- Flushes to disk writes in file spaces of the given type possibly cached by
- the OS. */
---- a/storage/innodb_plugin/include/ha_prototypes.h
-+++ b/storage/innodb_plugin/include/ha_prototypes.h
-@@ -268,4 +268,12 @@
-       void*   thd);   /*!< in: thread handle (THD*), or NULL to query
-                       the global innodb_lock_wait_timeout */
-+/******************************************************************//**
-+*/
-+
-+ulong
-+thd_flush_log_at_trx_commit_session(
-+/*================================*/
-+      void*   thd);
-+
- #endif
---- a/storage/innodb_plugin/include/os0file.h
-+++ b/storage/innodb_plugin/include/os0file.h
-@@ -466,7 +466,8 @@
- ibool
- os_file_flush(
- /*==========*/
--      os_file_t       file);  /*!< in, own: handle to a file */
-+      os_file_t       file,   /*!< in, own: handle to a file */
-+      ibool           metadata);
- /***********************************************************************//**
- Retrieves the last error number if an error occurs in a file io function.
- The number should be retrieved before any other OS calls (because they may
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -205,6 +205,16 @@
- extern ulong  srv_max_purge_lag;
- extern ulong  srv_replication_delay;
-+
-+extern long long      srv_ibuf_max_size;
-+extern ulint  srv_ibuf_active_contract;
-+extern ulint  srv_ibuf_accel_rate;
-+extern ulint  srv_checkpoint_age_target;
-+extern ulint  srv_flush_neighbor_pages;
-+extern ulint  srv_enable_unsafe_group_commit;
-+extern ulint  srv_read_ahead;
-+extern ulint  srv_adaptive_checkpoint;
-+
- /*-------------------------------------------*/
- extern ulint  srv_n_rows_inserted;
-@@ -338,8 +348,9 @@
-                               when writing data files, but do flush
-                               after writing to log files */
-       SRV_UNIX_NOSYNC,        /*!< do not flush after writing */
--      SRV_UNIX_O_DIRECT       /*!< invoke os_file_set_nocache() on
-+      SRV_UNIX_O_DIRECT,      /*!< invoke os_file_set_nocache() on
-                               data files */
-+      SRV_UNIX_ALL_O_DIRECT  /* new method for examination: logfile also open O_DIRECT */
- };
- /** Alternatives for file i/o in Windows */
---- a/storage/innodb_plugin/include/trx0trx.h
-+++ b/storage/innodb_plugin/include/trx0trx.h
-@@ -508,6 +508,7 @@
-                                       FALSE, one can save CPU time and about
-                                       150 bytes in the undo log size as then
-                                       we skip XA steps */
-+      ulint           flush_log_at_trx_commit_session;
-       ulint           flush_log_later;/* In 2PC, we hold the
-                                       prepare_commit mutex across
-                                       both phases. In that case, we
---- a/storage/innodb_plugin/log/log0log.c
-+++ b/storage/innodb_plugin/log/log0log.c
-@@ -347,6 +347,33 @@
- }
- /************************************************************//**
-+*/
-+UNIV_INLINE
-+ulint
-+log_max_modified_age_async()
-+{
-+      if (srv_checkpoint_age_target) {
-+              return(ut_min(log_sys->max_modified_age_async,
-+                              srv_checkpoint_age_target
-+                              - srv_checkpoint_age_target / 8));
-+      } else {
-+              return(log_sys->max_modified_age_async);
-+      }
-+}
-+
-+UNIV_INLINE
-+ulint
-+log_max_checkpoint_age_async()
-+{
-+      if (srv_checkpoint_age_target) {
-+              return(ut_min(log_sys->max_checkpoint_age_async,
-+                              srv_checkpoint_age_target));
-+      } else {
-+              return(log_sys->max_checkpoint_age_async);
-+      }
-+}
-+
-+/************************************************************//**
- Closes the log.
- @return       lsn */
- UNIV_INTERN
-@@ -415,7 +442,7 @@
-               }
-       }
--      if (checkpoint_age <= log->max_modified_age_async) {
-+      if (checkpoint_age <= log_max_modified_age_async()) {
-               goto function_exit;
-       }
-@@ -423,8 +450,8 @@
-       oldest_lsn = buf_pool_get_oldest_modification();
-       if (!oldest_lsn
--          || lsn - oldest_lsn > log->max_modified_age_async
--          || checkpoint_age > log->max_checkpoint_age_async) {
-+          || lsn - oldest_lsn > log_max_modified_age_async()
-+          || checkpoint_age > log_max_checkpoint_age_async()) {
-               log->check_flush_or_checkpoint = TRUE;
-       }
-@@ -1082,9 +1109,10 @@
-               group = (log_group_t*)((ulint)group - 1);
-               if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC
-+                  && srv_unix_file_flush_method != SRV_UNIX_ALL_O_DIRECT
-                   && srv_unix_file_flush_method != SRV_UNIX_NOSYNC) {
--                      fil_flush(group->space_id);
-+                      fil_flush(group->space_id, FALSE);
-               }
- #ifdef UNIV_DEBUG
-@@ -1103,10 +1131,11 @@
-                       logs and cannot end up here! */
-       if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC
-+          && srv_unix_file_flush_method != SRV_UNIX_ALL_O_DIRECT
-           && srv_unix_file_flush_method != SRV_UNIX_NOSYNC
-           && srv_flush_log_at_trx_commit != 2) {
--              fil_flush(group->space_id);
-+              fil_flush(group->space_id, FALSE);
-       }
-       mutex_enter(&(log_sys->mutex));
-@@ -1483,7 +1512,8 @@
-       mutex_exit(&(log_sys->mutex));
--      if (srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
-+      if (srv_unix_file_flush_method == SRV_UNIX_O_DSYNC
-+          || srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT) {
-               /* O_DSYNC means the OS did not buffer the log file at all:
-               so we have also flushed to disk what we have written */
-@@ -1493,7 +1523,7 @@
-               group = UT_LIST_GET_FIRST(log_sys->log_groups);
--              fil_flush(group->space_id);
-+              fil_flush(group->space_id, FALSE);
-               log_sys->flushed_to_disk_lsn = log_sys->write_lsn;
-       }
-@@ -2102,10 +2132,10 @@
-               sync = TRUE;
-               advance = 2 * (age - log->max_modified_age_sync);
--      } else if (age > log->max_modified_age_async) {
-+      } else if (age > log_max_modified_age_async()) {
-               /* A flush is not urgent: we do an asynchronous preflush */
--              advance = age - log->max_modified_age_async;
-+              advance = age - log_max_modified_age_async();
-       } else {
-               advance = 0;
-       }
-@@ -2119,7 +2149,7 @@
-               do_checkpoint = TRUE;
--      } else if (checkpoint_age > log->max_checkpoint_age_async) {
-+      } else if (checkpoint_age > log_max_checkpoint_age_async()) {
-               /* A checkpoint is not urgent: do it asynchronously */
-               do_checkpoint = TRUE;
-@@ -2587,7 +2617,7 @@
-       mutex_exit(&(log_sys->mutex));
--      fil_flush(group->archive_space_id);
-+      fil_flush(group->archive_space_id, TRUE);
-       mutex_enter(&(log_sys->mutex));
-@@ -3328,6 +3358,17 @@
-               log_sys->flushed_to_disk_lsn,
-               log_sys->last_checkpoint_lsn);
-+      fprintf(file,
-+              "Max checkpoint age    %lu\n"
-+              "Checkpoint age target %lu\n"
-+              "Modified age          %lu\n"
-+              "Checkpoint age        %lu\n",
-+                      (ulong) log_sys->max_checkpoint_age,
-+                      (ulong) log_max_checkpoint_age_async(),
-+                      (ulong) (log_sys->lsn -
-+                                      log_buf_pool_get_oldest_modification()),
-+                      (ulong) (log_sys->lsn - log_sys->last_checkpoint_lsn));
-+
-       current_time = time(NULL);
-       time_elapsed = 0.001 + difftime(current_time,
---- a/storage/innodb_plugin/log/log0recv.c
-+++ b/storage/innodb_plugin/log/log0recv.c
-@@ -2893,9 +2893,12 @@
-       ib_uint64_t     archived_lsn;
- #endif /* UNIV_LOG_ARCHIVE */
-       byte*           buf;
--      byte            log_hdr_buf[LOG_FILE_HDR_SIZE];
-+      byte*           log_hdr_buf;
-+      byte            log_hdr_buf_base[LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE];
-       ulint           err;
-+      log_hdr_buf = ut_align(log_hdr_buf_base, OS_FILE_LOG_BLOCK_SIZE);
-+
- #ifdef UNIV_LOG_ARCHIVE
-       ut_ad(type != LOG_CHECKPOINT || limit_lsn == IB_ULONGLONG_MAX);
- /** TRUE when recovering from a checkpoint */
-@@ -3453,7 +3456,7 @@
-                       exit(1);
-               }
--              os_file_flush(log_file);
-+              os_file_flush(log_file, TRUE);
-               os_file_close(log_file);
-       }
-@@ -3476,7 +3479,7 @@
-       os_file_write(name, log_file, buf, 0, 0,
-                     LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE);
--      os_file_flush(log_file);
-+      os_file_flush(log_file, TRUE);
-       os_file_close(log_file);
-       ut_free(buf);
---- a/storage/innodb_plugin/os/os0file.c
-+++ b/storage/innodb_plugin/os/os0file.c
-@@ -91,6 +91,28 @@
- /** Flag: enable debug printout for asynchronous i/o */
- UNIV_INTERN ibool     os_aio_print_debug      = FALSE;
-+/* State for the state of an IO request in simulated AIO.
-+   Protocol for simulated aio:
-+     client requests IO: find slot with reserved = FALSE. Add entry with
-+                         status = OS_AIO_NOT_ISSUED.
-+     IO thread wakes: find adjacent slots with reserved = TRUE and status =
-+                      OS_AIO_NOT_ISSUED. Change status for slots to
-+                      OS_AIO_ISSUED.
-+     IO operation completes: set status for slots to OS_AIO_DONE. set status
-+                             for the first slot to OS_AIO_CLAIMED and return
-+                             result for that slot.
-+   When there are multiple read and write threads, they all compete to execute
-+   the requests in the array (os_aio_array_t). This avoids the need to load
-+   balance requests at the time the request is made at the cost of waking all
-+   threads when a request is available.
-+*/
-+typedef enum {
-+      OS_AIO_NOT_ISSUED, /* Available to be processed by an IO thread. */
-+      OS_AIO_ISSUED,     /* Being processed by an IO thread. */
-+      OS_AIO_DONE,       /* Request processed. */
-+      OS_AIO_CLAIMED     /* Result being returned to client. */
-+} os_aio_status;
-+
- /** The asynchronous i/o array slot structure */
- typedef struct os_aio_slot_struct     os_aio_slot_t;
-@@ -100,6 +122,8 @@
-       ulint           pos;            /*!< index of the slot in the aio
-                                       array */
-       ibool           reserved;       /*!< TRUE if this slot is reserved */
-+      os_aio_status   status;         /* Status for current request. Valid when reserved
-+                                      is TRUE. Used only in simulated aio. */
-       time_t          reservation_time;/*!< time when reserved */
-       ulint           len;            /*!< length of the block to read or
-                                       write */
-@@ -110,11 +134,11 @@
-       ulint           offset_high;    /*!< 32 high bits of file offset */
-       os_file_t       file;           /*!< file where to read or write */
-       const char*     name;           /*!< file name or path */
--      ibool           io_already_done;/*!< used only in simulated aio:
--                                      TRUE if the physical i/o already
--                                      made and only the slot message
--                                      needs to be passed to the caller
--                                      of os_aio_simulated_handle */
-+//    ibool           io_already_done;/*!< used only in simulated aio:
-+//                                    TRUE if the physical i/o already
-+//                                    made and only the slot message
-+//                                    needs to be passed to the caller
-+//                                    of os_aio_simulated_handle */
-       fil_node_t*     message1;       /*!< message which is given by the */
-       void*           message2;       /*!< the requester of an aio operation
-                                       and which can be used to identify
-@@ -168,6 +192,13 @@
- /** Array of events used in simulated aio */
- static os_event_t*    os_aio_segment_wait_events      = NULL;
-+/* Number for the first global segment for reading. */
-+const ulint os_aio_first_read_segment = 2;
-+
-+/* Number for the first global segment for writing. Set to
-+2 + os_aio_read_write_threads. */
-+ulint os_aio_first_write_segment = 0;
-+
- /** The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
- are NULL when the module has not yet been initialized. @{ */
- static os_aio_array_t*        os_aio_read_array       = NULL; /*!< Reads */
-@@ -177,12 +208,18 @@
- static os_aio_array_t*        os_aio_sync_array       = NULL; /*!< Synchronous I/O */
- /* @} */
-+/* Per thread buffer used for merged IO requests. Used by
-+os_aio_simulated_handle so that a buffer doesn't have to be allocated
-+for each request. */
-+static byte* os_aio_thread_buffer[SRV_MAX_N_IO_THREADS];
-+static ulint os_aio_thread_buffer_size[SRV_MAX_N_IO_THREADS];
-+
- /** Number of asynchronous I/O segments.  Set by os_aio_init(). */
- static ulint  os_aio_n_segments       = ULINT_UNDEFINED;
- /** If the following is TRUE, read i/o handler threads try to
- wait until a batch of new read requests have been posted */
--static ibool  os_aio_recommend_sleep_for_read_threads = FALSE;
-+static volatile ibool os_aio_recommend_sleep_for_read_threads = FALSE;
- #endif /* UNIV_HOTBACKUP */
- UNIV_INTERN ulint     os_n_file_reads         = 0;
-@@ -1445,6 +1482,11 @@
-               os_file_set_nocache(file, name, mode_str);
-       }
-+      /* ALL_O_DIRECT: O_DIRECT also for transaction log file */
-+      if (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT) {
-+              os_file_set_nocache(file, name, mode_str);
-+      }
-+
- #ifdef USE_FILE_LOCK
-       if (create_mode != OS_FILE_OPEN_RAW && os_file_lock(file, name)) {
-@@ -1866,7 +1908,7 @@
-       ut_free(buf2);
--      ret = os_file_flush(file);
-+      ret = os_file_flush(file, TRUE);
-       if (ret) {
-               return(TRUE);
-@@ -1904,7 +1946,8 @@
- int
- os_file_fsync(
- /*==========*/
--      os_file_t       file)   /*!< in: handle to a file */
-+      os_file_t       file,   /*!< in: handle to a file */
-+      ibool           metadata)
- {
-       int     ret;
-       int     failures;
-@@ -1913,7 +1956,16 @@
-       failures = 0;
-       do {
-+#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC
-+              if (metadata) {
-+                      ret = fsync(file);
-+              } else {
-+                      ret = fdatasync(file);
-+              }
-+#else
-+              (void) metadata;
-               ret = fsync(file);
-+#endif
-               os_n_fsyncs++;
-@@ -1949,7 +2001,8 @@
- ibool
- os_file_flush(
- /*==========*/
--      os_file_t       file)   /*!< in, own: handle to a file */
-+      os_file_t       file,   /*!< in, own: handle to a file */
-+      ibool           metadata)
- {
- #ifdef __WIN__
-       BOOL    ret;
-@@ -1999,18 +2052,18 @@
-               /* If we are not on an operating system that supports this,
-               then fall back to a plain fsync. */
--              ret = os_file_fsync(file);
-+              ret = os_file_fsync(file, metadata);
-       } else {
-               ret = fcntl(file, F_FULLFSYNC, NULL);
-               if (ret) {
-                       /* If we are not on a file system that supports this,
-                       then fall back to a plain fsync. */
--                      ret = os_file_fsync(file);
-+                      ret = os_file_fsync(file, metadata);
-               }
-       }
- #else
--      ret = os_file_fsync(file);
-+      ret = os_file_fsync(file, metadata);
- #endif
-       if (ret == 0) {
-@@ -2193,7 +2246,7 @@
-               the OS crashes, a database page is only partially
-               physically written to disk. */
--              ut_a(TRUE == os_file_flush(file));
-+              ut_a(TRUE == os_file_flush(file, TRUE));
-       }
- # endif /* UNIV_DO_FLUSH */
-@@ -2235,7 +2288,7 @@
-                       the OS crashes, a database page is only partially
-                       physically written to disk. */
--                      ut_a(TRUE == os_file_flush(file));
-+                      ut_a(TRUE == os_file_flush(file, TRUE));
-               }
- # endif /* UNIV_DO_FLUSH */
-@@ -2601,7 +2654,7 @@
- # ifdef UNIV_DO_FLUSH
-       if (!os_do_not_call_flush_at_each_write) {
--              ut_a(TRUE == os_file_flush(file));
-+              ut_a(TRUE == os_file_flush(file, TRUE));
-       }
- # endif /* UNIV_DO_FLUSH */
-@@ -3088,11 +3141,14 @@
-       for (i = 0; i < n_segments; i++) {
-               srv_set_io_thread_op_info(i, "not started yet");
-+              os_aio_thread_buffer[i] = 0;
-+              os_aio_thread_buffer_size[i] = 0;
-       }
-       /* fprintf(stderr, "Array n per seg %lu\n", n_per_seg); */
-+      os_aio_first_write_segment = os_aio_first_read_segment + n_read_segs;
-       os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
-       srv_io_thread_function[0] = "insert buffer thread";
-@@ -3101,14 +3157,14 @@
-       srv_io_thread_function[1] = "log thread";
--      os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg,
-+      os_aio_read_array = os_aio_array_create(n_per_seg,
-                                               n_read_segs);
-       for (i = 2; i < 2 + n_read_segs; i++) {
-               ut_a(i < SRV_MAX_N_IO_THREADS);
-               srv_io_thread_function[i] = "read thread";
-       }
--      os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg,
-+      os_aio_write_array = os_aio_array_create(n_per_seg,
-                                                n_write_segs);
-       for (i = 2 + n_read_segs; i < n_segments; i++) {
-               ut_a(i < SRV_MAX_N_IO_THREADS);
-@@ -3390,7 +3446,8 @@
-       slot->buf      = buf;
-       slot->offset   = offset;
-       slot->offset_high = offset_high;
--      slot->io_already_done = FALSE;
-+//    slot->io_already_done = FALSE;
-+      slot->status = OS_AIO_NOT_ISSUED;
- #ifdef WIN_ASYNC_IO
-       control = &(slot->control);
-@@ -3421,6 +3478,7 @@
-       ut_ad(slot->reserved);
-       slot->reserved = FALSE;
-+      slot->status = OS_AIO_NOT_ISSUED;
-       array->n_reserved--;
-@@ -3457,16 +3515,18 @@
-       segment = os_aio_get_array_and_local_segment(&array, global_segment);
--      n = array->n_slots / array->n_segments;
-+      n = array->n_slots;
-       /* Look through n slots after the segment * n'th slot */
-       os_mutex_enter(array->mutex);
-       for (i = 0; i < n; i++) {
--              slot = os_aio_array_get_nth_slot(array, i + segment * n);
-+              slot = os_aio_array_get_nth_slot(array, i);
--              if (slot->reserved) {
-+              if (slot->reserved &&
-+                  (slot->status == OS_AIO_NOT_ISSUED ||
-+                   slot->status == OS_AIO_DONE)) {
-                       /* Found an i/o request */
-                       break;
-@@ -3476,7 +3536,25 @@
-       os_mutex_exit(array->mutex);
-       if (i < n) {
--              os_event_set(os_aio_segment_wait_events[global_segment]);
-+              if (array == os_aio_ibuf_array) {
-+                      os_event_set(os_aio_segment_wait_events[0]);
-+
-+              } else if (array == os_aio_log_array) {
-+                      os_event_set(os_aio_segment_wait_events[1]);
-+
-+              } else if (array == os_aio_read_array) {
-+                      ulint   x;
-+                      for (x = os_aio_first_read_segment; x < os_aio_first_write_segment; x++)
-+                              os_event_set(os_aio_segment_wait_events[x]);
-+
-+              } else if (array == os_aio_write_array) {
-+                      ulint   x;
-+                      for (x = os_aio_first_write_segment; x < os_aio_n_segments; x++)
-+                              os_event_set(os_aio_segment_wait_events[x]);
-+
-+              } else {
-+                      ut_a(0);
-+              }
-       }
- }
-@@ -3487,8 +3565,6 @@
- os_aio_simulated_wake_handler_threads(void)
- /*=======================================*/
- {
--      ulint   i;
--
-       if (os_aio_use_native_aio) {
-               /* We do not use simulated aio: do nothing */
-@@ -3497,9 +3573,10 @@
-       os_aio_recommend_sleep_for_read_threads = FALSE;
--      for (i = 0; i < os_aio_n_segments; i++) {
--              os_aio_simulated_wake_handler_thread(i);
--      }
-+      os_aio_simulated_wake_handler_thread(0);
-+      os_aio_simulated_wake_handler_thread(1);
-+      os_aio_simulated_wake_handler_thread(os_aio_first_read_segment);
-+      os_aio_simulated_wake_handler_thread(os_aio_first_write_segment);
- }
- /**********************************************************************//**
-@@ -3790,7 +3867,7 @@
-       ut_ad(os_aio_validate());
-       ut_ad(segment < array->n_segments);
--      n = array->n_slots / array->n_segments;
-+      n = array->n_slots;
-       if (array == os_aio_sync_array) {
-               os_event_wait(os_aio_array_get_nth_slot(array, pos)->event);
-@@ -3799,12 +3876,12 @@
-               srv_set_io_thread_op_info(orig_seg, "wait Windows aio");
-               i = os_event_wait_multiple(n,
-                                          (array->native_events)
--                                         + segment * n);
-+                                         );
-       }
-       os_mutex_enter(array->mutex);
--      slot = os_aio_array_get_nth_slot(array, i + segment * n);
-+      slot = os_aio_array_get_nth_slot(array, i);
-       ut_a(slot->reserved);
-@@ -3826,7 +3903,7 @@
- #ifdef UNIV_DO_FLUSH
-               if (slot->type == OS_FILE_WRITE
-                   && !os_do_not_call_flush_at_each_write) {
--                      ut_a(TRUE == os_file_flush(slot->file));
-+                      ut_a(TRUE == os_file_flush(slot->file, TRUE));
-               }
- #endif /* UNIV_DO_FLUSH */
-       } else if (os_file_handle_error(slot->name, "Windows aio")) {
-@@ -3909,10 +3986,13 @@
-       os_aio_slot_t*  slot;
-       os_aio_slot_t*  slot2;
-       os_aio_slot_t*  consecutive_ios[OS_AIO_MERGE_N_CONSECUTIVE];
-+      os_aio_slot_t*  lowest_request;
-+      os_aio_slot_t*  oldest_request;
-       ulint           n_consecutive;
-       ulint           total_len;
-       ulint           offs;
-       ulint           lowest_offset;
-+      ulint           oldest_offset;
-       ulint           biggest_age;
-       ulint           age;
-       byte*           combined_buf;
-@@ -3920,6 +4000,7 @@
-       ibool           ret;
-       ulint           n;
-       ulint           i;
-+      time_t          now;
-       /* Fix compiler warning */
-       *consecutive_ios = NULL;
-@@ -3935,7 +4016,7 @@
-       ut_ad(os_aio_validate());
-       ut_ad(segment < array->n_segments);
--      n = array->n_slots / array->n_segments;
-+      n = array->n_slots;
-       /* Look through n slots after the segment * n'th slot */
-@@ -3957,9 +4038,9 @@
-       done */
-       for (i = 0; i < n; i++) {
--              slot = os_aio_array_get_nth_slot(array, i + segment * n);
-+              slot = os_aio_array_get_nth_slot(array, i);
--              if (slot->reserved && slot->io_already_done) {
-+              if (slot->reserved && slot->status == OS_AIO_DONE) {
-                       if (os_aio_print_debug) {
-                               fprintf(stderr,
-@@ -3981,67 +4062,57 @@
-       then pick the one at the lowest offset. */
-       biggest_age = 0;
--      lowest_offset = ULINT_MAX;
-+      now = time(NULL);
-+      oldest_request = lowest_request = NULL;
-+      oldest_offset = lowest_offset = ULINT_MAX;
-+      /* Find the oldest request and the request with the smallest offset */
-       for (i = 0; i < n; i++) {
--              slot = os_aio_array_get_nth_slot(array, i + segment * n);
-+              slot = os_aio_array_get_nth_slot(array, i);
--              if (slot->reserved) {
--                      age = (ulint)difftime(time(NULL),
--                                            slot->reservation_time);
-+              if (slot->reserved && slot->status == OS_AIO_NOT_ISSUED) {
-+                      age = (ulint)difftime(now, slot->reservation_time);
-                       if ((age >= 2 && age > biggest_age)
-                           || (age >= 2 && age == biggest_age
--                              && slot->offset < lowest_offset)) {
-+                              && slot->offset < oldest_offset)) {
-                               /* Found an i/o request */
--                              consecutive_ios[0] = slot;
--
--                              n_consecutive = 1;
--
-                               biggest_age = age;
--                              lowest_offset = slot->offset;
-+                              oldest_request = slot;
-+                              oldest_offset = slot->offset;
-                       }
--              }
--      }
--
--      if (n_consecutive == 0) {
--              /* There were no old requests. Look for an i/o request at the
--              lowest offset in the array (we ignore the high 32 bits of the
--              offset in these heuristics) */
--
--              lowest_offset = ULINT_MAX;
--
--              for (i = 0; i < n; i++) {
--                      slot = os_aio_array_get_nth_slot(array,
--                                                       i + segment * n);
--
--                      if (slot->reserved && slot->offset < lowest_offset) {
-+                      /* Look for an i/o request at the lowest offset in the array
-+                       * (we ignore the high 32 bits of the offset) */
-+                      if (slot->offset < lowest_offset) {
-                               /* Found an i/o request */
--                              consecutive_ios[0] = slot;
--
--                              n_consecutive = 1;
--
-+                              lowest_request = slot;
-                               lowest_offset = slot->offset;
-                       }
-               }
-       }
--      if (n_consecutive == 0) {
-+      if (!lowest_request && !oldest_request) {
-               /* No i/o requested at the moment */
-               goto wait_for_io;
-       }
--      slot = consecutive_ios[0];
-+      if (oldest_request) {
-+              slot = oldest_request;
-+      } else {
-+              slot = lowest_request;
-+      }
-+      consecutive_ios[0] = slot;
-+      n_consecutive = 1;
-       /* Check if there are several consecutive blocks to read or write */
- consecutive_loop:
-       for (i = 0; i < n; i++) {
--              slot2 = os_aio_array_get_nth_slot(array, i + segment * n);
-+              slot2 = os_aio_array_get_nth_slot(array, i);
-               if (slot2->reserved && slot2 != slot
-                   && slot2->offset == slot->offset + slot->len
-@@ -4049,7 +4120,8 @@
-                   && slot->offset + slot->len > slot->offset
-                   && slot2->offset_high == slot->offset_high
-                   && slot2->type == slot->type
--                  && slot2->file == slot->file) {
-+                  && slot2->file == slot->file
-+                  && slot2->status == OS_AIO_NOT_ISSUED) {
-                       /* Found a consecutive i/o request */
-@@ -4078,6 +4150,8 @@
-       for (i = 0; i < n_consecutive; i++) {
-               total_len += consecutive_ios[i]->len;
-+              ut_a(consecutive_ios[i]->status == OS_AIO_NOT_ISSUED);
-+              consecutive_ios[i]->status = OS_AIO_ISSUED;
-       }
-       if (n_consecutive == 1) {
-@@ -4085,7 +4159,14 @@
-               combined_buf = slot->buf;
-               combined_buf2 = NULL;
-       } else {
--              combined_buf2 = ut_malloc(total_len + UNIV_PAGE_SIZE);
-+              if ((total_len + UNIV_PAGE_SIZE) > os_aio_thread_buffer_size[global_segment]) {
-+                      if (os_aio_thread_buffer[global_segment])
-+                              ut_free(os_aio_thread_buffer[global_segment]);
-+
-+                      os_aio_thread_buffer[global_segment] = ut_malloc(total_len + UNIV_PAGE_SIZE);
-+                      os_aio_thread_buffer_size[global_segment] = total_len + UNIV_PAGE_SIZE;
-+              }
-+              combined_buf2 = os_aio_thread_buffer[global_segment];
-               ut_a(combined_buf2);
-@@ -4096,6 +4177,9 @@
-       this assumes that there is just one i/o-handler thread serving
-       a single segment of slots! */
-+      ut_a(slot->reserved);
-+      ut_a(slot->status == OS_AIO_ISSUED);
-+
-       os_mutex_exit(array->mutex);
-       if (slot->type == OS_FILE_WRITE && n_consecutive > 1) {
-@@ -4151,16 +4235,13 @@
-               }
-       }
--      if (combined_buf2) {
--              ut_free(combined_buf2);
--      }
--
-       os_mutex_enter(array->mutex);
-       /* Mark the i/os done in slots */
-       for (i = 0; i < n_consecutive; i++) {
--              consecutive_ios[i]->io_already_done = TRUE;
-+              ut_a(consecutive_ios[i]->status == OS_AIO_ISSUED);
-+              consecutive_ios[i]->status = OS_AIO_DONE;
-       }
-       /* We return the messages for the first slot now, and if there were
-@@ -4170,6 +4251,8 @@
- slot_io_done:
-       ut_a(slot->reserved);
-+      ut_a(slot->status == OS_AIO_DONE);
-+      slot->status = OS_AIO_CLAIMED;
-       *message1 = slot->message1;
-       *message2 = slot->message2;
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -377,6 +377,17 @@
- UNIV_INTERN ulong     srv_replication_delay           = 0;
-+UNIV_INTERN long long srv_ibuf_max_size = 0;
-+UNIV_INTERN ulint     srv_ibuf_active_contract = 0; /* 0:disable 1:enable */
-+UNIV_INTERN ulint     srv_ibuf_accel_rate = 100;
-+#define PCT_IBUF_IO(pct) ((ulint) (srv_io_capacity * srv_ibuf_accel_rate * ((double) pct / 10000.0)))
-+
-+UNIV_INTERN ulint     srv_checkpoint_age_target = 0;
-+UNIV_INTERN ulint     srv_flush_neighbor_pages = 1; /* 0:disable 1:enable */
-+
-+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_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
- /*-------------------------------------------*/
- UNIV_INTERN ulong     srv_n_spin_wait_rounds  = 30;
- UNIV_INTERN ulong     srv_n_free_tickets_to_enter = 500;
-@@ -2495,15 +2506,31 @@
-       ulint           n_pages_purged  = 0;
-       ulint           n_bytes_merged;
-       ulint           n_pages_flushed;
-+      ulint           n_pages_flushed_prev = 0;
-       ulint           n_bytes_archived;
-       ulint           n_tables_to_drop;
-       ulint           n_ios;
-       ulint           n_ios_old;
-       ulint           n_ios_very_old;
-       ulint           n_pend_ios;
-+      ulint           next_itr_time;
-+      ulint           prev_adaptive_checkpoint = ULINT_UNDEFINED;
-+      ulint           inner_loop = 0;
-       ibool           skip_sleep      = FALSE;
-       ulint           i;
-+      struct t_prev_flush_info_struct {
-+              ulint           count;
-+              unsigned        space:32;
-+              unsigned        offset:32;
-+              ib_uint64_t     oldest_modification;
-+      };
-+      struct t_prev_flush_info_struct prev_flush_info = {0,0,0,0};
-+
-+      ib_uint64_t     lsn_old;
-+
-+      ib_uint64_t     oldest_lsn;
-+
- #ifdef UNIV_DEBUG_THREAD_CREATION
-       fprintf(stderr, "Master thread starts, id %lu\n",
-               os_thread_pf(os_thread_get_curr_id()));
-@@ -2519,6 +2546,9 @@
-       mutex_exit(&kernel_mutex);
-+      mutex_enter(&(log_sys->mutex));
-+      lsn_old = log_sys->lsn;
-+      mutex_exit(&(log_sys->mutex));
- loop:
-       /*****************************************************************/
-       /* ---- When there is database activity by users, we cycle in this
-@@ -2546,16 +2576,40 @@
-       srv_last_log_flush_time = time(NULL);
-       skip_sleep = FALSE;
-+      next_itr_time = ut_time_ms() + 1000;
-+
-       for (i = 0; i < 10; i++) {
-+              ulint   cur_time = ut_time_ms();
-+
-+              n_pages_flushed = 0; /* initialize */
-+
-               n_ios_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
-                       + buf_pool->stat.n_pages_written;
-               srv_main_thread_op_info = "sleeping";
-               srv_main_1_second_loops++;
-               if (!skip_sleep) {
-+              if (next_itr_time > cur_time) {
--                      os_thread_sleep(1000000);
-+                      os_thread_sleep(ut_min(1000000, (next_itr_time - cur_time) * 1000));
-                       srv_main_sleeps++;
-+
-+                      /*
-+                      mutex_enter(&(log_sys->mutex));
-+                      oldest_lsn = buf_pool_get_oldest_modification();
-+                      ib_uint64_t     lsn = log_sys->lsn;
-+                      mutex_exit(&(log_sys->mutex));
-+
-+                      if(oldest_lsn)
-+                      fprintf(stderr,
-+                              "InnoDB flush: age pct: %lu, lsn progress: %lu\n",
-+                              (lsn - oldest_lsn) * 100 / log_sys->max_checkpoint_age,
-+                              lsn - lsn_old);
-+                      */
-+              }
-+
-+              /* Each iteration should happen at 1 second interval. */
-+              next_itr_time = ut_time_ms() + 1000;
-               }
-               skip_sleep = FALSE;
-@@ -2592,7 +2646,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";
--                      ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
-+                      ibuf_contract_for_n_pages(FALSE, PCT_IBUF_IO(5));
-                       /* Flush logs if needed */
-                       srv_sync_log_buffer_in_background();
-@@ -2616,6 +2670,11 @@
-                       iteration of this loop. */
-                       skip_sleep = TRUE;
-+
-+                      mutex_enter(&(log_sys->mutex));
-+                      lsn_old = log_sys->lsn;
-+                      mutex_exit(&(log_sys->mutex));
-+                      prev_adaptive_checkpoint = ULINT_UNDEFINED;
-               } else if (srv_adaptive_flushing) {
-                       /* Try to keep the rate of flushing of dirty
-@@ -2637,6 +2696,256 @@
-                                       skip_sleep = TRUE;
-                               }
-                       }
-+
-+                      mutex_enter(&(log_sys->mutex));
-+                      lsn_old = log_sys->lsn;
-+                      mutex_exit(&(log_sys->mutex));
-+                      prev_adaptive_checkpoint = ULINT_UNDEFINED;
-+              } else if (srv_adaptive_checkpoint == 1) {
-+                      /* adaptive_flushing option is prior to adaptive_checkpoint option, for now */
-+
-+                      /* Try to keep modified age not to exceed
-+                      max_checkpoint_age * 7/8 line */
-+
-+                      mutex_enter(&(log_sys->mutex));
-+                      lsn_old = log_sys->lsn;
-+                      oldest_lsn = buf_pool_get_oldest_modification();
-+                      if (oldest_lsn == 0) {
-+
-+                              mutex_exit(&(log_sys->mutex));
-+
-+                      } else {
-+                              if ((log_sys->lsn - oldest_lsn)
-+                                  > (log_sys->max_checkpoint_age) - ((log_sys->max_checkpoint_age) / 8)) {
-+                                      /* LOG_POOL_PREFLUSH_RATIO_ASYNC is exceeded. */
-+                                      /* We should not flush from here. */
-+                                      mutex_exit(&(log_sys->mutex));
-+                              } else if ((log_sys->lsn - oldest_lsn)
-+                                  > (log_sys->max_checkpoint_age) - ((log_sys->max_checkpoint_age) / 4)) {
-+
-+                                      /* 2nd defence line (max_checkpoint_age * 3/4) */
-+
-+                                      mutex_exit(&(log_sys->mutex));
-+
-+                                      n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
-+                                                                        IB_ULONGLONG_MAX);
-+                                      skip_sleep = TRUE;
-+                              } else if ((log_sys->lsn - oldest_lsn)
-+                                         > (log_sys->max_checkpoint_age)/2 ) {
-+
-+                                      /* 1st defence line (max_checkpoint_age * 1/2) */
-+
-+                                      mutex_exit(&(log_sys->mutex));
-+
-+                                      n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(10),
-+                                                                        IB_ULONGLONG_MAX);
-+                                      skip_sleep = TRUE;
-+                              } else {
-+                                      mutex_exit(&(log_sys->mutex));
-+                              }
-+                      }
-+                      prev_adaptive_checkpoint = 1;
-+              } else if (srv_adaptive_checkpoint == 2) {
-+
-+                      /* Try to keep modified age not to exceed
-+                      max_checkpoint_age * 7/8 line */
-+
-+                      mutex_enter(&(log_sys->mutex));
-+
-+                      oldest_lsn = buf_pool_get_oldest_modification();
-+                      if (oldest_lsn == 0) {
-+                              lsn_old = log_sys->lsn;
-+                              mutex_exit(&(log_sys->mutex));
-+
-+                      } else {
-+                              if ((log_sys->lsn - oldest_lsn)
-+                                  > (log_sys->max_checkpoint_age) - ((log_sys->max_checkpoint_age) / 8)) {
-+                                      /* LOG_POOL_PREFLUSH_RATIO_ASYNC is exceeded. */
-+                                      /* We should not flush from here. */
-+                                      lsn_old = log_sys->lsn;
-+                                      mutex_exit(&(log_sys->mutex));
-+                              } else if ((log_sys->lsn - oldest_lsn)
-+                                         > (log_sys->max_checkpoint_age)/4 ) {
-+
-+                                      /* defence line (max_checkpoint_age * 1/2) */
-+                                      ib_uint64_t     lsn = log_sys->lsn;
-+
-+                                      ib_uint64_t level, bpl;
-+                                      buf_page_t* bpage;
-+
-+                                      mutex_exit(&(log_sys->mutex));
-+
-+                                      buf_pool_mutex_enter();
-+
-+                                      level = 0;
-+                                      bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-+
-+                                      while (bpage != NULL) {
-+                                              ib_uint64_t     oldest_modification = bpage->oldest_modification;
-+                                              if (oldest_modification != 0) {
-+                                                      level += log_sys->max_checkpoint_age
-+                                                               - (lsn - oldest_modification);
-+                                              }
-+                                              bpage = UT_LIST_GET_NEXT(flush_list, bpage);
-+                                      }
-+
-+                                      if (level) {
-+                                              bpl = ((ib_uint64_t) UT_LIST_GET_LEN(buf_pool->flush_list)
-+                                                      * UT_LIST_GET_LEN(buf_pool->flush_list)
-+                                                      * (lsn - lsn_old)) / level;
-+                                      } else {
-+                                              bpl = 0;
-+                                      }
-+
-+                                      buf_pool_mutex_exit();
-+
-+                                      if (!srv_use_doublewrite_buf) {
-+                                              /* flush is faster than when doublewrite */
-+                                              bpl = (bpl * 7) / 8;
-+                                      }
-+
-+                                      if (bpl) {
-+retry_flush_batch:
-+                                              n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
-+                                                                      bpl,
-+                                                                      oldest_lsn + (lsn - lsn_old));
-+                                              if (n_pages_flushed == ULINT_UNDEFINED) {
-+                                                      os_thread_sleep(5000);
-+                                                      goto retry_flush_batch;
-+                                              }
-+                                      }
-+
-+                                      lsn_old = lsn;
-+                                      /*
-+                                      fprintf(stderr,
-+                                              "InnoDB flush: age pct: %lu, lsn progress: %lu, blocks to flush:%llu\n",
-+                                              (lsn - oldest_lsn) * 100 / log_sys->max_checkpoint_age,
-+                                              lsn - lsn_old, bpl);
-+                                      */
-+                              } else {
-+                                      lsn_old = log_sys->lsn;
-+                                      mutex_exit(&(log_sys->mutex));
-+                              }
-+                      }
-+                      prev_adaptive_checkpoint = 2;
-+              } else if (srv_adaptive_checkpoint == 3) {
-+                      buf_page_t*     bpage;
-+                      ib_uint64_t     lsn;
-+
-+                      mutex_enter(&(log_sys->mutex));
-+                      oldest_lsn = buf_pool_get_oldest_modification();
-+                      lsn = log_sys->lsn;
-+                      mutex_exit(&(log_sys->mutex));
-+
-+                      /* upper loop/sec. (x10) */
-+                      next_itr_time -= 900; /* 1000 - 900 == 100 */
-+                      inner_loop++;
-+                      if (inner_loop < 10) {
-+                              i--;
-+                      } else {
-+                              inner_loop = 0;
-+                      }
-+
-+                      if (prev_adaptive_checkpoint == 3) {
-+                              lint    n_flush;
-+                              lint    blocks_sum;
-+                              ulint   new_blocks_sum, flushed_blocks_sum;
-+
-+                              blocks_sum = new_blocks_sum = flushed_blocks_sum = 0;
-+
-+                              /* prev_flush_info should be the previous loop's */
-+                              {
-+                                      lint    blocks_num, new_blocks_num, flushed_blocks_num;
-+                                      ibool   found;
-+
-+                                      blocks_num = UT_LIST_GET_LEN(buf_pool->flush_list);
-+                                      bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-+                                      new_blocks_num = 0;
-+
-+                                      found = FALSE;
-+                                      while (bpage != NULL) {
-+                                              if (prev_flush_info.space == bpage->space
-+                                                  && prev_flush_info.offset == bpage->offset
-+                                                  && prev_flush_info.oldest_modification
-+                                                              == bpage->oldest_modification) {
-+                                                      found = TRUE;
-+                                                      break;
-+                                              }
-+                                              bpage = UT_LIST_GET_NEXT(flush_list, bpage);
-+                                              new_blocks_num++;
-+                                      }
-+                                      if (!found) {
-+                                              new_blocks_num = blocks_num;
-+                                      }
-+
-+                                      flushed_blocks_num = new_blocks_num + prev_flush_info.count
-+                                                              - blocks_num;
-+                                      if (flushed_blocks_num < 0) {
-+                                              flushed_blocks_num = 0;
-+                                      }
-+
-+                                      bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-+
-+                                      prev_flush_info.count = UT_LIST_GET_LEN(buf_pool->flush_list);
-+                                      if (bpage) {
-+                                              prev_flush_info.space = bpage->space;
-+                                              prev_flush_info.offset = bpage->offset;
-+                                              prev_flush_info.oldest_modification = bpage->oldest_modification;
-+                                      } else {
-+                                              prev_flush_info.space = 0;
-+                                              prev_flush_info.offset = 0;
-+                                              prev_flush_info.oldest_modification = 0;
-+                                      }
-+
-+                                      new_blocks_sum += new_blocks_num;
-+                                      flushed_blocks_sum += flushed_blocks_num;
-+                                      blocks_sum += blocks_num;
-+                              }
-+
-+                              n_flush = blocks_sum * (lsn - lsn_old) / log_sys->max_modified_age_async;
-+                              if (flushed_blocks_sum > n_pages_flushed_prev) {
-+                                      n_flush -= (flushed_blocks_sum - n_pages_flushed_prev);
-+                              }
-+
-+                              if (n_flush > 0) {
-+                                      n_flush++;
-+                                      n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, n_flush,
-+                                                                        oldest_lsn + (lsn - lsn_old));
-+                              } else {
-+                                      n_pages_flushed = 0;
-+                              }                                       
-+                      } else {
-+                              /* store previous first pages of the flush_list */
-+                              {
-+                                      bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-+
-+                                      prev_flush_info.count = UT_LIST_GET_LEN(buf_pool->flush_list);
-+                                      if (bpage) {
-+                                              prev_flush_info.space = bpage->space;
-+                                              prev_flush_info.offset = bpage->offset;
-+                                              prev_flush_info.oldest_modification = bpage->oldest_modification;
-+                                      } else {
-+                                              prev_flush_info.space = 0;
-+                                              prev_flush_info.offset = 0;
-+                                              prev_flush_info.oldest_modification = 0;
-+                                      }
-+                              }
-+                              n_pages_flushed = 0;
-+                      }
-+
-+                      lsn_old = lsn;
-+                      prev_adaptive_checkpoint = 3;
-+              } else {
-+                      mutex_enter(&(log_sys->mutex));
-+                      lsn_old = log_sys->lsn;
-+                      mutex_exit(&(log_sys->mutex));
-+                      prev_adaptive_checkpoint = ULINT_UNDEFINED;
-+              }
-+
-+              if (n_pages_flushed == ULINT_UNDEFINED) {
-+                      n_pages_flushed_prev = 0;
-+              } else {
-+                      n_pages_flushed_prev = n_pages_flushed;
-               }
-               if (srv_activity_count == old_activity_count) {
-@@ -2685,7 +2994,7 @@
-       even if the server were active */
-       srv_main_thread_op_info = "doing insert buffer merge";
--      ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
-+      ibuf_contract_for_n_pages(FALSE, PCT_IBUF_IO(5));
-       /* Flush logs if needed */
-       srv_sync_log_buffer_in_background();
-@@ -2810,7 +3119,7 @@
-               buf_flush_batch below. Otherwise, the system favors
-               clean pages over cleanup throughput. */
-               n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
--                                                         PCT_IO(100));
-+                                                         PCT_IBUF_IO(100));
-       }
-       srv_main_thread_op_info = "reserving kernel mutex";
---- a/storage/innodb_plugin/srv/srv0start.c
-+++ b/storage/innodb_plugin/srv/srv0start.c
-@@ -1141,7 +1141,12 @@
-               break;
-       default:
-               /* On Win 2000 and XP use async i/o */
--              os_aio_use_native_aio = TRUE;
-+              //os_aio_use_native_aio = TRUE;
-+              os_aio_use_native_aio = FALSE;
-+              fprintf(stderr,
-+                      "InnoDB: Windows native async i/o is disabled as default.\n"
-+                      "InnoDB:   It is not applicable for the current"
-+                      " multi io threads implementation.\n");
-               break;
-       }
- #endif
-@@ -1161,6 +1166,9 @@
-       } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
-               srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
-+      } else if (0 == ut_strcmp(srv_file_flush_method_str, "ALL_O_DIRECT")) {
-+              srv_unix_file_flush_method = SRV_UNIX_ALL_O_DIRECT;
-+
-       } else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
-               srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
-@@ -1178,6 +1186,12 @@
-       } else if (0 == ut_strcmp(srv_file_flush_method_str,
-                                 "async_unbuffered")) {
-               srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
-+              os_aio_use_native_aio = TRUE;
-+              srv_n_read_io_threads = srv_n_write_io_threads = 1;
-+              fprintf(stderr,
-+                      "InnoDB: 'async_unbuffered' was detected as innodb_flush_method.\n"
-+                      "InnoDB:   Windows native async i/o is enabled.\n"
-+                      "InnoDB:   And io threads are restricted.\n");
- #endif
-       } else {
-               fprintf(stderr,
---- a/storage/innodb_plugin/trx/trx0trx.c
-+++ b/storage/innodb_plugin/trx/trx0trx.c
-@@ -112,6 +112,8 @@
-       trx->support_xa = TRUE;
-+      trx->flush_log_at_trx_commit_session = 3; /* means to use innodb_flush_log_at_trx_commit value */
-+
-       trx->check_foreigns = TRUE;
-       trx->check_unique_secondary = TRUE;
-@@ -764,6 +766,9 @@
-       generated by the same transaction, doesn't. */
-       trx->support_xa = thd_supports_xa(trx->mysql_thd);
-+      trx->flush_log_at_trx_commit_session =
-+              thd_flush_log_at_trx_commit_session(trx->mysql_thd);
-+
-       mutex_enter(&kernel_mutex);
-       ret = trx_start_low(trx, rseg_id);
-@@ -927,6 +932,7 @@
-       trx->read_view = NULL;
-       if (lsn) {
-+              ulint   flush_log_at_trx_commit;
-               mutex_exit(&kernel_mutex);
-@@ -935,6 +941,12 @@
-                       trx_undo_insert_cleanup(trx);
-               }
-+              if (trx->flush_log_at_trx_commit_session == 3) {
-+                      flush_log_at_trx_commit = srv_flush_log_at_trx_commit;
-+              } else {
-+                      flush_log_at_trx_commit = trx->flush_log_at_trx_commit_session;
-+              }
-+
-               /* NOTE that we could possibly make a group commit more
-               efficient here: call os_thread_yield here to allow also other
-               trxs to come to commit! */
-@@ -966,9 +978,9 @@
-               if (trx->flush_log_later) {
-                       /* Do nothing yet */
-                       trx->must_flush_log_later = TRUE;
--              } else if (srv_flush_log_at_trx_commit == 0) {
-+              } else if (flush_log_at_trx_commit == 0) {
-                       /* Do nothing */
--              } else if (srv_flush_log_at_trx_commit == 1) {
-+              } else if (flush_log_at_trx_commit == 1) {
-                       if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
-                               /* Write the log but do not flush it to disk */
-@@ -980,7 +992,7 @@
-                               log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
-                       }
--              } else if (srv_flush_log_at_trx_commit == 2) {
-+              } else if (flush_log_at_trx_commit == 2) {
-                       /* Write the log but do not flush it to disk */
-@@ -1644,16 +1656,23 @@
-       trx_t*  trx)    /*!< in: trx handle */
- {
-       ib_uint64_t     lsn     = trx->commit_lsn;
-+      ulint           flush_log_at_trx_commit;
-       ut_a(trx);
-       trx->op_info = "flushing log";
-+      if (trx->flush_log_at_trx_commit_session == 3) {
-+              flush_log_at_trx_commit = srv_flush_log_at_trx_commit;
-+      } else {
-+              flush_log_at_trx_commit = trx->flush_log_at_trx_commit_session;
-+      }
-+
-       if (!trx->must_flush_log_later) {
-               /* Do nothing */
--      } else if (srv_flush_log_at_trx_commit == 0) {
-+      } else if (flush_log_at_trx_commit == 0) {
-               /* Do nothing */
--      } else if (srv_flush_log_at_trx_commit == 1) {
-+      } else if (flush_log_at_trx_commit == 1) {
-               if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
-                       /* Write the log but do not flush it to disk */
-@@ -1664,7 +1683,7 @@
-                       log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
-               }
--      } else if (srv_flush_log_at_trx_commit == 2) {
-+      } else if (flush_log_at_trx_commit == 2) {
-               /* Write the log but do not flush it to disk */
-@@ -1925,6 +1944,8 @@
-       /*--------------------------------------*/
-       if (lsn) {
-+              ulint   flush_log_at_trx_commit;
-+
-               /* Depending on the my.cnf options, we may now write the log
-               buffer to the log files, making the prepared state of the
-               transaction durable if the OS does not crash. We may also
-@@ -1944,9 +1965,15 @@
-               mutex_exit(&kernel_mutex);
--              if (srv_flush_log_at_trx_commit == 0) {
-+              if (trx->flush_log_at_trx_commit_session == 3) {
-+                      flush_log_at_trx_commit = srv_flush_log_at_trx_commit;
-+              } else {
-+                      flush_log_at_trx_commit = trx->flush_log_at_trx_commit_session;
-+              }
-+
-+              if (flush_log_at_trx_commit == 0) {
-                       /* Do nothing */
--              } else if (srv_flush_log_at_trx_commit == 1) {
-+              } else if (flush_log_at_trx_commit == 1) {
-                       if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
-                               /* Write the log but do not flush it to disk */
-@@ -1958,7 +1985,7 @@
-                               log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
-                       }
--              } else if (srv_flush_log_at_trx_commit == 2) {
-+              } else if (flush_log_at_trx_commit == 2) {
-                       /* Write the log but do not flush it to disk */
diff --git a/mysql-innodb_lru_dump_restore.patch b/mysql-innodb_lru_dump_restore.patch
deleted file mode 100644 (file)
index 3357e03..0000000
+++ /dev/null
@@ -1,754 +0,0 @@
-# name       : innodb_lru_dump_restore.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- /dev/null
-+++ b/mysql-test/suite/innodb_plugin/r/percona_bug692211.result
-@@ -0,0 +1,7 @@
-+#
-+# LP bug #692211: innodb_auto_lru_dump crashes if ib_lru_dump doesn't 
-+#                 exist
-+#
-+SELECT @@innodb_auto_lru_dump;
-+@@innodb_auto_lru_dump
-+300
---- /dev/null
-+++ b/mysql-test/suite/innodb_plugin/t/percona_bug692211-master.opt
-@@ -0,0 +1 @@
-+--innodb_auto_lru_dump=300
---- /dev/null
-+++ b/mysql-test/suite/innodb_plugin/t/percona_bug692211.test
-@@ -0,0 +1,17 @@
-+--source include/have_innodb_plugin.inc
-+
-+--echo #
-+--echo # LP bug #692211: innodb_auto_lru_dump crashes if ib_lru_dump doesn't 
-+--echo #                 exist
-+--echo #
-+
-+SELECT @@innodb_auto_lru_dump;
-+
-+# We want to check that the server does not crash on startup when there is no 
-+# ib_lru_dump in the datadir. If we are here, we have already started up
-+# successfully. So we only have to check that there is no ib_lru_dump in the 
-+# datadir.
-+
-+--let $MYSQLD_DATADIR= `SELECT @@datadir`
-+--error 1
-+--file_exists $MYSQLD_DATADIR/ib_lru_dump;
---- a/storage/innodb_plugin/buf/buf0lru.c
-+++ b/storage/innodb_plugin/buf/buf0lru.c
-@@ -2042,6 +2042,282 @@
-       memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
- }
-+/********************************************************************//**
-+Dump the LRU page list to the specific file. */
-+#define LRU_DUMP_FILE "ib_lru_dump"
-+
-+UNIV_INTERN
-+ibool
-+buf_LRU_file_dump(void)
-+/*===================*/
-+{
-+      os_file_t       dump_file = -1;
-+      ibool           success;
-+      byte*           buffer_base = NULL;
-+      byte*           buffer = NULL;
-+      buf_page_t*     bpage;
-+      ulint           buffers;
-+      ulint           offset;
-+      ibool           ret = FALSE;
-+      ulint           i;
-+
-+      for (i = 0; i < srv_n_data_files; i++) {
-+              if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
-+                      fprintf(stderr,
-+                              " InnoDB: The name '%s' seems to be used for"
-+                              " innodb_data_file_path. Dumping LRU list is not"
-+                              " done for safeness.\n", LRU_DUMP_FILE);
-+                      goto end;
-+              }
-+      }
-+
-+      buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
-+      buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
-+      if (!buffer) {
-+              fprintf(stderr,
-+                      " InnoDB: cannot allocate buffer.\n");
-+              goto end;
-+      }
-+
-+      dump_file = os_file_create(LRU_DUMP_FILE, OS_FILE_OVERWRITE,
-+                              OS_FILE_NORMAL, OS_DATA_FILE, &success);
-+      if (!success) {
-+              os_file_get_last_error(TRUE);
-+              fprintf(stderr,
-+                      " InnoDB: cannot open %s\n", LRU_DUMP_FILE);
-+              goto end;
-+      }
-+
-+      mutex_enter(&LRU_list_mutex);
-+      bpage = UT_LIST_GET_LAST(buf_pool->LRU);
-+
-+      buffers = offset = 0;
-+      while (bpage != NULL) {
-+              if (offset == 0) {
-+                      memset(buffer, 0, UNIV_PAGE_SIZE);
-+              }
-+
-+              mach_write_to_4(buffer + offset * 4, bpage->space);
-+              offset++;
-+              mach_write_to_4(buffer + offset * 4, bpage->offset);
-+              offset++;
-+
-+              if (offset == UNIV_PAGE_SIZE/4) {
-+                      success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
-+                                      (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
-+                                      (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
-+                                      UNIV_PAGE_SIZE);
-+                      if (!success) {
-+                              mutex_exit(&LRU_list_mutex);
-+                              fprintf(stderr,
-+                                      " InnoDB: cannot write page %lu of %s\n",
-+                                      buffers, LRU_DUMP_FILE);
-+                              goto end;
-+                      }
-+                      buffers++;
-+                      offset = 0;
-+              }
-+
-+              bpage = UT_LIST_GET_PREV(LRU, bpage);
-+      }
-+      mutex_exit(&LRU_list_mutex);
-+
-+      if (offset == 0) {
-+              memset(buffer, 0, UNIV_PAGE_SIZE);
-+      }
-+
-+      mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
-+      offset++;
-+      mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
-+      offset++;
-+
-+      success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
-+                      (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
-+                      (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
-+                      UNIV_PAGE_SIZE);
-+      if (!success) {
-+              goto end;
-+      }
-+
-+      ret = TRUE;
-+end:
-+      if (dump_file != -1)
-+              os_file_close(dump_file);
-+      if (buffer_base)
-+              ut_free(buffer_base);
-+
-+      return(ret);
-+}
-+
-+typedef struct {
-+      ib_uint32_t space_id;
-+      ib_uint32_t page_no;
-+} dump_record_t;
-+
-+static int dump_record_cmp(const void *a, const void *b)
-+{
-+      const dump_record_t *rec1 = (dump_record_t *) a;
-+      const dump_record_t *rec2 = (dump_record_t *) b;
-+
-+      if (rec1->space_id < rec2->space_id)
-+              return -1;
-+      if (rec1->space_id > rec2->space_id)
-+              return 1;
-+      if (rec1->page_no < rec2->page_no)
-+              return -1;
-+      return rec1->page_no > rec2->page_no;
-+}
-+
-+/********************************************************************//**
-+Read the pages based on the specific file.*/
-+UNIV_INTERN
-+ibool
-+buf_LRU_file_restore(void)
-+/*======================*/
-+{
-+      os_file_t       dump_file = -1;
-+      ibool           success;
-+      byte*           buffer_base = NULL;
-+      byte*           buffer = NULL;
-+      ulint           buffers;
-+      ulint           offset;
-+      ulint           reads = 0;
-+      ulint           req = 0;
-+      ibool           terminated = FALSE;
-+      ibool           ret = FALSE;
-+      dump_record_t*  records = NULL;
-+      ulint           size;
-+      ulint           size_high;
-+      ulint           length;
-+
-+      dump_file = os_file_create_simple_no_error_handling(
-+              LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
-+      if (!success || !os_file_get_size(dump_file, &size, &size_high)) {
-+              os_file_get_last_error(TRUE);
-+              fprintf(stderr,
-+                      " 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;
-+      }
-+      buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
-+      buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
-+      records = ut_malloc(size);
-+      if (!buffer || !records) {
-+              fprintf(stderr,
-+                      " InnoDB: cannot allocate buffer.\n");
-+              goto end;
-+      }
-+
-+      buffers = 0;
-+      length = 0;
-+      while (!terminated) {
-+              success = os_file_read(dump_file, buffer,
-+                              (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
-+                              (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
-+                              UNIV_PAGE_SIZE);
-+              if (!success) {
-+                      fprintf(stderr,
-+                              " InnoDB: cannot read page %lu of %s,"
-+                              " or meet unexpected terminal.\n",
-+                              buffers, LRU_DUMP_FILE);
-+                      goto end;
-+              }
-+
-+              for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
-+                      ulint   space_id;
-+                      ulint   page_no;
-+
-+                      space_id = mach_read_from_4(buffer + offset * 4);
-+                      page_no = mach_read_from_4(buffer + (offset + 1) * 4);
-+                      if (space_id == 0xFFFFFFFFUL
-+                          || page_no == 0xFFFFFFFFUL) {
-+                              terminated = TRUE;
-+                              break;
-+                      }
-+
-+                      records[length].space_id = space_id;
-+                      records[length].page_no = page_no;
-+                      length++;
-+                      if (length * 8 >= size) {
-+                              fprintf(stderr,
-+                                      " InnoDB: could not find the "
-+                                      "end-of-file marker after reading "
-+                                      "the expected %lu bytes from the "
-+                                      "LRU dump file.\n"
-+                                      " InnoDB: this could be caused by a "
-+                                      "broken or incomplete file.\n"
-+                                      " InnoDB: trying to process what has "
-+                                      "been read so far.\n",
-+                                      size);
-+                              terminated= TRUE;
-+                              break;
-+                      }
-+              }
-+              buffers++;
-+      }
-+
-+      qsort(records, length, sizeof(dump_record_t), dump_record_cmp);
-+
-+      for (offset = 0; offset < length; offset++) {
-+              ulint           space_id;
-+              ulint           page_no;
-+              ulint           zip_size;
-+              ulint           err;
-+              ib_int64_t      tablespace_version;
-+
-+              space_id = records[offset].space_id;
-+              page_no = records[offset].page_no;
-+
-+              if (offset % 16 == 15) {
-+                      os_aio_simulated_wake_handler_threads();
-+                      buf_flush_free_margin(FALSE);
-+              }
-+
-+              zip_size = fil_space_get_zip_size(space_id);
-+              if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
-+                      continue;
-+              }
-+
-+              if (fil_is_exist(space_id, page_no)) {
-+
-+                      tablespace_version = fil_space_get_version(space_id);
-+
-+                      req++;
-+                      reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
-+                                                 | OS_AIO_SIMULATED_WAKE_LATER,
-+                                                 space_id, zip_size, TRUE,
-+                                                 tablespace_version, page_no, NULL);
-+                      buf_LRU_stat_inc_io();
-+              }
-+      }
-+
-+      os_aio_simulated_wake_handler_threads();
-+      buf_flush_free_margin(FALSE);
-+
-+      ut_print_timestamp(stderr);
-+      fprintf(stderr,
-+              " InnoDB: Completed reading buffer pool pages"
-+              " (requested: %lu, read: %lu)\n", req, reads);
-+      ret = TRUE;
-+end:
-+      if (dump_file != -1)
-+              os_file_close(dump_file);
-+      if (buffer_base)
-+              ut_free(buffer_base);
-+      if (records)
-+              ut_free(records);
-+
-+      return(ret);
-+}
-+
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- /**********************************************************************//**
- Validates the LRU list.
---- a/storage/innodb_plugin/buf/buf0rea.c
-+++ b/storage/innodb_plugin/buf/buf0rea.c
-@@ -64,7 +64,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 */
--static
-+UNIV_INTERN
- ulint
- buf_read_page_low(
- /*==============*/
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -5241,6 +5241,70 @@
-       return(DB_SUCCESS);
- }
-+/********************************************************************//**
-+Confirm whether the parameters are valid or not */
-+UNIV_INTERN
-+ibool
-+fil_is_exist(
-+/*==============*/
-+      ulint   space_id,       /*!< in: space id */
-+      ulint   block_offset)   /*!< in: offset in number of blocks */
-+{
-+      fil_space_t*    space;
-+      fil_node_t*     node;
-+
-+      /* Reserve the fil_system mutex and make sure that we can open at
-+      least one file while holding it, if the file is not already open */
-+
-+      fil_mutex_enter_and_prepare_for_io(space_id);
-+
-+      space = fil_space_get_by_id(space_id);
-+
-+      if (!space) {
-+              mutex_exit(&fil_system->mutex);
-+              return(FALSE);
-+      }
-+
-+      node = UT_LIST_GET_FIRST(space->chain);
-+
-+      for (;;) {
-+              if (UNIV_UNLIKELY(node == NULL)) {
-+                      mutex_exit(&fil_system->mutex);
-+                      return(FALSE);
-+              }
-+
-+              if (space->id != 0 && node->size == 0) {
-+                      /* We do not know the size of a single-table tablespace
-+                      before we open the file */
-+
-+                      break;
-+              }
-+
-+              if (node->size > block_offset) {
-+                      /* Found! */
-+                      break;
-+              } else {
-+                      block_offset -= node->size;
-+                      node = UT_LIST_GET_NEXT(chain, node);
-+              }
-+      }
-+
-+      /* Open file if closed */
-+      fil_node_prepare_for_io(node, fil_system, space);
-+      fil_node_complete_io(node, fil_system, OS_FILE_READ);
-+
-+      /* Check that at least the start offset is within the bounds of a
-+      single-table tablespace */
-+      if (UNIV_UNLIKELY(node->size <= block_offset)
-+          && space->id != 0 && space->purpose == FIL_TABLESPACE) {
-+              mutex_exit(&fil_system->mutex);
-+              return(FALSE);
-+      }
-+
-+      mutex_exit(&fil_system->mutex);
-+      return(TRUE);
-+}
-+
- #ifndef UNIV_HOTBACKUP
- /**********************************************************************//**
- Waits for an aio operation to complete. This function is used to write the
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -197,6 +197,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 */
-@@ -2410,6 +2412,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;
-@@ -11473,6 +11477,18 @@
-   "Limit the allocated memory for dictionary cache. (0: unlimited)",
-   NULL, NULL, 0, 0, LONG_MAX, 0);
-+static MYSQL_SYSVAR_UINT(auto_lru_dump, srv_auto_lru_dump,
-+  PLUGIN_VAR_RQCMDARG,
-+  "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_lru_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),
-@@ -11553,6 +11569,8 @@
-   MYSQL_SYSVAR(random_read_ahead),
-   MYSQL_SYSVAR(read_ahead_threshold),
-   MYSQL_SYSVAR(io_capacity),
-+  MYSQL_SYSVAR(auto_lru_dump),
-+  MYSQL_SYSVAR(blocking_lru_restore),
-   MYSQL_SYSVAR(use_purge_thread),
-   NULL
- };
---- a/storage/innodb_plugin/handler/i_s.cc
-+++ b/storage/innodb_plugin/handler/i_s.cc
-@@ -45,6 +45,7 @@
- #include "btr0btr.h" /* for btr_page_get_index_id */
- #include "trx0rseg.h" /* for trx_rseg_struct */
- #include "trx0sys.h" /* for trx_sys */
-+#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
- }
- static const char plugin_author[] = "Innobase Oy";
-@@ -2695,6 +2696,36 @@
-                       "Hello!");
-               goto end_func;
-       }
-+      else if (!strncasecmp("XTRA_LRU_DUMP", ptr, 13)) {
-+              ut_print_timestamp(stderr);
-+              fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_DUMP'"
-+                              " was detected.\n");
-+
-+              if (buf_LRU_file_dump()) {
-+                      field_store_string(i_s_table->field[0],
-+                              "XTRA_LRU_DUMP was succeeded.");
-+              } else {
-+                      field_store_string(i_s_table->field[0],
-+                              "XTRA_LRU_DUMP was failed.");
-+              }
-+
-+              goto end_func;
-+      }
-+      else if (!strncasecmp("XTRA_LRU_RESTORE", ptr, 16)) {
-+              ut_print_timestamp(stderr);
-+              fprintf(stderr, " InnoDB: administration command 'XTRA_LRU_RESTORE'"
-+                              " was detected.\n");
-+
-+              if (buf_LRU_file_restore()) {
-+                      field_store_string(i_s_table->field[0],
-+                              "XTRA_LRU_RESTORE was succeeded.");
-+              } else {
-+                      field_store_string(i_s_table->field[0],
-+                              "XTRA_LRU_RESTORE was failed.");
-+              }
-+
-+              goto end_func;
-+      }
-       field_store_string(i_s_table->field[0],
-               "Undefined XTRA_* command.");
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -40,5 +40,6 @@
- {"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/buf0lru.h
-+++ b/storage/innodb_plugin/include/buf0lru.h
-@@ -198,6 +198,18 @@
- void
- buf_LRU_stat_update(void);
- /*=====================*/
-+/********************************************************************//**
-+Dump the LRU page list to the specific file. */
-+UNIV_INTERN
-+ibool
-+buf_LRU_file_dump(void);
-+/*===================*/
-+/********************************************************************//**
-+Read the pages based on the specific file.*/
-+UNIV_INTERN
-+ibool
-+buf_LRU_file_restore(void);
-+/*======================*/
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- /**********************************************************************//**
---- a/storage/innodb_plugin/include/buf0rea.h
-+++ b/storage/innodb_plugin/include/buf0rea.h
-@@ -31,6 +31,37 @@
- #include "buf0types.h"
- /********************************************************************//**
-+Low-level function which reads a page asynchronously from a file to the
-+buffer buf_pool if it is not already there, in which case does nothing.
-+Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
-+flag is cleared and the x-lock released by an i/o-handler thread.
-+@return 1 if a read request was queued, 0 if the page already resided
-+in buf_pool, or if the page is in the doublewrite buffer blocks in
-+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 */
-+UNIV_INTERN
-+ulint
-+buf_read_page_low(
-+/*==============*/
-+      ulint*  err,    /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
-+                      trying to read from a non-existent tablespace, or a
-+                      tablespace which is just now being dropped */
-+      ibool   sync,   /*!< in: TRUE if synchronous aio is desired */
-+      ulint   mode,   /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
-+                      ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
-+                      at read-ahead functions) */
-+      ulint   space,  /*!< in: space id */
-+      ulint   zip_size,/*!< in: compressed page size, or 0 */
-+      ibool   unzip,  /*!< in: TRUE=request uncompressed page */
-+      ib_int64_t tablespace_version, /*!< in: if the space memory object has
-+                      this timestamp different from what we are giving here,
-+                      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 */
-+      ulint   offset, /*!< in: page number */
-+      trx_t*  trx);
-+/********************************************************************//**
- High-level function which reads a page asynchronously from a file to the
- buffer buf_pool if it is not already there. Sets the io_fix flag and sets
- an exclusive lock on the buffer frame. The flag is cleared and the x-lock
---- a/storage/innodb_plugin/include/fil0fil.h
-+++ b/storage/innodb_plugin/include/fil0fil.h
-@@ -643,6 +643,14 @@
-       void*   message,        /*!< in: message for aio handler if non-sync
-                               aio used, else ignored */
-       trx_t*  trx);
-+/********************************************************************//**
-+Confirm whether the parameters are valid or not */
-+UNIV_INTERN
-+ibool
-+fil_is_exist(
-+/*==============*/
-+      ulint   space_id,       /*!< in: space id */
-+      ulint   block_offset);  /*!< in: offset in number of blocks */
- /**********************************************************************//**
- Waits for an aio operation to complete. This function is used to write the
- handler for completed requests. The aio array of pending requests is divided
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -333,6 +333,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;
-@@ -614,6 +620,16 @@
- /*=====================*/
-       void*   arg);   /*!< in: a dummy parameter required by
-                       os_thread_create */
-+/*********************************************************************//**
-+A thread which restores the buffer pool from a dump file on startup and does
-+periodic buffer pool dumps.
-+@return       a dummy parameter */
-+UNIV_INTERN
-+os_thread_ret_t
-+srv_LRU_dump_restore_thread(
-+/*====================*/
-+      void*   arg);   /*!< in: a dummy parameter required by
-+                      os_thread_create */
- /******************************************************************//**
- Outputs to a file the output of the InnoDB Monitor.
- @return FALSE if not all information printed
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -305,6 +305,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;
-@@ -2556,6 +2562,58 @@
-       OS_THREAD_DUMMY_RETURN;
- }
-+/*********************************************************************//**
-+A thread which restores the buffer pool from a dump file on startup and does
-+periodic buffer pool dumps.
-+@return       a dummy parameter */
-+UNIV_INTERN
-+os_thread_ret_t
-+srv_LRU_dump_restore_thread(
-+/*====================*/
-+      void*   arg __attribute__((unused)))
-+                      /*!< in: a dummy parameter required by
-+                      os_thread_create */
-+{
-+      uint    auto_lru_dump;
-+      time_t  last_dump_time;
-+      time_t  time_elapsed;
-+
-+#ifdef UNIV_DEBUG_THREAD_CREATION
-+      fprintf(stderr, "LRU dump/restore thread starts, id %lu\n",
-+              os_thread_pf(os_thread_get_curr_id()));
-+#endif
-+
-+      /* 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);
-+
-+loop:
-+      os_thread_sleep(5000000);
-+
-+      if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
-+              goto exit_func;
-+      }
-+
-+      time_elapsed = time(NULL) - last_dump_time;
-+      auto_lru_dump = srv_auto_lru_dump;
-+      if (auto_lru_dump > 0 && (time_t) auto_lru_dump < time_elapsed) {
-+              last_dump_time = time(NULL);
-+              buf_LRU_file_dump();
-+      }
-+
-+      goto loop;
-+exit_func:
-+      /* We count the number of threads in os_thread_exit(). A created
-+      thread should always use that to exit and not use return() to exit. */
-+
-+      os_thread_exit(NULL);
-+
-+      OS_THREAD_DUMMY_RETURN;
-+}
-+
- /*******************************************************************//**
- Tells the InnoDB server that there has been activity in the database
- and wakes up the master thread if it is suspended (not sleeping). Used
---- a/storage/innodb_plugin/srv/srv0start.c
-+++ b/storage/innodb_plugin/srv/srv0start.c
-@@ -88,6 +88,7 @@
- # include "thr0loc.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;
-@@ -126,9 +127,9 @@
- static ulint          ios;
- /** io_handler_thread parameters for thread identification */
--static ulint          n[SRV_MAX_N_IO_THREADS + 6 + UNIV_MAX_PARALLELISM];
-+static ulint          n[SRV_MAX_N_IO_THREADS + 7 + UNIV_MAX_PARALLELISM];
- /** io_handler_thread identifiers */
--static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6 + UNIV_MAX_PARALLELISM];
-+static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 7 + UNIV_MAX_PARALLELISM];
- /** 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. */
-@@ -1706,6 +1707,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;
-       if (trx_doublewrite == NULL) {
-@@ -1730,13 +1740,13 @@
-               ulint i;
-               os_thread_create(&srv_purge_thread, NULL, thread_ids
--                               + (5 + SRV_MAX_N_IO_THREADS));
-+                               + (6 + SRV_MAX_N_IO_THREADS));
-               for (i = 0; i < srv_use_purge_thread - 1; i++) {
--                      n[6 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */
-+                      n[7 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */
-                       os_thread_create(&srv_purge_worker_thread,
--                                       n + (6 + i + SRV_MAX_N_IO_THREADS),
--                                       thread_ids + (6 + i + SRV_MAX_N_IO_THREADS));
-+                                       n + (7 + i + SRV_MAX_N_IO_THREADS),
-+                                       thread_ids + (7 + i + SRV_MAX_N_IO_THREADS));
-               }
-       }
- #ifdef UNIV_DEBUG
diff --git a/mysql-innodb_opt_lru_count.patch b/mysql-innodb_opt_lru_count.patch
deleted file mode 100644 (file)
index 32c9a84..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-# name       : innodb_opt_lru_count.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0buddy.c
-+++ b/storage/innodb_plugin/buf/buf0buddy.c
-@@ -129,7 +129,7 @@
-       ut_d(BUF_BUDDY_LIST_VALIDATE(i));
--      bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
-+      bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
-       if (bpage) {
-               ut_a(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -669,9 +669,9 @@
-       block->page.in_zip_hash = FALSE;
-       block->page.in_flush_list = FALSE;
-       block->page.in_free_list = FALSE;
--      block->page.in_LRU_list = FALSE;
-       block->in_unzip_LRU_list = FALSE;
- #endif /* UNIV_DEBUG */
-+      block->page.in_LRU_list = FALSE;
- #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-       block->n_pointers = 0;
- #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-@@ -1085,7 +1085,7 @@
-       memcpy(dpage, bpage, sizeof *dpage);
--      ut_d(bpage->in_LRU_list = FALSE);
-+      bpage->in_LRU_list = FALSE;
-       ut_d(bpage->in_page_hash = FALSE);
-       /* relocate buf_pool->LRU */
-@@ -2582,8 +2582,8 @@
-               bpage->in_zip_hash = FALSE;
-               bpage->in_flush_list = FALSE;
-               bpage->in_free_list = FALSE;
--              bpage->in_LRU_list = FALSE;
- #endif /* UNIV_DEBUG */
-+              bpage->in_LRU_list = FALSE;
-               ut_d(bpage->in_page_hash = TRUE);
-               HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
-@@ -2731,7 +2731,7 @@
-       ibuf_merge_or_delete_for_page(NULL, space, offset, zip_size, TRUE);
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
-       frame = block->frame;
-@@ -3485,7 +3485,7 @@
- {
-       ulint   ratio;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter(); /* optimistic */
-       ratio = (100 * UT_LIST_GET_LEN(buf_pool->flush_list))
-               / (1 + UT_LIST_GET_LEN(buf_pool->LRU)
-@@ -3493,7 +3493,7 @@
-       /* 1 + is there to avoid division by zero */
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit(); /* optimistic */
-       return(ratio);
- }
---- a/storage/innodb_plugin/buf/buf0flu.c
-+++ b/storage/innodb_plugin/buf/buf0flu.c
-@@ -351,17 +351,19 @@
-       buf_page_t*     bpage)  /*!< in: buffer control block, must be
-                               buf_page_in_file(bpage) and in the LRU list */
- {
--      ut_ad(buf_pool_mutex_own());
--      ut_ad(mutex_own(buf_page_get_mutex(bpage)));
--      ut_ad(bpage->in_LRU_list);
-+      //ut_ad(buf_pool_mutex_own());
-+      //ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-+      //ut_ad(bpage->in_LRU_list); /* optimistic use */
--      if (UNIV_LIKELY(buf_page_in_file(bpage))) {
-+      if (UNIV_LIKELY(bpage->in_LRU_list && buf_page_in_file(bpage))) {
-               return(bpage->oldest_modification == 0
-                      && buf_page_get_io_fix(bpage) == BUF_IO_NONE
-                      && bpage->buf_fix_count == 0);
-       }
-+      /* permited not to own LRU_mutex..  */
-+/*
-       ut_print_timestamp(stderr);
-       fprintf(stderr,
-               "  InnoDB: Error: buffer block state %lu"
-@@ -369,6 +371,7 @@
-               (ulong) buf_page_get_state(bpage));
-       ut_print_buf(stderr, bpage, sizeof(buf_page_t));
-       putc('\n', stderr);
-+*/
-       return(FALSE);
- }
-@@ -1506,8 +1509,14 @@
-       buf_page_t*     bpage;
-       ulint           n_replaceable;
-       ulint           distance        = 0;
-+      ibool           have_LRU_mutex = FALSE;
--      buf_pool_mutex_enter();
-+      if(UT_LIST_GET_LEN(buf_pool->unzip_LRU))
-+              have_LRU_mutex = TRUE;
-+retry:
-+      //buf_pool_mutex_enter();
-+      if (have_LRU_mutex)
-+              buf_pool_mutex_enter();
-       n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
-@@ -1518,7 +1527,13 @@
-                  + BUF_FLUSH_EXTRA_MARGIN)
-              && (distance < BUF_LRU_FREE_SEARCH_LEN)) {
--              mutex_t* block_mutex = buf_page_get_mutex(bpage);
-+              mutex_t* block_mutex;
-+              if (!bpage->in_LRU_list) {
-+                      /* reatart. but it is very optimistic */
-+                      bpage = UT_LIST_GET_LAST(buf_pool->LRU);
-+                      continue;
-+              }
-+              block_mutex = buf_page_get_mutex(bpage);
-               mutex_enter(block_mutex);
-@@ -1533,11 +1548,18 @@
-               bpage = UT_LIST_GET_PREV(LRU, bpage);
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      if (have_LRU_mutex)
-+              buf_pool_mutex_exit();
-       if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN) {
-               return(0);
-+      } else if (!have_LRU_mutex) {
-+              /* confirm it again with LRU_mutex for exactness */
-+              have_LRU_mutex = TRUE;
-+              distance = 0;
-+              goto retry;
-       }
-       return(BUF_FLUSH_FREE_BLOCK_MARGIN + BUF_FLUSH_EXTRA_MARGIN
-@@ -1552,8 +1574,9 @@
- immediately, without waiting. */
- UNIV_INTERN
- void
--buf_flush_free_margin(void)
-+buf_flush_free_margin(
- /*=======================*/
-+      ibool   wait)
- {
-       ulint   n_to_flush;
-       ulint   n_flushed;
-@@ -1562,7 +1585,7 @@
-       if (n_to_flush > 0) {
-               n_flushed = buf_flush_batch(BUF_FLUSH_LRU, n_to_flush, 0);
--              if (n_flushed == ULINT_UNDEFINED) {
-+              if (wait && n_flushed == ULINT_UNDEFINED) {
-                       /* There was an LRU type flush batch already running;
-                       let us wait for it to end */
---- a/storage/innodb_plugin/buf/buf0lru.c
-+++ b/storage/innodb_plugin/buf/buf0lru.c
-@@ -863,7 +863,7 @@
-       /* No free block was found: try to flush the LRU list */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(TRUE);
-       ++srv_buf_pool_wait_free;
-       os_aio_simulated_wake_handler_threads();
-@@ -1054,7 +1054,7 @@
-       /* Remove the block from the LRU list */
-       UT_LIST_REMOVE(LRU, buf_pool->LRU, bpage);
--      ut_d(bpage->in_LRU_list = FALSE);
-+      bpage->in_LRU_list = FALSE;
-       buf_unzip_LRU_remove_block_if_needed(bpage);
-@@ -1129,7 +1129,7 @@
-       ut_ad(!bpage->in_LRU_list);
-       UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
--      ut_d(bpage->in_LRU_list = TRUE);
-+      bpage->in_LRU_list = TRUE;
-       if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
-@@ -1197,7 +1197,7 @@
-               buf_pool->LRU_old_len++;
-       }
--      ut_d(bpage->in_LRU_list = TRUE);
-+      bpage->in_LRU_list = TRUE;
-       if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
-@@ -1433,7 +1433,7 @@
-                               buf_page_set_old(b, buf_page_is_old(b));
- #endif /* UNIV_LRU_DEBUG */
-                       } else {
--                              ut_d(b->in_LRU_list = FALSE);
-+                              b->in_LRU_list = FALSE;
-                               buf_LRU_add_block_low(b, buf_page_is_old(b));
-                       }
---- a/storage/innodb_plugin/buf/buf0rea.c
-+++ b/storage/innodb_plugin/buf/buf0rea.c
-@@ -365,7 +365,7 @@
-       }
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
-       /* Increment number of I/O operations used for LRU policy. */
-       buf_LRU_stat_inc_io();
-@@ -640,7 +640,7 @@
-       os_aio_simulated_wake_handler_threads();
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints && (count > 0)) {
-@@ -725,7 +725,7 @@
-       os_aio_simulated_wake_handler_threads();
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints) {
-@@ -818,7 +818,7 @@
-       os_aio_simulated_wake_handler_threads();
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints) {
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -26,5 +26,6 @@
- {"xtradb_show_enhancements","I_S.XTRADB_ENHANCEMENTS","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_show_status","Improvements to SHOW INNODB STATUS","Memory information and lock info fixes","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_io","Improvements to InnoDB IO","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_opt_lru_count","Fix of buffer_pool mutex","Decreases contention on buffer_pool mutex on LRU operations","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/buf0buf.h
-+++ b/storage/innodb_plugin/include/buf0buf.h
-@@ -1166,11 +1166,11 @@
-       UT_LIST_NODE_T(buf_page_t) LRU;
-                                       /*!< node of the LRU list */
--#ifdef UNIV_DEBUG
-+//#ifdef UNIV_DEBUG
-       ibool           in_LRU_list;    /*!< TRUE if the page is in
-                                       the LRU list; used in
-                                       debugging */
--#endif /* UNIV_DEBUG */
-+//#endif /* UNIV_DEBUG */
-       unsigned        old:1;          /*!< TRUE if the block is in the old
-                                       blocks in buf_pool->LRU_old */
-       unsigned        freed_page_clock:31;/*!< the value of
---- a/storage/innodb_plugin/include/buf0flu.h
-+++ b/storage/innodb_plugin/include/buf0flu.h
-@@ -61,8 +61,9 @@
- a margin of replaceable pages there. */
- UNIV_INTERN
- void
--buf_flush_free_margin(void);
-+buf_flush_free_margin(
- /*=======================*/
-+      ibool   wait);
- #endif /* !UNIV_HOTBACKUP */
- /********************************************************************//**
- Initializes a page for writing to the tablespace. */
diff --git a/mysql-innodb_overwrite_relay_log_info.patch b/mysql-innodb_overwrite_relay_log_info.patch
deleted file mode 100644 (file)
index 60ce549..0000000
+++ /dev/null
@@ -1,493 +0,0 @@
-# name       : innodb_overwrite_relay_log_info.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -43,7 +43,17 @@
- #pragma implementation                                // gcc: Class implementation
- #endif
-+#define MYSQL_SERVER
-+
- #include <mysql_priv.h>
-+#ifdef MYSQL_SERVER
-+#include <rpl_mi.h>
-+#include <slave.h>
-+// Defined in slave.cc
-+int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
-+int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
-+                        const char *default_val);
-+#endif /* MYSQL_SERVER */
- #include <m_ctype.h>
- #include <mysys_err.h>
-@@ -88,6 +98,14 @@
- #include "ha_innodb.h"
- #include "i_s.h"
-+#ifdef MYSQL_SERVER
-+// Defined in trx0sys.c
-+extern char           trx_sys_mysql_master_log_name[];
-+extern ib_int64_t     trx_sys_mysql_master_log_pos;
-+extern char           trx_sys_mysql_relay_log_name[];
-+extern ib_int64_t     trx_sys_mysql_relay_log_pos;
-+#endif /* MYSQL_SERVER */
-+
- #ifndef MYSQL_SERVER
- # ifndef MYSQL_PLUGIN_IMPORT
- #  define MYSQL_PLUGIN_IMPORT /* nothing */
-@@ -167,6 +185,7 @@
- static my_bool        innobase_use_checksums                  = TRUE;
- static my_bool        innobase_extra_undoslots                = FALSE;
- 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;
- static my_bool        innobase_create_status_file             = FALSE;
- static my_bool        innobase_stats_on_metadata              = TRUE;
-@@ -2042,6 +2061,89 @@
-       }
- #endif /* UNIV_DEBUG */
-+#ifndef MYSQL_SERVER
-+      innodb_overwrite_relay_log_info = FALSE;
-+#endif
-+
-+#ifdef HAVE_REPLICATION
-+#ifdef MYSQL_SERVER
-+      /* read master log position from relay-log.info if exists */
-+      char fname[FN_REFLEN+128];
-+      int pos;
-+      int info_fd;
-+      IO_CACHE info_file;
-+
-+      fname[0] = '\0';
-+
-+      if(innobase_overwrite_relay_log_info) {
-+
-+      fprintf(stderr,
-+              "InnoDB: Warning: innodb_overwrite_relay_log_info is enabled."
-+              " Updates in other storage engines may have problem with consistency.\n");
-+
-+      bzero((char*) &info_file, sizeof(info_file));
-+      fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32);
-+
-+      int error=0;
-+
-+      if (!access(fname,F_OK)) {
-+              /* exist */
-+              if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0) {
-+                      error=1;
-+              } else if (init_io_cache(&info_file, info_fd, IO_SIZE*2,
-+                                      READ_CACHE, 0L, 0, MYF(MY_WME))) {
-+                      error=1;
-+              }
-+
-+              if (error) {
-+relay_info_error:
-+                      if (info_fd >= 0)
-+                              my_close(info_fd, MYF(0));
-+                      fname[0] = '\0';
-+                      goto skip_relay;
-+              }
-+      } else {
-+              fname[0] = '\0';
-+              goto skip_relay;
-+      }
-+
-+      if (init_strvar_from_file(fname, sizeof(fname), &info_file, "") || /* dummy (it is relay-log) */
-+          init_intvar_from_file(&pos, &info_file, BIN_LOG_HEADER_SIZE)) { 
-+              end_io_cache(&info_file);
-+              error=1;
-+              goto relay_info_error;
-+      }
-+
-+      fprintf(stderr,
-+              "InnoDB: relay-log.info is detected.\n"
-+              "InnoDB: relay log: position %u, file name %s\n",
-+              pos, fname);
-+
-+      strncpy(trx_sys_mysql_relay_log_name, fname, TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
-+      trx_sys_mysql_relay_log_pos = (ib_int64_t) pos;
-+
-+      if (init_strvar_from_file(fname, sizeof(fname), &info_file, "") ||
-+          init_intvar_from_file(&pos, &info_file, 0)) {
-+              end_io_cache(&info_file);
-+              error=1;
-+              goto relay_info_error;
-+      }
-+
-+      fprintf(stderr,
-+              "InnoDB: master log: position %u, file name %s\n",
-+              pos, fname);
-+
-+      strncpy(trx_sys_mysql_master_log_name, fname, TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
-+      trx_sys_mysql_master_log_pos = (ib_int64_t) pos;
-+
-+      end_io_cache(&info_file);
-+      if (info_fd >= 0)
-+              my_close(info_fd, MYF(0));
-+      }
-+skip_relay:
-+#endif /* MYSQL_SERVER */
-+#endif /* HAVE_REPLICATION */
-+
-       /* Check that values don't overflow on 32-bit systems. */
-       if (sizeof(ulint) == 4) {
-               if (innobase_buffer_pool_size > UINT_MAX32) {
-@@ -2310,6 +2412,76 @@
-               goto mem_free_and_error;
-       }
-+#ifdef HAVE_REPLICATION
-+#ifdef MYSQL_SERVER
-+      if(innobase_overwrite_relay_log_info) {
-+      /* If InnoDB progressed from relay-log.info, overwrite it */
-+      if (fname[0] == '\0') {
-+              fprintf(stderr,
-+                      "InnoDB: something wrong with relay-info.log. InnoDB will not overwrite it.\n");
-+      } else if (0 != strcmp(fname, trx_sys_mysql_master_log_name)
-+                 || pos != trx_sys_mysql_master_log_pos) {
-+              /* Overwrite relay-log.info */
-+              bzero((char*) &info_file, sizeof(info_file));
-+              fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32);
-+
-+              int error = 0;
-+
-+              if (!access(fname,F_OK)) {
-+                      /* exist */
-+                      if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0) {
-+                              error = 1;
-+                      } else if (init_io_cache(&info_file, info_fd, IO_SIZE*2,
-+                                              WRITE_CACHE, 0L, 0, MYF(MY_WME))) {
-+                              error = 1;
-+                      }
-+
-+                      if (error) {
-+                              if (info_fd >= 0)
-+                                      my_close(info_fd, MYF(0));
-+                              goto skip_overwrite;
-+                      }
-+              } else {
-+                      error = 1;
-+                      goto skip_overwrite;
-+              }
-+
-+              char buff[FN_REFLEN*2+22*2+4], *pos;
-+
-+              my_b_seek(&info_file, 0L);
-+              pos=strmov(buff, trx_sys_mysql_relay_log_name);
-+              *pos++='\n';
-+              pos=longlong2str(trx_sys_mysql_relay_log_pos, pos, 10);
-+              *pos++='\n';
-+              pos=strmov(pos, trx_sys_mysql_master_log_name);
-+              *pos++='\n';
-+              pos=longlong2str(trx_sys_mysql_master_log_pos, pos, 10);
-+              *pos='\n';
-+
-+              if (my_b_write(&info_file, (uchar*) buff, (size_t) (pos-buff)+1))
-+                      error = 1;
-+              if (flush_io_cache(&info_file))
-+                      error = 1;
-+
-+              end_io_cache(&info_file);
-+              if (info_fd >= 0)
-+                      my_close(info_fd, MYF(0));
-+skip_overwrite:
-+              if (error) {
-+                      fprintf(stderr,
-+                              "InnoDB: ERROR: error occured during overwriting relay-log.info.\n");
-+              } else {
-+                      fprintf(stderr,
-+                              "InnoDB: relay-log.info was overwritten.\n");
-+              }
-+      } else {
-+              fprintf(stderr,
-+                      "InnoDB: InnoDB and relay-log.info are synchronized. InnoDB will not overwrite it.\n");
-+      }
-+      }
-+#endif /* MYSQL_SERVER */
-+#endif /* HAVE_REPLICATION */
-+
-       innobase_open_tables = hash_create(200);
-       pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
-       pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
-@@ -2424,6 +2596,26 @@
-               return;
-       }
-+#ifdef HAVE_REPLICATION
-+#ifdef MYSQL_SERVER
-+      THD *thd=current_thd;
-+
-+      if (thd && thd->slave_thread) {
-+              /* Update the replication position info inside InnoDB */
-+              trx->mysql_master_log_file_name
-+                      = active_mi->rli.group_master_log_name;
-+              trx->mysql_master_log_pos
-+                      = ((ib_int64_t)active_mi->rli.group_master_log_pos +
-+                         ((ib_int64_t)active_mi->rli.future_event_relay_log_pos -
-+                          (ib_int64_t)active_mi->rli.group_relay_log_pos));
-+              trx->mysql_relay_log_file_name
-+                      = active_mi->rli.group_relay_log_name;
-+              trx->mysql_relay_log_pos
-+                      = (ib_int64_t)active_mi->rli.future_event_relay_log_pos;
-+      }
-+#endif /* MYSQL_SERVER */
-+#endif /* HAVE_REPLICATION */
-+
-       trx_commit_for_mysql(trx);
- }
-@@ -10781,6 +10973,12 @@
-   "don't use the datafile for normal mysqld or ibbackup! ####",
-   NULL, NULL, FALSE);
-+static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
-+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-+  "During InnoDB crash recovery on slave overwrite relay-log.info "
-+  "to align master log file position if information in InnoDB and relay-log.info is different.",
-+  NULL, NULL, FALSE);
-+
- static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
-   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-   "Enable InnoDB doublewrite buffer (enabled by default). "
-@@ -11211,6 +11409,7 @@
-   MYSQL_SYSVAR(old_blocks_pct),
-   MYSQL_SYSVAR(old_blocks_time),
-   MYSQL_SYSVAR(open_files),
-+  MYSQL_SYSVAR(overwrite_relay_log_info),
-   MYSQL_SYSVAR(rollback_on_timeout),
-   MYSQL_SYSVAR(stats_on_metadata),
-   MYSQL_SYSVAR(stats_sample_pages),
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -30,5 +30,6 @@
- {"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/trx0sys.h
-+++ b/storage/innodb_plugin/include/trx0sys.h
-@@ -52,6 +52,9 @@
- extern ib_int64_t     trx_sys_mysql_master_log_pos;
- /* @} */
-+extern char           trx_sys_mysql_relay_log_name[];
-+extern ib_int64_t     trx_sys_mysql_relay_log_pos;
-+
- /** If this MySQL server uses binary logging, after InnoDB has been inited
- and if it has done a crash recovery, we store the binlog file name and position
- here. */
-@@ -311,7 +314,8 @@
- void
- trx_sys_update_mysql_binlog_offset(
- /*===============================*/
--      const char*     file_name,/*!< in: MySQL log file name */
-+      trx_sysf_t*     sys_header,
-+      const char*     file_name_in,/*!< in: MySQL log file name */
-       ib_int64_t      offset, /*!< in: position in that log file */
-       ulint           field,  /*!< in: offset of the MySQL log info field in
-                               the trx sys header */
-@@ -493,6 +497,7 @@
- @see trx_sys_mysql_master_log_name
- @see trx_sys_mysql_bin_log_name */
- #define TRX_SYS_MYSQL_LOG_NAME_LEN    512
-+#define TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN     480     /* (500 - 12) is dead line. */
- /** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
- #define TRX_SYS_MYSQL_LOG_MAGIC_N     873422344
-@@ -502,6 +507,7 @@
- /** The offset of the MySQL replication info in the trx system header;
- this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
- #define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
-+#define TRX_SYS_MYSQL_RELAY_LOG_INFO  (UNIV_PAGE_SIZE - 1500)
- /** The offset of the MySQL binlog offset info in the trx system header */
- #define TRX_SYS_MYSQL_LOG_INFO                (UNIV_PAGE_SIZE - 1000)
---- a/storage/innodb_plugin/include/trx0trx.h
-+++ b/storage/innodb_plugin/include/trx0trx.h
-@@ -580,6 +580,21 @@
-       ib_int64_t      mysql_log_offset;/* if MySQL binlog is used, this field
-                                       contains the end offset of the binlog
-                                       entry */
-+      const char*     mysql_master_log_file_name;
-+                                      /* if the database server is a MySQL
-+                                      replication slave, we have here the
-+                                      master binlog name up to which
-+                                      replication has processed; otherwise
-+                                      this is a pointer to a null
-+                                      character */
-+      ib_int64_t      mysql_master_log_pos;
-+                                      /* if the database server is a MySQL
-+                                      replication slave, this is the
-+                                      position in the log file up to which
-+                                      replication has processed */
-+      const char*     mysql_relay_log_file_name;
-+      ib_int64_t      mysql_relay_log_pos;
-+
-       os_thread_id_t  mysql_thread_id;/* id of the MySQL thread associated
-                                       with this transaction object */
-       ulint           mysql_process_no;/* since in Linux, 'top' reports
---- a/storage/innodb_plugin/trx/trx0sys.c
-+++ b/storage/innodb_plugin/trx/trx0sys.c
-@@ -75,13 +75,16 @@
- file name and position here. */
- /* @{ */
- /** Master binlog file name */
--UNIV_INTERN char      trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
-+UNIV_INTERN char      trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN];
- /** Master binlog file position.  We have successfully got the updates
- up to this position.  -1 means that no crash recovery was needed, or
- there was no master log position info inside InnoDB.*/
- UNIV_INTERN ib_int64_t        trx_sys_mysql_master_log_pos    = -1;
- /* @} */
-+UNIV_INTERN char      trx_sys_mysql_relay_log_name[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN];
-+UNIV_INTERN ib_int64_t        trx_sys_mysql_relay_log_pos     = -1;
-+
- /** If this MySQL server uses binary logging, after InnoDB has been inited
- and if it has done a crash recovery, we store the binlog file name and position
- here. */
-@@ -676,22 +679,25 @@
- void
- trx_sys_update_mysql_binlog_offset(
- /*===============================*/
--      const char*     file_name,/*!< in: MySQL log file name */
-+      trx_sysf_t*     sys_header,
-+      const char*     file_name_in,/*!< in: MySQL log file name */
-       ib_int64_t      offset, /*!< in: position in that log file */
-       ulint           field,  /*!< in: offset of the MySQL log info field in
-                               the trx sys header */
-       mtr_t*          mtr)    /*!< in: mtr */
- {
--      trx_sysf_t*     sys_header;
-+      const char*     file_name;
--      if (ut_strlen(file_name) >= TRX_SYS_MYSQL_LOG_NAME_LEN) {
-+      if (ut_strlen(file_name_in) >= TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN) {
-               /* We cannot fit the name to the 512 bytes we have reserved */
-+              /* -> To store relay log file information, file_name must fit to the 480 bytes */
--              return;
-+              file_name = "";
-+      }
-+      else {
-+              file_name = file_name_in;
-       }
--
--      sys_header = trx_sysf_get(mtr);
-       if (mach_read_from_4(sys_header + field
-                            + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
-@@ -814,13 +820,26 @@
-                                        + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
-               sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
-               + TRX_SYS_MYSQL_LOG_NAME);
-+
-+      fprintf(stderr,
-+              "InnoDB: and relay log file\n"
-+              "InnoDB: position %lu %lu, file name %s\n",
-+              (ulong) mach_read_from_4(sys_header
-+                                       + TRX_SYS_MYSQL_RELAY_LOG_INFO
-+                                       + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
-+              (ulong) mach_read_from_4(sys_header
-+                                       + TRX_SYS_MYSQL_RELAY_LOG_INFO
-+                                       + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
-+              sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO
-+              + TRX_SYS_MYSQL_LOG_NAME);
-+
-       /* Copy the master log position info to global variables we can
-       use in ha_innobase.cc to initialize glob_mi to right values */
-       ut_memcpy(trx_sys_mysql_master_log_name,
-                 sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
-                 + TRX_SYS_MYSQL_LOG_NAME,
--                TRX_SYS_MYSQL_LOG_NAME_LEN);
-+                TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
-       trx_sys_mysql_master_log_pos
-               = (((ib_int64_t) mach_read_from_4(
-@@ -829,6 +848,19 @@
-               + ((ib_int64_t) mach_read_from_4(
-                          sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
-                          + TRX_SYS_MYSQL_LOG_OFFSET_LOW));
-+
-+      ut_memcpy(trx_sys_mysql_relay_log_name,
-+                sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO
-+                + TRX_SYS_MYSQL_LOG_NAME,
-+                TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN);
-+
-+      trx_sys_mysql_relay_log_pos
-+              = (((ib_int64_t) mach_read_from_4(
-+                          sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO
-+                          + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) << 32)
-+              + ((ib_int64_t) mach_read_from_4(
-+                         sys_header + TRX_SYS_MYSQL_RELAY_LOG_INFO
-+                         + TRX_SYS_MYSQL_LOG_OFFSET_LOW));
-       mtr_commit(&mtr);
- }
---- a/storage/innodb_plugin/trx/trx0trx.c
-+++ b/storage/innodb_plugin/trx/trx0trx.c
-@@ -132,6 +132,10 @@
-       trx->mysql_log_file_name = NULL;
-       trx->mysql_log_offset = 0;
-+      trx->mysql_master_log_file_name = "";
-+      trx->mysql_master_log_pos = 0;
-+      trx->mysql_relay_log_file_name = "";
-+      trx->mysql_relay_log_pos = 0;
-       mutex_create(&trx->undo_mutex, SYNC_TRX_UNDO);
-@@ -791,6 +795,7 @@
-       trx_rseg_t*     rseg;
-       trx_undo_t*     undo;
-       mtr_t           mtr;
-+      trx_sysf_t*     sys_header = NULL;
-       ut_ad(mutex_own(&kernel_mutex));
-@@ -848,13 +853,35 @@
-               if (trx->mysql_log_file_name
-                   && trx->mysql_log_file_name[0] != '\0') {
-+                      if (!sys_header) {
-+                              sys_header = trx_sysf_get(&mtr);
-+                      }
-                       trx_sys_update_mysql_binlog_offset(
-+                              sys_header,
-                               trx->mysql_log_file_name,
-                               trx->mysql_log_offset,
-                               TRX_SYS_MYSQL_LOG_INFO, &mtr);
-                       trx->mysql_log_file_name = NULL;
-               }
-+              if (trx->mysql_master_log_file_name[0] != '\0') {
-+                      /* This database server is a MySQL replication slave */
-+                      if (!sys_header) {
-+                              sys_header = trx_sysf_get(&mtr);
-+                      }
-+                      trx_sys_update_mysql_binlog_offset(
-+                              sys_header,
-+                              trx->mysql_relay_log_file_name,
-+                              trx->mysql_relay_log_pos,
-+                              TRX_SYS_MYSQL_RELAY_LOG_INFO, &mtr);
-+                      trx_sys_update_mysql_binlog_offset(
-+                              sys_header,
-+                              trx->mysql_master_log_file_name,
-+                              trx->mysql_master_log_pos,
-+                              TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr);
-+                      trx->mysql_master_log_file_name = "";
-+              }
-+
-               /* The following call commits the mini-transaction, making the
-               whole transaction committed in the file-based world, at this
-               log sequence number. The transaction becomes 'durable' when
diff --git a/mysql-innodb_pass_corrupt_table.patch b/mysql-innodb_pass_corrupt_table.patch
deleted file mode 100644 (file)
index 8f026c9..0000000
+++ /dev/null
@@ -1,1345 +0,0 @@
-# name       : innodb_pass_corrupt_table.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/btr/btr0btr.c
-+++ b/storage/innodb_plugin/btr/btr0btr.c
-@@ -691,6 +691,12 @@
-       root_page_no = dict_index_get_page(index);
-       block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
-+
-+      if (srv_pass_corrupt_table && !block) {
-+              return(0);
-+      }
-+      ut_a(block);
-+
-       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 @@
-       root = btr_root_get(index, &mtr);
-+      if (srv_pass_corrupt_table && !root) {
-+              mtr_commit(&mtr);
-+              return(0);
-+      }
-+      ut_a(root);
-+
-       if (flag == BTR_N_LEAF_PAGES) {
-               seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
-@@ -1431,6 +1443,13 @@
-       mtr_start(&mtr);
-       root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &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));
-@@ -1453,6 +1472,12 @@
-       mtr_start(&mtr);
-       root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &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_TOP
-                                   + root, space));
-@@ -1486,6 +1511,11 @@
-       block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
-+      if (srv_pass_corrupt_table && !block) {
-+              return;
-+      }
-+      ut_a(block);
-+
-       btr_search_drop_page_hash_index(block);
-       header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
---- a/storage/innodb_plugin/btr/btr0cur.c
-+++ b/storage/innodb_plugin/btr/btr0cur.c
-@@ -239,6 +239,11 @@
-       case BTR_MODIFY_LEAF:
-               mode = latch_mode == BTR_SEARCH_LEAF ? RW_S_LATCH : RW_X_LATCH;
-               get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
-+
-+              if (srv_pass_corrupt_table && !get_block) {
-+                      return;
-+              }
-+              ut_a(get_block);
- #ifdef UNIV_BTR_DEBUG
-               ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
- #endif /* UNIV_BTR_DEBUG */
-@@ -252,6 +257,11 @@
-                       get_block = btr_block_get(space, zip_size,
-                                                 left_page_no,
-                                                 RW_X_LATCH, mtr);
-+
-+                      if (srv_pass_corrupt_table && !get_block) {
-+                              return;
-+                      }
-+                      ut_a(get_block);
- #ifdef UNIV_BTR_DEBUG
-                       ut_a(page_is_comp(get_block->frame)
-                            == page_is_comp(page));
-@@ -263,6 +273,11 @@
-               get_block = btr_block_get(space, zip_size, page_no,
-                                         RW_X_LATCH, mtr);
-+
-+              if (srv_pass_corrupt_table && !get_block) {
-+                      return;
-+              }
-+              ut_a(get_block);
- #ifdef UNIV_BTR_DEBUG
-               ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
- #endif /* UNIV_BTR_DEBUG */
-@@ -274,6 +289,11 @@
-                       get_block = btr_block_get(space, zip_size,
-                                                 right_page_no,
-                                                 RW_X_LATCH, mtr);
-+
-+                      if (srv_pass_corrupt_table && !get_block) {
-+                              return;
-+                      }
-+                      ut_a(get_block);
- #ifdef UNIV_BTR_DEBUG
-                       ut_a(page_is_comp(get_block->frame)
-                            == page_is_comp(page));
-@@ -295,6 +315,11 @@
-                       get_block = btr_block_get(space, zip_size,
-                                                 left_page_no, mode, mtr);
-                       cursor->left_block = get_block;
-+
-+                      if (srv_pass_corrupt_table && !get_block) {
-+                              return;
-+                      }
-+                      ut_a(get_block);
- #ifdef UNIV_BTR_DEBUG
-                       ut_a(page_is_comp(get_block->frame)
-                            == page_is_comp(page));
-@@ -305,6 +330,11 @@
-               }
-               get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
-+
-+              if (srv_pass_corrupt_table && !get_block) {
-+                      return;
-+              }
-+              ut_a(get_block);
- #ifdef UNIV_BTR_DEBUG
-               ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
- #endif /* UNIV_BTR_DEBUG */
-@@ -536,6 +566,16 @@
-                                        rw_latch, guess, buf_mode,
-                                        file, line, mtr);
-               if (block == NULL) {
-+                      if (srv_pass_corrupt_table && buf_mode != BUF_GET_IF_IN_POOL) {
-+                              page_cursor->block = 0;
-+                              page_cursor->rec = 0;
-+                              if (estimate) {
-+                                      cursor->path_arr->nth_rec = ULINT_UNDEFINED;
-+                              }
-+                              break;
-+                      }
-+                      ut_a(buf_mode == BUF_GET_IF_IN_POOL);
-+
-                       /* This must be a search to perform an insert;
-                       try insert to the insert buffer */
-@@ -563,6 +603,16 @@
-               page = buf_block_get_frame(block);
-+              if (srv_pass_corrupt_table && !page) {
-+                      page_cursor->block = 0;
-+                      page_cursor->rec = 0;
-+                      if (estimate) {
-+                              cursor->path_arr->nth_rec = ULINT_UNDEFINED;
-+                      }
-+                      break;
-+              }
-+              ut_a(page);
-+
-               block->check_index_page_at_flush = TRUE;
-               if (rw_latch != RW_NO_LATCH) {
-@@ -746,6 +796,17 @@
-                                        RW_NO_LATCH, NULL, BUF_GET,
-                                        file, line, mtr);
-               page = buf_block_get_frame(block);
-+
-+              if (srv_pass_corrupt_table && !page) {
-+                      page_cursor->block = 0;
-+                      page_cursor->rec = 0;
-+                      if (estimate) {
-+                              cursor->path_arr->nth_rec = ULINT_UNDEFINED;
-+                      }
-+                      break;
-+              }
-+              ut_a(page);
-+
-               ut_ad(0 == ut_dulint_cmp(index->id,
-                                        btr_page_get_index_id(page)));
-@@ -867,6 +928,14 @@
-                                        RW_NO_LATCH, NULL, BUF_GET,
-                                        file, line, mtr);
-               page = buf_block_get_frame(block);
-+
-+              if (srv_pass_corrupt_table && !page) {
-+                      page_cursor->block = 0;
-+                      page_cursor->rec = 0;
-+                      break;
-+              }
-+              ut_a(page);
-+
-               ut_ad(0 == ut_dulint_cmp(index->id,
-                                        btr_page_get_index_id(page)));
-@@ -1081,6 +1150,12 @@
-       *big_rec = NULL;
-       block = btr_cur_get_block(cursor);
-+
-+      if (srv_pass_corrupt_table && !block) {
-+              return(DB_CORRUPTION);
-+      }
-+      ut_a(block);
-+
-       page = buf_block_get_frame(block);
-       index = cursor->index;
-       zip_size = buf_block_get_zip_size(block);
-@@ -2869,6 +2944,11 @@
-       block = btr_cur_get_block(cursor);
-+      if (srv_pass_corrupt_table && !block) {
-+              return(DB_CORRUPTION);
-+      }
-+      ut_a(block);
-+
-       ut_ad(page_is_leaf(buf_block_get_frame(block)));
-       rec = btr_cur_get_rec(cursor);
-@@ -3413,6 +3493,11 @@
-               page = btr_cur_get_page(&cursor);
-+              if (srv_pass_corrupt_table && !page) {
-+                      break;
-+              }
-+              ut_a(page);
-+
-               rec = page_rec_get_next(page_get_infimum_rec(page));
-               if (!page_rec_is_supremum(rec)) {
---- a/storage/innodb_plugin/btr/btr0pcur.c
-+++ b/storage/innodb_plugin/btr/btr0pcur.c
-@@ -32,7 +32,7 @@
- #include "ut0byte.h"
- #include "rem0cmp.h"
- #include "trx0trx.h"
--
-+#include "srv0srv.h"
- /**************************************************************//**
- Allocates memory for a persistent cursor object and initializes the cursor.
- @return       own: persistent cursor */
-@@ -102,6 +102,12 @@
-       ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
-       block = btr_pcur_get_block(cursor);
-+
-+      if (srv_pass_corrupt_table && !block) {
-+              return;
-+      }
-+      ut_a(block);
-+
-       index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
-       page_cursor = btr_pcur_get_page_cur(cursor);
-@@ -392,6 +398,15 @@
-       next_block = btr_block_get(space, zip_size, next_page_no,
-                                  cursor->latch_mode, mtr);
-       next_page = buf_block_get_frame(next_block);
-+
-+      if (srv_pass_corrupt_table && !next_page) {
-+              btr_leaf_page_release(btr_pcur_get_block(cursor),
-+                                    cursor->latch_mode, mtr);
-+              btr_pcur_get_page_cur(cursor)->block = 0;
-+              btr_pcur_get_page_cur(cursor)->rec = 0;
-+              return;
-+      }
-+      ut_a(next_page);
- #ifdef UNIV_BTR_DEBUG
-       ut_a(page_is_comp(next_page) == page_is_comp(page));
-       ut_a(btr_page_get_prev(next_page, mtr)
---- a/storage/innodb_plugin/btr/btr0sea.c
-+++ b/storage/innodb_plugin/btr/btr0sea.c
-@@ -42,7 +42,7 @@
- #include "btr0pcur.h"
- #include "btr0btr.h"
- #include "ha0ha.h"
--
-+#include "srv0srv.h"
- /** Flag: has the search system been enabled?
- Protected by btr_search_latch and btr_search_enabled_mutex. */
- UNIV_INTERN char              btr_search_enabled      = TRUE;
-@@ -595,6 +595,11 @@
-       block = btr_cur_get_block(cursor);
-+      if (srv_pass_corrupt_table && !block) {
-+              return;
-+      }
-+      ut_a(block);
-+
-       /* NOTE that the following two function calls do NOT protect
-       info or block->n_fields etc. with any semaphore, to save CPU time!
-       We cannot assume the fields are consistent when we return from
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -52,6 +52,7 @@
- #include "log0recv.h"
- #include "page0zip.h"
- #include "trx0trx.h"
-+#include "srv0start.h"
- /* prototypes for new functions added to ha_innodb.cc */
- trx_t* innobase_get_trx();
-@@ -899,6 +900,11 @@
-                       ready = buf_flush_ready_for_replace(&block->page);
-                       mutex_exit(&block->mutex);
-+                      if (block->page.is_corrupt) {
-+                              /* corrupt page may remain, it can be skipped */
-+                              break;
-+                      }
-+
-                       if (!ready) {
-                               return(block);
-@@ -1420,6 +1426,13 @@
-               return(NULL);
-       }
-+      if (srv_pass_corrupt_table <= 1) {
-+              if (bpage->is_corrupt) {
-+                      rw_lock_s_unlock(&page_hash_latch);
-+                      return(NULL);
-+              }
-+      }
-+
-       block_mutex = buf_page_get_mutex_enter(bpage);
-       rw_lock_s_unlock(&page_hash_latch);
-@@ -1909,6 +1922,13 @@
-               return(NULL);
-       }
-+      if (srv_pass_corrupt_table <= 1) {
-+              if (block->page.is_corrupt) {
-+                      mutex_exit(block_mutex);
-+                      return(NULL);
-+              }
-+      }
-+
-       switch (buf_block_get_state(block)) {
-               buf_page_t*     bpage;
-               ibool           success;
-@@ -2557,6 +2577,7 @@
-       bpage->newest_modification = 0;
-       bpage->oldest_modification = 0;
-       HASH_INVALIDATE(bpage, hash);
-+      bpage->is_corrupt = FALSE;
- #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
-       bpage->file_page_was_freed = FALSE;
- #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
-@@ -3087,6 +3108,7 @@
-                               (ulong) bpage->offset);
-               }
-+              if (!srv_pass_corrupt_table || !bpage->is_corrupt) {
-               /* From version 3.23.38 up we store the page checksum
-               to the 4 first bytes of the page end lsn field */
-@@ -3128,6 +3150,23 @@
-                             REFMAN "forcing-innodb-recovery.html\n"
-                             "InnoDB: about forcing recovery.\n", stderr);
-+                      if (srv_pass_corrupt_table && !trx_sys_sys_space(bpage->space)
-+                          && bpage->space < SRV_LOG_SPACE_FIRST_ID) {
-+                              trx_t*  trx;
-+
-+                              fprintf(stderr,
-+                                      "InnoDB: space %u will be treated as corrupt.\n",
-+                                      bpage->space);
-+                              fil_space_set_corrupt(bpage->space);
-+
-+                              trx = innobase_get_trx();
-+                              if (trx && trx->dict_operation_lock_mode == RW_X_LATCH) {
-+                                      dict_table_set_corrupt_by_space(bpage->space, FALSE);
-+                              } else {
-+                                      dict_table_set_corrupt_by_space(bpage->space, TRUE);
-+                              }
-+                              bpage->is_corrupt = TRUE;
-+                      } else
-                       if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
-                               fputs("InnoDB: Ending processing because of"
-                                     " a corrupt database page.\n",
-@@ -3135,6 +3174,7 @@
-                               exit(1);
-                       }
-               }
-+              } /**/
-               if (recv_recovery_is_on()) {
-                       /* Pages must be uncompressed for crash recovery. */
-@@ -3144,8 +3184,11 @@
-               if (uncompressed && !recv_no_ibuf_operations) {
-                       ibuf_merge_or_delete_for_page(
-+                              /* Delete possible entries, if bpage is_corrupt */
-+                              (srv_pass_corrupt_table && bpage->is_corrupt) ? NULL :
-                               (buf_block_t*) bpage, bpage->space,
-                               bpage->offset, buf_page_get_zip_size(bpage),
-+                              (srv_pass_corrupt_table && bpage->is_corrupt) ? FALSE :
-                               TRUE);
-               }
-       }
---- a/storage/innodb_plugin/buf/buf0rea.c
-+++ b/storage/innodb_plugin/buf/buf0rea.c
-@@ -197,7 +197,14 @@
-                             sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
-                             ((buf_block_t*) bpage)->frame, bpage, trx);
-       }
-+
-+      if (srv_pass_corrupt_table) {
-+              if (*err != DB_SUCCESS) {
-+                      bpage->is_corrupt = TRUE;
-+              }
-+      } else {
-       ut_a(*err == DB_SUCCESS);
-+      }
-       if (sync) {
-               /* The i/o is already completed when we arrive from
---- a/storage/innodb_plugin/dict/dict0dict.c
-+++ b/storage/innodb_plugin/dict/dict0dict.c
-@@ -54,6 +54,7 @@
- #include "row0merge.h"
- #include "m_ctype.h" /* my_isspace() */
- #include "ha_prototypes.h" /* innobase_strcasecmp() */
-+#include "srv0start.h" /* SRV_LOG_SPACE_FIRST_ID */
- #include <ctype.h>
-@@ -734,7 +735,7 @@
-       mutex_exit(&(dict_sys->mutex));
--      if (table != NULL) {
-+      if (table != NULL && !table->is_corrupt) {
-               /* If table->ibd_file_missing == TRUE, this will
-               print an error message and return without doing
-               anything. */
-@@ -1275,7 +1276,7 @@
-                   + dict_sys->size) > srv_dict_size_limit ) {
-               prev_table = UT_LIST_GET_PREV(table_LRU, table);
--              if (table == self || table->n_mysql_handles_opened)
-+              if (table == self || table->n_mysql_handles_opened || table->is_corrupt)
-                       goto next_loop;
-               cached_foreign_tables = 0;
-@@ -4328,6 +4329,12 @@
-       }
-       do {
-+              if (table->is_corrupt) {
-+                      ut_a(srv_pass_corrupt_table);
-+                      dict_table_stats_unlock(table, RW_X_LATCH);
-+                      return;
-+              }
-+
-               if (UNIV_LIKELY
-                   (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE
-                    || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
-@@ -5054,4 +5061,42 @@
-               rw_lock_free(&dict_table_stats_latches[i]);
-       }
- }
-+
-+/*************************************************************************
-+set is_corrupt flag by space_id*/
-+
-+void
-+dict_table_set_corrupt_by_space(
-+/*============================*/
-+      ulint   space_id,
-+      ibool   need_mutex)
-+{
-+      dict_table_t*   table;
-+      ibool           found = FALSE;
-+
-+      ut_a(!trx_sys_sys_space(space_id) && space_id < SRV_LOG_SPACE_FIRST_ID);
-+
-+      if (need_mutex)
-+              mutex_enter(&(dict_sys->mutex));
-+
-+      table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
-+
-+      while (table) {
-+              if (table->space == space_id) {
-+                      table->is_corrupt = TRUE;
-+                      found = TRUE;
-+              }
-+
-+              table = UT_LIST_GET_NEXT(table_LRU, table);
-+      }
-+
-+      if (need_mutex)
-+              mutex_exit(&(dict_sys->mutex));
-+
-+      if (!found) {
-+              fprintf(stderr, "InnoDB: space to be marked as "
-+                      "crashed was not found for id %lu.\n",
-+                      (ulong) space_id);
-+      }
-+}
- #endif /* !UNIV_HOTBACKUP */
---- a/storage/innodb_plugin/dict/dict0mem.c
-+++ b/storage/innodb_plugin/dict/dict0mem.c
-@@ -89,6 +89,8 @@
-       /* The number of transactions that are either waiting on the
-       AUTOINC lock or have been granted the lock. */
-       table->n_waiting_or_granted_auto_inc_locks = 0;
-+
-+      table->is_corrupt = FALSE;
- #endif /* !UNIV_HOTBACKUP */
-       ut_d(table->magic_n = DICT_TABLE_MAGIC_N);
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -225,6 +225,7 @@
-                               file we have written to */
-       ibool           is_in_unflushed_spaces; /*!< TRUE if this space is
-                               currently in unflushed_spaces */
-+      ibool           is_corrupt;
-       UT_LIST_NODE_T(fil_space_t) space_list;
-                               /*!< list of all spaces */
-       ulint           magic_n;/*!< FIL_SPACE_MAGIC_N */
-@@ -1248,6 +1249,8 @@
-                   ut_fold_string(name), space);
-       space->is_in_unflushed_spaces = FALSE;
-+      space->is_corrupt = FALSE;
-+
-       UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
-       mutex_exit(&fil_system->mutex);
-@@ -5219,6 +5222,34 @@
-       ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
-       ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
-+      if (srv_pass_corrupt_table == 1 && space->is_corrupt) {
-+              /* should ignore i/o for the crashed space */
-+              mutex_enter(&fil_system->mutex);
-+              fil_node_complete_io(node, fil_system, type);
-+              mutex_exit(&fil_system->mutex);
-+              if (mode == OS_AIO_NORMAL) {
-+                      ut_a(space->purpose == FIL_TABLESPACE);
-+                      buf_page_io_complete(message);
-+              }
-+              if (type == OS_FILE_READ) {
-+                      return(DB_TABLESPACE_DELETED);
-+              } else {
-+                      return(DB_SUCCESS);
-+              }
-+      } else {
-+              if (srv_pass_corrupt_table > 1 && space->is_corrupt) {
-+                      /* should ignore write i/o for the crashed space */
-+                      if (type == OS_FILE_WRITE) {
-+                              mutex_enter(&fil_system->mutex);
-+                              fil_node_complete_io(node, fil_system, type);
-+                              mutex_exit(&fil_system->mutex);
-+                              if (mode == OS_AIO_NORMAL) {
-+                                      ut_a(space->purpose == FIL_TABLESPACE);
-+                                      buf_page_io_complete(message);
-+                              }
-+                              return(DB_SUCCESS);
-+                      }
-+              }
- #ifdef UNIV_HOTBACKUP
-       /* In ibbackup do normal i/o, not aio */
-       if (type == OS_FILE_READ) {
-@@ -5233,6 +5264,8 @@
-       ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
-                    offset_low, offset_high, len, node, message, trx);
- #endif
-+      } /**/
-+
-       ut_a(ret);
-       if (mode == OS_AIO_SYNC) {
-@@ -5726,3 +5759,46 @@
-                return 0;
-        }
- }
-+
-+/*************************************************************************
-+functions to access is_corrupt flag of fil_space_t*/
-+
-+ibool
-+fil_space_is_corrupt(
-+/*=================*/
-+      ulint   space_id)
-+{
-+      fil_space_t*    space;
-+      ibool           ret = FALSE;
-+
-+      mutex_enter(&fil_system->mutex);
-+
-+      space = fil_space_get_by_id(space_id);
-+
-+      if (space && space->is_corrupt) {
-+              ret = TRUE;
-+      }
-+
-+      mutex_exit(&fil_system->mutex);
-+
-+      return(ret);
-+}
-+
-+void
-+fil_space_set_corrupt(
-+/*==================*/
-+      ulint   space_id)
-+{
-+      fil_space_t*    space;
-+
-+      mutex_enter(&fil_system->mutex);
-+
-+      space = fil_space_get_by_id(space_id);
-+
-+      if (space) {
-+              space->is_corrupt = TRUE;
-+      }
-+
-+      mutex_exit(&fil_system->mutex);
-+}
-+
---- a/storage/innodb_plugin/fsp/fsp0fsp.c
-+++ b/storage/innodb_plugin/fsp/fsp0fsp.c
-@@ -370,6 +370,12 @@
-       ut_ad(id || !zip_size);
-       block = buf_page_get(id, zip_size, 0, RW_X_LATCH, mtr);
-+
-+      if (srv_pass_corrupt_table && !block) {
-+              return(0);
-+      }
-+      ut_a(block);
-+
-       header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
-       buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
-@@ -788,6 +794,12 @@
-       fsp_header_t*   sp_header;
-       block = buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
-+
-+      if (srv_pass_corrupt_table && !block) {
-+              return(0);
-+      }
-+      ut_a(block);
-+
-       buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
-       sp_header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
-@@ -1867,6 +1879,11 @@
- {
-       fseg_inode_t*   inode;
-+      if (srv_pass_corrupt_table && !page) {
-+              return(ULINT_UNDEFINED);
-+      }
-+      ut_a(page);
-+
-       for (; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
-               inode = fsp_seg_inode_page_get_nth_inode(
-@@ -1980,6 +1997,11 @@
-       page = buf_block_get_frame(block);
-+      if (srv_pass_corrupt_table && !page) {
-+              return(0);
-+      }
-+      ut_a(page);
-+
-       n = fsp_seg_inode_page_find_free(page, 0, zip_size, mtr);
-       ut_a(n != ULINT_UNDEFINED);
-@@ -2073,6 +2095,11 @@
-       inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
-+      if (srv_pass_corrupt_table && !inode) {
-+              return(0);
-+      }
-+      ut_a(inode);
-+
-       if (UNIV_UNLIKELY
-           (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) {
-@@ -2100,7 +2127,7 @@
- {
-       fseg_inode_t*   inode
-               = fseg_inode_try_get(header, space, zip_size, mtr);
--      ut_a(inode);
-+      ut_a(srv_pass_corrupt_table || inode);
-       return(inode);
- }
-@@ -3309,6 +3336,11 @@
-       descr = xdes_get_descriptor(space, zip_size, page, mtr);
-+      if (srv_pass_corrupt_table && !descr) {
-+              /* The page may be corrupt. pass it. */
-+              return;
-+      }
-+
-       ut_a(descr);
-       if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) {
-               fputs("InnoDB: Dump of the tablespace extent descriptor: ",
-@@ -3561,6 +3593,11 @@
-       descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
-+      if (srv_pass_corrupt_table && !descr) {
-+              /* The page may be corrupt. pass it. */
-+              return(TRUE);
-+      }
-+
-       /* Check that the header resides on a page which has not been
-       freed yet */
-@@ -3645,6 +3682,12 @@
-       inode = fseg_inode_get(header, space, zip_size, mtr);
-+      if (srv_pass_corrupt_table && !inode) {
-+              /* ignore the corruption */
-+              return(TRUE);
-+      }
-+      ut_a(inode);
-+
-       descr = fseg_get_first_extent(inode, space, zip_size, mtr);
-       if (descr != NULL) {
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -3738,6 +3738,12 @@
-               DBUG_RETURN(1);
-       }
-+      if (srv_pass_corrupt_table <= 1 && share->ib_table && share->ib_table->is_corrupt) {
-+              free_share(share);
-+
-+              DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
-+      }
-+
-       /* 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
-@@ -3765,6 +3771,19 @@
-       /* Get pointer to a table object in InnoDB dictionary cache */
-       ib_table = dict_table_get(norm_name, TRUE);
-       
-+      if (srv_pass_corrupt_table <= 1 && ib_table && ib_table->is_corrupt) {
-+              free_share(share);
-+              my_free(upd_buff, MYF(0));
-+
-+              DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
-+      }
-+
-+      share->ib_table = ib_table;
-+
-+
-+
-+
-+
-       if (NULL == ib_table) {
-               if (is_part && retries < 10) {
-                       ++retries;
-@@ -4912,6 +4931,10 @@
-       ha_statistic_increment(&SSV::ha_write_count);
-+      if (share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
-               table->timestamp_field->set_time();
-@@ -5125,6 +5148,10 @@
- func_exit:
-       innobase_active_small();
-+      if (share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       DBUG_RETURN(error_result);
- }
-@@ -5301,6 +5328,10 @@
-       ha_statistic_increment(&SSV::ha_update_count);
-+      if (share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
-               table->timestamp_field->set_time();
-@@ -5386,6 +5417,10 @@
-       innobase_active_small();
-+      if (share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       DBUG_RETURN(error);
- }
-@@ -5407,6 +5442,10 @@
-       ha_statistic_increment(&SSV::ha_delete_count);
-+      if (share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       if (!prebuilt->upd_node) {
-               row_get_prebuilt_update_vector(prebuilt);
-       }
-@@ -5429,6 +5468,10 @@
-       innobase_active_small();
-+      if (share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       DBUG_RETURN(error);
- }
-@@ -5668,6 +5711,10 @@
-       ha_statistic_increment(&SSV::ha_read_key_count);
-+      if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       index = prebuilt->index;
-       if (UNIV_UNLIKELY(index == NULL)) {
-@@ -5733,6 +5780,10 @@
-               ret = DB_UNSUPPORTED;
-       }
-+      if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       switch (ret) {
-       case DB_SUCCESS:
-               error = 0;
-@@ -5843,6 +5894,10 @@
- {
-       DBUG_ENTER("change_active_index");
-+      if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       ut_ad(user_thd == ha_thd());
-       ut_a(prebuilt->trx == thd_to_trx(user_thd));
-@@ -5933,6 +5988,10 @@
-       DBUG_ENTER("general_fetch");
-+      if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       ut_a(prebuilt->trx == thd_to_trx(user_thd));
-       innodb_srv_conc_enter_innodb(prebuilt->trx);
-@@ -5942,6 +6001,10 @@
-       innodb_srv_conc_exit_innodb(prebuilt->trx);
-+      if (srv_pass_corrupt_table <= 1 && share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       switch (ret) {
-       case DB_SUCCESS:
-               error = 0;
-@@ -7189,6 +7252,10 @@
-               DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
-       }
-+      if (share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       /* Truncate the table in InnoDB */
-       error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
-@@ -7197,6 +7264,10 @@
-               goto fallback;
-       }
-+      if (share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       error = convert_error_code_to_mysql(error, prebuilt->table->flags,
-                                           NULL);
-@@ -7701,6 +7772,16 @@
-       return(ranges + (double) rows / (double) total_rows * time_for_scan);
- }
-+UNIV_INTERN
-+bool
-+ha_innobase::is_corrupt() const
-+{
-+      if (share->ib_table)
-+              return ((bool)share->ib_table->is_corrupt);
-+      else
-+              return (FALSE);
-+}
-+
- /*********************************************************************//**
- 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
-@@ -7881,7 +7962,7 @@
-       ib_table = prebuilt->table;
-       if (flag & HA_STATUS_TIME) {
--              if (called_from_analyze || innobase_stats_on_metadata) {
-+              if ((called_from_analyze || innobase_stats_on_metadata) && !share->ib_table->is_corrupt) {
-                       /* In sql_show we call with this flag: update
-                       then statistics so that they are up-to-date */
-@@ -8154,10 +8235,18 @@
-       THD*            thd,            /*!< in: connection thread handle */
-       HA_CHECK_OPT*   check_opt)      /*!< in: currently ignored */
- {
-+      if (share->ib_table->is_corrupt) {
-+              return(HA_ADMIN_CORRUPT);
-+      }
-+
-       /* Simply call ::info() with all the flags */
-       info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE,
-                true /* called from analyze */);
-+      if (share->ib_table->is_corrupt) {
-+              return(HA_ADMIN_CORRUPT);
-+      }
-+
-       return(0);
- }
-@@ -8339,6 +8428,10 @@
-               my_error(ER_QUERY_INTERRUPTED, MYF(0));
-       }
-+      if (share->ib_table->is_corrupt) {
-+              return(HA_ADMIN_CORRUPT);
-+      }
-+
-       DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
- }
-@@ -9072,6 +9165,10 @@
-       update_thd(thd);
-+      if (share->ib_table->is_corrupt) {
-+              DBUG_RETURN(HA_ERR_CRASHED);
-+      }
-+
-       if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) {
-               ut_print_timestamp(stderr);
-               fprintf(stderr,
-@@ -11497,6 +11594,14 @@
-   "dump file (if present). Disabled by default.",
-   NULL, NULL, FALSE);
-+static        MYSQL_SYSVAR_ULONG(pass_corrupt_table, srv_pass_corrupt_table,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Pass corruptions of user tables as 'corrupt table' instead of not crashing itself, "
-+  "when used with file_per_table. "
-+  "All file io for the datafile after detected as corrupt are disabled, "
-+  "except for the deletion.",
-+  NULL, NULL, 0, 0, 2, 0);
-+
- static struct st_mysql_sys_var* innobase_system_variables[]= {
-   MYSQL_SYSVAR(additional_mem_pool_size),
-   MYSQL_SYSVAR(autoextend_increment),
-@@ -11581,6 +11686,7 @@
-   MYSQL_SYSVAR(auto_lru_dump),
-   MYSQL_SYSVAR(blocking_lru_restore),
-   MYSQL_SYSVAR(use_purge_thread),
-+  MYSQL_SYSVAR(pass_corrupt_table),
-   NULL
- };
---- a/storage/innodb_plugin/handler/ha_innodb.h
-+++ b/storage/innodb_plugin/handler/ha_innodb.h
-@@ -52,6 +52,7 @@
-       innodb_idx_translate_t  idx_trans_tbl;  /*!< index translation
-                                               table between MySQL and
-                                               Innodb */
-+      dict_table_t*           ib_table;
- } INNOBASE_SHARE;
-@@ -135,6 +136,7 @@
-       int close(void);
-       double scan_time();
-       double read_time(uint index, uint ranges, ha_rows rows);
-+      bool is_corrupt() const;
-       int write_row(uchar * buf);
-       int update_row(const uchar * old_data, uchar * new_data);
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -42,5 +42,6 @@
- {"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_separate_doublewrite","Add option 'innodb_doublewrite_file' to separate doublewrite dedicated tablespace","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/btr0btr.ic
-+++ b/storage/innodb_plugin/include/btr0btr.ic
-@@ -28,7 +28,7 @@
- #include "mtr0mtr.h"
- #include "mtr0log.h"
- #include "page0zip.h"
--
-+#include "srv0srv.h"
- #define BTR_MAX_NODE_LEVEL    50      /*!< Maximum B-tree page level
-                                       (not really a hard limit).
-                                       Used in debug assertions
-@@ -55,7 +55,9 @@
-       block = buf_page_get_gen(space, zip_size, page_no, mode,
-                                NULL, BUF_GET, file, line, mtr);
--      if (mode != RW_NO_LATCH) {
-+      ut_a(srv_pass_corrupt_table || block);
-+
-+      if (block && mode != RW_NO_LATCH) {
-               buf_block_dbg_add_level(block, SYNC_TREE_NODE);
-       }
---- a/storage/innodb_plugin/include/buf0buf.h
-+++ b/storage/innodb_plugin/include/buf0buf.h
-@@ -898,7 +898,7 @@
-       const buf_block_t*      block)  /*!< in: pointer to the control block */
-       __attribute__((pure));
- #else /* UNIV_DEBUG */
--# define buf_block_get_frame(block) (block)->frame
-+# define buf_block_get_frame(block) (block ? (block)->frame : 0)
- #endif /* UNIV_DEBUG */
- /*********************************************************************//**
- Gets the space id of a block.
-@@ -1198,6 +1198,7 @@
-                                       0 if the block was never accessed
-                                       in the buffer pool */
-       /* @} */
-+      ibool           is_corrupt;
- # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
-       ibool           file_page_was_freed;
-                                       /*!< this is set to TRUE when fsp
---- a/storage/innodb_plugin/include/buf0buf.ic
-+++ b/storage/innodb_plugin/include/buf0buf.ic
-@@ -35,7 +35,7 @@
- #include "buf0flu.h"
- #include "buf0lru.h"
- #include "buf0rea.h"
--
-+#include "srv0srv.h"
- /********************************************************************//**
- Reads the freed_page_clock of a buffer block.
- @return       freed_page_clock */
-@@ -597,6 +597,12 @@
- /*================*/
-       const buf_block_t*      block)  /*!< in: pointer to the control block */
- {
-+      ut_a(srv_pass_corrupt_table || block);
-+
-+      if (srv_pass_corrupt_table && !block) {
-+              return(0);
-+      }
-+
-       ut_ad(block);
-       switch (buf_block_get_state(block)) {
---- a/storage/innodb_plugin/include/dict0dict.h
-+++ b/storage/innodb_plugin/include/dict0dict.h
-@@ -1197,6 +1197,15 @@
- dict_close(void);
- /*============*/
-+/*************************************************************************
-+set is_corrupt flag by space_id*/
-+
-+void
-+dict_table_set_corrupt_by_space(
-+/*============================*/
-+      ulint   space_id,
-+      ibool   need_mutex);
-+
- #ifndef UNIV_NONINL
- #include "dict0dict.ic"
- #endif
---- a/storage/innodb_plugin/include/dict0mem.h
-+++ b/storage/innodb_plugin/include/dict0mem.h
-@@ -573,6 +573,7 @@
-                               the AUTOINC lock on this table. */
-                               /* @} */
-       /*----------------------*/
-+      ibool           is_corrupt;
- #endif /* !UNIV_HOTBACKUP */
- #ifdef UNIV_DEBUG
---- a/storage/innodb_plugin/include/fil0fil.h
-+++ b/storage/innodb_plugin/include/fil0fil.h
-@@ -749,6 +749,19 @@
- fil_system_hash_nodes(void);
- /*========================*/
-+/*************************************************************************
-+functions to access is_corrupt flag of fil_space_t*/
-+
-+ibool
-+fil_space_is_corrupt(
-+/*=================*/
-+      ulint   space_id);
-+
-+void
-+fil_space_set_corrupt(
-+/*==================*/
-+      ulint   space_id);
-+
- typedef       struct fil_space_struct fil_space_t;
- #endif
---- a/storage/innodb_plugin/include/fut0fut.ic
-+++ b/storage/innodb_plugin/include/fut0fut.ic
-@@ -23,6 +23,7 @@
- Created 12/13/1995 Heikki Tuuri
- ***********************************************************************/
-+#include "srv0srv.h"
- #include "sync0rw.h"
- #include "buf0buf.h"
-@@ -48,6 +49,12 @@
-       ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
-       block = buf_page_get(space, zip_size, addr.page, rw_latch, mtr);
-+
-+      if (srv_pass_corrupt_table && !block) {
-+              return(0);
-+      }
-+      ut_a(block);
-+
-       ptr = buf_block_get_frame(block) + addr.boffset;
-       buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
---- a/storage/innodb_plugin/include/page0page.h
-+++ b/storage/innodb_plugin/include/page0page.h
-@@ -527,7 +527,7 @@
- page_is_leaf(
- /*=========*/
-       const page_t*   page)   /*!< in: page */
--      __attribute__((nonnull, pure));
-+      __attribute__((pure));
- /************************************************************//**
- Gets the pointer to the next record on the page.
- @return       pointer to next record */
---- a/storage/innodb_plugin/include/page0page.ic
-+++ b/storage/innodb_plugin/include/page0page.ic
-@@ -275,6 +275,9 @@
- /*=========*/
-       const page_t*   page)   /*!< in: page */
- {
-+      if (!page) {
-+              return(FALSE);
-+      }
-       return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
- }
---- a/storage/innodb_plugin/include/page0zip.h
-+++ b/storage/innodb_plugin/include/page0zip.h
-@@ -114,7 +114,7 @@
-       const page_t*   page,   /*!< in: uncompressed page */
-       dict_index_t*   index,  /*!< in: index of the B-tree node */
-       mtr_t*          mtr)    /*!< in: mini-transaction, or NULL */
--      __attribute__((nonnull(1,2,3)));
-+      __attribute__((nonnull(1,3)));
- /**********************************************************************//**
- Decompress a page.  This function should tolerate errors on the compressed
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -229,6 +229,7 @@
- extern ulint  srv_adaptive_checkpoint;
- extern ulint  srv_expand_import;
-+extern ulint  srv_pass_corrupt_table;
- extern ulint  srv_extra_rsegments;
- extern ulint  srv_dict_size_limit;
---- a/storage/innodb_plugin/page/page0zip.c
-+++ b/storage/innodb_plugin/page/page0zip.c
-@@ -1195,6 +1195,10 @@
-       FILE*           logfile = NULL;
- #endif
-+      if (!page) {
-+              return(FALSE);
-+      }
-+
-       ut_a(page_is_comp(page));
-       ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX);
-       ut_ad(page_simple_validate_new((page_t*) page));
---- a/storage/innodb_plugin/row/row0ins.c
-+++ b/storage/innodb_plugin/row/row0ins.c
-@@ -1348,6 +1348,12 @@
-               const rec_t*            rec = btr_pcur_get_rec(&pcur);
-               const buf_block_t*      block = btr_pcur_get_block(&pcur);
-+              if (srv_pass_corrupt_table && !block) {
-+                      err = DB_CORRUPTION;
-+                      break;
-+              }
-+              ut_a(block);
-+
-               if (page_rec_is_infimum(rec)) {
-                       continue;
---- a/storage/innodb_plugin/row/row0merge.c
-+++ b/storage/innodb_plugin/row/row0merge.c
-@@ -1224,6 +1224,13 @@
-               if (UNIV_LIKELY(has_next)) {
-                       rec = btr_pcur_get_rec(&pcur);
-+
-+                      if (srv_pass_corrupt_table && !rec) {
-+                              err = DB_CORRUPTION;
-+                              goto err_exit;
-+                      }
-+                      ut_a(rec);
-+
-                       offsets = rec_get_offsets(rec, clust_index, NULL,
-                                                 ULINT_UNDEFINED, &row_heap);
---- a/storage/innodb_plugin/row/row0sel.c
-+++ b/storage/innodb_plugin/row/row0sel.c
-@@ -3896,6 +3896,13 @@
-       /* PHASE 4: Look for matching records in a loop */
-       rec = btr_pcur_get_rec(pcur);
-+
-+      if (srv_pass_corrupt_table && !rec) {
-+              err = DB_CORRUPTION;
-+              goto lock_wait_or_error;
-+      }
-+      ut_a(rec);
-+
-       ut_ad(!!page_rec_is_comp(rec) == comp);
- #ifdef UNIV_SEARCH_DEBUG
-       /*
-@@ -3973,7 +3980,13 @@
-       if (UNIV_UNLIKELY(next_offs >= UNIV_PAGE_SIZE - PAGE_DIR)) {
- wrong_offs:
--              if (srv_force_recovery == 0 || moves_up == FALSE) {
-+              if (srv_pass_corrupt_table && !trx_sys_sys_space(index->table->space)) {
-+                      index->table->is_corrupt = TRUE;
-+                      fil_space_set_corrupt(index->table->space);
-+              }
-+
-+              if ((srv_force_recovery == 0 || moves_up == FALSE)
-+                  && srv_pass_corrupt_table <= 1) {
-                       ut_print_timestamp(stderr);
-                       buf_page_print(page_align(rec), 0);
-                       fprintf(stderr,
-@@ -4024,7 +4037,8 @@
-       offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
--      if (UNIV_UNLIKELY(srv_force_recovery > 0)) {
-+      if (UNIV_UNLIKELY(srv_force_recovery > 0)
-+          || (srv_pass_corrupt_table == 2 && index->table->is_corrupt)) {
-               if (!rec_validate(rec, offsets)
-                   || !btr_index_rec_validate(rec, index, FALSE)) {
-                       fprintf(stderr,
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -408,6 +408,7 @@
- UNIV_INTERN ulint     srv_adaptive_checkpoint = 0; /* 0: none  1: reflex  2: estimate */
- UNIV_INTERN ulint     srv_expand_import = 0; /* 0:disable 1:enable */
-+UNIV_INTERN ulint     srv_pass_corrupt_table = 0; /* 0:disable 1:enable */
- UNIV_INTERN ulint     srv_extra_rsegments = 0; /* extra rseg for users */
- UNIV_INTERN ulint     srv_dict_size_limit = 0;
---- a/storage/innodb_plugin/srv/srv0start.c
-+++ b/storage/innodb_plugin/srv/srv0start.c
-@@ -2006,6 +2006,13 @@
-       os_fast_mutex_free(&srv_os_test_mutex);
-+      if (!srv_file_per_table_original_value
-+          && srv_pass_corrupt_table) {
-+              fprintf(stderr, "InnoDB: Warning:"
-+                      " innodb_file_per_table is diabled."
-+                      " So innodb_pass_corrupt_table doesn't make sence\n");
-+      }
-+
-       if (srv_print_verbose_log) {
-               ut_print_timestamp(stderr);
-               fprintf(stderr,
diff --git a/mysql-innodb_purge_thread.patch b/mysql-innodb_purge_thread.patch
deleted file mode 100644 (file)
index b441fce..0000000
+++ /dev/null
@@ -1,514 +0,0 @@
-# name       : innodb_purge_thread.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -11001,6 +11001,11 @@
-   "Output statistics of recovery process after it.",
-   NULL, NULL, FALSE);
-+static MYSQL_SYSVAR_ULONG(use_purge_thread, srv_use_purge_thread,
-+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-+  "Number of purge devoted threads. #### over 1 is EXPERIMENTAL ####",
-+  NULL, NULL, 0, 0, UNIV_MAX_PARALLELISM, 0);
-+
- static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
-   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-   "During InnoDB crash recovery on slave overwrite relay-log.info "
-@@ -11495,6 +11500,7 @@
-   MYSQL_SYSVAR(random_read_ahead),
-   MYSQL_SYSVAR(read_ahead_threshold),
-   MYSQL_SYSVAR(io_capacity),
-+  MYSQL_SYSVAR(use_purge_thread),
-   NULL
- };
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -36,5 +36,6 @@
- {"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -116,6 +116,8 @@
- extern ibool  srv_recovery_stats;
-+extern ulint  srv_use_purge_thread;
-+
- extern ibool  srv_auto_extend_last_data_file;
- extern ulint  srv_last_file_size_max;
- extern char** srv_log_group_home_dirs;
-@@ -419,6 +421,8 @@
-       SRV_RECOVERY,   /**< threads finishing a recovery */
-       SRV_INSERT,     /**< thread flushing the insert buffer to disk */
- #endif
-+      SRV_PURGE,      /* thread purging undo records */
-+      SRV_PURGE_WORKER,       /* thread purging undo records */
-       SRV_MASTER      /**< the master thread, (whose type number must
-                       be biggest) */
- };
-@@ -492,6 +496,21 @@
- /*==============*/
-       void*   arg);   /*!< in: a dummy parameter required by
-                       os_thread_create */
-+/*************************************************************************
-+The undo purge thread. */
-+UNIV_INTERN
-+os_thread_ret_t
-+srv_purge_thread(
-+/*=============*/
-+      void*   arg);   /* in: a dummy parameter required by
-+                      os_thread_create */
-+/*************************************************************************
-+The undo purge thread. */
-+UNIV_INTERN
-+os_thread_ret_t
-+srv_purge_worker_thread(
-+/*====================*/
-+      void*   arg);
- /*******************************************************************//**
- Tells the Innobase server that there has been activity in the database
- and wakes up the master thread if it is suspended (not sleeping). Used
---- a/storage/innodb_plugin/include/trx0purge.h
-+++ b/storage/innodb_plugin/include/trx0purge.h
-@@ -114,6 +114,25 @@
- ulint
- trx_purge(void);
- /*===========*/
-+/**********************************************************************
-+This function runs a purge worker batch */
-+UNIV_INTERN
-+void
-+trx_purge_worker(
-+/*=============*/
-+      ulint   worker_id);
-+/**********************************************************************
-+This function waits the event for worker batch */
-+UNIV_INTERN
-+void
-+trx_purge_worker_wait(void);
-+/*========================*/
-+/**********************************************************************
-+This function wakes the waiting worker batch */
-+UNIV_INTERN
-+void
-+trx_purge_worker_wake(void);
-+/*========================*/
- /******************************************************************//**
- Prints information of the purge system to stderr. */
- UNIV_INTERN
-@@ -131,6 +150,11 @@
-                                       of the trx system and it never ends */
-       que_t*          query;          /*!< The query graph which will do the
-                                       parallelized purge operation */
-+      ulint           n_worker;
-+      os_event_t      worker_event;
-+      sess_t**        sess_arr;
-+      trx_t**         trx_arr;
-+      que_t**         query_arr;
-       rw_lock_t       latch;          /*!< The latch protecting the purge view.
-                                       A purge operation must acquire an
-                                       x-latch here for the instant at which
---- a/storage/innodb_plugin/log/log0log.c
-+++ b/storage/innodb_plugin/log/log0log.c
-@@ -3151,6 +3151,16 @@
-               goto loop;
-       }
-+      /* Check that the purge threads ended */
-+      if (srv_use_purge_thread
-+          && (srv_n_threads_active[SRV_PURGE] != 0
-+              || srv_n_threads_active[SRV_PURGE_WORKER] != 0)) {
-+
-+              mutex_exit(&kernel_mutex);
-+
-+              goto loop;
-+      }
-+
-       mutex_exit(&kernel_mutex);
-       mutex_enter(&(log_sys->mutex));
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -146,6 +146,8 @@
- UNIV_INTERN ibool     srv_recovery_stats = FALSE;
-+UNIV_INTERN ulint     srv_use_purge_thread = 0;
-+
- /* if TRUE, then we auto-extend the last data file */
- UNIV_INTERN ibool     srv_auto_extend_last_data_file  = FALSE;
- /* if != 0, this tells the max size auto-extending may increase the
-@@ -2640,10 +2642,10 @@
-       srv_main_thread_process_no = os_proc_get_number();
-       srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
--      srv_table_reserve_slot(SRV_MASTER);
-       mutex_enter(&kernel_mutex);
-+      srv_table_reserve_slot(SRV_MASTER);
-       srv_n_threads_active[SRV_MASTER]++;
-       mutex_exit(&kernel_mutex);
-@@ -3101,6 +3103,7 @@
-       /* Flush logs if needed */
-       srv_sync_log_buffer_in_background();
-+      if (!srv_use_purge_thread) {
-       /* We run a full purge every 10 seconds, even if the server
-       were active */
-       do {
-@@ -3117,6 +3120,7 @@
-               srv_sync_log_buffer_in_background();
-       } while (n_pages_purged);
-+      }
-       srv_main_thread_op_info = "flushing buffer pool pages";
-@@ -3185,6 +3189,7 @@
-               os_thread_sleep(100000);
-       }
-+      if (!srv_use_purge_thread) {
-       srv_main_thread_op_info = "purging";
-       /* Run a full purge */
-@@ -3201,6 +3206,7 @@
-               srv_sync_log_buffer_in_background();
-       } while (n_pages_purged);
-+      }
-       srv_main_thread_op_info = "reserving kernel mutex";
-@@ -3353,3 +3359,143 @@
-       OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
- }
-+
-+/*************************************************************************
-+A thread which is devoted to purge, for take over the master thread's
-+purging */
-+UNIV_INTERN
-+os_thread_ret_t
-+srv_purge_thread(
-+/*=============*/
-+      void*   arg __attribute__((unused)))
-+                      /* in: a dummy parameter required by os_thread_create */
-+{
-+      ulint   n_pages_purged;
-+      ulint   n_pages_purged_sum = 1; /* dummy */
-+      ulint   history_len;
-+      ulint   sleep_ms= 10000; /* initial: 10 sec. */
-+      ibool   can_be_last = FALSE;
-+
-+#ifdef UNIV_DEBUG_THREAD_CREATION
-+      fprintf(stderr, "Purge thread starts, id %lu\n",
-+              os_thread_pf(os_thread_get_curr_id()));
-+#endif
-+
-+      mutex_enter(&kernel_mutex);
-+      srv_table_reserve_slot(SRV_PURGE);
-+      srv_n_threads_active[SRV_PURGE]++;
-+      mutex_exit(&kernel_mutex);
-+
-+loop:
-+      if (srv_shutdown_state > 0) {
-+              if (srv_fast_shutdown) {
-+                      /* someone other should wait the end of the workers */
-+                      goto exit_func;
-+              }
-+
-+              mutex_enter(&kernel_mutex);
-+              if (srv_n_threads_active[SRV_PURGE_WORKER]) {
-+                      can_be_last = FALSE;
-+              } else {
-+                      can_be_last = TRUE;
-+              }
-+              mutex_exit(&kernel_mutex);
-+
-+              sleep_ms = 10;
-+      }
-+
-+      os_thread_sleep( sleep_ms * 1000 );
-+
-+      history_len = trx_sys->rseg_history_len;
-+      if (history_len > 1000)
-+              sleep_ms /= 10;
-+      if (sleep_ms < 10)
-+              sleep_ms = 10;
-+
-+      n_pages_purged_sum = 0;
-+
-+      do {
-+              if (srv_fast_shutdown && srv_shutdown_state > 0) {
-+                      goto exit_func;
-+              }
-+              n_pages_purged = trx_purge();
-+              n_pages_purged_sum += n_pages_purged;
-+      } while (n_pages_purged);
-+
-+      if (srv_shutdown_state > 0 && can_be_last) {
-+              /* the last trx_purge() is executed without workers */
-+              goto exit_func;
-+      }
-+
-+      if (n_pages_purged_sum) {
-+              srv_active_wake_master_thread();
-+      }
-+
-+      if (n_pages_purged_sum == 0)
-+              sleep_ms *= 10;
-+      if (sleep_ms > 10000)
-+              sleep_ms = 10000;
-+
-+      goto loop;
-+
-+exit_func:
-+      trx_purge_worker_wake(); /* It may not make sense. for safety only */
-+
-+      /* wake master thread to flush the pages */
-+      srv_wake_master_thread();
-+
-+      mutex_enter(&kernel_mutex);
-+      srv_n_threads_active[SRV_PURGE]--;
-+      mutex_exit(&kernel_mutex);
-+      os_thread_exit(NULL);
-+
-+      OS_THREAD_DUMMY_RETURN;
-+}
-+
-+/*************************************************************************
-+A thread which is devoted to purge, for take over the master thread's
-+purging */
-+UNIV_INTERN
-+os_thread_ret_t
-+srv_purge_worker_thread(
-+/*====================*/
-+      void*   arg)
-+{
-+      ulint   worker_id; /* index for array */
-+
-+      worker_id = *((ulint*)arg);
-+
-+#ifdef UNIV_DEBUG_THREAD_CREATION
-+      fprintf(stderr, "Purge worker thread starts, id %lu\n",
-+              os_thread_pf(os_thread_get_curr_id()));
-+#endif
-+      mutex_enter(&kernel_mutex);
-+      srv_table_reserve_slot(SRV_PURGE_WORKER);
-+      srv_n_threads_active[SRV_PURGE_WORKER]++;
-+      mutex_exit(&kernel_mutex);
-+
-+loop:
-+      /* purge worker threads only works when srv_shutdown_state==0 */
-+      /* for safety and exactness. */
-+      if (srv_shutdown_state > 0) {
-+              goto exit_func;
-+      }
-+
-+      trx_purge_worker_wait();
-+
-+      if (srv_shutdown_state > 0) {
-+              goto exit_func;
-+      }
-+
-+      trx_purge_worker(worker_id);
-+
-+      goto loop;
-+
-+exit_func:
-+      mutex_enter(&kernel_mutex);
-+      srv_n_threads_active[SRV_PURGE_WORKER]--;
-+      mutex_exit(&kernel_mutex);
-+      os_thread_exit(NULL);
-+
-+      OS_THREAD_DUMMY_RETURN;
-+}
---- a/storage/innodb_plugin/srv/srv0start.c
-+++ b/storage/innodb_plugin/srv/srv0start.c
-@@ -126,9 +126,9 @@
- static ulint          ios;
- /** io_handler_thread parameters for thread identification */
--static ulint          n[SRV_MAX_N_IO_THREADS + 6];
-+static ulint          n[SRV_MAX_N_IO_THREADS + 6 + UNIV_MAX_PARALLELISM];
- /** io_handler_thread identifiers */
--static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6];
-+static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6 + UNIV_MAX_PARALLELISM];
- /** 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. */
-@@ -1725,6 +1725,20 @@
-       os_thread_create(&srv_master_thread, NULL, thread_ids
-                        + (1 + SRV_MAX_N_IO_THREADS));
-+
-+      if (srv_use_purge_thread) {
-+              ulint i;
-+
-+              os_thread_create(&srv_purge_thread, NULL, thread_ids
-+                               + (5 + SRV_MAX_N_IO_THREADS));
-+
-+              for (i = 0; i < srv_use_purge_thread - 1; i++) {
-+                      n[6 + i + SRV_MAX_N_IO_THREADS] = i; /* using as index for arrays in purge_sys */
-+                      os_thread_create(&srv_purge_worker_thread,
-+                                       n + (6 + i + SRV_MAX_N_IO_THREADS),
-+                                       thread_ids + (6 + i + SRV_MAX_N_IO_THREADS));
-+              }
-+      }
- #ifdef UNIV_DEBUG
-       /* buf_debug_prints = TRUE; */
- #endif /* UNIV_DEBUG */
---- a/storage/innodb_plugin/trx/trx0purge.c
-+++ b/storage/innodb_plugin/trx/trx0purge.c
-@@ -184,8 +184,9 @@
- @return       own: the query graph */
- static
- que_t*
--trx_purge_graph_build(void)
-+trx_purge_graph_build(
- /*=======================*/
-+      trx_t*  trx)
- {
-       mem_heap_t*     heap;
-       que_fork_t*     fork;
-@@ -194,7 +195,7 @@
-       heap = mem_heap_create(512);
-       fork = que_fork_create(NULL, NULL, QUE_FORK_PURGE, heap);
--      fork->trx = purge_sys->trx;
-+      fork->trx = trx;
-       thr = que_thr_create(fork, heap);
-@@ -243,10 +244,35 @@
-       ut_a(trx_start_low(purge_sys->trx, ULINT_UNDEFINED));
--      purge_sys->query = trx_purge_graph_build();
-+      purge_sys->query = trx_purge_graph_build(purge_sys->trx);
-       purge_sys->view = read_view_oldest_copy_or_open_new(ut_dulint_zero,
-                                                           purge_sys->heap);
-+
-+      purge_sys->n_worker = 0;
-+      if (srv_use_purge_thread > 1) {
-+              /* Use worker threads */
-+              ulint i;
-+
-+              purge_sys->n_worker = srv_use_purge_thread - 1;
-+
-+              purge_sys->sess_arr = mem_alloc(sizeof(sess_t*) * purge_sys->n_worker);
-+              purge_sys->trx_arr = mem_alloc(sizeof(trx_t*) * purge_sys->n_worker);
-+              purge_sys->query_arr = mem_alloc(sizeof(que_t*) * purge_sys->n_worker);
-+
-+              purge_sys->worker_event = os_event_create(NULL);
-+              os_event_reset(purge_sys->worker_event);
-+
-+              for (i = 0; i < purge_sys->n_worker; i++) {
-+                      purge_sys->sess_arr[i] = sess_open();
-+
-+                      purge_sys->trx_arr[i] = purge_sys->sess_arr[i]->trx;
-+                      purge_sys->trx_arr[i]->is_purge = 1;
-+                      ut_a(trx_start_low(purge_sys->trx_arr[i], ULINT_UNDEFINED));
-+
-+                      purge_sys->query_arr[i] = trx_purge_graph_build(purge_sys->trx_arr[i]);
-+              }
-+      }
- }
- /************************************************************************
-@@ -1144,7 +1170,7 @@
-       /* Handle at most 20 undo log pages in one purge batch */
--      purge_sys->handle_limit = purge_sys->n_pages_handled + 20;
-+      purge_sys->handle_limit = purge_sys->n_pages_handled + 20 * (srv_use_purge_thread + 1);
-       old_pages_handled = purge_sys->n_pages_handled;
-@@ -1163,6 +1189,9 @@
-       mutex_exit(&kernel_mutex);
-+      if (purge_sys->n_worker)
-+              os_event_set(purge_sys->worker_event);
-+
-       /*      srv_que_task_enqueue(thr2); */
-       if (srv_print_thread_releases) {
-@@ -1172,6 +1201,9 @@
-       que_run_threads(thr);
-+      if (purge_sys->n_worker)
-+              os_event_reset(purge_sys->worker_event);
-+
-       if (srv_print_thread_releases) {
-               fprintf(stderr,
-@@ -1182,6 +1214,52 @@
-       return(purge_sys->n_pages_handled - old_pages_handled);
- }
-+/**********************************************************************
-+This function runs a purge worker batch */
-+UNIV_INTERN
-+void
-+trx_purge_worker(
-+/*=============*/
-+      ulint   worker_id)
-+{
-+      que_thr_t*      thr;
-+
-+      mutex_enter(&kernel_mutex);
-+
-+      thr = que_fork_start_command(purge_sys->query_arr[worker_id]);
-+
-+      ut_ad(thr);
-+
-+      mutex_exit(&kernel_mutex);
-+
-+      que_run_threads(thr);
-+
-+      if (purge_sys->state == TRX_STOP_PURGE) { /* optimistic */
-+              os_event_reset(purge_sys->worker_event);
-+      }
-+}
-+
-+/**********************************************************************
-+This function waits the event for worker batch */
-+UNIV_INTERN
-+void
-+trx_purge_worker_wait(void)
-+/*=======================*/
-+{
-+      os_event_wait(purge_sys->worker_event);
-+}
-+
-+/**********************************************************************
-+This function wakes the waiting worker batch */
-+UNIV_INTERN
-+void
-+trx_purge_worker_wake(void)
-+/*=======================*/
-+{
-+      if (purge_sys->n_worker)
-+              os_event_set(purge_sys->worker_event);
-+}
-+
- /******************************************************************//**
- Prints information of the purge system to stderr. */
- UNIV_INTERN
diff --git a/mysql-innodb_recovery_patches.patch b/mysql-innodb_recovery_patches.patch
deleted file mode 100644 (file)
index 25de3de..0000000
+++ /dev/null
@@ -1,513 +0,0 @@
-# name       : innodb_recovery_patches.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0rea.c
-+++ b/storage/innodb_plugin/buf/buf0rea.c
-@@ -128,6 +128,46 @@
-       bpage = buf_page_init_for_read(err, mode, space, zip_size, unzip,
-                                      tablespace_version, offset);
-       if (bpage == NULL) {
-+              /* bugfix: http://bugs.mysql.com/bug.php?id=43948 */
-+              if (recv_recovery_is_on() && *err == DB_TABLESPACE_DELETED) {
-+                      /* hashed log recs must be treated here */
-+                      recv_addr_t*    recv_addr;
-+
-+                      mutex_enter(&(recv_sys->mutex));
-+
-+                      if (recv_sys->apply_log_recs == FALSE) {
-+                              mutex_exit(&(recv_sys->mutex));
-+                              goto not_to_recover;
-+                      }
-+
-+                      /* recv_get_fil_addr_struct() */
-+                      recv_addr = HASH_GET_FIRST(recv_sys->addr_hash,
-+                                      hash_calc_hash(ut_fold_ulint_pair(space, offset),
-+                                              recv_sys->addr_hash));
-+                      while (recv_addr) {
-+                              if ((recv_addr->space == space)
-+                                      && (recv_addr->page_no == offset)) {
-+                                      break;
-+                              }
-+                              recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
-+                      }
-+
-+                      if ((recv_addr == NULL)
-+                          || (recv_addr->state == RECV_BEING_PROCESSED)
-+                          || (recv_addr->state == RECV_PROCESSED)) {
-+                              mutex_exit(&(recv_sys->mutex));
-+                              goto not_to_recover;
-+                      }
-+
-+                      fprintf(stderr, " (cannot find space: %lu)", space);
-+                      recv_addr->state = RECV_PROCESSED;
-+
-+                      ut_a(recv_sys->n_addrs);
-+                      recv_sys->n_addrs--;
-+
-+                      mutex_exit(&(recv_sys->mutex));
-+              }
-+not_to_recover:
-               return(0);
-       }
-@@ -782,6 +822,50 @@
-               /* It is a single table tablespace and the .ibd file is
-               missing: do nothing */
-+              /* the log records should be treated here same reason
-+              for http://bugs.mysql.com/bug.php?id=43948 */
-+
-+              if (recv_recovery_is_on()) {
-+                      recv_addr_t*    recv_addr;
-+
-+                      mutex_enter(&(recv_sys->mutex));
-+
-+                      if (recv_sys->apply_log_recs == FALSE) {
-+                              mutex_exit(&(recv_sys->mutex));
-+                              goto not_to_recover;
-+                      }
-+
-+                      for (i = 0; i < n_stored; i++) {
-+                              /* recv_get_fil_addr_struct() */
-+                              recv_addr = HASH_GET_FIRST(recv_sys->addr_hash,
-+                                              hash_calc_hash(ut_fold_ulint_pair(space, page_nos[i]),
-+                                                      recv_sys->addr_hash));
-+                              while (recv_addr) {
-+                                      if ((recv_addr->space == space)
-+                                              && (recv_addr->page_no == page_nos[i])) {
-+                                              break;
-+                                      }
-+                                      recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
-+                              }
-+
-+                              if ((recv_addr == NULL)
-+                                  || (recv_addr->state == RECV_BEING_PROCESSED)
-+                                  || (recv_addr->state == RECV_PROCESSED)) {
-+                                      continue;
-+                              }
-+
-+                              recv_addr->state = RECV_PROCESSED;
-+
-+                              ut_a(recv_sys->n_addrs);
-+                              recv_sys->n_addrs--;
-+                      }
-+
-+                      mutex_exit(&(recv_sys->mutex));
-+
-+                      fprintf(stderr, " (cannot find space: %lu)", space);
-+              }
-+not_to_recover:
-+
-               return;
-       }
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -185,6 +185,8 @@
- static my_bool        innobase_use_doublewrite                = TRUE;
- static my_bool        innobase_use_checksums                  = TRUE;
- static my_bool        innobase_extra_undoslots                = FALSE;
-+static my_bool        innobase_fast_recovery                  = FALSE;
-+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;
- static my_bool        innobase_rollback_on_timeout            = FALSE;
-@@ -2367,6 +2369,8 @@
-       srv_force_recovery = (ulint) innobase_force_recovery;
-+      srv_recovery_stats = (ibool) innobase_recovery_stats;
-+
-       srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
-       srv_use_checksums = (ibool) innobase_use_checksums;
-@@ -10987,6 +10991,16 @@
-   "don't use the datafile for normal mysqld or ibbackup! ####",
-   NULL, NULL, FALSE);
-+static MYSQL_SYSVAR_BOOL(fast_recovery, innobase_fast_recovery,
-+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-+  "obsolete option. affects nothing.",
-+  NULL, NULL, FALSE);
-+
-+static MYSQL_SYSVAR_BOOL(recovery_stats, innobase_recovery_stats,
-+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-+  "Output statistics of recovery process after it.",
-+  NULL, NULL, FALSE);
-+
- static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
-   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-   "During InnoDB crash recovery on slave overwrite relay-log.info "
-@@ -11412,6 +11426,8 @@
-   MYSQL_SYSVAR(data_home_dir),
-   MYSQL_SYSVAR(doublewrite),
-   MYSQL_SYSVAR(extra_undoslots),
-+  MYSQL_SYSVAR(fast_recovery),
-+  MYSQL_SYSVAR(recovery_stats),
-   MYSQL_SYSVAR(fast_shutdown),
-   MYSQL_SYSVAR(file_io_threads),
-   MYSQL_SYSVAR(read_io_threads),
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -35,5 +35,6 @@
- {"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/log0recv.h
-+++ b/storage/innodb_plugin/include/log0recv.h
-@@ -438,6 +438,39 @@
-       hash_table_t*   addr_hash;/*!< hash table of file addresses of pages */
-       ulint           n_addrs;/*!< number of not processed hashed file
-                               addresses in the hash table */
-+
-+/* If you modified the following defines at original file,
-+   You should also modify them. */
-+/* defined in os0file.c */
-+#define OS_AIO_MERGE_N_CONSECUTIVE    64
-+/* defined in log0recv.c */
-+#define RECV_READ_AHEAD_AREA  32
-+      time_t          stats_recv_start_time;
-+      ulint           stats_recv_turns;
-+
-+      ulint           stats_read_requested_pages;
-+      ulint           stats_read_in_area[RECV_READ_AHEAD_AREA];
-+
-+      ulint           stats_read_io_pages;
-+      ulint           stats_read_io_consecutive[OS_AIO_MERGE_N_CONSECUTIVE];
-+      ulint           stats_write_io_pages;
-+      ulint           stats_write_io_consecutive[OS_AIO_MERGE_N_CONSECUTIVE];
-+
-+      ulint           stats_doublewrite_check_pages;
-+      ulint           stats_doublewrite_overwrite_pages;
-+
-+      ulint           stats_recover_pages_with_read;
-+      ulint           stats_recover_pages_without_read;
-+
-+      ulint           stats_log_recs;
-+      ulint           stats_log_len_sum;
-+
-+      ulint           stats_applied_log_recs;
-+      ulint           stats_applied_log_len_sum;
-+      ulint           stats_pages_already_new;
-+
-+      ib_uint64_t     stats_oldest_modified_lsn;
-+      ib_uint64_t     stats_newest_modified_lsn;
- };
- /** The recovery system */
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -114,6 +114,8 @@
- extern ibool  srv_extra_undoslots;
-+extern ibool  srv_recovery_stats;
-+
- extern ibool  srv_auto_extend_last_data_file;
- extern ulint  srv_last_file_size_max;
- extern char** srv_log_group_home_dirs;
---- a/storage/innodb_plugin/log/log0recv.c
-+++ b/storage/innodb_plugin/log/log0recv.c
-@@ -179,6 +179,9 @@
-       recv_sys->heap = NULL;
-       recv_sys->addr_hash = NULL;
-+
-+      recv_sys->stats_recv_start_time = time(NULL);
-+      recv_sys->stats_oldest_modified_lsn = IB_ULONGLONG_MAX;
- }
- /********************************************************//**
-@@ -317,6 +320,11 @@
-               recv_n_pool_free_frames = 512;
-       }
-+      if (buf_pool_get_curr_size() >= (32 * 1024 * 1024)) {
-+              /* Buffer pool of size greater than 32 MB. */
-+              recv_n_pool_free_frames = 1024;
-+      }
-+
-       recv_sys->buf = ut_malloc(RECV_PARSING_BUF_SIZE);
-       recv_sys->len = 0;
-       recv_sys->recovered_offset = 0;
-@@ -1353,6 +1361,11 @@
-       len = rec_end - body;
-+      if (srv_recovery_stats) {
-+              recv_sys->stats_log_recs++;
-+              recv_sys->stats_log_len_sum += len;
-+      }
-+
-       recv = mem_heap_alloc(recv_sys->heap, sizeof(recv_t));
-       recv->type = type;
-       recv->len = rec_end - body;
-@@ -1464,6 +1477,7 @@
-       ib_uint64_t     start_lsn;
-       ib_uint64_t     end_lsn;
-       ib_uint64_t     page_lsn;
-+      ib_uint64_t     page_lsn_orig;
-       ib_uint64_t     page_newest_lsn;
-       ibool           modification_to_page;
- #ifndef UNIV_HOTBACKUP
-@@ -1486,6 +1500,8 @@
-                                            buf_block_get_page_no(block));
-       if ((recv_addr == NULL)
-+              /* bugfix: http://bugs.mysql.com/bug.php?id=44140 */
-+          || (recv_addr->state == RECV_BEING_READ && !just_read_in)
-           || (recv_addr->state == RECV_BEING_PROCESSED)
-           || (recv_addr->state == RECV_PROCESSED)) {
-@@ -1501,6 +1517,14 @@
-       recv_addr->state = RECV_BEING_PROCESSED;
-+      if (srv_recovery_stats) {
-+              if (just_read_in) {
-+                      recv_sys->stats_recover_pages_with_read++;
-+              } else {
-+                      recv_sys->stats_recover_pages_without_read++;
-+              }
-+      }
-+
-       mutex_exit(&(recv_sys->mutex));
-       mtr_start(&mtr);
-@@ -1530,6 +1554,7 @@
-       /* Read the newest modification lsn from the page */
-       page_lsn = mach_read_ull(page + FIL_PAGE_LSN);
-+      page_lsn_orig = page_lsn;
- #ifndef UNIV_HOTBACKUP
-       /* It may be that the page has been modified in the buffer
-@@ -1549,6 +1574,21 @@
-       modification_to_page = FALSE;
-       start_lsn = end_lsn = 0;
-+      if (srv_recovery_stats) {
-+              mutex_enter(&(recv_sys->mutex));
-+              if (page_lsn_orig && recv_sys->stats_oldest_modified_lsn > page_lsn_orig) {
-+                      recv_sys->stats_oldest_modified_lsn = page_lsn_orig;
-+              }
-+              if (page_lsn_orig && recv_sys->stats_newest_modified_lsn < page_lsn_orig) {
-+                      recv_sys->stats_newest_modified_lsn = page_lsn_orig;
-+              }
-+              if (UT_LIST_GET_LAST(recv_addr->rec_list)->start_lsn
-+                  < page_lsn_orig) {
-+                      recv_sys->stats_pages_already_new++;
-+              }
-+              mutex_exit(&(recv_sys->mutex));
-+      }
-+
-       recv = UT_LIST_GET_FIRST(recv_addr->rec_list);
-       while (recv) {
-@@ -1603,6 +1643,13 @@
-                                                        buf + recv->len,
-                                                        block, &mtr);
-+                      if (srv_recovery_stats) {
-+                              mutex_enter(&(recv_sys->mutex));
-+                              recv_sys->stats_applied_log_recs++;
-+                              recv_sys->stats_applied_log_len_sum += recv->len;
-+                              mutex_exit(&(recv_sys->mutex));
-+                      }
-+
-                       end_lsn = recv->start_lsn + recv->len;
-                       mach_write_ull(FIL_PAGE_LSN + page, end_lsn);
-                       mach_write_ull(UNIV_PAGE_SIZE
-@@ -1703,6 +1750,13 @@
-               }
-       }
-+      if (srv_recovery_stats && n) {
-+              mutex_enter(&(recv_sys->mutex));
-+              recv_sys->stats_read_requested_pages += n;
-+              recv_sys->stats_read_in_area[n - 1]++;
-+              mutex_exit(&(recv_sys->mutex));
-+      }
-+
-       buf_read_recv_pages(FALSE, space, zip_size, page_nos, n);
-       /*
-       fprintf(stderr, "Recv pages at %lu n %lu\n", page_nos[0], n);
-@@ -1856,6 +1910,10 @@
-       if (has_printed) {
-               fprintf(stderr, "InnoDB: Apply batch completed\n");
-+
-+              if (srv_recovery_stats) {
-+                      recv_sys->stats_recv_turns++;
-+              }
-       }
-       mutex_exit(&(recv_sys->mutex));
-@@ -3257,6 +3315,83 @@
-       }
- #endif /* UNIV_DEBUG */
-+      if (recv_needed_recovery && srv_recovery_stats) {
-+              ulint   i;
-+
-+              fprintf(stderr,
-+                      "InnoDB: Applying log records was done. Its statistics are followings.\n");
-+
-+              fprintf(stderr,
-+                      "============================================================\n"
-+                      "-------------------\n"
-+                      "RECOVERY STATISTICS\n"
-+                      "-------------------\n");
-+              fprintf(stderr,
-+                      "Recovery time: %g sec. (%lu turns)\n",
-+                      difftime(time(NULL), recv_sys->stats_recv_start_time),
-+                      recv_sys->stats_recv_turns);
-+
-+              fprintf(stderr,
-+                      "\n"
-+                      "Data page IO statistics\n"
-+                      "  Requested pages: %lu\n"
-+                      "  Read pages:      %lu\n"
-+                      "  Written pages:   %lu\n"
-+                      "  (Dirty blocks):  %lu\n",
-+                      recv_sys->stats_read_requested_pages,
-+                      recv_sys->stats_read_io_pages,
-+                      recv_sys->stats_write_io_pages,
-+                      UT_LIST_GET_LEN(buf_pool->flush_list));
-+
-+              fprintf(stderr,
-+                      "  Grouping IO [times]:\n"
-+                      "\tnumber of pages,\n"
-+                      "\t\tread request neighbors (in %d pages chunk),\n"
-+                      "\t\t\tcombined read IO,\n"
-+                      "\t\t\t\tcombined write IO\n",
-+                      RECV_READ_AHEAD_AREA);
-+              for (i = 0; i < ut_max(RECV_READ_AHEAD_AREA,
-+                                      OS_AIO_MERGE_N_CONSECUTIVE); i++) {
-+                      fprintf(stderr,
-+                              "\t%3lu,\t%lu,\t%lu,\t%lu\n", i + 1,
-+                              (i < RECV_READ_AHEAD_AREA) ?
-+                                      recv_sys->stats_read_in_area[i] : 0,
-+                              (i < OS_AIO_MERGE_N_CONSECUTIVE) ?
-+                                      recv_sys->stats_read_io_consecutive[i] : 0,
-+                              (i < OS_AIO_MERGE_N_CONSECUTIVE) ?
-+                                      recv_sys->stats_write_io_consecutive[i] : 0);
-+              }
-+
-+              fprintf(stderr,
-+                      "\n"
-+                      "Recovery process statistics\n"
-+                      "  Checked pages by doublewrite buffer: %lu\n"
-+                      "  Overwritten pages from doublewrite:  %lu\n"
-+                      "  Recovered pages by io_thread:        %lu\n"
-+                      "  Recovered pages by main thread:      %lu\n"
-+                      "  Parsed log records to apply:         %lu\n"
-+                      "            Sum of the length:         %lu\n"
-+                      "  Applied log records:                 %lu\n"
-+                      "            Sum of the length:         %lu\n"
-+                      "  Pages which are already new enough:  %lu (It may not be accurate, if turns > 1)\n"
-+                      "  Oldest page's LSN:                   %llu\n"
-+                      "  Newest page's LSN:                   %llu\n",
-+                      recv_sys->stats_doublewrite_check_pages,
-+                      recv_sys->stats_doublewrite_overwrite_pages,
-+                      recv_sys->stats_recover_pages_with_read,
-+                      recv_sys->stats_recover_pages_without_read,
-+                      recv_sys->stats_log_recs,
-+                      recv_sys->stats_log_len_sum,
-+                      recv_sys->stats_applied_log_recs,
-+                      recv_sys->stats_applied_log_len_sum,
-+                      recv_sys->stats_pages_already_new,
-+                      recv_sys->stats_oldest_modified_lsn,
-+                      recv_sys->stats_newest_modified_lsn);
-+
-+              fprintf(stderr,
-+                      "============================================================\n");
-+      }
-+
-       if (recv_needed_recovery) {
-               trx_sys_print_mysql_master_log_pos();
-               trx_sys_print_mysql_binlog_offset();
---- a/storage/innodb_plugin/os/os0file.c
-+++ b/storage/innodb_plugin/os/os0file.c
-@@ -38,6 +38,7 @@
- #include "srv0start.h"
- #include "fil0fil.h"
- #include "buf0buf.h"
-+#include "log0recv.h"
- #ifndef UNIV_HOTBACKUP
- # include "os0sync.h"
- # include "os0thread.h"
-@@ -4235,6 +4236,18 @@
-               }
-       }
-+      if (srv_recovery_stats && recv_recovery_is_on() && n_consecutive) {
-+              mutex_enter(&(recv_sys->mutex));
-+              if (slot->type == OS_FILE_READ) {
-+                      recv_sys->stats_read_io_pages += n_consecutive;
-+                      recv_sys->stats_read_io_consecutive[n_consecutive - 1]++;
-+              } else if (slot->type == OS_FILE_WRITE) {
-+                      recv_sys->stats_write_io_pages += n_consecutive;
-+                      recv_sys->stats_write_io_consecutive[n_consecutive - 1]++;
-+              }
-+              mutex_exit(&(recv_sys->mutex));
-+      }
-+
-       os_mutex_enter(array->mutex);
-       /* Mark the i/os done in slots */
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -144,6 +144,8 @@
- UNIV_INTERN ibool     srv_extra_undoslots = FALSE;
-+UNIV_INTERN ibool     srv_recovery_stats = FALSE;
-+
- /* if TRUE, then we auto-extend the last data file */
- UNIV_INTERN ibool     srv_auto_extend_last_data_file  = FALSE;
- /* if != 0, this tells the max size auto-extending may increase the
---- a/storage/innodb_plugin/trx/trx0sys.c
-+++ b/storage/innodb_plugin/trx/trx0sys.c
-@@ -40,6 +40,7 @@
- #include "srv0start.h"
- #include "trx0purge.h"
- #include "log0log.h"
-+#include "log0recv.h"
- #include "os0file.h"
- #include "read0read.h"
-@@ -559,6 +560,12 @@
-                              zip_size ? zip_size : UNIV_PAGE_SIZE,
-                              read_buf, NULL);
-+                      if (srv_recovery_stats && recv_recovery_is_on()) {
-+                              mutex_enter(&(recv_sys->mutex));
-+                              recv_sys->stats_doublewrite_check_pages++;
-+                              mutex_exit(&(recv_sys->mutex));
-+                      }
-+
-                       /* Check if the page is corrupt */
-                       if (UNIV_UNLIKELY
-@@ -606,6 +613,13 @@
-                                      zip_size, page_no, 0,
-                                      zip_size ? zip_size : UNIV_PAGE_SIZE,
-                                      page, NULL);
-+
-+                              if (srv_recovery_stats && recv_recovery_is_on()) {
-+                                      mutex_enter(&(recv_sys->mutex));
-+                                      recv_sys->stats_doublewrite_overwrite_pages++;
-+                                      mutex_exit(&(recv_sys->mutex));
-+                              }
-+
-                               fprintf(stderr,
-                                       "InnoDB: Recovered the page from"
-                                       " the doublewrite buffer.\n");
diff --git a/mysql-innodb_rw_lock.patch b/mysql-innodb_rw_lock.patch
deleted file mode 100644 (file)
index f4a33fb..0000000
+++ /dev/null
@@ -1,1309 +0,0 @@
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.h mysql-5.1.29-rc/storage/innobase/include/sync0rw.h
---- mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.h    2008-10-12 06:54:14.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/sync0rw.h 2008-11-17 15:34:00.000000000 +0900
-@@ -328,7 +328,17 @@
- Accessor functions for rw lock. */
- UNIV_INLINE
- ulint
--rw_lock_get_waiters(
-+rw_lock_get_s_waiters(
-+/*==================*/
-+      rw_lock_t*      lock);
-+UNIV_INLINE
-+ulint
-+rw_lock_get_x_waiters(
-+/*==================*/
-+      rw_lock_t*      lock);
-+UNIV_INLINE
-+ulint
-+rw_lock_get_wx_waiters(
- /*================*/
-       rw_lock_t*      lock);
- UNIV_INLINE
-@@ -412,6 +422,11 @@
-       rw_lock_debug_t*        info);  /* in: debug struct */
- #endif /* UNIV_SYNC_DEBUG */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+/* This value means NOT_LOCKED */
-+#define RW_LOCK_BIAS          0x00100000
-+#endif
-+
- /* NOTE! The structure appears here only for the compiler to know its size.
- Do not use its fields directly! The structure used in the spin lock
- implementation of a read-write lock. Several threads may have a shared lock
-@@ -421,9 +436,9 @@
- field. Then no new readers are allowed in. */
- struct rw_lock_struct {
--      os_event_t      event;  /* Used by sync0arr.c for thread queueing */
--
--#ifdef __WIN__
-+                      /* Used by sync0arr.c for thread queueing */
-+      os_event_t      s_event;        /* Used for s_lock */
-+      os_event_t      x_event;        /* Used for x_lock */
-       os_event_t      wait_ex_event;  /* This windows specific event is
-                               used by the thread which has set the
-                               lock state to RW_LOCK_WAIT_EX. The
-@@ -431,30 +446,34 @@
-                               thread will be the next one to proceed
-                               once the current the event gets
-                               signalled. See LEMMA 2 in sync0sync.c */
-+
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      volatile lint   lock_word;      /* Used by using atomic builtin */
- #endif
--      ulint   reader_count;   /* Number of readers who have locked this
-+      volatile ulint  reader_count;   /* Number of readers who have locked this
-                               lock in the shared mode */
--      ulint   writer;         /* This field is set to RW_LOCK_EX if there
-+      volatile ulint  writer;         /* This field is set to RW_LOCK_EX if there
-                               is a writer owning the lock (in exclusive
-                               mode), RW_LOCK_WAIT_EX if a writer is
-                               queueing for the lock, and
-                               RW_LOCK_NOT_LOCKED, otherwise. */
--      os_thread_id_t  writer_thread;
-+      volatile os_thread_id_t writer_thread;
-                               /* Thread id of a possible writer thread */
--      ulint   writer_count;   /* Number of times the same thread has
-+      volatile ulint  writer_count;   /* Number of times the same thread has
-                               recursively locked the lock in the exclusive
-                               mode */
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_t mutex;          /* The mutex protecting rw_lock_struct */
-+#endif
-       ulint   pass;           /* Default value 0. This is set to some
-                               value != 0 given by the caller of an x-lock
-                               operation, if the x-lock is to be passed to
-                               another thread to unlock (which happens in
-                               asynchronous i/o). */
--      ulint   waiters;        /* This ulint is set to 1 if there are
--                              waiters (readers or writers) in the global
--                              wait array, waiting for this rw_lock.
--                              Otherwise, == 0. */
-+      volatile ulint  s_waiters;      /* 1: there are waiters (s_lock) */
-+      volatile ulint  x_waiters;      /* 1: there are waiters (x_lock) */
-+      volatile ulint  wait_ex_waiters;        /* 1: there are waiters (wait_ex) */
-       UT_LIST_NODE_T(rw_lock_t) list;
-                               /* All allocated rw locks are put into a
-                               list */
-@@ -467,7 +486,7 @@
-       const char*     cfile_name;/* File name where lock created */
-       const char*     last_s_file_name;/* File name where last s-locked */
-       const char*     last_x_file_name;/* File name where last x-locked */
--      ibool           writer_is_wait_ex;
-+      volatile ibool          writer_is_wait_ex;
-                               /* This is TRUE if the writer field is
-                               RW_LOCK_WAIT_EX; this field is located far
-                               from the memory update hotspot fields which
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.ic mysql-5.1.29-rc/storage/innobase/include/sync0rw.ic
---- mysql-5.1.29-rc_orig/storage/innobase/include/sync0rw.ic   2008-10-12 06:54:14.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/sync0rw.ic        2008-11-17 16:07:32.000000000 +0900
-@@ -47,20 +47,52 @@
- Accessor functions for rw lock. */
- UNIV_INLINE
- ulint
--rw_lock_get_waiters(
-+rw_lock_get_s_waiters(
- /*================*/
-       rw_lock_t*      lock)
- {
--      return(lock->waiters);
-+      return(lock->s_waiters);
- }
- UNIV_INLINE
--void
--rw_lock_set_waiters(
-+ulint
-+rw_lock_get_x_waiters(
-+/*================*/
-+      rw_lock_t*      lock)
-+{
-+      return(lock->x_waiters);
-+}
-+UNIV_INLINE
-+ulint
-+rw_lock_get_wx_waiters(
- /*================*/
-+      rw_lock_t*      lock)
-+{
-+      return(lock->wait_ex_waiters);
-+}
-+UNIV_INLINE
-+void
-+rw_lock_set_s_waiters(
-+      rw_lock_t*      lock,
-+      ulint           flag)
-+{
-+      lock->s_waiters = flag;
-+}
-+UNIV_INLINE
-+void
-+rw_lock_set_x_waiters(
-       rw_lock_t*      lock,
-       ulint           flag)
- {
--      lock->waiters = flag;
-+      lock->x_waiters = flag;
-+}
-+UNIV_INLINE
-+void
-+rw_lock_set_wx_waiters(
-+/*================*/
-+      rw_lock_t*      lock,
-+      ulint           flag)
-+{
-+      lock->wait_ex_waiters = flag;
- }
- UNIV_INLINE
- ulint
-@@ -68,7 +100,19 @@
- /*===============*/
-       rw_lock_t*      lock)
- {
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (lock->writer == RW_LOCK_NOT_LOCKED) {
-+              return(RW_LOCK_NOT_LOCKED);
-+      }
-+
-+      if (lock->writer_is_wait_ex) {
-+              return(RW_LOCK_WAIT_EX);
-+      } else {
-+              return(RW_LOCK_EX);
-+      }
-+#else
-       return(lock->writer);
-+#endif
- }
- UNIV_INLINE
- void
-@@ -96,6 +140,7 @@
- {
-       lock->reader_count = count;
- }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
- UNIV_INLINE
- mutex_t*
- rw_lock_get_mutex(
-@@ -104,6 +149,7 @@
- {
-       return(&(lock->mutex));
- }
-+#endif
- /**********************************************************************
- Returns the value of writer_count for the lock. Does not reserve the lock
-@@ -133,13 +179,27 @@
-       const char*     file_name, /* in: file name where lock requested */
-       ulint           line)   /* in: line where requested */
- {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       ut_ad(mutex_own(rw_lock_get_mutex(lock)));
-+#endif
-       /* Check if the writer field is free */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (UNIV_LIKELY(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED)) {
-+              /* try s-lock */
-+              if(__sync_sub_and_fetch(&(lock->lock_word),1) <= 0) {
-+                      /* fail */
-+                      __sync_fetch_and_add(&(lock->lock_word),1);
-+                      return(FALSE);  /* locking did not succeed */
-+              }
-+              /* success */
-+              __sync_fetch_and_add(&(lock->reader_count),1);
-+#else
-       if (UNIV_LIKELY(lock->writer == RW_LOCK_NOT_LOCKED)) {
-               /* Set the shared lock by incrementing the reader count */
-               lock->reader_count++;
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-               rw_lock_add_debug_info(lock, pass, RW_LOCK_SHARED, file_name,
-@@ -166,11 +226,15 @@
-       const char*     file_name,      /* in: file name where requested */
-       ulint           line)           /* in: line where lock requested */
- {
--      ut_ad(lock->writer == RW_LOCK_NOT_LOCKED);
-+      ut_ad(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
-       ut_ad(rw_lock_get_reader_count(lock) == 0);
-       /* Set the shared lock by incrementing the reader count */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      __sync_fetch_and_add(&(lock->reader_count),1);
-+#else
-       lock->reader_count++;
-+#endif
-       lock->last_s_file_name = file_name;
-       lock->last_s_line = line;
-@@ -198,7 +262,11 @@
-       rw_lock_set_writer(lock, RW_LOCK_EX);
-       lock->writer_thread = os_thread_get_curr_id();
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      __sync_fetch_and_add(&(lock->writer_count),1);
-+#else
-       lock->writer_count++;
-+#endif
-       lock->pass = 0;
-       lock->last_x_file_name = file_name;
-@@ -240,15 +308,21 @@
-       ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */
- #endif /* UNIV_SYNC_DEBUG */
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-       if (UNIV_LIKELY(rw_lock_s_lock_low(lock, pass, file_name, line))) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               return; /* Success */
-       } else {
-               /* Did not succeed, try spin wait */
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               rw_lock_s_lock_spin(lock, pass, file_name, line);
-@@ -271,11 +345,23 @@
- {
-       ibool   success = FALSE;
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
-+              /* try s-lock */
-+              if(__sync_sub_and_fetch(&(lock->lock_word),1) <= 0) {
-+                      /* fail */
-+                      __sync_fetch_and_add(&(lock->lock_word),1);
-+                      return(FALSE);  /* locking did not succeed */
-+              }
-+              /* success */
-+              __sync_fetch_and_add(&(lock->reader_count),1);
-+#else
-       mutex_enter(rw_lock_get_mutex(lock));
-       if (lock->writer == RW_LOCK_NOT_LOCKED) {
-               /* Set the shared lock by incrementing the reader count */
-               lock->reader_count++;
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-               rw_lock_add_debug_info(lock, 0, RW_LOCK_SHARED, file_name,
-@@ -288,7 +374,9 @@
-               success = TRUE;
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-       return(success);
- }
-@@ -308,6 +396,55 @@
- {
-       ibool           success         = FALSE;
-       os_thread_id_t  curr_thread     = os_thread_get_curr_id();
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if ((lock->lock_word == RW_LOCK_BIAS)
-+                      && rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
-+              /* try x-lock */
-+              if(__sync_sub_and_fetch(&(lock->lock_word),
-+                              RW_LOCK_BIAS) == 0) {
-+                      /* success */
-+                      /* try to lock writer */
-+                      if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
-+                                      == RW_LOCK_NOT_LOCKED) {
-+                              /* success */
-+                              lock->writer_thread = curr_thread;
-+                              lock->pass = 0;
-+                              lock->writer_is_wait_ex = FALSE;
-+                              /* next function may work as memory barrier */
-+                      relock:
-+                              __sync_fetch_and_add(&(lock->writer_count),1);
-+
-+#ifdef UNIV_SYNC_DEBUG
-+                              rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line);
-+#endif
-+
-+                              lock->last_x_file_name = file_name;
-+                              lock->last_x_line = line;
-+
-+                              ut_ad(rw_lock_validate(lock));
-+
-+                              return(TRUE);
-+                      } else {
-+                              /* x-unlock */
-+                              __sync_fetch_and_add(&(lock->lock_word),
-+                                      RW_LOCK_BIAS);
-+                      }
-+              } else {
-+                      /* fail (x-lock) */
-+                      __sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS);
-+              }
-+      }
-+
-+      if (lock->pass == 0
-+                      && os_thread_eq(lock->writer_thread, curr_thread)
-+                      && rw_lock_get_writer(lock) == RW_LOCK_EX) {
-+              goto relock;
-+      }
-+
-+      ut_ad(rw_lock_validate(lock));
-+
-+      return(FALSE);
-+#else
-       mutex_enter(rw_lock_get_mutex(lock));
-       if (UNIV_UNLIKELY(rw_lock_get_reader_count(lock) != 0)) {
-@@ -338,6 +475,7 @@
-       ut_ad(rw_lock_validate(lock));
-       return(success);
-+#endif
- }
- /**********************************************************************
-@@ -353,16 +491,33 @@
- #endif
-       )
- {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_t*        mutex   = &(lock->mutex);
--      ibool           sg      = FALSE;
-+#endif
-+      ibool           x_sg    = FALSE;
-+      ibool           wx_sg   = FALSE;
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      ibool           last    = FALSE;
-+#endif
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       /* Acquire the mutex protecting the rw-lock fields */
-       mutex_enter(mutex);
-+#endif
-       /* Reset the shared lock by decrementing the reader count */
-       ut_a(lock->reader_count > 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      /* unlock lock_word */
-+      __sync_fetch_and_add(&(lock->lock_word),1);
-+
-+      if(__sync_sub_and_fetch(&(lock->reader_count),1) == 0) {
-+              last = TRUE;
-+      }
-+#else
-       lock->reader_count--;
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-       rw_lock_remove_debug_info(lock, pass, RW_LOCK_SHARED);
-@@ -371,20 +526,36 @@
-       /* If there may be waiters and this was the last s-lock,
-       signal the object */
--      if (UNIV_UNLIKELY(lock->waiters)
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (UNIV_UNLIKELY(last && lock->wait_ex_waiters)) {
-+#else
-+      if (UNIV_UNLIKELY(lock->wait_ex_waiters)
-           && lock->reader_count == 0) {
--              sg = TRUE;
-+#endif
-+              wx_sg = TRUE;
--              rw_lock_set_waiters(lock, 0);
-+              rw_lock_set_wx_waiters(lock, 0);
-       }
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      else if (UNIV_UNLIKELY(last && lock->x_waiters)) {
-+#else
-+      else if (UNIV_UNLIKELY(lock->x_waiters)
-+               && lock->reader_count == 0) {
-+#endif
-+              x_sg = TRUE;
-+              rw_lock_set_x_waiters(lock, 0);
-+      }
-+
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(mutex);
-+#endif
--      if (UNIV_UNLIKELY(sg)) {
--#ifdef __WIN__
-+      if (UNIV_UNLIKELY(wx_sg)) {
-               os_event_set(lock->wait_ex_event);
--#endif
--              os_event_set(lock->event);
-+              sync_array_object_signalled(sync_primary_wait_array);
-+      } else if (UNIV_UNLIKELY(x_sg)) {
-+              os_event_set(lock->x_event);
-               sync_array_object_signalled(sync_primary_wait_array);
-       }
-@@ -408,13 +579,19 @@
-       ut_ad(lock->reader_count > 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      __sync_sub_and_fetch(&(lock->reader_count),1);
-+#else
-       lock->reader_count--;
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-       rw_lock_remove_debug_info(lock, 0, RW_LOCK_SHARED);
- #endif
--      ut_ad(!lock->waiters);
-+      ut_ad(!lock->s_waiters);
-+      ut_ad(!lock->x_waiters);
-+      ut_ad(!lock->wait_ex_waiters);
-       ut_ad(rw_lock_validate(lock));
- #ifdef UNIV_SYNC_PERF_STAT
-       rw_s_exit_count++;
-@@ -434,41 +611,81 @@
- #endif
-       )
- {
--      ibool   sg      = FALSE;
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      ibool   last    = FALSE;
-+#endif
-+      ibool   s_sg    = FALSE;
-+      ibool   x_sg    = FALSE;
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       /* Acquire the mutex protecting the rw-lock fields */
-       mutex_enter(&(lock->mutex));
-+#endif
-       /* Reset the exclusive lock if this thread no longer has an x-mode
-       lock */
-       ut_ad(lock->writer_count > 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if(__sync_sub_and_fetch(&(lock->writer_count),1) == 0) {
-+              last = TRUE;
-+      }
-+
-+      if (last) {
-+              /* unlock lock_word */
-+              __sync_fetch_and_add(&(lock->lock_word),RW_LOCK_BIAS);
-+
-+              /* FIXME: It is a value of bad manners for pthread.
-+                        But we shouldn't keep an ID of not-owner. */
-+              lock->writer_thread = -1;
-+
-+              /* atomic operation may be safer about memory order. */
-+              rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
-+              __sync_synchronize();
-+      }
-+#else
-       lock->writer_count--;
-       if (lock->writer_count == 0) {
-               rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
-       }
-+#endif
- #ifdef UNIV_SYNC_DEBUG
-       rw_lock_remove_debug_info(lock, pass, RW_LOCK_EX);
- #endif
-       /* If there may be waiters, signal the lock */
--      if (UNIV_UNLIKELY(lock->waiters)
--          && lock->writer_count == 0) {
--
--              sg = TRUE;
--              rw_lock_set_waiters(lock, 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (last) {
-+#else
-+      if (lock->writer_count == 0) {
-+#endif
-+              if(lock->s_waiters){
-+                      s_sg = TRUE;
-+                      rw_lock_set_s_waiters(lock, 0);
-+              }
-+              if(lock->x_waiters){
-+                      x_sg = TRUE;
-+                      rw_lock_set_x_waiters(lock, 0);
-+              }
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(&(lock->mutex));
-+#endif
--      if (UNIV_UNLIKELY(sg)) {
-+      if (UNIV_UNLIKELY(s_sg)) {
-+              os_event_set(lock->s_event);
-+              sync_array_object_signalled(sync_primary_wait_array);
-+      }
-+      if (UNIV_UNLIKELY(x_sg)) {
- #ifdef __WIN__
-+              /* I doubt the necessity of it. */
-               os_event_set(lock->wait_ex_event);
- #endif
--              os_event_set(lock->event);
-+              os_event_set(lock->x_event);
-               sync_array_object_signalled(sync_primary_wait_array);
-       }
-@@ -493,9 +710,13 @@
-       ut_ad(lock->writer_count > 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if(__sync_sub_and_fetch(&(lock->writer_count),1) == 0) {
-+#else
-       lock->writer_count--;
-       if (lock->writer_count == 0) {
-+#endif
-               rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
-       }
-@@ -503,7 +724,9 @@
-       rw_lock_remove_debug_info(lock, 0, RW_LOCK_EX);
- #endif
--      ut_ad(!lock->waiters);
-+      ut_ad(!lock->s_waiters);
-+      ut_ad(!lock->x_waiters);
-+      ut_ad(!lock->wait_ex_waiters);
-       ut_ad(rw_lock_validate(lock));
- #ifdef UNIV_SYNC_PERF_STAT
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/sync/sync0arr.c mysql-5.1.29-rc/storage/innobase/sync/sync0arr.c
---- mysql-5.1.29-rc_orig/storage/innobase/sync/sync0arr.c      2008-10-12 06:54:15.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/sync/sync0arr.c   2008-11-17 16:17:39.000000000 +0900
-@@ -307,13 +307,13 @@
- {
-       if (type == SYNC_MUTEX) {
-               return(os_event_reset(((mutex_t *) object)->event));
--#ifdef __WIN__
-       } else if (type == RW_LOCK_WAIT_EX) {
-               return(os_event_reset(
-                      ((rw_lock_t *) object)->wait_ex_event));
--#endif
--      } else {
--              return(os_event_reset(((rw_lock_t *) object)->event));
-+      } else if (type == RW_LOCK_SHARED) {
-+              return(os_event_reset(((rw_lock_t *) object)->s_event));
-+      } else { /* RW_LOCK_EX */
-+              return(os_event_reset(((rw_lock_t *) object)->x_event));
-       }
- }
-@@ -413,15 +413,12 @@
-       if (cell->request_type == SYNC_MUTEX) {
-               event = ((mutex_t*) cell->wait_object)->event;
--#ifdef __WIN__
--      /* On windows if the thread about to wait is the one which
--      has set the state of the rw_lock to RW_LOCK_WAIT_EX, then
--      it waits on a special event i.e.: wait_ex_event. */
-       } else if (cell->request_type == RW_LOCK_WAIT_EX) {
-               event = ((rw_lock_t*) cell->wait_object)->wait_ex_event;
--#endif
-+      } else if (cell->request_type == RW_LOCK_SHARED) {
-+              event = ((rw_lock_t*) cell->wait_object)->s_event;
-       } else {
--              event = ((rw_lock_t*) cell->wait_object)->event;
-+              event = ((rw_lock_t*) cell->wait_object)->x_event;
-       }
-               cell->waiting = TRUE;
-@@ -462,6 +459,7 @@
-       mutex_t*        mutex;
-       rw_lock_t*      rwlock;
-       ulint           type;
-+      ulint           writer;
-       type = cell->request_type;
-@@ -491,12 +489,10 @@
-                       (ulong) mutex->waiters);
-       } else if (type == RW_LOCK_EX
--#ifdef __WIN__
-                  || type == RW_LOCK_WAIT_EX
--#endif
-                  || type == RW_LOCK_SHARED) {
--              fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
-+              fputs(type == RW_LOCK_SHARED ? "S-lock on" : "X-lock on", file);
-               rwlock = cell->old_wait_rw_lock;
-@@ -504,22 +500,24 @@
-                       " RW-latch at %p created in file %s line %lu\n",
-                       (void*) rwlock, rwlock->cfile_name,
-                       (ulong) rwlock->cline);
--              if (rwlock->writer != RW_LOCK_NOT_LOCKED) {
-+              writer = rw_lock_get_writer(rwlock);
-+              if (writer != RW_LOCK_NOT_LOCKED) {
-                       fprintf(file,
-                               "a writer (thread id %lu) has"
-                               " reserved it in mode %s",
-                               (ulong) os_thread_pf(rwlock->writer_thread),
--                              rwlock->writer == RW_LOCK_EX
-+                              writer == RW_LOCK_EX
-                               ? " exclusive\n"
-                               : " wait exclusive\n");
-               }
-               fprintf(file,
--                      "number of readers %lu, waiters flag %lu\n"
-+                      "number of readers %lu, s_waiters flag %lu, x_waiters flag %lu\n"
-                       "Last time read locked in file %s line %lu\n"
-                       "Last time write locked in file %s line %lu\n",
-                       (ulong) rwlock->reader_count,
--                      (ulong) rwlock->waiters,
-+                      (ulong) rwlock->s_waiters,
-+                      (ulong) (rwlock->x_waiters || rwlock->wait_ex_waiters),
-                       rwlock->last_s_file_name,
-                       (ulong) rwlock->last_s_line,
-                       rwlock->last_x_file_name,
-@@ -844,11 +842,15 @@
- /*========================*/
-       sync_array_t*   arr)    /* in: wait array */
- {
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      __sync_fetch_and_add(&(arr->sg_count),1);
-+#else
-       sync_array_enter(arr);
-       arr->sg_count++;
-       sync_array_exit(arr);
-+#endif
- }
- /**************************************************************************
-@@ -889,19 +891,23 @@
-                                       mutex = cell->wait_object;
-                                       os_event_set(mutex->event);
--#ifdef __WIN__
-                               } else if (cell->request_type
-                                          == RW_LOCK_WAIT_EX) {
-                                       rw_lock_t*      lock;
-                                       lock = cell->wait_object;
-                                       os_event_set(lock->wait_ex_event);
--#endif
--                              } else {
-+                              } else if (cell->request_type
-+                                         == RW_LOCK_SHARED) {
-                                       rw_lock_t*      lock;
-                                       lock = cell->wait_object;
--                                      os_event_set(lock->event);
-+                                      os_event_set(lock->s_event);
-+                              } else {
-+                                      rw_lock_t*      lock;
-+
-+                                      lock = cell->wait_object;
-+                                      os_event_set(lock->x_event);
-                               }
-                       }
-               }
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/sync/sync0rw.c mysql-5.1.29-rc/storage/innobase/sync/sync0rw.c
---- mysql-5.1.29-rc_orig/storage/innobase/sync/sync0rw.c       2008-10-12 06:54:15.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/sync/sync0rw.c    2008-11-17 17:43:45.000000000 +0900
-@@ -119,6 +119,7 @@
-       /* If this is the very first time a synchronization object is
-       created, then the following call initializes the sync system. */
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
-       lock->mutex.cfile_name = cfile_name;
-@@ -128,8 +129,14 @@
-       lock->mutex.cmutex_name = cmutex_name;
-       lock->mutex.mutex_type = 1;
- #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-+#endif /* !HAVE_GCC_ATOMIC_BUILTINS */
--      rw_lock_set_waiters(lock, 0);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      lock->lock_word = RW_LOCK_BIAS;
-+#endif
-+      rw_lock_set_s_waiters(lock, 0);
-+      rw_lock_set_x_waiters(lock, 0);
-+      rw_lock_set_wx_waiters(lock, 0);
-       rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
-       lock->writer_count = 0;
-       rw_lock_set_reader_count(lock, 0);
-@@ -151,11 +158,9 @@
-       lock->last_x_file_name = "not yet reserved";
-       lock->last_s_line = 0;
-       lock->last_x_line = 0;
--      lock->event = os_event_create(NULL);
--
--#ifdef __WIN__
-+      lock->s_event = os_event_create(NULL);
-+      lock->x_event = os_event_create(NULL);
-       lock->wait_ex_event = os_event_create(NULL);
--#endif
-       mutex_enter(&rw_lock_list_mutex);
-@@ -181,19 +186,21 @@
- {
-       ut_ad(rw_lock_validate(lock));
-       ut_a(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
--      ut_a(rw_lock_get_waiters(lock) == 0);
-+      ut_a(rw_lock_get_s_waiters(lock) == 0);
-+      ut_a(rw_lock_get_x_waiters(lock) == 0);
-+      ut_a(rw_lock_get_wx_waiters(lock) == 0);
-       ut_a(rw_lock_get_reader_count(lock) == 0);
-       lock->magic_n = 0;
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_free(rw_lock_get_mutex(lock));
-+#endif
-       mutex_enter(&rw_lock_list_mutex);
--      os_event_free(lock->event);
--
--#ifdef __WIN__
-+      os_event_free(lock->s_event);
-+      os_event_free(lock->x_event);
-       os_event_free(lock->wait_ex_event);
--#endif
-       if (UT_LIST_GET_PREV(list, lock)) {
-               ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
-@@ -212,6 +219,8 @@
- Checks that the rw-lock has been initialized and that there are no
- simultaneous shared and exclusive locks. */
-+/* MEMO: If HAVE_GCC_ATOMIC_BUILTINS, we should use this function statically. */
-+
- ibool
- rw_lock_validate(
- /*=============*/
-@@ -219,7 +228,9 @@
- {
-       ut_a(lock);
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-       ut_a(lock->magic_n == RW_LOCK_MAGIC_N);
-       ut_a((rw_lock_get_reader_count(lock) == 0)
-@@ -227,11 +238,17 @@
-       ut_a((rw_lock_get_writer(lock) == RW_LOCK_EX)
-            || (rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX)
-            || (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED));
--      ut_a((rw_lock_get_waiters(lock) == 0)
--           || (rw_lock_get_waiters(lock) == 1));
-+      ut_a((rw_lock_get_s_waiters(lock) == 0)
-+           || (rw_lock_get_s_waiters(lock) == 1));
-+      ut_a((rw_lock_get_x_waiters(lock) == 0)
-+           || (rw_lock_get_x_waiters(lock) == 1));
-+      ut_a((rw_lock_get_wx_waiters(lock) == 0)
-+           || (rw_lock_get_wx_waiters(lock) == 1));
-       ut_a((lock->writer != RW_LOCK_EX) || (lock->writer_count > 0));
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-       return(TRUE);
- }
-@@ -258,13 +275,14 @@
-       ut_ad(rw_lock_validate(lock));
- lock_loop:
-+      i = 0;
-+spin_loop:
-       rw_s_spin_wait_count++;
-       /* Spin waiting for the writer field to become free */
--      i = 0;
--      while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
--             && i < SYNC_SPIN_ROUNDS) {
-+      while (i < SYNC_SPIN_ROUNDS
-+             && rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) {
-               if (srv_spin_wait_delay) {
-                       ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
-               }
-@@ -285,15 +303,27 @@
-                       lock->cfile_name, (ulong) lock->cline, (ulong) i);
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-       /* We try once again to obtain the lock */
-       if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               return; /* Success */
-       } else {
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+              /* like sync0sync.c doing */
-+              i++;
-+
-+              if (i < SYNC_SPIN_ROUNDS) {
-+                      goto spin_loop;
-+              }
-+#endif
-               /* If we get here, locking did not succeed, we may
-               suspend the thread to wait in the wait array */
-@@ -304,9 +334,19 @@
-                                       file_name, line,
-                                       &index);
--              rw_lock_set_waiters(lock, 1);
-+              rw_lock_set_s_waiters(lock, 1);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+              /* like sync0sync.c doing */
-+              for (i = 0; i < 4; i++) {
-+                      if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
-+                              sync_array_free_cell(sync_primary_wait_array, index);
-+                              return; /* Success */
-+                      }
-+              }
-+#else
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               if (srv_print_latch_waits) {
-                       fprintf(stderr,
-@@ -343,13 +383,19 @@
- {
-       ut_ad(rw_lock_is_locked(lock, RW_LOCK_EX));
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(&(lock->mutex));
-+#endif
-       lock->writer_thread = os_thread_get_curr_id();
-       lock->pass = 0;
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(&(lock->mutex));
-+#else
-+      __sync_synchronize();
-+#endif
- }
- /**********************************************************************
-@@ -367,6 +413,89 @@
-       const char*     file_name,/* in: file name where lock requested */
-       ulint           line)   /* in: line where requested */
- {
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      os_thread_id_t  curr_thread     = os_thread_get_curr_id();
-+
-+      /* try to lock writer */
-+      if(__sync_lock_test_and_set(&(lock->writer),RW_LOCK_EX)
-+                      == RW_LOCK_NOT_LOCKED) {
-+              /* success */
-+              /* obtain RW_LOCK_WAIT_EX right */
-+              lock->writer_thread = curr_thread;
-+              lock->pass = pass;
-+              lock->writer_is_wait_ex = TRUE;
-+              /* atomic operation may be safer about memory order. */
-+              __sync_synchronize();
-+#ifdef UNIV_SYNC_DEBUG
-+              rw_lock_add_debug_info(lock, pass, RW_LOCK_WAIT_EX,
-+                                      file_name, line);
-+#endif
-+      }
-+
-+      if (!os_thread_eq(lock->writer_thread, curr_thread)) {
-+              return(RW_LOCK_NOT_LOCKED);
-+      }
-+
-+      switch(rw_lock_get_writer(lock)) {
-+          case RW_LOCK_WAIT_EX:
-+              /* have right to try x-lock */
-+              if (lock->lock_word == RW_LOCK_BIAS) {
-+                      /* try x-lock */
-+                      if(__sync_sub_and_fetch(&(lock->lock_word),
-+                                      RW_LOCK_BIAS) == 0) {
-+                              /* success */
-+                              lock->pass = pass;
-+                              lock->writer_is_wait_ex = FALSE;
-+                              __sync_fetch_and_add(&(lock->writer_count),1);
-+
-+#ifdef UNIV_SYNC_DEBUG
-+                              rw_lock_remove_debug_info(lock, pass, RW_LOCK_WAIT_EX);
-+                              rw_lock_add_debug_info(lock, pass, RW_LOCK_EX,
-+                                                      file_name, line);
-+#endif
-+
-+                              lock->last_x_file_name = file_name;
-+                              lock->last_x_line = line;
-+
-+                              /* Locking succeeded, we may return */
-+                              return(RW_LOCK_EX);
-+                      } else {
-+                              /* fail */
-+                              __sync_fetch_and_add(&(lock->lock_word),
-+                                      RW_LOCK_BIAS);
-+                      }
-+              }
-+              /* There are readers, we have to wait */
-+              return(RW_LOCK_WAIT_EX);
-+
-+              break;
-+
-+          case RW_LOCK_EX:
-+              /* already have x-lock */
-+              if ((lock->pass == 0)&&(pass == 0)) {
-+                      __sync_fetch_and_add(&(lock->writer_count),1);
-+
-+#ifdef UNIV_SYNC_DEBUG
-+                      rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name,
-+                                              line);
-+#endif
-+
-+                      lock->last_x_file_name = file_name;
-+                      lock->last_x_line = line;
-+
-+                      /* Locking succeeded, we may return */
-+                      return(RW_LOCK_EX);
-+              }
-+
-+              return(RW_LOCK_NOT_LOCKED);
-+
-+              break;
-+
-+          default: /* ??? */
-+              return(RW_LOCK_NOT_LOCKED);
-+      }
-+#else /* HAVE_GCC_ATOMIC_BUILTINS */
-+
-       ut_ad(mutex_own(rw_lock_get_mutex(lock)));
-       if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
-@@ -447,6 +576,7 @@
-               /* Locking succeeded, we may return */
-               return(RW_LOCK_EX);
-       }
-+#endif /* HAVE_GCC_ATOMIC_BUILTINS */
-       /* Locking did not succeed */
-       return(RW_LOCK_NOT_LOCKED);
-@@ -472,19 +602,33 @@
-       ulint           line)   /* in: line where requested */
- {
-       ulint   index;  /* index of the reserved wait cell */
--      ulint   state;  /* lock state acquired */
-+      ulint   state = RW_LOCK_NOT_LOCKED;     /* lock state acquired */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      ulint   prev_state = RW_LOCK_NOT_LOCKED;
-+#endif
-       ulint   i;      /* spin round count */
-       ut_ad(rw_lock_validate(lock));
- lock_loop:
-+      i = 0;
-+
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      prev_state = state;
-+#else
-       /* Acquire the mutex protecting the rw-lock fields */
-       mutex_enter_fast(&(lock->mutex));
-+#endif
-       state = rw_lock_x_lock_low(lock, pass, file_name, line);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (state != prev_state) i=0; /* if progress, reset counter. */
-+#else
-       mutex_exit(&(lock->mutex));
-+#endif
-+spin_loop:
-       if (state == RW_LOCK_EX) {
-               return; /* Locking succeeded */
-@@ -492,10 +636,9 @@
-       } else if (state == RW_LOCK_NOT_LOCKED) {
-               /* Spin waiting for the writer field to become free */
--              i = 0;
--              while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
--                     && i < SYNC_SPIN_ROUNDS) {
-+              while (i < SYNC_SPIN_ROUNDS
-+                     && rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) {
-                       if (srv_spin_wait_delay) {
-                               ut_delay(ut_rnd_interval(0,
-                                                        srv_spin_wait_delay));
-@@ -509,9 +652,12 @@
-       } else if (state == RW_LOCK_WAIT_EX) {
-               /* Spin waiting for the reader count field to become zero */
--              i = 0;
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+              while (lock->lock_word != RW_LOCK_BIAS
-+#else
-               while (rw_lock_get_reader_count(lock) != 0
-+#endif
-                      && i < SYNC_SPIN_ROUNDS) {
-                       if (srv_spin_wait_delay) {
-                               ut_delay(ut_rnd_interval(0,
-@@ -524,7 +670,6 @@
-                       os_thread_yield();
-               }
-       } else {
--              i = 0; /* Eliminate a compiler warning */
-               ut_error;
-       }
-@@ -541,34 +686,69 @@
-       /* We try once again to obtain the lock. Acquire the mutex protecting
-       the rw-lock fields */
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      prev_state = state;
-+#else
-       mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-       state = rw_lock_x_lock_low(lock, pass, file_name, line);
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      if (state != prev_state) i=0; /* if progress, reset counter. */
-+#endif
-+
-       if (state == RW_LOCK_EX) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               return; /* Locking succeeded */
-       }
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      /* like sync0sync.c doing */
-+      i++;
-+
-+      if (i < SYNC_SPIN_ROUNDS) {
-+              goto spin_loop;
-+      }
-+#endif
-+
-       rw_x_system_call_count++;
-       sync_array_reserve_cell(sync_primary_wait_array,
-                               lock,
--#ifdef __WIN__
--                              /* On windows RW_LOCK_WAIT_EX signifies
--                              that this thread should wait on the
--                              special wait_ex_event. */
-                               (state == RW_LOCK_WAIT_EX)
-                                ? RW_LOCK_WAIT_EX :
--#endif
-                               RW_LOCK_EX,
-                               file_name, line,
-                               &index);
--      rw_lock_set_waiters(lock, 1);
-+      if (state == RW_LOCK_WAIT_EX) {
-+              rw_lock_set_wx_waiters(lock, 1);
-+      } else {
-+              rw_lock_set_x_waiters(lock, 1);
-+      }
-+#ifdef HAVE_GCC_ATOMIC_BUILTINS
-+      /* like sync0sync.c doing */
-+      for (i = 0; i < 4; i++) {
-+              prev_state = state;
-+              state = rw_lock_x_lock_low(lock, pass, file_name, line);
-+              if (state == RW_LOCK_EX) {
-+                      sync_array_free_cell(sync_primary_wait_array, index);
-+                      return; /* Locking succeeded */
-+              }
-+              if (state != prev_state) {
-+                      /* retry! */
-+                      sync_array_free_cell(sync_primary_wait_array, index);
-+                      goto lock_loop;
-+              }
-+      }
-+#else
-       mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-       if (srv_print_latch_waits) {
-               fprintf(stderr,
-@@ -730,7 +910,9 @@
-       ut_ad(lock);
-       ut_ad(rw_lock_validate(lock));
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(&(lock->mutex));
-+#endif
-       info = UT_LIST_GET_FIRST(lock->debug_list);
-@@ -740,7 +922,9 @@
-                   && (info->pass == 0)
-                   && (info->lock_type == lock_type)) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-                       mutex_exit(&(lock->mutex));
-+#endif
-                       /* Found! */
-                       return(TRUE);
-@@ -748,7 +932,9 @@
-               info = UT_LIST_GET_NEXT(list, info);
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(&(lock->mutex));
-+#endif
-       return(FALSE);
- }
-@@ -770,21 +956,25 @@
-       ut_ad(lock);
-       ut_ad(rw_lock_validate(lock));
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_enter(&(lock->mutex));
-+#endif
-       if (lock_type == RW_LOCK_SHARED) {
-               if (lock->reader_count > 0) {
-                       ret = TRUE;
-               }
-       } else if (lock_type == RW_LOCK_EX) {
--              if (lock->writer == RW_LOCK_EX) {
-+              if (rw_lock_get_writer(lock) == RW_LOCK_EX) {
-                       ret = TRUE;
-               }
-       } else {
-               ut_error;
-       }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-       mutex_exit(&(lock->mutex));
-+#endif
-       return(ret);
- }
-@@ -814,16 +1004,26 @@
-               count++;
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_enter(&(lock->mutex));
-+#endif
-               if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
-                   || (rw_lock_get_reader_count(lock) != 0)
--                  || (rw_lock_get_waiters(lock) != 0)) {
-+                  || (rw_lock_get_s_waiters(lock) != 0)
-+                  || (rw_lock_get_x_waiters(lock) != 0)
-+                  || (rw_lock_get_wx_waiters(lock) != 0)) {
-                       fprintf(file, "RW-LOCK: %p ", (void*) lock);
--                      if (rw_lock_get_waiters(lock)) {
--                              fputs(" Waiters for the lock exist\n", file);
-+                      if (rw_lock_get_s_waiters(lock)) {
-+                              fputs(" s_waiters for the lock exist,", file);
-+                      }
-+                      if (rw_lock_get_x_waiters(lock)) {
-+                              fputs(" x_waiters for the lock exist\n", file);
-+                      }
-+                      if (rw_lock_get_wx_waiters(lock)) {
-+                              fputs(" wait_ex_waiters for the lock exist\n", file);
-                       } else {
-                               putc('\n', file);
-                       }
-@@ -835,7 +1035,9 @@
-                       }
-               }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(&(lock->mutex));
-+#endif
-               lock = UT_LIST_GET_NEXT(list, lock);
-       }
-@@ -860,10 +1062,18 @@
-       if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
-           || (rw_lock_get_reader_count(lock) != 0)
--          || (rw_lock_get_waiters(lock) != 0)) {
-+          || (rw_lock_get_s_waiters(lock) != 0)
-+          || (rw_lock_get_x_waiters(lock) != 0)
-+          || (rw_lock_get_wx_waiters(lock) != 0)) {
--              if (rw_lock_get_waiters(lock)) {
--                      fputs(" Waiters for the lock exist\n", stderr);
-+              if (rw_lock_get_s_waiters(lock)) {
-+                      fputs(" s_waiters for the lock exist,", stderr);
-+              }
-+              if (rw_lock_get_x_waiters(lock)) {
-+                      fputs(" x_waiters for the lock exist\n", stderr);
-+              }
-+              if (rw_lock_get_wx_waiters(lock)) {
-+                      fputs(" wait_ex_waiters for the lock exist\n", stderr);
-               } else {
-                       putc('\n', stderr);
-               }
-@@ -922,14 +1132,18 @@
-       lock = UT_LIST_GET_FIRST(rw_lock_list);
-       while (lock != NULL) {
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_enter(rw_lock_get_mutex(lock));
-+#endif
-               if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
-                   || (rw_lock_get_reader_count(lock) != 0)) {
-                       count++;
-               }
-+#ifndef HAVE_GCC_ATOMIC_BUILTINS
-               mutex_exit(rw_lock_get_mutex(lock));
-+#endif
-               lock = UT_LIST_GET_NEXT(list, lock);
-       }
-diff -ruN mysql-5.1.29-rc_orig/patch_info/innodb_rw_lock.info mysql-5.1.29-rc/patch_info/innodb_rw_lock.info
---- /dev/null  1970-01-01 09:00:00.000000000 +0900
-+++ mysql-5.1.29-rc/patch_info/innodb_rw_lock.info     2008-11-17 15:23:46.000000000 +0900
-@@ -0,0 +1,6 @@
-+File=innodb_rw_lock.patch
-+Name=Fix of InnoDB rw_locks
-+Version=1.0
-+Author=Yasufumi Kinoshita
-+License=BSD
-+Comment=
diff --git a/mysql-innodb_separate_doublewrite.patch b/mysql-innodb_separate_doublewrite.patch
deleted file mode 100644 (file)
index 50e262c..0000000
+++ /dev/null
@@ -1,1096 +0,0 @@
-# name       : innodb_separate_doublewrite.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -3056,7 +3056,8 @@
-               read_space_id = mach_read_from_4(
-                       frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
--              if (bpage->space == TRX_SYS_SPACE
-+              if ((bpage->space == TRX_SYS_SPACE
-+                   || (srv_doublewrite_file && bpage->space == TRX_DOUBLEWRITE_SPACE))
-                   && trx_doublewrite_page_inside(bpage->offset)) {
-                       ut_print_timestamp(stderr);
---- a/storage/innodb_plugin/buf/buf0flu.c
-+++ b/storage/innodb_plugin/buf/buf0flu.c
-@@ -695,7 +695,8 @@
-       write_buf = trx_doublewrite->write_buf;
-       i = 0;
--      fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, 0,
-+      fil_io(OS_FILE_WRITE, TRUE,
-+             (srv_doublewrite_file ? TRX_DOUBLEWRITE_SPACE : TRX_SYS_SPACE), 0,
-              trx_doublewrite->block1, 0, len,
-              (void*) write_buf, NULL);
-@@ -732,7 +733,8 @@
-               + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
-       ut_ad(i == TRX_SYS_DOUBLEWRITE_BLOCK_SIZE);
--      fil_io(OS_FILE_WRITE, TRUE, TRX_SYS_SPACE, 0,
-+      fil_io(OS_FILE_WRITE, TRUE,
-+             (srv_doublewrite_file ? TRX_DOUBLEWRITE_SPACE : TRX_SYS_SPACE), 0,
-              trx_doublewrite->block2, 0, len,
-              (void*) write_buf, NULL);
-@@ -762,7 +764,7 @@
- flush:
-       /* Now flush the doublewrite buffer data to disk */
--      fil_flush(TRX_SYS_SPACE, FALSE);
-+      fil_flush(srv_doublewrite_file ? TRX_DOUBLEWRITE_SPACE : TRX_SYS_SPACE, FALSE);
-       /* We know that the writes have been flushed to disk now
-       and in recovery we will find them in the doublewrite buffer
---- a/storage/innodb_plugin/buf/buf0rea.c
-+++ b/storage/innodb_plugin/buf/buf0rea.c
-@@ -94,7 +94,9 @@
-       wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
-       mode = mode & ~OS_AIO_SIMULATED_WAKE_LATER;
--      if (trx_doublewrite && space == TRX_SYS_SPACE
-+      if (trx_doublewrite
-+          && (space == TRX_SYS_SPACE
-+              || (srv_doublewrite_file && space == TRX_DOUBLEWRITE_SPACE))
-           && (   (offset >= trx_doublewrite->block1
-                   && offset < trx_doublewrite->block1
-                   + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
---- a/storage/innodb_plugin/dict/dict0load.c
-+++ b/storage/innodb_plugin/dict/dict0load.c
-@@ -40,6 +40,7 @@
- #include "rem0cmp.h"
- #include "srv0start.h"
- #include "srv0srv.h"
-+#include "trx0sys.h"
- /****************************************************************//**
- Compare the name of an index column.
-@@ -396,7 +397,7 @@
-               mtr_commit(&mtr);
--              if (space_id == 0) {
-+              if (trx_sys_sys_space(space_id)) {
-                       /* The system tablespace always exists. */
-               } else if (in_crash_recovery) {
-                       /* Check that the tablespace (the .ibd file) really
-@@ -946,7 +947,7 @@
-       space = mach_read_from_4(field);
-       /* Check if the tablespace exists and has the right name */
--      if (space != 0) {
-+      if (!trx_sys_sys_space(space)) {
-               flags = dict_sys_tables_get_flags(rec);
-               if (UNIV_UNLIKELY(flags == ULINT_UNDEFINED)) {
-@@ -999,7 +1000,7 @@
-       }
-       /* See if the tablespace is available. */
--      if (space == 0) {
-+      if (trx_sys_sys_space(space)) {
-               /* The system tablespace is always available. */
-       } else if (!fil_space_for_table_exists_in_mem(
-                          space, name,
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -619,7 +619,7 @@
-       UT_LIST_ADD_LAST(chain, space->chain, node);
--      if (id < SRV_LOG_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
-+      if (id < SRV_EXTRA_SYS_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
-               fil_system->max_assigned_id = id;
-       }
-@@ -682,14 +682,14 @@
-               size_bytes = (((ib_int64_t)size_high) << 32)
-                       + (ib_int64_t)size_low;
- #ifdef UNIV_HOTBACKUP
--              if (space->id == 0) {
-+              if (trx_sys_sys_space(space->id)) {
-                       node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
-                       os_file_close(node->handle);
-                       goto add_size;
-               }
- #endif /* UNIV_HOTBACKUP */
-               ut_a(space->purpose != FIL_LOG);
--              ut_a(space->id != 0);
-+              ut_a(!trx_sys_sys_space(space->id));
-               if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
-                       fprintf(stderr,
-@@ -735,7 +735,7 @@
-               }
-               if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED
--                                || space_id == 0)) {
-+                                || trx_sys_sys_space(space_id))) {
-                       fprintf(stderr,
-                               "InnoDB: Error: tablespace id %lu"
-                               " in file %s is not sensible\n",
-@@ -797,7 +797,7 @@
-       system->n_open++;
--      if (space->purpose == FIL_TABLESPACE && space->id != 0) {
-+      if (space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(space->id)) {
-               /* Put the node to the LRU list */
-               UT_LIST_ADD_FIRST(LRU, system->LRU, node);
-       }
-@@ -830,7 +830,7 @@
-       ut_a(system->n_open > 0);
-       system->n_open--;
--      if (node->space->purpose == FIL_TABLESPACE && node->space->id != 0) {
-+      if (node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) {
-               ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
-               /* The node is in the LRU list, remove it */
-@@ -916,7 +916,7 @@
- retry:
-       mutex_enter(&fil_system->mutex);
--      if (space_id == 0 || space_id >= SRV_LOG_SPACE_FIRST_ID) {
-+      if (trx_sys_sys_space(space_id) || space_id >= SRV_LOG_SPACE_FIRST_ID) {
-               /* We keep log files and system tablespace files always open;
-               this is important in preventing deadlocks in this module, as
-               a page read completion often performs another read from the
-@@ -1147,7 +1147,7 @@
-                       " tablespace memory cache!\n",
-                       (ulong) space->id);
--              if (id == 0 || purpose != FIL_TABLESPACE) {
-+              if (trx_sys_sys_space(id) || purpose != FIL_TABLESPACE) {
-                       mutex_exit(&fil_system->mutex);
-@@ -1209,6 +1209,7 @@
-       space->mark = FALSE;
-       if (UNIV_LIKELY(purpose == FIL_TABLESPACE && !recv_recovery_on)
-+          && UNIV_UNLIKELY(id < SRV_EXTRA_SYS_SPACE_FIRST_ID)
-           && UNIV_UNLIKELY(id > fil_system->max_assigned_id)) {
-               if (!fil_system->space_id_reuse_warned) {
-                       fil_system->space_id_reuse_warned = TRUE;
-@@ -1292,7 +1293,7 @@
-                       (ulong) SRV_LOG_SPACE_FIRST_ID);
-       }
--      success = (id < SRV_LOG_SPACE_FIRST_ID);
-+      success = (id < SRV_EXTRA_SYS_SPACE_FIRST_ID);
-       if (success) {
-               *space_id = fil_system->max_assigned_id = id;
-@@ -1554,6 +1555,8 @@
-       UT_LIST_INIT(fil_system->LRU);
-       fil_system->max_n_open = max_n_open;
-+
-+      fil_system->max_assigned_id = TRX_SYS_SPACE_MAX;
- }
- /*******************************************************************//**
-@@ -1575,7 +1578,7 @@
-       space = UT_LIST_GET_FIRST(fil_system->space_list);
-       while (space != NULL) {
--              if (space->purpose != FIL_TABLESPACE || space->id == 0) {
-+              if (space->purpose != FIL_TABLESPACE || trx_sys_sys_space(space->id)) {
-                       node = UT_LIST_GET_FIRST(space->chain);
-                       while (node != NULL) {
-@@ -1665,6 +1668,10 @@
-               ut_error;
-       }
-+      if (max_id >= SRV_EXTRA_SYS_SPACE_FIRST_ID) {
-+              return;
-+      }
-+
-       mutex_enter(&fil_system->mutex);
-       if (fil_system->max_assigned_id < max_id) {
-@@ -1683,6 +1690,7 @@
- ulint
- fil_write_lsn_and_arch_no_to_file(
- /*==============================*/
-+      ulint           space_id,
-       ulint           sum_of_sizes,   /*!< in: combined size of previous files
-                                       in space, in database pages */
-       ib_uint64_t     lsn,            /*!< in: lsn to write */
-@@ -1692,14 +1700,16 @@
-       byte*   buf1;
-       byte*   buf;
-+      ut_a(trx_sys_sys_space(space_id));
-+
-       buf1 = mem_alloc(2 * UNIV_PAGE_SIZE);
-       buf = ut_align(buf1, UNIV_PAGE_SIZE);
--      fil_read(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
-+      fil_read(TRUE, space_id, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
-       mach_write_ull(buf + FIL_PAGE_FILE_FLUSH_LSN, lsn);
--      fil_write(TRUE, 0, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
-+      fil_write(TRUE, space_id, 0, sum_of_sizes, 0, UNIV_PAGE_SIZE, buf, NULL);
-       mem_free(buf1);
-@@ -1735,7 +1745,7 @@
-               always open. */
-               if (space->purpose == FIL_TABLESPACE
--                  && space->id == 0) {
-+                  && trx_sys_sys_space(space->id)) {
-                       sum_of_sizes = 0;
-                       node = UT_LIST_GET_FIRST(space->chain);
-@@ -1743,7 +1753,7 @@
-                               mutex_exit(&fil_system->mutex);
-                               err = fil_write_lsn_and_arch_no_to_file(
--                                      sum_of_sizes, lsn, arch_log_no);
-+                                      space->id, sum_of_sizes, lsn, arch_log_no);
-                               if (err != DB_SUCCESS) {
-                                       return(err);
-@@ -4108,7 +4118,7 @@
-       }
- #ifndef UNIV_HOTBACKUP
--      if (space_id == ULINT_UNDEFINED || space_id == 0) {
-+      if (space_id == ULINT_UNDEFINED || trx_sys_sys_space(space_id)) {
-               fprintf(stderr,
-                       "InnoDB: Error: tablespace id %lu in file %s"
-                       " is not sensible\n",
-@@ -4117,7 +4127,7 @@
-               goto func_exit;
-       }
- #else
--      if (space_id == ULINT_UNDEFINED || space_id == 0) {
-+      if (space_id == ULINT_UNDEFINED || trx_sys_sys_space(space_id)) {
-               char*   new_path;
-               fprintf(stderr,
-@@ -4938,7 +4948,7 @@
-       }
-       if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
--          && space->id != 0) {
-+          && !trx_sys_sys_space(space->id)) {
-               /* The node is in the LRU list, remove it */
-               ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
-@@ -4984,7 +4994,7 @@
-       }
-       if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
--          && node->space->id != 0) {
-+          && !trx_sys_sys_space(node->space->id)) {
-               /* The node must be put back to the LRU list */
-               UT_LIST_ADD_FIRST(LRU, system->LRU, node);
-       }
-@@ -5590,7 +5600,7 @@
-               ut_a(fil_node->n_pending == 0);
-               ut_a(fil_node->open);
-               ut_a(fil_node->space->purpose == FIL_TABLESPACE);
--              ut_a(fil_node->space->id != 0);
-+              ut_a(!trx_sys_sys_space(fil_node->space->id));
-               fil_node = UT_LIST_GET_NEXT(LRU, fil_node);
-       }
---- a/storage/innodb_plugin/fsp/fsp0fsp.c
-+++ b/storage/innodb_plugin/fsp/fsp0fsp.c
-@@ -48,7 +48,7 @@
- # include "log0log.h"
- #endif /* UNIV_HOTBACKUP */
- #include "dict0mem.h"
--
-+#include "trx0sys.h"
- #define FSP_HEADER_OFFSET     FIL_PAGE_DATA   /* Offset of the space header
-                                               within a file page */
-@@ -1000,10 +1000,10 @@
-       flst_init(header + FSP_SEG_INODES_FREE, mtr);
-       mlog_write_dulint(header + FSP_SEG_ID, ut_dulint_create(0, 1), mtr);
--      if (space == 0) {
-+      if (space == TRX_SYS_SPACE || space == TRX_DOUBLEWRITE_SPACE) {
-               fsp_fill_free_list(FALSE, space, header, mtr);
-               btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
--                         0, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
-+                         space, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
-                          dict_ind_redundant, mtr);
-       } else {
-               fsp_fill_free_list(TRUE, space, header, mtr);
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -166,6 +166,7 @@
- static char*  innobase_log_group_home_dir             = NULL;
- static char*  innobase_file_format_name               = NULL;
- static char*  innobase_change_buffering               = NULL;
-+static char*  innobase_doublewrite_file               = NULL;
- /* Note: This variable can be set to on/off and any of the supported
- file formats in the configuration file, but can only be set to any
-@@ -2270,6 +2271,8 @@
-               goto error;
-       }
-+      srv_doublewrite_file = innobase_doublewrite_file;
-+
-       srv_extra_undoslots = (ibool) innobase_extra_undoslots;
-       /* -------------- Log files ---------------------------*/
-@@ -11313,6 +11316,11 @@
-   "Path to individual files and their sizes.",
-   NULL, NULL, NULL);
-+static MYSQL_SYSVAR_STR(doublewrite_file, innobase_doublewrite_file,
-+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-+  "Path to special datafile for doublewrite buffer. (default is "": not used) ### ONLY FOR EXPERTS!!! ###",
-+  NULL, NULL, NULL);
-+
- static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
-   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-   "The AUTOINC lock modes supported by InnoDB:               "
-@@ -11497,6 +11505,7 @@
-   MYSQL_SYSVAR(commit_concurrency),
-   MYSQL_SYSVAR(concurrency_tickets),
-   MYSQL_SYSVAR(data_file_path),
-+  MYSQL_SYSVAR(doublewrite_file),
-   MYSQL_SYSVAR(data_home_dir),
-   MYSQL_SYSVAR(doublewrite),
-   MYSQL_SYSVAR(extra_undoslots),
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -41,5 +41,6 @@
- {"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_separate_doublewrite","Add option 'innodb_doublewrite_file' to separate doublewrite dedicated tablespace","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/mtr0log.ic
-+++ b/storage/innodb_plugin/include/mtr0log.ic
-@@ -27,8 +27,8 @@
- #include "ut0lst.h"
- #include "buf0buf.h"
- #include "fsp0types.h"
-+#include "srv0srv.h"
- #include "trx0sys.h"
--
- /********************************************************//**
- Opens a buffer to mlog. It must be closed with mlog_close.
- @return       buffer, NULL if log mode MTR_LOG_NONE */
-@@ -201,7 +201,8 @@
-       the doublewrite buffer is located in pages
-       FSP_EXTENT_SIZE, ..., 3 * FSP_EXTENT_SIZE - 1 in the
-       system tablespace */
--      if (space == TRX_SYS_SPACE
-+      if ((space == TRX_SYS_SPACE
-+           || (srv_doublewrite_file && space == TRX_DOUBLEWRITE_SPACE))
-           && offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
-               if (trx_doublewrite_buf_is_being_created) {
-                       /* Do nothing: we only come to this branch in an
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -115,6 +115,8 @@
- extern ulint* srv_data_file_sizes;
- extern ulint* srv_data_file_is_raw_partition;
-+extern char*  srv_doublewrite_file;
-+
- extern ibool  srv_extra_undoslots;
- extern ibool  srv_recovery_stats;
---- a/storage/innodb_plugin/include/srv0start.h
-+++ b/storage/innodb_plugin/include/srv0start.h
-@@ -131,4 +131,7 @@
- /** Log 'spaces' have id's >= this */
- #define SRV_LOG_SPACE_FIRST_ID                0xFFFFFFF0UL
-+/** reserved for extra system tables */
-+#define SRV_EXTRA_SYS_SPACE_FIRST_ID  0xFFFFFFE0UL
-+
- #endif
---- a/storage/innodb_plugin/include/trx0sys.h
-+++ b/storage/innodb_plugin/include/trx0sys.h
-@@ -124,6 +124,22 @@
- /*=============*/
-       ulint   space,  /*!< in: space */
-       ulint   page_no);/*!< in: page number */
-+/***************************************************************//**
-+Checks if a space is the system tablespaces.
-+@return TRUE if system tablespace */
-+UNIV_INLINE
-+ibool
-+trx_sys_sys_space(
-+/*==============*/
-+      ulint   space); /*!< in: space */
-+/***************************************************************//**
-+Checks if a space is the doublewrite tablespace.
-+@return TRUE if doublewrite tablespace */
-+UNIV_INLINE
-+ibool
-+trx_sys_doublewrite_space(
-+/*======================*/
-+      ulint   space); /*!< in: space */
- /*****************************************************************//**
- Creates and initializes the central memory structures for the transaction
- system. This is called when the database is started. */
-@@ -137,6 +153,13 @@
- void
- trx_sys_create(void);
- /*================*/
-+/*****************************************************************//**
-+Creates and initializes the dummy transaction system page for tablespace. */
-+UNIV_INTERN
-+void
-+trx_sys_dummy_create(
-+/*=================*/
-+      ulint   space);
- /*********************************************************************
- Create extra rollback segments when create_new_db */
- UNIV_INTERN
-@@ -458,6 +481,8 @@
- /* Space id and page no where the trx system file copy resides */
- #define       TRX_SYS_SPACE   0       /* the SYSTEM tablespace */
-+#define       TRX_DOUBLEWRITE_SPACE   0xFFFFFFE0UL    /* the doublewrite buffer tablespace if used */
-+#define       TRX_SYS_SPACE_MAX       9       /* reserved max space id for system tablespaces */
- #include "fsp0fsp.h"
- #define       TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
---- a/storage/innodb_plugin/include/trx0sys.ic
-+++ b/storage/innodb_plugin/include/trx0sys.ic
-@@ -71,6 +71,40 @@
- }
- /***************************************************************//**
-+Checks if a space is the system tablespaces.
-+@return TRUE if system tablespace */
-+UNIV_INLINE
-+ibool
-+trx_sys_sys_space(
-+/*==============*/
-+      ulint   space)  /*!< in: space */
-+{
-+      if (srv_doublewrite_file) {
-+              /* several spaces are reserved */
-+              return((ibool)(space == TRX_SYS_SPACE || space == TRX_DOUBLEWRITE_SPACE));
-+      } else {
-+              return((ibool)(space == TRX_SYS_SPACE));
-+      }
-+}
-+
-+/***************************************************************//**
-+Checks if a space is the doublewrite tablespace.
-+@return TRUE if doublewrite tablespace */
-+UNIV_INLINE
-+ibool
-+trx_sys_doublewrite_space(
-+/*======================*/
-+      ulint   space)  /*!< in: space */
-+{
-+      if (srv_doublewrite_file) {
-+              /* doublewrite buffer is separated */
-+              return((ibool)(space == TRX_DOUBLEWRITE_SPACE));
-+      } else {
-+              return((ibool)(space == TRX_SYS_SPACE));
-+      }
-+}
-+
-+/***************************************************************//**
- Gets the pointer in the nth slot of the rseg array.
- @return       pointer to rseg object, NULL if slot not in use */
- UNIV_INLINE
---- a/storage/innodb_plugin/row/row0mysql.c
-+++ b/storage/innodb_plugin/row/row0mysql.c
-@@ -3331,7 +3331,7 @@
-               /* Do not drop possible .ibd tablespace if something went
-               wrong: we do not want to delete valuable data of the user */
--              if (err == DB_SUCCESS && space_id > 0) {
-+              if (err == DB_SUCCESS && !trx_sys_sys_space(space_id)) {
-                       if (!fil_space_for_table_exists_in_mem(space_id,
-                                                              name_or_path,
-                                                              is_temp, FALSE,
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -145,6 +145,8 @@
- /* size in database pages */
- UNIV_INTERN ulint*    srv_data_file_sizes = NULL;
-+UNIV_INTERN char*     srv_doublewrite_file = NULL;
-+
- UNIV_INTERN ibool     srv_extra_undoslots = FALSE;
- UNIV_INTERN ibool     srv_recovery_stats = FALSE;
---- a/storage/innodb_plugin/srv/srv0start.c
-+++ b/storage/innodb_plugin/srv/srv0start.c
-@@ -709,6 +709,7 @@
- /*======================*/
-       ibool*          create_new_db,  /*!< out: TRUE if new database should be
-                                       created */
-+      ibool*          create_new_doublewrite_file,
- #ifdef UNIV_LOG_ARCHIVE
-       ulint*          min_arch_log_no,/*!< out: min of archived log
-                                       numbers in data files */
-@@ -741,6 +742,7 @@
-       *sum_of_new_sizes = 0;
-       *create_new_db = FALSE;
-+      *create_new_doublewrite_file = FALSE;
-       srv_normalize_path_for_win(srv_data_home);
-@@ -973,6 +975,142 @@
-                               srv_data_file_is_raw_partition[i] != 0);
-       }
-+      /* special file for doublewrite buffer */
-+      if (srv_doublewrite_file)
-+      {
-+              srv_normalize_path_for_win(srv_doublewrite_file);
-+
-+              fprintf(stderr,
-+                      "InnoDB: Notice: innodb_doublewrite_file is specified.\n"
-+                      "InnoDB: This is for expert only. Don't use if you don't understand what is it 'WELL'.\n"
-+                      "InnoDB: ### Don't specify older file than the last checkpoint ###\n"
-+                      "InnoDB: otherwise the older doublewrite buffer will break your data during recovery!\n");
-+
-+              strcpy(name, srv_doublewrite_file);
-+
-+              /* First we try to create the file: if it already
-+              exists, ret will get value FALSE */
-+
-+              files[i] = os_file_create(name, OS_FILE_CREATE,
-+                                        OS_FILE_NORMAL,
-+                                        OS_DATA_FILE, &ret);
-+
-+              if (ret == FALSE && os_file_get_last_error(FALSE)
-+                  != OS_FILE_ALREADY_EXISTS
-+#ifdef UNIV_AIX
-+                  /* AIX 5.1 after security patch ML7 may have
-+                  errno set to 0 here, which causes our function
-+                  to return 100; work around that AIX problem */
-+                  && os_file_get_last_error(FALSE) != 100
-+#endif
-+                  ) {
-+                      fprintf(stderr,
-+                              "InnoDB: Error in creating"
-+                              " or opening %s\n",
-+                              name);
-+
-+                      return(DB_ERROR);
-+              }
-+
-+              if (ret == FALSE) {
-+                      /* We open the data file */
-+
-+                      files[i] = os_file_create(
-+                              name, OS_FILE_OPEN, OS_FILE_NORMAL,
-+                              OS_DATA_FILE, &ret);
-+
-+                      if (!ret) {
-+                              fprintf(stderr,
-+                                      "InnoDB: Error in opening %s\n", name);
-+                              os_file_get_last_error(TRUE);
-+
-+                              return(DB_ERROR);
-+                      }
-+
-+                      ret = os_file_get_size(files[i], &size, &size_high);
-+                      ut_a(ret);
-+                      /* Round size downward to megabytes */
-+
-+                      rounded_size_pages
-+                              = (size / (1024 * 1024) + 4096 * size_high)
-+                                      << (20 - UNIV_PAGE_SIZE_SHIFT);
-+
-+                      if (rounded_size_pages != TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9) {
-+
-+                              fprintf(stderr,
-+                                      "InnoDB: Warning: doublewrite buffer file %s"
-+                                      " is of a different size\n"
-+                                      "InnoDB: %lu pages"
-+                                      " (rounded down to MB)\n"
-+                                      "InnoDB: than intended size"
-+                                      " %lu pages...\n",
-+                                      name,
-+                                      (ulong) rounded_size_pages,
-+                                      (ulong) TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9);
-+                      }
-+
-+                      fil_read_flushed_lsn_and_arch_log_no(
-+                              files[i], one_opened,
-+#ifdef UNIV_LOG_ARCHIVE
-+                              min_arch_log_no, max_arch_log_no,
-+#endif /* UNIV_LOG_ARCHIVE */
-+                              min_flushed_lsn, max_flushed_lsn);
-+                      one_opened = TRUE;
-+              } else {
-+                      /* We created the data file and now write it full of
-+                      zeros */
-+
-+                      *create_new_doublewrite_file = TRUE;
-+
-+                      ut_print_timestamp(stderr);
-+                      fprintf(stderr,
-+                              "  InnoDB: Doublewrite buffer file %s did not"
-+                              " exist: new to be created\n",
-+                              name);
-+
-+                      if (*create_new_db == FALSE) {
-+                              fprintf(stderr,
-+                                      "InnoDB: Warning: Previous version's ibdata files may cause crash.\n"
-+                                      "        If you use that, please use the ibdata files of this version.\n");
-+                      }
-+
-+                      ut_print_timestamp(stderr);
-+                      fprintf(stderr,
-+                              "  InnoDB: Setting file %s size to %lu MB\n",
-+                              name,
-+                              (ulong) ((TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9)
-+                                       >> (20 - UNIV_PAGE_SIZE_SHIFT)));
-+
-+                      fprintf(stderr,
-+                              "InnoDB: Database physically writes the"
-+                              " file full: wait...\n");
-+
-+                      ret = os_file_set_size(
-+                              name, files[i],
-+                              srv_calc_low32(TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9),
-+                              srv_calc_high32(TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9));
-+
-+                      if (!ret) {
-+                              fprintf(stderr,
-+                                      "InnoDB: Error in creating %s:"
-+                                      " probably out of disk space\n", name);
-+
-+                              return(DB_ERROR);
-+                      }
-+              }
-+
-+              ret = os_file_close(files[i]);
-+              ut_a(ret);
-+
-+              fil_space_create(name, TRX_DOUBLEWRITE_SPACE, 0, FIL_TABLESPACE);
-+
-+              ut_a(fil_validate());
-+
-+              fil_node_create(name, TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9, TRX_DOUBLEWRITE_SPACE, FALSE);
-+
-+              i++;
-+      }
-+
-       ios = 0;
-       mutex_create(&ios_mutex, SYNC_NO_ORDER_CHECK);
-@@ -991,6 +1129,7 @@
- {
-       buf_pool_t*     ret;
-       ibool           create_new_db;
-+      ibool           create_new_doublewrite_file;
-       ibool           log_file_created;
-       ibool           log_created     = FALSE;
-       ibool           log_opened      = FALSE;
-@@ -1408,6 +1547,7 @@
-       }
-       err = open_or_create_data_files(&create_new_db,
-+                                      &create_new_doublewrite_file,
- #ifdef UNIV_LOG_ARCHIVE
-                                       &min_arch_log_no, &max_arch_log_no,
- #endif /* UNIV_LOG_ARCHIVE */
-@@ -1531,6 +1671,15 @@
-               mtr_commit(&mtr);
-               trx_sys_create();
-+
-+              if (create_new_doublewrite_file) {
-+                      mtr_start(&mtr);
-+                      fsp_header_init(TRX_DOUBLEWRITE_SPACE, TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9, &mtr);
-+                      mtr_commit(&mtr);
-+
-+                      trx_sys_dummy_create(TRX_DOUBLEWRITE_SPACE);
-+              }
-+
-               dict_create();
-               srv_startup_is_before_trx_rollback_phase = FALSE;
-@@ -1568,6 +1717,13 @@
-               recv_recovery_from_archive_finish();
- #endif /* UNIV_LOG_ARCHIVE */
-       } else {
-+              char*   save_srv_doublewrite_file = NULL;
-+
-+              if (create_new_doublewrite_file) {
-+                      /* doublewrite_file cannot be used for recovery yet. */
-+                      save_srv_doublewrite_file = srv_doublewrite_file;
-+                      srv_doublewrite_file = NULL;
-+              }
-               /* Check if we support the max format that is stamped
-               on the system tablespace. 
-@@ -1654,6 +1810,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();
-+
-+              if (create_new_doublewrite_file) {
-+                      /* restore the value */
-+                      srv_doublewrite_file = save_srv_doublewrite_file;
-+
-+                      mtr_start(&mtr);
-+                      fsp_header_init(TRX_DOUBLEWRITE_SPACE, TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 9, &mtr);
-+                      mtr_commit(&mtr);
-+
-+                      trx_sys_dummy_create(TRX_DOUBLEWRITE_SPACE);
-+              }
-       }
-       if (!create_new_db && sum_of_new_sizes > 0) {
---- a/storage/innodb_plugin/trx/trx0sys.c
-+++ b/storage/innodb_plugin/trx/trx0sys.c
-@@ -408,6 +408,152 @@
-               goto start_again;
-       }
-+
-+    if (srv_doublewrite_file) {
-+      /* the same doublewrite buffer to TRX_SYS_SPACE should exist.
-+      check and create if not exist.*/
-+
-+      mtr_start(&mtr);
-+      trx_doublewrite_buf_is_being_created = TRUE;
-+
-+      block = buf_page_get(TRX_DOUBLEWRITE_SPACE, 0, TRX_SYS_PAGE_NO,
-+                           RW_X_LATCH, &mtr);
-+      buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
-+
-+      doublewrite = buf_block_get_frame(block) + TRX_SYS_DOUBLEWRITE;
-+
-+      if (mach_read_from_4(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC)
-+          == TRX_SYS_DOUBLEWRITE_MAGIC_N) {
-+              /* The doublewrite buffer has already been created:
-+              just read in some numbers */
-+
-+              mtr_commit(&mtr);
-+      } else {
-+              fprintf(stderr,
-+                      "InnoDB: Doublewrite buffer not found in the doublewrite file:"
-+                      " creating new\n");
-+
-+              if (buf_pool_get_curr_size()
-+                  < ((2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
-+                      + FSP_EXTENT_SIZE / 2 + 100)
-+                     * UNIV_PAGE_SIZE)) {
-+                      fprintf(stderr,
-+                              "InnoDB: Cannot create doublewrite buffer:"
-+                              " you must\n"
-+                              "InnoDB: increase your buffer pool size.\n"
-+                              "InnoDB: Cannot continue operation.\n");
-+
-+                      exit(1);
-+              }
-+
-+              block2 = fseg_create(TRX_DOUBLEWRITE_SPACE, TRX_SYS_PAGE_NO,
-+                                   TRX_SYS_DOUBLEWRITE
-+                                   + TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
-+
-+              /* fseg_create acquires a second latch on the page,
-+              therefore we must declare it: */
-+
-+              buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
-+
-+              if (block2 == NULL) {
-+                      fprintf(stderr,
-+                              "InnoDB: Cannot create doublewrite buffer:"
-+                              " you must\n"
-+                              "InnoDB: increase your tablespace size.\n"
-+                              "InnoDB: Cannot continue operation.\n");
-+
-+                      /* We exit without committing the mtr to prevent
-+                      its modifications to the database getting to disk */
-+
-+                      exit(1);
-+              }
-+
-+              fseg_header = buf_block_get_frame(block)
-+                      + TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG;
-+              prev_page_no = 0;
-+
-+              for (i = 0; i < 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
-+                           + FSP_EXTENT_SIZE / 2; i++) {
-+                      page_no = fseg_alloc_free_page(fseg_header,
-+                                                     prev_page_no + 1,
-+                                                     FSP_UP, &mtr);
-+                      if (page_no == FIL_NULL) {
-+                              fprintf(stderr,
-+                                      "InnoDB: Cannot create doublewrite"
-+                                      " buffer: you must\n"
-+                                      "InnoDB: increase your"
-+                                      " tablespace size.\n"
-+                                      "InnoDB: Cannot continue operation.\n"
-+                                      );
-+
-+                              exit(1);
-+                      }
-+
-+                      /* We read the allocated pages to the buffer pool;
-+                      when they are written to disk in a flush, the space
-+                      id and page number fields are also written to the
-+                      pages. When we at database startup read pages
-+                      from the doublewrite buffer, we know that if the
-+                      space id and page number in them are the same as
-+                      the page position in the tablespace, then the page
-+                      has not been written to in doublewrite. */
-+
-+#ifdef UNIV_SYNC_DEBUG
-+                      new_block =
-+#endif /* UNIV_SYNC_DEBUG */
-+                      buf_page_get(TRX_DOUBLEWRITE_SPACE, 0, page_no,
-+                                               RW_X_LATCH, &mtr);
-+                      buf_block_dbg_add_level(new_block,
-+                                              SYNC_NO_ORDER_CHECK);
-+
-+                      if (i == FSP_EXTENT_SIZE / 2) {
-+                              ut_a(page_no == FSP_EXTENT_SIZE);
-+                              mlog_write_ulint(doublewrite
-+                                               + TRX_SYS_DOUBLEWRITE_BLOCK1,
-+                                               page_no, MLOG_4BYTES, &mtr);
-+                              mlog_write_ulint(doublewrite
-+                                               + TRX_SYS_DOUBLEWRITE_REPEAT
-+                                               + TRX_SYS_DOUBLEWRITE_BLOCK1,
-+                                               page_no, MLOG_4BYTES, &mtr);
-+                      } else if (i == FSP_EXTENT_SIZE / 2
-+                                 + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
-+                              ut_a(page_no == 2 * FSP_EXTENT_SIZE);
-+                              mlog_write_ulint(doublewrite
-+                                               + TRX_SYS_DOUBLEWRITE_BLOCK2,
-+                                               page_no, MLOG_4BYTES, &mtr);
-+                              mlog_write_ulint(doublewrite
-+                                               + TRX_SYS_DOUBLEWRITE_REPEAT
-+                                               + TRX_SYS_DOUBLEWRITE_BLOCK2,
-+                                               page_no, MLOG_4BYTES, &mtr);
-+                      } else if (i > FSP_EXTENT_SIZE / 2) {
-+                              ut_a(page_no == prev_page_no + 1);
-+                      }
-+
-+                      prev_page_no = page_no;
-+              }
-+
-+              mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC,
-+                               TRX_SYS_DOUBLEWRITE_MAGIC_N,
-+                               MLOG_4BYTES, &mtr);
-+              mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC
-+                               + TRX_SYS_DOUBLEWRITE_REPEAT,
-+                               TRX_SYS_DOUBLEWRITE_MAGIC_N,
-+                               MLOG_4BYTES, &mtr);
-+
-+              mlog_write_ulint(doublewrite
-+                               + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED,
-+                               TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N,
-+                               MLOG_4BYTES, &mtr);
-+              mtr_commit(&mtr);
-+
-+              /* Flush the modified pages to disk and make a checkpoint */
-+              log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
-+
-+              fprintf(stderr, "InnoDB: Doublewrite buffer created in the doublewrite file\n");
-+              trx_sys_multiple_tablespace_format = TRUE;
-+      }
-+      trx_doublewrite_buf_is_being_created = FALSE;
-+    }
- }
- /****************************************************************//**
-@@ -431,10 +577,19 @@
-       ulint   source_page_no;
-       byte*   page;
-       byte*   doublewrite;
-+      ulint   doublewrite_space_id;
-       ulint   space_id;
-       ulint   page_no;
-       ulint   i;
-+      doublewrite_space_id = (srv_doublewrite_file ? TRX_DOUBLEWRITE_SPACE : TRX_SYS_SPACE);
-+
-+      if (srv_doublewrite_file) {
-+              fprintf(stderr,
-+                      "InnoDB: doublewrite file '%s' is used.\n",
-+                      srv_doublewrite_file);
-+      }
-+
-       /* We do the file i/o past the buffer pool */
-       unaligned_read_buf = ut_malloc(2 * UNIV_PAGE_SIZE);
-@@ -443,7 +598,7 @@
-       /* Read the trx sys header to check if we are using the doublewrite
-       buffer */
--      fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO, 0,
-+      fil_io(OS_FILE_READ, TRUE, doublewrite_space_id, 0, TRX_SYS_PAGE_NO, 0,
-              UNIV_PAGE_SIZE, read_buf, NULL);
-       doublewrite = read_buf + TRX_SYS_DOUBLEWRITE;
-@@ -481,10 +636,10 @@
-       /* Read the pages from the doublewrite buffer to memory */
--      fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, 0, block1, 0,
-+      fil_io(OS_FILE_READ, TRUE, doublewrite_space_id, 0, block1, 0,
-              TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
-              buf, NULL);
--      fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, 0, block2, 0,
-+      fil_io(OS_FILE_READ, TRUE, doublewrite_space_id, 0, block2, 0,
-              TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
-              buf + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
-              NULL);
-@@ -540,7 +695,8 @@
-                               " doublewrite buf.\n",
-                               (ulong) space_id, (ulong) page_no, (ulong) i);
--              } else if (space_id == TRX_SYS_SPACE
-+              } else if ((space_id == TRX_SYS_SPACE
-+                          || (srv_doublewrite_file && space_id == TRX_DOUBLEWRITE_SPACE))
-                          && ((page_no >= block1
-                               && page_no
-                               < block1 + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE)
-@@ -986,6 +1142,83 @@
- }
- /*****************************************************************//**
-+Creates dummy of the file page for the transaction system. */
-+static
-+void
-+trx_sysf_dummy_create(
-+/*==================*/
-+      ulint   space,
-+      mtr_t*  mtr)
-+{
-+      buf_block_t*    block;
-+      page_t*         page;
-+
-+      ut_ad(mtr);
-+
-+      /* Note that below we first reserve the file space x-latch, and
-+      then enter the kernel: we must do it in this order to conform
-+      to the latching order rules. */
-+
-+      mtr_x_lock(fil_space_get_latch(space, NULL), mtr);
-+      mutex_enter(&kernel_mutex);
-+
-+      /* Create the trx sys file block in a new allocated file segment */
-+      block = fseg_create(space, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,
-+                          mtr);
-+      buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
-+
-+      fprintf(stderr, "%lu\n", buf_block_get_page_no(block));
-+      ut_a(buf_block_get_page_no(block) == TRX_SYS_PAGE_NO);
-+
-+      page = buf_block_get_frame(block);
-+
-+      mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_TRX_SYS,
-+                       MLOG_2BYTES, mtr);
-+
-+      /* Reset the doublewrite buffer magic number to zero so that we
-+      know that the doublewrite buffer has not yet been created (this
-+      suppresses a Valgrind warning) */
-+
-+      mlog_write_ulint(page + TRX_SYS_DOUBLEWRITE
-+                       + TRX_SYS_DOUBLEWRITE_MAGIC, 0, MLOG_4BYTES, mtr);
-+
-+#ifdef UNDEFINED
-+      /* TODO: REMOVE IT: The bellow is not needed, I think */
-+      sys_header = trx_sysf_get(mtr);
-+
-+      /* Start counting transaction ids from number 1 up */
-+      mlog_write_dulint(sys_header + TRX_SYS_TRX_ID_STORE,
-+                        ut_dulint_create(0, 1), mtr);
-+
-+      /* Reset the rollback segment slots */
-+      for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
-+
-+              trx_sysf_rseg_set_space(sys_header, i, ULINT_UNDEFINED, mtr);
-+              trx_sysf_rseg_set_page_no(sys_header, i, FIL_NULL, mtr);
-+      }
-+
-+      /* The remaining area (up to the page trailer) is uninitialized.
-+      Silence Valgrind warnings about it. */
-+      UNIV_MEM_VALID(sys_header + (TRX_SYS_RSEGS
-+                                   + TRX_SYS_N_RSEGS * TRX_SYS_RSEG_SLOT_SIZE
-+                                   + TRX_SYS_RSEG_SPACE),
-+                     (UNIV_PAGE_SIZE - FIL_PAGE_DATA_END
-+                      - (TRX_SYS_RSEGS
-+                         + TRX_SYS_N_RSEGS * TRX_SYS_RSEG_SLOT_SIZE
-+                         + TRX_SYS_RSEG_SPACE))
-+                     + page - sys_header);
-+
-+      /* Create the first rollback segment in the SYSTEM tablespace */
-+      page_no = trx_rseg_header_create(space, 0, ULINT_MAX, &slot_no,
-+                                       mtr);
-+      ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
-+      ut_a(page_no != FIL_NULL);
-+#endif
-+
-+      mutex_exit(&kernel_mutex);
-+}
-+
-+/*****************************************************************//**
- Creates and initializes the central memory structures for the transaction
- system. This is called when the database is started. */
- UNIV_INTERN
-@@ -1091,6 +1324,26 @@
-       trx_sys_init_at_db_start();
- }
-+/*****************************************************************//**
-+Creates and initializes the dummy transaction system page for tablespace. */
-+UNIV_INTERN
-+void
-+trx_sys_dummy_create(
-+/*=================*/
-+      ulint   space)
-+{
-+      mtr_t   mtr;
-+
-+      /* This function is only for doublewrite file for now */
-+      ut_a(space == TRX_DOUBLEWRITE_SPACE);
-+
-+      mtr_start(&mtr);
-+
-+      trx_sysf_dummy_create(space, &mtr);
-+
-+      mtr_commit(&mtr);
-+}
-+
- /*********************************************************************
- Create extra rollback segments when create_new_db */
- UNIV_INTERN
---- /dev/null
-+++ b/mysql-test/r/percona_innodb_doublewrite_file.result
-@@ -0,0 +1,4 @@
-+show variables like 'innodb_doublewrite%';
-+Variable_name Value
-+innodb_doublewrite    ON
-+innodb_doublewrite_file       ib_doublewrite
---- /dev/null
-+++ b/mysql-test/t/percona_innodb_doublewrite_file-master.opt
-@@ -0,0 +1 @@
-+--innodb_doublewrite_file=ib_doublewrite
---- /dev/null
-+++ b/mysql-test/t/percona_innodb_doublewrite_file.test
-@@ -0,0 +1,2 @@
-+--source include/have_innodb.inc
-+show variables like 'innodb_doublewrite%';
diff --git a/mysql-innodb_show_enhancements.patch b/mysql-innodb_show_enhancements.patch
deleted file mode 100644 (file)
index 7a9e0ab..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-# name       : innodb_show_enhancements.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/Makefile.am
-+++ b/storage/innodb_plugin/Makefile.am
-@@ -226,6 +226,7 @@
-                       include/ut0vec.h        \
-                       include/ut0vec.ic       \
-                       include/ut0wqueue.h     \
-+                      handler/innodb_patch_info.h     \
-                       mem/mem0dbg.c
- EXTRA_LIBRARIES=      libinnobase.a
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -11113,7 +11113,8 @@
- i_s_innodb_cmp,
- i_s_innodb_cmp_reset,
- i_s_innodb_cmpmem,
--i_s_innodb_cmpmem_reset
-+i_s_innodb_cmpmem_reset,
-+i_s_innodb_patches
- mysql_declare_plugin_end;
- /** @brief Initialize the default value of innodb_commit_concurrency.
---- a/storage/innodb_plugin/handler/i_s.cc
-+++ b/storage/innodb_plugin/handler/i_s.cc
-@@ -32,6 +32,7 @@
- #include <mysys_err.h>
- #include <my_sys.h>
- #include "i_s.h"
-+#include "innodb_patch_info.h"
- #include <mysql/plugin.h>
- extern "C" {
-@@ -217,6 +218,168 @@
-       return(ret);
- }
-+/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_patches */
-+static ST_FIELD_INFO  innodb_patches_fields_info[] =
-+{
-+#define IDX_PATCH_NAME                0
-+      {STRUCT_FLD(field_name,         "name"),
-+       STRUCT_FLD(field_length,       255),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+#define IDX_PATCH_DESCR               1
-+      {STRUCT_FLD(field_name,         "description"),
-+       STRUCT_FLD(field_length,       255),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+#define IDX_PATCH_COMMENT             2
-+      {STRUCT_FLD(field_name,         "comment"),
-+       STRUCT_FLD(field_length,       100),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+#define IDX_PATCH_LINK                        3
-+      {STRUCT_FLD(field_name,         "link"),
-+       STRUCT_FLD(field_length,       255),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      END_OF_ST_FIELD_INFO
-+};
-+
-+static struct st_mysql_information_schema     i_s_info =
-+{
-+      MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
-+};
-+
-+/***********************************************************************
-+Fill the dynamic table information_schema.innodb_patches */
-+static
-+int
-+innodb_patches_fill(
-+/*=============*/
-+                              /* out: 0 on success, 1 on failure */
-+      THD*            thd,    /* in: thread */
-+      TABLE_LIST*     tables, /* in/out: tables to fill */
-+      COND*           cond)   /* in: condition (ignored) */
-+{
-+      TABLE*  table   = (TABLE *) tables->table;
-+      int     status  = 0;
-+      int     i;
-+      Field** fields;
-+
-+
-+      DBUG_ENTER("innodb_patches_fill");
-+      fields = table->field;
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+
-+              DBUG_RETURN(0);
-+      }
-+
-+      RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
-+      
-+      for (i = 0; innodb_enhancements[i].file; i++) {
-+
-+      field_store_string(fields[0],innodb_enhancements[i].file);
-+      field_store_string(fields[1],innodb_enhancements[i].name);
-+      field_store_string(fields[2],innodb_enhancements[i].comment);
-+      field_store_string(fields[3],innodb_enhancements[i].link);
-+
-+      if (schema_table_store_record(thd, table)) {
-+              status = 1;
-+              break;
-+      }
-+
-+      }
-+
-+
-+      DBUG_RETURN(status);
-+}
-+
-+/***********************************************************************
-+Bind the dynamic table information_schema.innodb_patches. */
-+static
-+int
-+innodb_patches_init(
-+/*=========*/
-+                      /* out: 0 on success */
-+      void*   p)      /* in/out: table schema object */
-+{
-+      DBUG_ENTER("innodb_patches_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = innodb_patches_fields_info;
-+      schema->fill_table = innodb_patches_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+
-+UNIV_INTERN struct st_mysql_plugin      i_s_innodb_patches =
-+{
-+        /* the plugin type (a MYSQL_XXX_PLUGIN value) */
-+        /* int */
-+        STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+
-+        /* pointer to type-specific plugin descriptor */
-+        /* void* */
-+        STRUCT_FLD(info, &i_s_info),
-+
-+        /* plugin name */
-+        /* const char* */
-+        STRUCT_FLD(name, "XTRADB_ENHANCEMENTS"),
-+
-+        /* plugin author (for SHOW PLUGINS) */
-+        /* const char* */
-+        STRUCT_FLD(author, "Percona"),
-+
-+        /* general descriptive text (for SHOW PLUGINS) */
-+        /* const char* */
-+        STRUCT_FLD(descr, "Enhancements applied to InnoDB plugin"),
-+
-+        /* the plugin license (PLUGIN_LICENSE_XXX) */
-+        /* int */
-+        STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+
-+        /* the function to invoke when plugin is loaded */
-+        /* int (*)(void*); */
-+        STRUCT_FLD(init, innodb_patches_init),
-+
-+        /* the function to invoke when plugin is unloaded */
-+        /* int (*)(void*); */
-+        STRUCT_FLD(deinit, i_s_common_deinit),
-+
-+        /* plugin version (for SHOW PLUGINS) */
-+        /* unsigned int */
-+        STRUCT_FLD(version, INNODB_VERSION_SHORT),
-+
-+        /* struct st_mysql_show_var* */
-+        STRUCT_FLD(status_vars, NULL),
-+
-+        /* struct st_mysql_sys_var** */
-+        STRUCT_FLD(system_vars, NULL),
-+
-+        /* reserved for dependency checking */
-+        /* void* */
-+        STRUCT_FLD(__reserved1, NULL)
-+};
-+
-+
- /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
- static ST_FIELD_INFO  innodb_trx_fields_info[] =
- {
-@@ -409,10 +572,6 @@
-       DBUG_RETURN(0);
- }
--static struct st_mysql_information_schema     i_s_info =
--{
--      MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
--};
- UNIV_INTERN struct st_mysql_plugin    i_s_innodb_trx =
- {
---- a/storage/innodb_plugin/handler/i_s.h
-+++ b/storage/innodb_plugin/handler/i_s.h
-@@ -33,5 +33,6 @@
- extern struct st_mysql_plugin i_s_innodb_cmp_reset;
- extern struct st_mysql_plugin i_s_innodb_cmpmem;
- extern struct st_mysql_plugin i_s_innodb_cmpmem_reset;
-+extern struct st_mysql_plugin i_s_innodb_patches;
- #endif /* i_s_h */
---- /dev/null
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -0,0 +1,28 @@
-+/* Copyright (C) 2002-2006 MySQL AB
-+  
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+  
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+#ifdef USE_PRAGMA_INTERFACE
-+#pragma interface                      /* gcc class implementation */
-+#endif
-+
-+struct innodb_enhancement {
-+       const char *file;
-+       const char *name;
-+       const char *comment;
-+       const char *link;
-+}innodb_enhancements[] = {
-+{"xtradb_show_enhancements","I_S.XTRADB_ENHANCEMENTS","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{NULL, NULL, NULL, NULL}
-+};
diff --git a/mysql-innodb_show_lock_name.patch b/mysql-innodb_show_lock_name.patch
deleted file mode 100644 (file)
index b0b3471..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-# name       : innodb_show_lock_name.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -9258,8 +9258,8 @@
-                       rw_lock_wait_time += mutex->lspent_time;
-               }
- #else /* UNIV_DEBUG */
--              buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s:%lu",
--                                   mutex->cfile_name, (ulong) mutex->cline);
-+              buf1len= (uint) my_snprintf(buf1, sizeof(buf1), "%s",
-+                                   mutex->cmutex_name);
-               buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
-                                    (ulong) mutex->count_os_wait);
-@@ -9274,9 +9274,8 @@
-       if (block_mutex) {
-               buf1len = (uint) my_snprintf(buf1, sizeof buf1,
--                                           "combined %s:%lu",
--                                           block_mutex->cfile_name,
--                                           (ulong) block_mutex->cline);
-+                                           "combined %s",
-+                                           block_mutex->cmutex_name);
-               buf2len = (uint) my_snprintf(buf2, sizeof buf2,
-                                            "os_waits=%lu",
-                                            (ulong) block_mutex_oswait_count);
-@@ -9305,8 +9304,8 @@
-                       continue;
-               }
--              buf1len = my_snprintf(buf1, sizeof buf1, "%s:%lu",
--                                   lock->cfile_name, (ulong) lock->cline);
-+              buf1len = my_snprintf(buf1, sizeof buf1, "%s",
-+                                   lock->lock_name);
-               buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu",
-                                     (ulong) lock->count_os_wait);
-@@ -9320,9 +9319,8 @@
-       if (block_lock) {
-               buf1len = (uint) my_snprintf(buf1, sizeof buf1,
--                                           "combined %s:%lu",
--                                           block_lock->cfile_name,
--                                           (ulong) block_lock->cline);
-+                                           "combined %s",
-+                                           block_lock->lock_name);
-               buf2len = (uint) my_snprintf(buf2, sizeof buf2,
-                                            "os_waits=%lu",
-                                            (ulong) block_lock_oswait_count);
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -38,5 +38,6 @@
- {"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/sync0rw.h
-+++ b/storage/innodb_plugin/include/sync0rw.h
-@@ -113,14 +113,14 @@
- #ifdef UNIV_DEBUG
- # ifdef UNIV_SYNC_DEBUG
- #  define rw_lock_create(L, level)                                    \
--      rw_lock_create_func((L), (level), #L, __FILE__, __LINE__)
-+      rw_lock_create_func((L), (level), __FILE__, __LINE__, #L)
- # else /* UNIV_SYNC_DEBUG */
- #  define rw_lock_create(L, level)                                    \
--      rw_lock_create_func((L), #L, __FILE__, __LINE__)
-+      rw_lock_create_func((L), __FILE__, __LINE__, #L)
- # endif /* UNIV_SYNC_DEBUG */
- #else /* UNIV_DEBUG */
- # define rw_lock_create(L, level)                                     \
--      rw_lock_create_func((L), __FILE__, __LINE__)
-+      rw_lock_create_func((L), #L)
- #endif /* UNIV_DEBUG */
- /******************************************************************//**
-@@ -137,10 +137,10 @@
- # ifdef UNIV_SYNC_DEBUG
-       ulint           level,          /*!< in: level */
- # endif /* UNIV_SYNC_DEBUG */
--      const char*     cmutex_name,    /*!< in: mutex name */
--#endif /* UNIV_DEBUG */
-       const char*     cfile_name,     /*!< in: file name where created */
--      ulint           cline);         /*!< in: file line where created */
-+      ulint           cline,          /*!< in: file line where created */
-+#endif /* UNIV_DEBUG */
-+      const char*     cmutex_name);   /*!< in: mutex name */
- /******************************************************************//**
- Calling this function is obligatory only if the memory buffer containing
- the rw-lock is freed. Removes an rw-lock object from the global list. The
-@@ -542,7 +542,8 @@
-       ulint   level;          /*!< Level in the global latching order. */
- #endif /* UNIV_SYNC_DEBUG */
-       ulint count_os_wait;    /*!< Count of os_waits. May not be accurate */
--      const char*     cfile_name;/*!< File name where lock created */
-+      //const char*   cfile_name;/*!< File name where lock created */
-+      const char*     lock_name;/*!< lock name */
-         /* last s-lock file/line is not guaranteed to be correct */
-       const char*     last_s_file_name;/*!< File name where last s-locked */
-       const char*     last_x_file_name;/*!< File name where last x-locked */
-@@ -553,7 +554,7 @@
-                               are at the start of this struct, thus we can
-                               peek this field without causing much memory
-                               bus traffic */
--      unsigned        cline:14;       /*!< Line where created */
-+      //unsigned      cline:14;       /*!< Line where created */
-       unsigned        last_s_line:14; /*!< Line number where last time s-locked */
-       unsigned        last_x_line:14; /*!< Line number where last time x-locked */
- #ifdef UNIV_DEBUG
---- a/storage/innodb_plugin/include/sync0sync.h
-+++ b/storage/innodb_plugin/include/sync0sync.h
-@@ -73,14 +73,14 @@
- #ifdef UNIV_DEBUG
- # ifdef UNIV_SYNC_DEBUG
- #  define mutex_create(M, level)                                      \
--      mutex_create_func((M), #M, (level), __FILE__, __LINE__)
-+      mutex_create_func((M), (level), __FILE__, __LINE__, #M)
- # else
- #  define mutex_create(M, level)                                      \
--      mutex_create_func((M), #M, __FILE__, __LINE__)
-+      mutex_create_func((M), __FILE__, __LINE__, #M)
- # endif
- #else
- # define mutex_create(M, level)                                       \
--      mutex_create_func((M), __FILE__, __LINE__)
-+      mutex_create_func((M), #M)
- #endif
- /******************************************************************//**
-@@ -94,13 +94,13 @@
- /*==============*/
-       mutex_t*        mutex,          /*!< in: pointer to memory */
- #ifdef UNIV_DEBUG
--      const char*     cmutex_name,    /*!< in: mutex name */
- # ifdef UNIV_SYNC_DEBUG
-       ulint           level,          /*!< in: level */
- # endif /* UNIV_SYNC_DEBUG */
--#endif /* UNIV_DEBUG */
-       const char*     cfile_name,     /*!< in: file name where created */
--      ulint           cline);         /*!< in: file line where created */
-+      ulint           cline,          /*!< in: file line where created */
-+#endif /* UNIV_DEBUG */
-+      const char*     cmutex_name);   /*!< in: mutex name */
- #undef mutex_free                     /* Fix for MacOS X */
-@@ -538,9 +538,9 @@
-       ulint   line;           /*!< Line where the mutex was locked */
-       ulint   level;          /*!< Level in the global latching order */
- #endif /* UNIV_SYNC_DEBUG */
-+#ifdef UNIV_DEBUG
-       const char*     cfile_name;/*!< File name where mutex created */
-       ulint           cline;  /*!< Line where created */
--#ifdef UNIV_DEBUG
-       os_thread_id_t thread_id; /*!< The thread id of the thread
-                               which locked the mutex. */
-       ulint           magic_n;        /*!< MUTEX_MAGIC_N */
-@@ -555,9 +555,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 */
--      const char*     cmutex_name;    /*!< mutex name */
-       ulint           mutex_type;     /*!< 0=usual mutex, 1=rw_lock mutex */
- #endif /* UNIV_DEBUG */
-+      const char*     cmutex_name;    /*!< mutex name */
- };
- /** The global array of wait cells for implementation of the databases own
---- a/storage/innodb_plugin/sync/sync0arr.c
-+++ b/storage/innodb_plugin/sync/sync0arr.c
-@@ -482,12 +482,12 @@
-               mutex = cell->old_wait_mutex;
-               fprintf(file,
--                      "Mutex at %p created file %s line %lu, lock var %lu\n"
-+                      "Mutex at %p '%s', lock var %lu\n"
- #ifdef UNIV_SYNC_DEBUG
-                       "Last time reserved in file %s line %lu, "
- #endif /* UNIV_SYNC_DEBUG */
-                       "waiters flag %lu\n",
--                      (void*) mutex, mutex->cfile_name, (ulong) mutex->cline,
-+                      (void*) mutex, mutex->cmutex_name,
-                       (ulong) mutex->lock_word,
- #ifdef UNIV_SYNC_DEBUG
-                       mutex->file_name, (ulong) mutex->line,
-@@ -505,9 +505,8 @@
-               rwlock = cell->old_wait_rw_lock;
-               fprintf(file,
--                      " RW-latch at %p created in file %s line %lu\n",
--                      (void*) rwlock, rwlock->cfile_name,
--                      (ulong) rwlock->cline);
-+                      " RW-latch at %p '%s'\n",
-+                      (void*) rwlock, rwlock->lock_name);
-               writer = rw_lock_get_writer(rwlock);
-               if (writer != RW_LOCK_NOT_LOCKED) {
-                       fprintf(file,
---- a/storage/innodb_plugin/sync/sync0rw.c
-+++ b/storage/innodb_plugin/sync/sync0rw.c
-@@ -231,10 +231,10 @@
- # ifdef UNIV_SYNC_DEBUG
-       ulint           level,          /*!< in: level */
- # endif /* UNIV_SYNC_DEBUG */
--      const char*     cmutex_name,    /*!< in: mutex name */
--#endif /* UNIV_DEBUG */
-       const char*     cfile_name,     /*!< in: file name where created */
--      ulint           cline)          /*!< in: file line where created */
-+      ulint           cline,          /*!< in: file line where created */
-+#endif /* UNIV_DEBUG */
-+      const char*     cmutex_name)    /*!< in: mutex name */
- {
-       /* If this is the very first time a synchronization object is
-       created, then the following call initializes the sync system. */
-@@ -242,14 +242,15 @@
- #ifndef INNODB_RW_LOCKS_USE_ATOMICS
-       mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
--      lock->mutex.cfile_name = cfile_name;
--      lock->mutex.cline = cline;
-+      ut_d(lock->mutex.cfile_name = cfile_name);
-+      ut_d(lock->mutex.cline = cline);
--      ut_d(lock->mutex.cmutex_name = cmutex_name);
-+      lock->mutex.cmutex_name = cmutex_name;
-       ut_d(lock->mutex.mutex_type = 1);
- #else /* INNODB_RW_LOCKS_USE_ATOMICS */
- # ifdef UNIV_DEBUG
--      UT_NOT_USED(cmutex_name);
-+      UT_NOT_USED(cfile_name);
-+      UT_NOT_USED(cline);
- # endif
- #endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-@@ -272,8 +273,7 @@
-       ut_d(lock->magic_n = RW_LOCK_MAGIC_N);
--      lock->cfile_name = cfile_name;
--      lock->cline = (unsigned int) cline;
-+      lock->lock_name = cmutex_name;
-       lock->count_os_wait = 0;
-       lock->last_s_file_name = "not yet reserved";
-@@ -393,10 +393,10 @@
-       if (srv_print_latch_waits) {
-               fprintf(stderr,
-                       "Thread %lu spin wait rw-s-lock at %p"
--                      " cfile %s cline %lu rnds %lu\n",
-+                      " '%s' rnds %lu\n",
-                       (ulong) os_thread_pf(os_thread_get_curr_id()),
-                       (void*) lock,
--                      lock->cfile_name, (ulong) lock->cline, (ulong) i);
-+                      lock->lock_name, (ulong) i);
-       }
-       /* We try once again to obtain the lock */
-@@ -429,10 +429,9 @@
-               if (srv_print_latch_waits) {
-                       fprintf(stderr,
-                               "Thread %lu OS wait rw-s-lock at %p"
--                              " cfile %s cline %lu\n",
-+                              " '%s'\n",
-                               os_thread_pf(os_thread_get_curr_id()),
--                              (void*) lock, lock->cfile_name,
--                              (ulong) lock->cline);
-+                              (void*) lock, lock->lock_name);
-               }
-               /* these stats may not be accurate */
-@@ -651,9 +650,9 @@
-       if (srv_print_latch_waits) {
-               fprintf(stderr,
-                       "Thread %lu spin wait rw-x-lock at %p"
--                      " cfile %s cline %lu rnds %lu\n",
-+                      " '%s' rnds %lu\n",
-                       os_thread_pf(os_thread_get_curr_id()), (void*) lock,
--                      lock->cfile_name, (ulong) lock->cline, (ulong) i);
-+                      lock->lock_name, (ulong) i);
-       }
-       sync_array_reserve_cell(sync_primary_wait_array,
-@@ -674,9 +673,9 @@
-       if (srv_print_latch_waits) {
-               fprintf(stderr,
-                       "Thread %lu OS wait for rw-x-lock at %p"
--                      " cfile %s cline %lu\n",
-+                      " '%s'\n",
-                       os_thread_pf(os_thread_get_curr_id()), (void*) lock,
--                      lock->cfile_name, (ulong) lock->cline);
-+                      lock->lock_name);
-       }
-       /* these stats may not be accurate */
---- a/storage/innodb_plugin/sync/sync0sync.c
-+++ b/storage/innodb_plugin/sync/sync0sync.c
-@@ -239,13 +239,13 @@
- /*==============*/
-       mutex_t*        mutex,          /*!< in: pointer to memory */
- #ifdef UNIV_DEBUG
--      const char*     cmutex_name,    /*!< in: mutex name */
- # ifdef UNIV_SYNC_DEBUG
-       ulint           level,          /*!< in: level */
- # endif /* UNIV_SYNC_DEBUG */
--#endif /* UNIV_DEBUG */
-       const char*     cfile_name,     /*!< in: file name where created */
--      ulint           cline)          /*!< in: file line where created */
-+      ulint           cline,          /*!< in: file line where created */
-+#endif /* UNIV_DEBUG */
-+      const char*     cmutex_name)    /*!< in: mutex name */
- {
- #if defined(HAVE_ATOMIC_BUILTINS)
-       mutex_reset_lock_word(mutex);
-@@ -263,11 +263,13 @@
-       mutex->file_name = "not yet reserved";
-       mutex->level = level;
- #endif /* UNIV_SYNC_DEBUG */
-+#ifdef UNIV_DEBUG
-       mutex->cfile_name = cfile_name;
-       mutex->cline = cline;
-+#endif /* UNIV_DEBUG */
-       mutex->count_os_wait = 0;
--#ifdef UNIV_DEBUG
-       mutex->cmutex_name=       cmutex_name;
-+#ifdef UNIV_DEBUG
-       mutex->count_using=       0;
-       mutex->mutex_type=        0;
-       mutex->lspent_time=       0;
-@@ -520,9 +522,9 @@
- #ifdef UNIV_SRV_PRINT_LATCH_WAITS
-       fprintf(stderr,
-               "Thread %lu spin wait mutex at %p"
--              " cfile %s cline %lu rnds %lu\n",
-+              " '%s' rnds %lu\n",
-               (ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
--              mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
-+              mutex->cmutex_name, (ulong) i);
- #endif
-       mutex_spin_round_count += i;
-@@ -597,9 +599,9 @@
- #ifdef UNIV_SRV_PRINT_LATCH_WAITS
-       fprintf(stderr,
--              "Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n",
-+              "Thread %lu OS wait mutex at %p '%s' rnds %lu\n",
-               (ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
--              mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
-+              mutex->cmutex_name, (ulong) i);
- #endif
-       mutex_os_wait_count++;
-@@ -901,9 +903,8 @@
-                               if (mutex->magic_n == MUTEX_MAGIC_N) {
-                                       fprintf(stderr,
--                                              "Mutex created at %s %lu\n",
--                                              mutex->cfile_name,
--                                              (ulong) mutex->cline);
-+                                              "Mutex '%s'\n",
-+                                              mutex->cmutex_name);
-                                       if (mutex_get_lock_word(mutex) != 0) {
-                                               const char*     file_name;
diff --git a/mysql-innodb_show_status.patch b/mysql-innodb_show_status.patch
deleted file mode 100644 (file)
index fa00b08..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-# name       : innodb_show_status.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -3515,14 +3515,16 @@
-       buf_pool_mutex_enter();
-       fprintf(file,
--              "Buffer pool size   %lu\n"
--              "Free buffers       %lu\n"
--              "Database pages     %lu\n"
--              "Old database pages %lu\n"
--              "Modified db pages  %lu\n"
-+              "Buffer pool size        %lu\n"
-+              "Buffer pool size, bytes %lu\n"
-+              "Free buffers            %lu\n"
-+              "Database pages          %lu\n"
-+              "Old database pages      %lu\n"
-+              "Modified db pages       %lu\n"
-               "Pending reads %lu\n"
-               "Pending writes: LRU %lu, flush list %lu, single page %lu\n",
-               (ulong) buf_pool->curr_size,
-+              (ulong) buf_pool->curr_size * UNIV_PAGE_SIZE,
-               (ulong) UT_LIST_GET_LEN(buf_pool->free),
-               (ulong) UT_LIST_GET_LEN(buf_pool->LRU),
-               (ulong) buf_pool->LRU_old_len,
---- a/storage/innodb_plugin/fil/fil0fil.c
-+++ b/storage/innodb_plugin/fil/fil0fil.c
-@@ -4833,3 +4833,30 @@
-       fil_system = NULL;
- }
-+
-+/*************************************************************************
-+Return local hash table informations. */
-+
-+ulint
-+fil_system_hash_cells(void)
-+/*=======================*/
-+{
-+       if (fil_system) {
-+               return (fil_system->spaces->n_cells
-+                       + fil_system->name_hash->n_cells);
-+       } else {
-+               return 0;
-+       }
-+}
-+
-+ulint
-+fil_system_hash_nodes(void)
-+/*=======================*/
-+{
-+       if (fil_system) {
-+               return (UT_LIST_GET_LEN(fil_system->space_list)
-+                       * (sizeof(fil_space_t) + MEM_BLOCK_HEADER_SIZE));
-+       } else {
-+               return 0;
-+       }
-+}
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -10807,6 +10807,16 @@
-   "Force InnoDB to not use next-key locking, to use only row-level locking.",
-   NULL, NULL, FALSE);
-+static MYSQL_SYSVAR_ULONG(show_verbose_locks, srv_show_verbose_locks,
-+  PLUGIN_VAR_OPCMDARG,
-+  "Whether to show records locked in SHOW INNODB STATUS.",
-+  NULL, NULL, 0, 0, 1, 0);
-+
-+static MYSQL_SYSVAR_ULONG(show_locks_held, srv_show_locks_held,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Number of locks held to print for each InnoDB transaction in SHOW INNODB STATUS.",
-+  NULL, NULL, 10, 0, 1000, 0);
-+
- #ifdef UNIV_LOG_ARCHIVE
- static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
-   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-@@ -10989,7 +10999,7 @@
- static MYSQL_SYSVAR_STR(version, innodb_version_str,
-   PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
--  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
-+  "Percona-InnoDB-plugin version", NULL, NULL, INNODB_VERSION_STR);
- static MYSQL_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
-   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-@@ -11080,6 +11090,8 @@
-   MYSQL_SYSVAR(thread_concurrency),
-   MYSQL_SYSVAR(thread_sleep_delay),
-   MYSQL_SYSVAR(autoinc_lock_mode),
-+  MYSQL_SYSVAR(show_verbose_locks),
-+  MYSQL_SYSVAR(show_locks_held),
-   MYSQL_SYSVAR(version),
-   MYSQL_SYSVAR(use_sys_malloc),
-   MYSQL_SYSVAR(change_buffering),
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -24,5 +24,6 @@
-        const char *link;
- }innodb_enhancements[] = {
- {"xtradb_show_enhancements","I_S.XTRADB_ENHANCEMENTS","","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_show_status","Improvements to SHOW INNODB STATUS","Memory information and lock info fixes","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/fil0fil.h
-+++ b/storage/innodb_plugin/include/fil0fil.h
-@@ -725,6 +725,17 @@
- /*============================*/
-       ulint           id);    /*!< in: space id */
-+/*************************************************************************
-+Return local hash table informations. */
-+
-+ulint
-+fil_system_hash_cells(void);
-+/*========================*/
-+
-+ulint
-+fil_system_hash_nodes(void);
-+/*========================*/
-+
- typedef       struct fil_space_struct fil_space_t;
- #endif
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -128,6 +128,9 @@
- extern char   srv_adaptive_flushing;
-+extern ulint    srv_show_locks_held;
-+extern ulint    srv_show_verbose_locks;
-+
- /* The sort order table of the MySQL latin1_swedish_ci character set
- collation */
- extern const byte*    srv_latin1_ordering;
---- a/storage/innodb_plugin/include/thr0loc.h
-+++ b/storage/innodb_plugin/include/thr0loc.h
-@@ -83,6 +83,17 @@
- thr_local_get_in_ibuf_field(void);
- /*=============================*/
-+/*************************************************************************
-+Return local hash table informations. */
-+
-+ulint
-+thr_local_hash_cells(void);
-+/*=======================*/
-+
-+ulint
-+thr_local_hash_nodes(void);
-+/*=======================*/
-+
- #ifndef UNIV_NONINL
- #include "thr0loc.ic"
- #endif
---- a/storage/innodb_plugin/lock/lock0lock.c
-+++ b/storage/innodb_plugin/lock/lock0lock.c
-@@ -4379,6 +4379,7 @@
-       putc('\n', file);
-+      if ( srv_show_verbose_locks ) {
-       block = buf_page_try_get(space, page_no, &mtr);
-       for (i = 0; i < lock_rec_get_n_bits(lock); ++i) {
-@@ -4405,6 +4406,7 @@
-               putc('\n', file);
-       }
-+      }
-       mtr_commit(&mtr);
-       if (UNIV_LIKELY_NULL(heap)) {
-@@ -4590,7 +4592,7 @@
-               }
-       }
--      if (!srv_print_innodb_lock_monitor) {
-+        if (!srv_print_innodb_lock_monitor && !srv_show_locks_held) {
-               nth_trx++;
-               goto loop;
-       }
-@@ -4662,8 +4664,8 @@
-       nth_lock++;
--      if (nth_lock >= 10) {
--              fputs("10 LOCKS PRINTED FOR THIS TRX:"
-+      if (nth_lock >= srv_show_locks_held) {
-+              fputs("TOO MANY LOCKS PRINTED FOR THIS TRX:"
-                     " SUPPRESSING FURTHER PRINTS\n",
-                     file);
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -171,6 +171,9 @@
- the checkpoints. */
- UNIV_INTERN char      srv_adaptive_flushing   = TRUE;
-+UNIV_INTERN ulint     srv_show_locks_held     = 10;
-+UNIV_INTERN ulint     srv_show_verbose_locks  = 0;
-+
- /** Maximum number of times allowed to conditionally acquire
- mutex before switching to blocking wait on the mutex */
- #define MAX_MUTEX_NOWAIT      20
-@@ -1707,6 +1710,13 @@
-       ulint   n_reserved;
-       ibool   ret;
-+      ulint   btr_search_sys_subtotal;
-+      ulint   lock_sys_subtotal;
-+      ulint   recv_sys_subtotal;
-+
-+      ulint   i;
-+      trx_t*  trx;
-+
-       mutex_enter(&srv_innodb_monitor_mutex);
-       current_time = time(NULL);
-@@ -1755,31 +1765,6 @@
-       mutex_exit(&dict_foreign_err_mutex);
--      /* Only if lock_print_info_summary proceeds correctly,
--      before we call the lock_print_info_all_transactions
--      to print all the lock information. */
--      ret = lock_print_info_summary(file, nowait);
--
--      if (ret) {
--              if (trx_start) {
--                      long    t = ftell(file);
--                      if (t < 0) {
--                              *trx_start = ULINT_UNDEFINED;
--                      } else {
--                              *trx_start = (ulint) t;
--                      }
--              }
--              lock_print_info_all_transactions(file);
--              if (trx_end) {
--                      long    t = ftell(file);
--                      if (t < 0) {
--                              *trx_end = ULINT_UNDEFINED;
--                      } else {
--                              *trx_end = (ulint) t;
--                      }
--              }
--      }
--
-       fputs("--------\n"
-             "FILE I/O\n"
-             "--------\n", file);
-@@ -1810,10 +1795,84 @@
-             "BUFFER POOL AND MEMORY\n"
-             "----------------------\n", file);
-       fprintf(file,
--              "Total memory allocated " ULINTPF
--              "; in additional pool allocated " ULINTPF "\n",
--              ut_total_allocated_memory,
--              mem_pool_get_reserved(mem_comm_pool));
-+                      "Total memory allocated " ULINTPF
-+                      "; in additional pool allocated " ULINTPF "\n",
-+                      ut_total_allocated_memory,
-+                      mem_pool_get_reserved(mem_comm_pool));
-+      /* Calcurate reserved memories */
-+      if (btr_search_sys && btr_search_sys->hash_index->heap) {
-+              btr_search_sys_subtotal = mem_heap_get_size(btr_search_sys->hash_index->heap);
-+      } else {
-+              btr_search_sys_subtotal = 0;
-+              for (i=0; i < btr_search_sys->hash_index->n_mutexes; i++) {
-+                      btr_search_sys_subtotal += mem_heap_get_size(btr_search_sys->hash_index->heaps[i]);
-+              }
-+      }
-+
-+      lock_sys_subtotal = 0;
-+      if (trx_sys) {
-+              mutex_enter(&kernel_mutex);
-+              trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list);
-+              while (trx) {
-+                      lock_sys_subtotal += ((trx->lock_heap) ? mem_heap_get_size(trx->lock_heap) : 0);
-+                      trx = UT_LIST_GET_NEXT(mysql_trx_list, trx);
-+              }
-+              mutex_exit(&kernel_mutex);
-+      }
-+
-+      recv_sys_subtotal = ((recv_sys && recv_sys->addr_hash)
-+                      ? mem_heap_get_size(recv_sys->heap) : 0);
-+
-+      fprintf(file,
-+                      "Internal hash tables (constant factor + variable factor)\n"
-+                      "    Adaptive hash index %lu \t(%lu + %lu)\n"
-+                      "    Page hash           %lu\n"
-+                      "    Dictionary cache    %lu \t(%lu + %lu)\n"
-+                      "    File system         %lu \t(%lu + %lu)\n"
-+                      "    Lock system         %lu \t(%lu + %lu)\n"
-+                      "    Recovery system     %lu \t(%lu + %lu)\n"
-+                      "    Threads             %lu \t(%lu + %lu)\n",
-+
-+                      (ulong) (btr_search_sys
-+                              ? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0)
-+                      + btr_search_sys_subtotal,
-+                      (ulong) (btr_search_sys
-+                              ? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0),
-+                      (ulong) btr_search_sys_subtotal,
-+
-+                      (ulong) (buf_pool->page_hash->n_cells * sizeof(hash_cell_t)),
-+
-+                      (ulong) (dict_sys ? ((dict_sys->table_hash->n_cells
-+                                              + dict_sys->table_id_hash->n_cells
-+                                              ) * sizeof(hash_cell_t)
-+                                      + dict_sys->size) : 0),
-+                      (ulong) (dict_sys ? ((dict_sys->table_hash->n_cells
-+                                                      + dict_sys->table_id_hash->n_cells
-+                                                      ) * sizeof(hash_cell_t)) : 0),
-+                      (ulong) (dict_sys ? (dict_sys->size) : 0),
-+
-+                      (ulong) (fil_system_hash_cells() * sizeof(hash_cell_t)
-+                                      + fil_system_hash_nodes()),
-+                      (ulong) (fil_system_hash_cells() * sizeof(hash_cell_t)),
-+                      (ulong) fil_system_hash_nodes(),
-+
-+                      (ulong) ((lock_sys ? (lock_sys->rec_hash->n_cells * sizeof(hash_cell_t)) : 0)
-+                                      + lock_sys_subtotal),
-+                      (ulong) (lock_sys ? (lock_sys->rec_hash->n_cells * sizeof(hash_cell_t)) : 0),
-+                      (ulong) lock_sys_subtotal,
-+
-+                      (ulong) (((recv_sys && recv_sys->addr_hash)
-+                                              ? (recv_sys->addr_hash->n_cells * sizeof(hash_cell_t)) : 0)
-+                                      + recv_sys_subtotal),
-+                      (ulong) ((recv_sys && recv_sys->addr_hash)
-+                                      ? (recv_sys->addr_hash->n_cells * sizeof(hash_cell_t)) : 0),
-+                      (ulong) recv_sys_subtotal,
-+
-+                      (ulong) (thr_local_hash_cells() * sizeof(hash_cell_t)
-+                                      + thr_local_hash_nodes()),
-+                      (ulong) (thr_local_hash_cells() * sizeof(hash_cell_t)),
-+                      (ulong) thr_local_hash_nodes());
-+
-       fprintf(file, "Dictionary memory allocated " ULINTPF "\n",
-               dict_sys->size);
-@@ -1872,6 +1931,31 @@
-       srv_n_rows_deleted_old = srv_n_rows_deleted;
-       srv_n_rows_read_old = srv_n_rows_read;
-+      /* Only if lock_print_info_summary proceeds correctly,
-+      before we call the lock_print_info_all_transactions
-+      to print all the lock information. */
-+      ret = lock_print_info_summary(file, nowait);
-+
-+      if (ret) {
-+              if (trx_start) {
-+                      long    t = ftell(file);
-+                      if (t < 0) {
-+                              *trx_start = ULINT_UNDEFINED;
-+                      } else {
-+                              *trx_start = (ulint) t;
-+                      }
-+              }
-+              lock_print_info_all_transactions(file);
-+              if (trx_end) {
-+                      long    t = ftell(file);
-+                      if (t < 0) {
-+                              *trx_end = ULINT_UNDEFINED;
-+                      } else {
-+                              *trx_end = (ulint) t;
-+                      }
-+              }
-+      }
-+
-       fputs("----------------------------\n"
-             "END OF INNODB MONITOR OUTPUT\n"
-             "============================\n", file);
---- a/storage/innodb_plugin/sync/sync0arr.c
-+++ b/storage/innodb_plugin/sync/sync0arr.c
-@@ -471,7 +471,7 @@
-       fprintf(file,
-               "--Thread %lu has waited at %s line %lu"
--              " for %.2f seconds the semaphore:\n",
-+              " for %#.5g seconds the semaphore:\n",
-               (ulong) os_thread_pf(cell->thread), cell->file,
-               (ulong) cell->line,
-               difftime(time(NULL), cell->reservation_time));
---- a/storage/innodb_plugin/thr/thr0loc.c
-+++ b/storage/innodb_plugin/thr/thr0loc.c
-@@ -49,6 +49,7 @@
- /** The hash table. The module is not yet initialized when it is NULL. */
- static hash_table_t*  thr_local_hash  = NULL;
-+ulint         thr_local_hash_n_nodes = 0;
- /** Thread local data */
- typedef struct thr_local_struct thr_local_t;
-@@ -216,6 +217,7 @@
-                   os_thread_pf(os_thread_get_curr_id()),
-                   local);
-+      thr_local_hash_n_nodes++;
-       mutex_exit(&thr_local_mutex);
- }
-@@ -244,6 +246,7 @@
-       HASH_DELETE(thr_local_t, hash, thr_local_hash,
-                   os_thread_pf(id), local);
-+      thr_local_hash_n_nodes--;
-       mutex_exit(&thr_local_mutex);
-@@ -299,3 +302,29 @@
-       hash_table_free(thr_local_hash);
-       thr_local_hash = NULL;
- }
-+
-+/*************************************************************************
-+Return local hash table informations. */
-+
-+ulint
-+thr_local_hash_cells(void)
-+/*======================*/
-+{
-+      if (thr_local_hash) {
-+              return (thr_local_hash->n_cells);
-+      } else {
-+              return 0;
-+      }
-+}
-+
-+ulint
-+thr_local_hash_nodes(void)
-+/*======================*/
-+{
-+      if (thr_local_hash) {
-+              return (thr_local_hash_n_nodes
-+                      * (sizeof(thr_local_t) + MEM_BLOCK_HEADER_SIZE));
-+      } else {
-+              return 0;
-+      }
-+}
diff --git a/mysql-innodb_show_sys_tables.patch b/mysql-innodb_show_sys_tables.patch
deleted file mode 100644 (file)
index 479a2d8..0000000
+++ /dev/null
@@ -1,736 +0,0 @@
-# name       : innodb_show_sys_tables.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -11874,6 +11874,9 @@
- i_s_innodb_table_stats,
- i_s_innodb_index_stats,
- i_s_innodb_admin_command,
-+i_s_innodb_sys_tables,
-+i_s_innodb_sys_indexes,
-+i_s_innodb_sys_stats,
- i_s_innodb_patches
- mysql_declare_plugin_end;
---- a/storage/innodb_plugin/handler/i_s.cc
-+++ b/storage/innodb_plugin/handler/i_s.cc
-@@ -46,6 +46,7 @@
- #include "trx0rseg.h" /* for trx_rseg_struct */
- #include "trx0sys.h" /* for trx_sys */
- #include "dict0dict.h" /* for dict_sys */
-+#include "btr0pcur.h"
- #include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
- }
-@@ -3114,3 +3115,671 @@
-       STRUCT_FLD(system_vars, NULL),
-       STRUCT_FLD(__reserved1, NULL)
- };
-+
-+static ST_FIELD_INFO  i_s_innodb_sys_tables_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "SCHEMA"),
-+       STRUCT_FLD(field_length,       NAME_LEN),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "NAME"),
-+       STRUCT_FLD(field_length,       NAME_LEN),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "ID"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "N_COLS"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "TYPE"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "MIX_ID"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "MIX_LEN"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "CLUSTER_NAME"),
-+       STRUCT_FLD(field_length,       NAME_LEN),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "SPACE"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+       END_OF_ST_FIELD_INFO
-+};
-+
-+static ST_FIELD_INFO  i_s_innodb_sys_indexes_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "TABLE_ID"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "ID"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "NAME"),
-+       STRUCT_FLD(field_length,       NAME_LEN),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "N_FIELDS"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "TYPE"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "SPACE"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "PAGE_NO"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+       END_OF_ST_FIELD_INFO
-+};
-+
-+static ST_FIELD_INFO  i_s_innodb_sys_stats_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "INDEX_ID"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "KEY_COLS"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "DIFF_VALS"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "NON_NULL_VALS"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      END_OF_ST_FIELD_INFO
-+};
-+
-+static
-+int
-+copy_string_field(
-+/*==============*/
-+      TABLE*                  table,
-+      int                     table_field,
-+      const rec_t*            rec,
-+      int                     rec_field)
-+{
-+      int             status;
-+      const byte*     data;
-+      ulint           len;
-+
-+      /*fprintf(stderr, "copy_string_field %d %d\n", table_field, rec_field);*/
-+
-+      data = rec_get_nth_field_old(rec, rec_field, &len);
-+      if (len == UNIV_SQL_NULL) {
-+              table->field[table_field]->set_null();
-+              status = 0; /* success */
-+      } else {
-+              table->field[table_field]->set_notnull();
-+              status = table->field[table_field]->store(
-+                      (char *) data, len, system_charset_info);
-+      }
-+
-+      return status;
-+}
-+
-+static
-+int
-+copy_name_fields(
-+/*=============*/
-+      TABLE*                  table,
-+      int                     table_field_1,
-+      const rec_t*            rec,
-+      int                     rec_field)
-+{
-+      int             status;
-+      const byte*     data;
-+      ulint           len;
-+
-+      data = rec_get_nth_field_old(rec, rec_field, &len);
-+      if (len == UNIV_SQL_NULL) {
-+              table->field[table_field_1]->set_null();
-+              table->field[table_field_1 + 1]->set_null();
-+              status = 0; /* success */
-+      } else {
-+              char    buf[NAME_LEN * 2 + 2];
-+              char*   ptr;
-+
-+              if (len > NAME_LEN * 2 + 1) {
-+                      table->field[table_field_1]->set_null();
-+                      status = field_store_string(table->field[table_field_1 + 1],
-+                                                  "###TOO LONG NAME###");
-+                      goto end_func;
-+              }
-+
-+              strncpy(buf, (char*)data, len);
-+              buf[len] = '\0';
-+              ptr = strchr(buf, '/');
-+              if (ptr) {
-+                      *ptr = '\0';
-+                      ++ptr;
-+
-+                      status = field_store_string(table->field[table_field_1], buf);
-+                      status |= field_store_string(table->field[table_field_1 + 1], ptr);
-+              } else {
-+                      table->field[table_field_1]->set_null();
-+                      status = field_store_string(table->field[table_field_1 + 1], buf);
-+              }
-+      }
-+
-+end_func:
-+      return status;
-+}
-+
-+static
-+int
-+copy_int_field(
-+/*===========*/
-+      TABLE*                  table,
-+      int                     table_field,
-+      const rec_t*            rec,
-+      int                     rec_field)
-+{
-+      int             status;
-+      const byte*     data;
-+      ulint           len;
-+
-+      /*fprintf(stderr, "copy_int_field %d %d\n", table_field, rec_field);*/
-+
-+      data = rec_get_nth_field_old(rec, rec_field, &len);
-+      if (len == UNIV_SQL_NULL) {
-+              table->field[table_field]->set_null();
-+              status = 0; /* success */
-+      } else {
-+              table->field[table_field]->set_notnull();
-+              status = table->field[table_field]->store(
-+                      mach_read_from_4(data), true);
-+      }
-+
-+      return status;
-+}
-+
-+static
-+int
-+copy_id_field(
-+/*==========*/
-+      TABLE*                  table,
-+      int                     table_field,
-+      const rec_t*            rec,
-+      int                     rec_field)
-+{
-+      int             status;
-+      const byte*     data;
-+      ulint           len;
-+
-+      /*fprintf(stderr, "copy_id_field %d %d\n", table_field, rec_field);*/
-+
-+      data = rec_get_nth_field_old(rec, rec_field, &len);
-+      if (len == UNIV_SQL_NULL) {
-+              table->field[table_field]->set_null();
-+              status = 0; /* success */
-+      } else {
-+              table->field[table_field]->set_notnull();
-+              status = table->field[table_field]->store(
-+                      ut_conv_dulint_to_longlong(mach_read_from_8(data)), true);
-+      }
-+
-+      return status;
-+}
-+
-+static
-+int
-+copy_sys_tables_rec(
-+/*================*/
-+      TABLE*                  table,
-+      const dict_index_t*     index,
-+      const rec_t*            rec
-+)
-+{
-+      int     status;
-+      int     field;
-+
-+      /* NAME */
-+      field = dict_index_get_nth_col_pos(index, 0);
-+      status = copy_name_fields(table, 0, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* ID */
-+      field = dict_index_get_nth_col_pos(index, 1);
-+      status = copy_id_field(table, 2, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* N_COLS */
-+      field = dict_index_get_nth_col_pos(index, 2);
-+      status = copy_int_field(table, 3, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* TYPE */
-+      field = dict_index_get_nth_col_pos(index, 3);
-+      status = copy_int_field(table, 4, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* MIX_ID */
-+      field = dict_index_get_nth_col_pos(index, 4);
-+      status = copy_id_field(table, 5, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* MIX_LEN */
-+      field = dict_index_get_nth_col_pos(index, 5);
-+      status = copy_int_field(table, 6, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* CLUSTER_NAME */
-+      field = dict_index_get_nth_col_pos(index, 6);
-+      status = copy_string_field(table, 7, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* SPACE */
-+      field = dict_index_get_nth_col_pos(index, 7);
-+      status = copy_int_field(table, 8, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+
-+      return 0;
-+}
-+
-+static
-+int
-+copy_sys_indexes_rec(
-+/*=================*/
-+      TABLE*                  table,
-+      const dict_index_t*     index,
-+      const rec_t*            rec
-+)
-+{
-+      int     status;
-+      int     field;
-+
-+      /* TABLE_ID */
-+      field = dict_index_get_nth_col_pos(index, 0);
-+      status = copy_id_field(table, 0, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* ID */
-+      field = dict_index_get_nth_col_pos(index, 1);
-+      status = copy_id_field(table, 1, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* NAME */
-+      field = dict_index_get_nth_col_pos(index, 2);
-+      status = copy_string_field(table, 2, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* N_FIELDS */
-+      field = dict_index_get_nth_col_pos(index, 3);
-+      status = copy_int_field(table, 3, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* TYPE */
-+      field = dict_index_get_nth_col_pos(index, 4);
-+      status = copy_int_field(table, 4, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* SPACE */
-+      field = dict_index_get_nth_col_pos(index, 5);
-+      status = copy_int_field(table, 5, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* PAGE_NO */
-+      field = dict_index_get_nth_col_pos(index, 6);
-+      status = copy_int_field(table, 6, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+
-+      return 0;
-+}
-+
-+static
-+int
-+copy_sys_stats_rec(
-+/*===============*/
-+      TABLE*                  table,
-+      const dict_index_t*     index,
-+      const rec_t*            rec
-+)
-+{
-+      int     status;
-+      int     field;
-+      ulint   n_fields;
-+
-+      n_fields = rec_get_n_fields_old(rec);
-+
-+      /* INDEX_ID */
-+      field = dict_index_get_nth_col_pos(index, 0);
-+      status = copy_id_field(table, 0, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* KEY_COLS */
-+      field = dict_index_get_nth_col_pos(index, 1);
-+      status = copy_int_field(table, 1, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* DIFF_VALS */
-+      field = dict_index_get_nth_col_pos(index, 2);
-+      status = copy_id_field(table, 2, rec, field);
-+      if (status) {
-+              return status;
-+      }
-+      /* NON_NULL_VALS */
-+      if (n_fields < 6) {
-+              table->field[3]->set_null();
-+      } else {
-+              field = dict_index_get_nth_col_pos(index, 3);
-+              status = copy_id_field(table, 3, rec, field);
-+              if (status) {
-+                      return status;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static
-+int
-+i_s_innodb_schema_table_fill(
-+/*=========================*/
-+      THD*            thd,
-+      TABLE_LIST*     tables,
-+      COND*           cond)
-+{
-+      int             status  = 0;
-+      TABLE*          table   = (TABLE *) tables->table;
-+      const char*     table_name = tables->schema_table_name;
-+      dict_table_t*   innodb_table;
-+      dict_index_t*   index;
-+      btr_pcur_t      pcur;
-+      const rec_t*    rec;
-+      mtr_t           mtr;
-+      int             id;
-+
-+      DBUG_ENTER("i_s_innodb_schema_table_fill");
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+              DBUG_RETURN(0);
-+      }
-+
-+      if (innobase_strcasecmp(table_name, "innodb_sys_tables") == 0) {
-+              id = 0;
-+      } else if (innobase_strcasecmp(table_name, "innodb_sys_indexes") == 0) {
-+              id = 1;
-+      } else if (innobase_strcasecmp(table_name, "innodb_sys_stats") == 0) {
-+              id = 2;
-+      } else {
-+              DBUG_RETURN(1);
-+      }
-+
-+
-+      RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
-+
-+      mutex_enter(&(dict_sys->mutex));
-+
-+      mtr_start(&mtr);
-+
-+      if (id == 0) {
-+              innodb_table = dict_table_get_low("SYS_TABLES");
-+      } else if (id == 1) {
-+              innodb_table = dict_table_get_low("SYS_INDEXES");
-+      } else {
-+              innodb_table = dict_table_get_low("SYS_STATS");
-+      }
-+      index = UT_LIST_GET_FIRST(innodb_table->indexes);
-+
-+      btr_pcur_open_at_index_side(TRUE, index, BTR_SEARCH_LEAF, &pcur,
-+                                  TRUE, &mtr);
-+      for (;;) {
-+              btr_pcur_move_to_next_user_rec(&pcur, &mtr);
-+
-+              rec = btr_pcur_get_rec(&pcur);
-+              if (!btr_pcur_is_on_user_rec(&pcur)) {
-+                      /* end of index */
-+                      break;
-+              }
-+
-+              btr_pcur_store_position(&pcur, &mtr);
-+
-+              if (rec_get_deleted_flag(rec, 0)) {
-+                      /* record marked as deleted */
-+                      goto next_record;
-+              }
-+
-+              if (id == 0) {
-+                      status = copy_sys_tables_rec(table, index, rec);
-+              } else if (id == 1) {
-+                      status = copy_sys_indexes_rec(table, index, rec);
-+              } else {
-+                      status = copy_sys_stats_rec(table, index, rec);
-+              }
-+              if (status) {
-+                      break;
-+              }
-+
-+              status = schema_table_store_record(thd, table);
-+              if (status) {
-+                      break;
-+              }
-+next_record:
-+              mtr_commit(&mtr);
-+
-+              mtr_start(&mtr);
-+              btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr);
-+      }
-+
-+      btr_pcur_close(&pcur);
-+      mtr_commit(&mtr);
-+
-+      mutex_exit(&(dict_sys->mutex));
-+
-+      DBUG_RETURN(status);
-+}
-+
-+static
-+int
-+i_s_innodb_sys_tables_init(
-+/*=======================*/
-+      void*   p)
-+{
-+      DBUG_ENTER("i_s_innodb_sys_tables_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_sys_tables_info;
-+      schema->fill_table = i_s_innodb_schema_table_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+static
-+int
-+i_s_innodb_sys_indexes_init(
-+/*========================*/
-+      void*   p)
-+{
-+      DBUG_ENTER("i_s_innodb_sys_indexes_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_sys_indexes_info;
-+      schema->fill_table = i_s_innodb_schema_table_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+static
-+int
-+i_s_innodb_sys_stats_init(
-+/*======================*/
-+      void*   p)
-+{
-+      DBUG_ENTER("i_s_innodb_sys_stats_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_sys_stats_info;
-+      schema->fill_table = i_s_innodb_schema_table_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+UNIV_INTERN struct st_mysql_plugin   i_s_innodb_sys_tables =
-+{
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+      STRUCT_FLD(info, &i_s_info),
-+      STRUCT_FLD(name, "INNODB_SYS_TABLES"),
-+      STRUCT_FLD(author, "Percona"),
-+      STRUCT_FLD(descr, "InnoDB SYS_TABLES table"),
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+      STRUCT_FLD(init, i_s_innodb_sys_tables_init),
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+      STRUCT_FLD(status_vars, NULL),
-+      STRUCT_FLD(system_vars, NULL),
-+      STRUCT_FLD(__reserved1, NULL)
-+};
-+
-+UNIV_INTERN struct st_mysql_plugin   i_s_innodb_sys_indexes =
-+{
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+      STRUCT_FLD(info, &i_s_info),
-+      STRUCT_FLD(name, "INNODB_SYS_INDEXES"),
-+      STRUCT_FLD(author, "Percona"),
-+      STRUCT_FLD(descr, "InnoDB SYS_INDEXES table"),
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+      STRUCT_FLD(init, i_s_innodb_sys_indexes_init),
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+      STRUCT_FLD(status_vars, NULL),
-+      STRUCT_FLD(system_vars, NULL),
-+      STRUCT_FLD(__reserved1, NULL)
-+};
-+
-+UNIV_INTERN struct st_mysql_plugin   i_s_innodb_sys_stats =
-+{
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+      STRUCT_FLD(info, &i_s_info),
-+      STRUCT_FLD(name, "INNODB_SYS_STATS"),
-+      STRUCT_FLD(author, "Percona"),
-+      STRUCT_FLD(descr, "InnoDB SYS_STATS table"),
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+      STRUCT_FLD(init, i_s_innodb_sys_stats_init),
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+      STRUCT_FLD(status_vars, NULL),
-+      STRUCT_FLD(system_vars, NULL),
-+      STRUCT_FLD(__reserved1, NULL)
-+};
---- a/storage/innodb_plugin/handler/i_s.h
-+++ b/storage/innodb_plugin/handler/i_s.h
-@@ -41,5 +41,8 @@
- extern struct st_mysql_plugin i_s_innodb_table_stats;
- extern struct st_mysql_plugin i_s_innodb_index_stats;
- extern struct st_mysql_plugin i_s_innodb_admin_command;
-+extern struct st_mysql_plugin   i_s_innodb_sys_tables;
-+extern struct st_mysql_plugin   i_s_innodb_sys_indexes;
-+extern struct st_mysql_plugin i_s_innodb_sys_stats;
- #endif /* i_s_h */
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -46,5 +46,6 @@
- {"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_sys_tables_sys_indexes","Expose InnoDB SYS_TABLES and SYS_INDEXES schema tables","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- /dev/null
-+++ b/mysql-test/r/percona_innodb_use_sys_stats_table.result
-@@ -0,0 +1,3 @@
-+show variables like 'innodb_use_sys_stats%';
-+Variable_name Value
-+innodb_use_sys_stats_table    ON
---- /dev/null
-+++ b/mysql-test/t/percona_innodb_use_sys_stats_table-master.opt
-@@ -0,0 +1 @@
-+--innodb_use_sys_stats_table
---- /dev/null
-+++ b/mysql-test/t/percona_innodb_use_sys_stats_table.test
-@@ -0,0 +1,2 @@
-+--source include/have_innodb.inc
-+show variables like 'innodb_use_sys_stats%';
diff --git a/mysql-innodb_split_buf_pool_mutex.patch b/mysql-innodb_split_buf_pool_mutex.patch
deleted file mode 100644 (file)
index f3366cf..0000000
+++ /dev/null
@@ -1,3951 +0,0 @@
-# name       : innodb_split_buf_pool_mutex.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/btr/btr0cur.c
-+++ b/storage/innodb_plugin/btr/btr0cur.c
-@@ -3853,7 +3853,8 @@
-       mtr_commit(mtr);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-       mutex_enter(&block->mutex);
-       /* Only free the block if it is still allocated to
-@@ -3864,16 +3865,21 @@
-           && buf_block_get_space(block) == space
-           && buf_block_get_page_no(block) == page_no) {
--              if (!buf_LRU_free_block(&block->page, all)
--                  && all && block->page.zip.data) {
-+              if (!buf_LRU_free_block(&block->page, all, TRUE)
-+                  && all && block->page.zip.data
-+                  /* Now, buf_LRU_free_block() may release mutex temporarily */
-+                  && buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
-+                  && buf_block_get_space(block) == space
-+                  && buf_block_get_page_no(block) == page_no) {
-                       /* Attempt to deallocate the uncompressed page
-                       if the whole block cannot be deallocted. */
--                      buf_LRU_free_block(&block->page, FALSE);
-+                      buf_LRU_free_block(&block->page, FALSE, TRUE);
-               }
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-       mutex_exit(&block->mutex);
- }
---- a/storage/innodb_plugin/btr/btr0sea.c
-+++ b/storage/innodb_plugin/btr/btr0sea.c
-@@ -1925,7 +1925,8 @@
-       rec_offs_init(offsets_);
-       rw_lock_x_lock(&btr_search_latch);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      rw_lock_x_lock(&page_hash_latch);
-       cell_count = hash_get_n_cells(btr_search_sys->hash_index);
-@@ -1933,11 +1934,13 @@
-               /* 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)) {
--                      buf_pool_mutex_exit();
-+                      //buf_pool_mutex_exit();
-+                      rw_lock_x_unlock(&page_hash_latch);
-                       rw_lock_x_unlock(&btr_search_latch);
-                       os_thread_yield();
-                       rw_lock_x_lock(&btr_search_latch);
--                      buf_pool_mutex_enter();
-+                      //buf_pool_mutex_enter();
-+                      rw_lock_x_lock(&page_hash_latch);
-               }
-               node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
-@@ -2044,11 +2047,13 @@
-               /* We release btr_search_latch every once in a while to
-               give other queries a chance to run. */
-               if (i != 0) {
--                      buf_pool_mutex_exit();
-+                      //buf_pool_mutex_exit();
-+                      rw_lock_x_unlock(&page_hash_latch);
-                       rw_lock_x_unlock(&btr_search_latch);
-                       os_thread_yield();
-                       rw_lock_x_lock(&btr_search_latch);
--                      buf_pool_mutex_enter();
-+                      //buf_pool_mutex_enter();
-+                      rw_lock_x_lock(&page_hash_latch);
-               }
-               if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
-@@ -2056,7 +2061,8 @@
-               }
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_x_unlock(&page_hash_latch);
-       rw_lock_x_unlock(&btr_search_latch);
-       if (UNIV_LIKELY_NULL(heap)) {
-               mem_heap_free(heap);
---- a/storage/innodb_plugin/buf/buf0buddy.c
-+++ b/storage/innodb_plugin/buf/buf0buddy.c
-@@ -47,7 +47,7 @@
- /** Validate a given zip_free list. */
- #define BUF_BUDDY_LIST_VALIDATE(i)                            \
--      UT_LIST_VALIDATE(list, buf_page_t,                      \
-+      UT_LIST_VALIDATE(zip_list, buf_page_t,                  \
-                        buf_pool->zip_free[i],                 \
-                        ut_ad(buf_page_get_state(              \
-                                      ut_list_node_313)        \
-@@ -84,10 +84,11 @@
-       buf_page_t*     bpage,  /*!< in,own: block to be freed */
-       ulint           i)      /*!< in: index of buf_pool->zip_free[] */
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&zip_free_mutex));
-       ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
-       ut_ad(buf_pool->zip_free[i].start != bpage);
--      UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage);
-+      UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_free[i], bpage);
- }
- /**********************************************************************//**
-@@ -100,16 +101,17 @@
-       ulint           i)      /*!< in: index of buf_pool->zip_free[] */
- {
- #ifdef UNIV_DEBUG
--      buf_page_t*     prev = UT_LIST_GET_PREV(list, bpage);
--      buf_page_t*     next = UT_LIST_GET_NEXT(list, bpage);
-+      buf_page_t*     prev = UT_LIST_GET_PREV(zip_list, bpage);
-+      buf_page_t*     next = UT_LIST_GET_NEXT(zip_list, bpage);
-       ut_ad(!prev || buf_page_get_state(prev) == BUF_BLOCK_ZIP_FREE);
-       ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
- #endif /* UNIV_DEBUG */
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&zip_free_mutex));
-       ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
--      UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
-+      UT_LIST_REMOVE(zip_list, buf_pool->zip_free[i], bpage);
- }
- /**********************************************************************//**
-@@ -123,7 +125,8 @@
- {
-       buf_page_t*     bpage;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&zip_free_mutex));
-       ut_a(i < BUF_BUDDY_SIZES);
-       ut_a(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
-@@ -164,16 +167,19 @@
- void
- buf_buddy_block_free(
- /*=================*/
--      void*   buf)    /*!< in: buffer frame to deallocate */
-+      void*   buf,    /*!< in: buffer frame to deallocate */
-+      ibool   have_page_hash_mutex)
- {
-       const ulint     fold    = BUF_POOL_ZIP_FOLD_PTR(buf);
-       buf_page_t*     bpage;
-       buf_block_t*    block;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(!mutex_own(&buf_pool_zip_mutex));
-       ut_a(!ut_align_offset(buf, UNIV_PAGE_SIZE));
-+      mutex_enter(&zip_hash_mutex);
-+
-       HASH_SEARCH(hash, buf_pool->zip_hash, fold, buf_page_t*, bpage,
-                   ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_MEMORY
-                         && bpage->in_zip_hash && !bpage->in_page_hash),
-@@ -185,12 +191,14 @@
-       ut_d(bpage->in_zip_hash = FALSE);
-       HASH_DELETE(buf_page_t, hash, buf_pool->zip_hash, fold, bpage);
-+      mutex_exit(&zip_hash_mutex);
-+
-       ut_d(memset(buf, 0, UNIV_PAGE_SIZE));
-       UNIV_MEM_INVALID(buf, UNIV_PAGE_SIZE);
-       block = (buf_block_t*) bpage;
-       mutex_enter(&block->mutex);
--      buf_LRU_block_free_non_file_page(block);
-+      buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
-       mutex_exit(&block->mutex);
-       ut_ad(buf_buddy_n_frames > 0);
-@@ -206,7 +214,7 @@
-       buf_block_t*    block)  /*!< in: buffer frame to allocate */
- {
-       const ulint     fold = BUF_POOL_ZIP_FOLD(block);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(!mutex_own(&buf_pool_zip_mutex));
-       ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
-@@ -218,7 +226,10 @@
-       ut_ad(!block->page.in_page_hash);
-       ut_ad(!block->page.in_zip_hash);
-       ut_d(block->page.in_zip_hash = TRUE);
-+
-+      mutex_enter(&zip_hash_mutex);
-       HASH_INSERT(buf_page_t, hash, buf_pool->zip_hash, fold, &block->page);
-+      mutex_exit(&zip_hash_mutex);
-       ut_d(buf_buddy_n_frames++);
- }
-@@ -269,25 +280,29 @@
- /*================*/
-       ulint   i,      /*!< in: index of buf_pool->zip_free[],
-                       or BUF_BUDDY_SIZES */
--      ibool*  lru)    /*!< in: pointer to a variable that will be assigned
-+      ibool*  lru,    /*!< in: pointer to a variable that will be assigned
-                       TRUE if storage was allocated from the LRU list
-                       and buf_pool_mutex was temporarily released */
-+      ibool   have_page_hash_mutex)
- {
-       buf_block_t*    block;
-       ut_ad(lru);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(!mutex_own(&buf_pool_zip_mutex));
-       ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
-       if (i < BUF_BUDDY_SIZES) {
-               /* Try to allocate from the buddy system. */
-+              mutex_enter(&zip_free_mutex);
-               block = buf_buddy_alloc_zip(i);
-               if (block) {
-                       goto func_exit;
-               }
-+
-+              mutex_exit(&zip_free_mutex);
-       }
-       /* Try allocating from the buf_pool->free list. */
-@@ -299,18 +314,29 @@
-       }
-       /* Try replacing an uncompressed page in the buffer pool. */
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-+      if (have_page_hash_mutex) {
-+              rw_lock_x_unlock(&page_hash_latch);
-+      }
-       block = buf_LRU_get_free_block();
-       *lru = TRUE;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-+      if (have_page_hash_mutex) {
-+              rw_lock_x_lock(&page_hash_latch);
-+      }
- alloc_big:
-       buf_buddy_block_register(block);
-+      mutex_enter(&zip_free_mutex);
-       block = buf_buddy_alloc_from(block->frame, i, BUF_BUDDY_SIZES);
- func_exit:
-       buf_buddy_stat[i].used++;
-+      mutex_exit(&zip_free_mutex);
-+
-       return(block);
- }
-@@ -323,7 +349,8 @@
- /*===============*/
-       void*   src,    /*!< in: block to relocate */
-       void*   dst,    /*!< in: free block to relocate to */
--      ulint   i)      /*!< in: index of buf_pool->zip_free[] */
-+      ulint   i,      /*!< in: index of buf_pool->zip_free[] */
-+      ibool   have_page_hash_mutex)
- {
-       buf_page_t*     bpage;
-       const ulint     size    = BUF_BUDDY_LOW << i;
-@@ -332,13 +359,20 @@
-       ulint           space;
-       ulint           page_no;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&zip_free_mutex));
-       ut_ad(!mutex_own(&buf_pool_zip_mutex));
-       ut_ad(!ut_align_offset(src, size));
-       ut_ad(!ut_align_offset(dst, size));
-       ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
-       UNIV_MEM_ASSERT_W(dst, size);
-+      if (!have_page_hash_mutex) {
-+              mutex_exit(&zip_free_mutex);
-+              mutex_enter(&LRU_list_mutex);
-+              rw_lock_x_lock(&page_hash_latch);
-+      }
-+
-       /* We assume that all memory from buf_buddy_alloc()
-       is used for compressed page frames. */
-@@ -372,6 +406,11 @@
-               added to buf_pool->page_hash yet.  Obviously,
-               it cannot be relocated. */
-+              if (!have_page_hash_mutex) {
-+                      mutex_enter(&zip_free_mutex);
-+                      mutex_exit(&LRU_list_mutex);
-+                      rw_lock_x_unlock(&page_hash_latch);
-+              }
-               return(FALSE);
-       }
-@@ -381,18 +420,27 @@
-               For the sake of simplicity, give up. */
-               ut_ad(page_zip_get_size(&bpage->zip) < size);
-+              if (!have_page_hash_mutex) {
-+                      mutex_enter(&zip_free_mutex);
-+                      mutex_exit(&LRU_list_mutex);
-+                      rw_lock_x_unlock(&page_hash_latch);
-+              }
-               return(FALSE);
-       }
-+      /* To keep latch order */
-+      if (have_page_hash_mutex)
-+              mutex_exit(&zip_free_mutex);
-+
-       /* The block must have been allocated, but it may
-       contain uninitialized data. */
-       UNIV_MEM_ASSERT_W(src, size);
--      mutex = buf_page_get_mutex(bpage);
-+      mutex = buf_page_get_mutex_enter(bpage);
--      mutex_enter(mutex);
-+      mutex_enter(&zip_free_mutex);
--      if (buf_page_can_relocate(bpage)) {
-+      if (mutex && buf_page_can_relocate(bpage)) {
-               /* Relocate the compressed page. */
-               ut_a(bpage->zip.data == src);
-               memcpy(dst, src, size);
-@@ -406,10 +454,22 @@
-                       buddy_stat->relocated_usec
-                               += ut_time_us(NULL) - usec;
-               }
-+
-+              if (!have_page_hash_mutex) {
-+                      mutex_exit(&LRU_list_mutex);
-+                      rw_lock_x_unlock(&page_hash_latch);
-+              }
-               return(TRUE);
-       }
--      mutex_exit(mutex);
-+      if (!have_page_hash_mutex) {
-+              mutex_exit(&LRU_list_mutex);
-+              rw_lock_x_unlock(&page_hash_latch);
-+      }
-+
-+      if (mutex) {
-+              mutex_exit(mutex);
-+      }
-       return(FALSE);
- }
-@@ -422,13 +482,15 @@
- /*===============*/
-       void*   buf,    /*!< in: block to be freed, must not be
-                       pointed to by the buffer pool */
--      ulint   i)      /*!< in: index of buf_pool->zip_free[],
-+      ulint   i,      /*!< in: index of buf_pool->zip_free[],
-                       or BUF_BUDDY_SIZES */
-+      ibool   have_page_hash_mutex)
- {
-       buf_page_t*     bpage;
-       buf_page_t*     buddy;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&zip_free_mutex));
-       ut_ad(!mutex_own(&buf_pool_zip_mutex));
-       ut_ad(i <= BUF_BUDDY_SIZES);
-       ut_ad(i >= buf_buddy_get_slot(PAGE_ZIP_MIN_SIZE));
-@@ -441,7 +503,9 @@
-       ((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE;
-       if (i == BUF_BUDDY_SIZES) {
--              buf_buddy_block_free(buf);
-+              mutex_exit(&zip_free_mutex);
-+              buf_buddy_block_free(buf, have_page_hash_mutex);
-+              mutex_enter(&zip_free_mutex);
-               return;
-       }
-@@ -489,7 +553,7 @@
-               ut_a(bpage != buf);
-               UNIV_MEM_ASSERT_W(bpage, BUF_BUDDY_LOW << i);
--              bpage = UT_LIST_GET_NEXT(list, bpage);
-+              bpage = UT_LIST_GET_NEXT(zip_list, bpage);
-       }
- #ifndef UNIV_DEBUG_VALGRIND
-@@ -499,7 +563,7 @@
-       ut_d(BUF_BUDDY_LIST_VALIDATE(i));
-       /* The buddy is not free. Is there a free block of this size? */
--      bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
-+      bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
-       if (bpage) {
-@@ -508,7 +572,7 @@
-               buf_buddy_remove_from_free(bpage, i);
-               /* Try to relocate the buddy of buf to the free block. */
--              if (buf_buddy_relocate(buddy, bpage, i)) {
-+              if (buf_buddy_relocate(buddy, bpage, i, have_page_hash_mutex)) {
-                       buddy->state = BUF_BLOCK_ZIP_FREE;
-                       goto buddy_is_free;
---- a/storage/innodb_plugin/buf/buf0buf.c
-+++ b/storage/innodb_plugin/buf/buf0buf.c
-@@ -251,6 +251,12 @@
- /** mutex protecting the buffer pool struct and control blocks, except the
- read-write lock in them */
- UNIV_INTERN mutex_t           buf_pool_mutex;
-+UNIV_INTERN mutex_t           LRU_list_mutex;
-+UNIV_INTERN mutex_t           flush_list_mutex;
-+UNIV_INTERN rw_lock_t         page_hash_latch;
-+UNIV_INTERN mutex_t           free_list_mutex;
-+UNIV_INTERN mutex_t           zip_free_mutex;
-+UNIV_INTERN mutex_t           zip_hash_mutex;
- /** mutex protecting the control blocks of compressed-only pages
- (of type buf_page_t, not buf_block_t) */
- UNIV_INTERN mutex_t           buf_pool_zip_mutex;
-@@ -661,9 +667,13 @@
-       block->page.in_zip_hash = FALSE;
-       block->page.in_flush_list = FALSE;
-       block->page.in_free_list = FALSE;
--      block->in_unzip_LRU_list = FALSE;
- #endif /* UNIV_DEBUG */
-+      block->page.flush_list.prev = NULL;
-+      block->page.flush_list.next = NULL;
-+      block->page.zip_list.prev = NULL;
-+      block->page.zip_list.next = NULL;
-       block->page.in_LRU_list = FALSE;
-+      block->in_unzip_LRU_list = FALSE;
- #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-       block->n_pointers = 0;
- #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-@@ -748,8 +758,10 @@
-               memset(block->frame, '\0', UNIV_PAGE_SIZE);
- #endif
-               /* Add the block to the free list */
--              UT_LIST_ADD_LAST(list, buf_pool->free, (&block->page));
-+              mutex_enter(&free_list_mutex);
-+              UT_LIST_ADD_LAST(free, buf_pool->free, (&block->page));
-               ut_d(block->page.in_free_list = TRUE);
-+              mutex_exit(&free_list_mutex);
-               block++;
-               frame += UNIV_PAGE_SIZE;
-@@ -774,7 +786,7 @@
-       ulint           i;
-       ut_ad(buf_pool);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       block = chunk->blocks;
-@@ -826,7 +838,7 @@
-       ulint           i;
-       ut_ad(buf_pool);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own()); /*optimistic...*/
-       block = chunk->blocks;
-@@ -881,8 +893,17 @@
-       /* 1. Initialize general fields
-       ------------------------------- */
-       mutex_create(&buf_pool_mutex, SYNC_BUF_POOL);
-+      mutex_create(&LRU_list_mutex, SYNC_BUF_LRU_LIST);
-+      mutex_create(&flush_list_mutex, SYNC_BUF_FLUSH_LIST);
-+      rw_lock_create(&page_hash_latch, SYNC_BUF_PAGE_HASH);
-+      mutex_create(&free_list_mutex, SYNC_BUF_FREE_LIST);
-+      mutex_create(&zip_free_mutex, SYNC_BUF_ZIP_FREE);
-+      mutex_create(&zip_hash_mutex, SYNC_BUF_ZIP_HASH);
-+
-       mutex_create(&buf_pool_zip_mutex, SYNC_BUF_BLOCK);
-+      mutex_enter(&LRU_list_mutex);
-+      rw_lock_x_lock(&page_hash_latch);
-       buf_pool_mutex_enter();
-       buf_pool->n_chunks = 1;
-@@ -917,6 +938,8 @@
-       --------------------------- */
-       /* All fields are initialized by mem_zalloc(). */
-+      mutex_exit(&LRU_list_mutex);
-+      rw_lock_x_unlock(&page_hash_latch);
-       buf_pool_mutex_exit();
-       btr_search_sys_create(buf_pool->curr_size
-@@ -1052,7 +1075,11 @@
-       buf_page_t*     b;
-       ulint           fold;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-+#ifdef UNIV_SYNC_DEBUG
-+      ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX));
-+#endif
-       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);
-@@ -1127,13 +1154,15 @@
- /*================*/
-       buf_page_t*     bpage)  /*!< in: buffer block of a file page */
- {
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-       ut_a(buf_page_in_file(bpage));
-       buf_LRU_make_block_young(bpage);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
- }
- /********************************************************************//**
-@@ -1155,14 +1184,20 @@
-       ut_a(buf_page_in_file(bpage));
-       if (buf_page_peek_if_too_old(bpage)) {
--              buf_pool_mutex_enter();
-+              //buf_pool_mutex_enter();
-+              mutex_enter(&LRU_list_mutex);
-               buf_LRU_make_block_young(bpage);
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&LRU_list_mutex);
-       } else if (!access_time) {
-               ulint   time_ms = ut_time_ms();
--              buf_pool_mutex_enter();
-+              mutex_t*        block_mutex = buf_page_get_mutex_enter(bpage);
-+              //buf_pool_mutex_enter();
-+              if (block_mutex) {
-               buf_page_set_accessed(bpage, time_ms);
--              buf_pool_mutex_exit();
-+              mutex_exit(block_mutex);
-+              }
-+              //buf_pool_mutex_exit();
-       }
- }
-@@ -1178,7 +1213,8 @@
- {
-       buf_block_t*    block;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      rw_lock_s_lock(&page_hash_latch);
-       block = (buf_block_t*) buf_page_hash_get(space, offset);
-@@ -1186,7 +1222,8 @@
-               block->check_index_page_at_flush = FALSE;
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_s_unlock(&page_hash_latch);
- }
- /********************************************************************//**
-@@ -1204,7 +1241,8 @@
-       buf_block_t*    block;
-       ibool           is_hashed;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      rw_lock_s_lock(&page_hash_latch);
-       block = (buf_block_t*) buf_page_hash_get(space, offset);
-@@ -1214,7 +1252,8 @@
-               is_hashed = block->is_hashed;
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_s_unlock(&page_hash_latch);
-       return(is_hashed);
- }
-@@ -1235,7 +1274,8 @@
- {
-       buf_page_t*     bpage;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      rw_lock_s_lock(&page_hash_latch);
-       bpage = buf_page_hash_get(space, offset);
-@@ -1245,7 +1285,8 @@
-               bpage->file_page_was_freed = TRUE;
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_s_unlock(&page_hash_latch);
-       return(bpage);
- }
-@@ -1265,7 +1306,8 @@
- {
-       buf_page_t*     bpage;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      rw_lock_s_lock(&page_hash_latch);
-       bpage = buf_page_hash_get(space, offset);
-@@ -1273,7 +1315,8 @@
-               bpage->file_page_was_freed = FALSE;
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_s_unlock(&page_hash_latch);
-       return(bpage);
- }
-@@ -1307,8 +1350,9 @@
-       buf_pool->stat.n_page_gets++;
-       for (;;) {
--              buf_pool_mutex_enter();
-+              //buf_pool_mutex_enter();
- lookup:
-+              rw_lock_s_lock(&page_hash_latch);
-               bpage = buf_page_hash_get(space, offset);
-               if (bpage) {
-                       break;
-@@ -1316,7 +1360,8 @@
-               /* Page not in buf_pool: needs to be read from file */
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              rw_lock_s_unlock(&page_hash_latch);
-               buf_read_page(space, zip_size, offset);
-@@ -1328,34 +1373,58 @@
-       if (UNIV_UNLIKELY(!bpage->zip.data)) {
-               /* There is no compressed page. */
- err_exit:
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              rw_lock_s_unlock(&page_hash_latch);
-               return(NULL);
-       }
-+      block_mutex = buf_page_get_mutex_enter(bpage);
-+
-+      rw_lock_s_unlock(&page_hash_latch);
-+
-       switch (buf_page_get_state(bpage)) {
-       case BUF_BLOCK_NOT_USED:
-       case BUF_BLOCK_READY_FOR_USE:
-       case BUF_BLOCK_MEMORY:
-       case BUF_BLOCK_REMOVE_HASH:
-       case BUF_BLOCK_ZIP_FREE:
-+              if (block_mutex)
-+                      mutex_exit(block_mutex);
-               break;
-       case BUF_BLOCK_ZIP_PAGE:
-       case BUF_BLOCK_ZIP_DIRTY:
--              block_mutex = &buf_pool_zip_mutex;
--              mutex_enter(block_mutex);
-+              ut_a(block_mutex == &buf_pool_zip_mutex);
-               bpage->buf_fix_count++;
-               goto got_block;
-       case BUF_BLOCK_FILE_PAGE:
--              block_mutex = &((buf_block_t*) bpage)->mutex;
-+              ut_a(block_mutex == &((buf_block_t*) bpage)->mutex);
-+
-+              /* release mutex to obey to latch-order */
-+              mutex_exit(block_mutex);
-+
-+              /* get LRU_list_mutex for buf_LRU_free_block() */
-+              mutex_enter(&LRU_list_mutex);
-               mutex_enter(block_mutex);
--              /* Discard the uncompressed page frame if possible. */
--              if (buf_LRU_free_block(bpage, FALSE)) {
-+              if (UNIV_UNLIKELY(bpage->space != space
-+                                || bpage->offset != offset
-+                                || !bpage->in_LRU_list
-+                                || !bpage->zip.data)) {
-+                      /* someone should interrupt, retry */
-+                      mutex_exit(&LRU_list_mutex);
-+                      mutex_exit(block_mutex);
-+                      goto lookup;
-+              }
-+              /* Discard the uncompressed page frame if possible. */
-+              if (buf_LRU_free_block(bpage, FALSE, TRUE)) {
-+                      mutex_exit(&LRU_list_mutex);
-                       mutex_exit(block_mutex);
-                       goto lookup;
-               }
-+              mutex_exit(&LRU_list_mutex);
-+
-               buf_block_buf_fix_inc((buf_block_t*) bpage,
-                                     __FILE__, __LINE__);
-               goto got_block;
-@@ -1368,7 +1437,7 @@
-       must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
-       access_time = buf_page_is_accessed(bpage);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-       mutex_exit(block_mutex);
-@@ -1626,7 +1695,7 @@
-       const buf_block_t*      block)  /*!< in: pointer to block,
-                                       not dereferenced */
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
-               /* The pointer should be aligned. */
-@@ -1660,6 +1729,7 @@
-       ulint           fix_type;
-       ibool           must_read;
-       ulint           retries = 0;
-+      mutex_t*        block_mutex = NULL;
-       ut_ad(mtr);
-       ut_ad(mtr->state == MTR_ACTIVE);
-@@ -1687,17 +1757,23 @@
-       buf_pool->stat.n_page_gets++;
- loop:
-       block = guess;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-       if (block) {
-+              block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
-+
-               /* If the guess is a compressed page descriptor that
-               has been allocated by buf_page_alloc_descriptor(),
-               it may have been freed by buf_relocate(). */
--              if (!buf_block_is_uncompressed(block)
-+              if (!block_mutex) {
-+                      block = guess = NULL;
-+              } else if (!buf_block_is_uncompressed(block)
-                   || offset != block->page.offset
-                   || space != block->page.space
-                   || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
-+                      mutex_exit(block_mutex);
-+
-                       block = guess = NULL;
-               } else {
-                       ut_ad(!block->page.in_zip_hash);
-@@ -1706,14 +1782,20 @@
-       }
-       if (block == NULL) {
-+              rw_lock_s_lock(&page_hash_latch);
-               block = (buf_block_t*) buf_page_hash_get(space, offset);
-+              if (block) {
-+                      block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
-+                      ut_a(block_mutex);
-+              }
-+              rw_lock_s_unlock(&page_hash_latch);
-       }
- loop2:
-       if (block == NULL) {
-               /* Page not in buf_pool: needs to be read from file */
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-               if (mode == BUF_GET_IF_IN_POOL
-                   || mode == BUF_PEEK_IF_IN_POOL) {
-@@ -1758,7 +1840,8 @@
-       if (must_read && (mode == BUF_GET_IF_IN_POOL
-                         || mode == BUF_PEEK_IF_IN_POOL)) {
-               /* The page is only being read to buffer */
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(block_mutex);
-               return(NULL);
-       }
-@@ -1768,38 +1851,50 @@
-               ibool           success;
-       case BUF_BLOCK_FILE_PAGE:
-+              if (block_mutex == &buf_pool_zip_mutex) {
-+                      /* it is wrong mutex... */
-+                      mutex_exit(block_mutex);
-+                      goto loop;
-+              }
-               break;
-       case BUF_BLOCK_ZIP_PAGE:
-       case BUF_BLOCK_ZIP_DIRTY:
-+              ut_ad(block_mutex == &buf_pool_zip_mutex);
-               bpage = &block->page;
-               /* Protect bpage->buf_fix_count. */
--              mutex_enter(&buf_pool_zip_mutex);
-+              /* Already proteced here. */
-+              //mutex_enter(&buf_pool_zip_mutex);
-               if (bpage->buf_fix_count
-                   || buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
-                       /* This condition often occurs when the buffer
-                       is not buffer-fixed, but I/O-fixed by
-                       buf_page_init_for_read(). */
--                      mutex_exit(&buf_pool_zip_mutex);
-+                      //mutex_exit(&buf_pool_zip_mutex);
- wait_until_unfixed:
-                       /* The block is buffer-fixed or I/O-fixed.
-                       Try again later. */
--                      buf_pool_mutex_exit();
-+                      //buf_pool_mutex_exit();
-+                      mutex_exit(block_mutex);
-                       os_thread_sleep(WAIT_FOR_READ);
-                       goto loop;
-               }
-               /* Allocate an uncompressed page. */
--              buf_pool_mutex_exit();
--              mutex_exit(&buf_pool_zip_mutex);
-+              //buf_pool_mutex_exit();
-+              //mutex_exit(&buf_pool_zip_mutex);
-+              mutex_exit(block_mutex);
-               block = buf_LRU_get_free_block();
-               ut_a(block);
-+              block_mutex = &block->mutex;
--              buf_pool_mutex_enter();
--              mutex_enter(&block->mutex);
-+              //buf_pool_mutex_enter();
-+              mutex_enter(&LRU_list_mutex);
-+              rw_lock_x_lock(&page_hash_latch);
-+              mutex_enter(block_mutex);
-               {
-                       buf_page_t*     hash_bpage
-@@ -1810,35 +1905,49 @@
-                               while buf_pool_mutex was released.
-                               Free the block that was allocated. */
--                              buf_LRU_block_free_non_file_page(block);
--                              mutex_exit(&block->mutex);
-+                              buf_LRU_block_free_non_file_page(block, TRUE);
-+                              mutex_exit(block_mutex);
-                               block = (buf_block_t*) hash_bpage;
-+                              if (block) {
-+                                      block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
-+                                      ut_a(block_mutex);
-+                              }
-+                              rw_lock_x_unlock(&page_hash_latch);
-+                              mutex_exit(&LRU_list_mutex);
-                               goto loop2;
-                       }
-               }
-+              mutex_enter(&buf_pool_zip_mutex);
-+
-               if (UNIV_UNLIKELY
-                   (bpage->buf_fix_count
-                    || buf_page_get_io_fix(bpage) != BUF_IO_NONE)) {
-+                      mutex_exit(&buf_pool_zip_mutex);
-                       /* The block was buffer-fixed or I/O-fixed
-                       while buf_pool_mutex was not held by this thread.
-                       Free the block that was allocated and try again.
-                       This should be extremely unlikely. */
--                      buf_LRU_block_free_non_file_page(block);
--                      mutex_exit(&block->mutex);
-+                      buf_LRU_block_free_non_file_page(block, TRUE);
-+                      //mutex_exit(&block->mutex);
-+                      rw_lock_x_unlock(&page_hash_latch);
-+                      mutex_exit(&LRU_list_mutex);
-                       goto wait_until_unfixed;
-               }
-               /* Move the compressed page from bpage to block,
-               and uncompress it. */
--              mutex_enter(&buf_pool_zip_mutex);
-+              mutex_enter(&flush_list_mutex);
-               buf_relocate(bpage, &block->page);
-+
-+              rw_lock_x_unlock(&page_hash_latch);
-+
-               buf_block_init_low(block);
-               block->lock_hash_val = lock_rec_hash(space, offset);
-@@ -1848,7 +1957,7 @@
-               if (buf_page_get_state(&block->page)
-                   == BUF_BLOCK_ZIP_PAGE) {
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
--                      UT_LIST_REMOVE(list, buf_pool->zip_clean,
-+                      UT_LIST_REMOVE(zip_list, buf_pool->zip_clean,
-                                      &block->page);
- #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-                       ut_ad(!block->page.in_flush_list);
-@@ -1858,6 +1967,8 @@
-                                                        &block->page);
-               }
-+              mutex_exit(&flush_list_mutex);
-+
-               /* Buffer-fix, I/O-fix, and X-latch the block
-               for the duration of the decompression.
-               Also add the block to the unzip_LRU list. */
-@@ -1866,17 +1977,22 @@
-               /* Insert at the front of unzip_LRU list */
-               buf_unzip_LRU_add_block(block, FALSE);
-+              mutex_exit(&LRU_list_mutex);
-+
-               block->page.buf_fix_count = 1;
-               buf_block_set_io_fix(block, BUF_IO_READ);
-               rw_lock_x_lock_func(&block->lock, 0, file, line);
-               UNIV_MEM_INVALID(bpage, sizeof *bpage);
--              mutex_exit(&block->mutex);
-+              mutex_exit(block_mutex);
-               mutex_exit(&buf_pool_zip_mutex);
-+
-+              mutex_enter(&buf_pool_mutex);
-               buf_pool->n_pend_unzip++;
-+              mutex_exit(&buf_pool_mutex);
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-               buf_page_free_descriptor(bpage);
-@@ -1891,12 +2007,15 @@
-               }
-               /* Unfix and unlatch the block. */
--              buf_pool_mutex_enter();
--              mutex_enter(&block->mutex);
-+              //buf_pool_mutex_enter();
-+              block_mutex = &block->mutex;
-+              mutex_enter(block_mutex);
-               block->page.buf_fix_count--;
-               buf_block_set_io_fix(block, BUF_IO_NONE);
--              mutex_exit(&block->mutex);
-+
-+              mutex_enter(&buf_pool_mutex);
-               buf_pool->n_pend_unzip--;
-+              mutex_exit(&buf_pool_mutex);
-               rw_lock_x_unlock(&block->lock);
-               break;
-@@ -1911,7 +2030,7 @@
-       ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
--      mutex_enter(&block->mutex);
-+      //mutex_enter(&block->mutex);
- #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
-@@ -1923,9 +2042,9 @@
-               /* Try to evict the block from the buffer pool, to use the
-               insert buffer as much as possible. */
--              if (buf_LRU_free_block(&block->page, TRUE)) {
--                      buf_pool_mutex_exit();
--                      mutex_exit(&block->mutex);
-+              if (buf_LRU_free_block(&block->page, TRUE, FALSE)) {
-+                      //buf_pool_mutex_exit();
-+                      mutex_exit(block_mutex);
-                       fprintf(stderr,
-                               "innodb_change_buffering_debug evict %u %u\n",
-                               (unsigned) space, (unsigned) offset);
-@@ -1944,13 +2063,14 @@
-       buf_block_buf_fix_inc(block, file, line);
--      mutex_exit(&block->mutex);
-+      //mutex_exit(&block->mutex);
-       /* Check if this is the first access to the page */
-       access_time = buf_page_is_accessed(&block->page);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(block_mutex);
-       if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
-               buf_page_set_accessed_make_young(&block->page, access_time);
-@@ -2180,9 +2300,11 @@
-       mutex_exit(&block->mutex);
-       if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
--              buf_pool_mutex_enter();
-+              //buf_pool_mutex_enter();
-+              mutex_enter(&LRU_list_mutex);
-               buf_LRU_make_block_young(&block->page);
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&LRU_list_mutex);
-       } 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
-@@ -2190,9 +2312,11 @@
-               field must be protected by mutex, however. */
-               ulint   time_ms = ut_time_ms();
--              buf_pool_mutex_enter();
-+              //buf_pool_mutex_enter();
-+              mutex_enter(&block->mutex);
-               buf_page_set_accessed(&block->page, time_ms);
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&block->mutex);
-       }
-       ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
-@@ -2258,16 +2382,19 @@
-       ut_ad(mtr);
-       ut_ad(mtr->state == MTR_ACTIVE);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      rw_lock_s_lock(&page_hash_latch);
-       block = buf_block_hash_get(space_id, page_no);
-       if (!block) {
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              rw_lock_s_unlock(&page_hash_latch);
-               return(NULL);
-       }
-       mutex_enter(&block->mutex);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_s_unlock(&page_hash_latch);
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-       ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-@@ -2354,7 +2481,10 @@
- {
-       buf_page_t*     hash_page;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+#ifdef UNIV_SYNC_DEBUG
-+      ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX));
-+#endif
-       ut_ad(mutex_own(&(block->mutex)));
-       ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
-@@ -2387,7 +2517,8 @@
-                       (const void*) hash_page, (const void*) block);
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-               mutex_exit(&block->mutex);
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              rw_lock_x_unlock(&page_hash_latch);
-               buf_print();
-               buf_LRU_print();
-               buf_validate();
-@@ -2466,16 +2597,24 @@
-               ut_ad(block);
-       }
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-+      rw_lock_x_lock(&page_hash_latch);
-       if (buf_page_hash_get(space, offset)) {
-               /* The page is already in the buffer pool. */
- err_exit:
-               if (block) {
-                       mutex_enter(&block->mutex);
--                      buf_LRU_block_free_non_file_page(block);
-+                      mutex_exit(&LRU_list_mutex);
-+                      rw_lock_x_unlock(&page_hash_latch);
-+                      buf_LRU_block_free_non_file_page(block, FALSE);
-                       mutex_exit(&block->mutex);
-               }
-+              else {
-+                      mutex_exit(&LRU_list_mutex);
-+                      rw_lock_x_unlock(&page_hash_latch);
-+              }
-               bpage = NULL;
-               goto func_exit;
-@@ -2495,6 +2634,8 @@
-               mutex_enter(&block->mutex);
-               buf_page_init(space, offset, block);
-+              rw_lock_x_unlock(&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 */);
-@@ -2522,7 +2663,7 @@
-                       been added to buf_pool->LRU and
-                       buf_pool->page_hash. */
-                       mutex_exit(&block->mutex);
--                      data = buf_buddy_alloc(zip_size, &lru);
-+                      data = buf_buddy_alloc(zip_size, &lru, FALSE);
-                       mutex_enter(&block->mutex);
-                       block->page.zip.data = data;
-@@ -2535,6 +2676,7 @@
-                       buf_unzip_LRU_add_block(block, TRUE);
-               }
-+              mutex_exit(&LRU_list_mutex);
-               mutex_exit(&block->mutex);
-       } else {
-@@ -2542,7 +2684,7 @@
-               control block (bpage), in order to avoid the
-               invocation of buf_buddy_relocate_block() on
-               uninitialized data. */
--              data = buf_buddy_alloc(zip_size, &lru);
-+              data = buf_buddy_alloc(zip_size, &lru, TRUE);
-               /* If buf_buddy_alloc() allocated storage from the LRU list,
-               it released and reacquired buf_pool_mutex.  Thus, we must
-@@ -2550,7 +2692,10 @@
-               if (UNIV_UNLIKELY(lru)
-                   && UNIV_LIKELY_NULL(buf_page_hash_get(space, offset))) {
--                      buf_buddy_free(data, zip_size);
-+                      buf_buddy_free(data, zip_size, TRUE);
-+
-+                      mutex_exit(&LRU_list_mutex);
-+                      rw_lock_x_unlock(&page_hash_latch);
-                       bpage = NULL;
-                       goto func_exit;
-               }
-@@ -2581,20 +2726,28 @@
-               HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
-                           buf_page_address_fold(space, offset), bpage);
-+              rw_lock_x_unlock(&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 */);
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-+              mutex_enter(&flush_list_mutex);
-               buf_LRU_insert_zip_clean(bpage);
-+              mutex_exit(&flush_list_mutex);
- #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-+              mutex_exit(&LRU_list_mutex);
-+
-               buf_page_set_io_fix(bpage, BUF_IO_READ);
-               mutex_exit(&buf_pool_zip_mutex);
-       }
-+      mutex_enter(&buf_pool_mutex);
-       buf_pool->n_pend_reads++;
-+      mutex_exit(&buf_pool_mutex);
- func_exit:
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-       if (mode == BUF_READ_IBUF_PAGES_ONLY) {
-@@ -2632,7 +2785,9 @@
-       free_block = buf_LRU_get_free_block();
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-+      rw_lock_x_lock(&page_hash_latch);
-       block = (buf_block_t*) buf_page_hash_get(space, offset);
-@@ -2645,7 +2800,9 @@
- #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
-               /* Page can be found in buf_pool */
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&LRU_list_mutex);
-+              rw_lock_x_unlock(&page_hash_latch);
-               buf_block_free(free_block);
-@@ -2667,6 +2824,7 @@
-       mutex_enter(&block->mutex);
-       buf_page_init(space, offset, block);
-+      rw_lock_x_unlock(&page_hash_latch);
-       /* The block must be put to the LRU list */
-       buf_LRU_add_block(&block->page, FALSE);
-@@ -2693,7 +2851,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. */
--              data = buf_buddy_alloc(zip_size, &lru);
-+              data = buf_buddy_alloc(zip_size, &lru, FALSE);
-               mutex_enter(&block->mutex);
-               block->page.zip.data = data;
-@@ -2711,7 +2869,8 @@
-       buf_page_set_accessed(&block->page, time_ms);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-       mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
-@@ -2761,6 +2920,7 @@
-       enum buf_io_fix io_type;
-       const ibool     uncompressed = (buf_page_get_state(bpage)
-                                       == BUF_BLOCK_FILE_PAGE);
-+      mutex_t*        block_mutex;
-       ut_a(buf_page_in_file(bpage));
-@@ -2894,8 +3054,13 @@
-               }
-       }
--      buf_pool_mutex_enter();
--      mutex_enter(buf_page_get_mutex(bpage));
-+      //buf_pool_mutex_enter();
-+      if (io_type == BUF_IO_WRITE) {
-+              mutex_enter(&LRU_list_mutex);
-+      }
-+      block_mutex = buf_page_get_mutex_enter(bpage);
-+      ut_a(block_mutex);
-+      mutex_enter(&buf_pool_mutex);
- #ifdef UNIV_IBUF_COUNT_DEBUG
-       if (io_type == BUF_IO_WRITE || uncompressed) {
-@@ -2935,6 +3100,11 @@
-               buf_flush_write_complete(bpage);
-+              /* to keep consistency at buf_LRU_insert_zip_clean() */
-+              //if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
-+                      mutex_exit(&LRU_list_mutex);
-+              //}
-+
-               if (uncompressed) {
-                       rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock,
-                                            BUF_IO_WRITE);
-@@ -2957,8 +3127,9 @@
-       }
- #endif /* UNIV_DEBUG */
--      mutex_exit(buf_page_get_mutex(bpage));
--      buf_pool_mutex_exit();
-+      mutex_exit(&buf_pool_mutex);
-+      mutex_exit(block_mutex);
-+      //buf_pool_mutex_exit();
- }
- /*********************************************************************//**
-@@ -3005,7 +3176,8 @@
-               freed = buf_LRU_search_and_free_block(100);
-       }
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-       ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
-       ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
-@@ -3018,7 +3190,8 @@
-       memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
-       buf_refresh_io_stats();
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
- }
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-@@ -3043,7 +3216,10 @@
-       ut_ad(buf_pool);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-+      rw_lock_x_lock(&page_hash_latch);
-+      /* for keep the new latch order, it cannot validate correctly... */
-       chunk = buf_pool->chunks;
-@@ -3142,7 +3318,7 @@
-       /* Check clean compressed-only blocks. */
-       for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
--           b = UT_LIST_GET_NEXT(list, b)) {
-+           b = UT_LIST_GET_NEXT(zip_list, b)) {
-               ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
-               switch (buf_page_get_io_fix(b)) {
-               case BUF_IO_NONE:
-@@ -3167,8 +3343,9 @@
-       /* Check dirty compressed-only blocks. */
-+      mutex_enter(&flush_list_mutex);
-       for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
--           b = UT_LIST_GET_NEXT(list, b)) {
-+           b = UT_LIST_GET_NEXT(flush_list, b)) {
-               ut_ad(b->in_flush_list);
-               switch (buf_page_get_state(b)) {
-@@ -3213,6 +3390,7 @@
-               }
-               ut_a(buf_page_hash_get(b->space, b->offset) == b);
-       }
-+      mutex_exit(&flush_list_mutex);
-       mutex_exit(&buf_pool_zip_mutex);
-@@ -3224,19 +3402,27 @@
-       }
-       ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);
-+      /* because of latching order with block->mutex, we cannot get free_list_mutex before that */
-+/*
-       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),
-                       (ulong) n_free);
-               ut_error;
-       }
-+*/
-+      /* because of latching order with block->mutex, we cannot get flush_list_mutex before that */
-+/*
-       ut_a(UT_LIST_GET_LEN(buf_pool->flush_list) == n_flush);
-       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);
-+*/
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-+      rw_lock_x_unlock(&page_hash_latch);
-       ut_a(buf_LRU_validate());
-       ut_a(buf_flush_validate());
-@@ -3270,7 +3456,10 @@
-       index_ids = mem_alloc(sizeof(dulint) * size);
-       counts = mem_alloc(sizeof(ulint) * size);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-+      mutex_enter(&free_list_mutex);
-+      mutex_enter(&flush_list_mutex);
-       fprintf(stderr,
-               "buf_pool size %lu\n"
-@@ -3337,7 +3526,10 @@
-               }
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-+      mutex_exit(&free_list_mutex);
-+      mutex_exit(&flush_list_mutex);
-       for (i = 0; i < n_found; i++) {
-               index = dict_index_get_if_in_cache(index_ids[i]);
-@@ -3376,7 +3568,7 @@
-       ulint           i;
-       ulint           fixed_pages_number = 0;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-       chunk = buf_pool->chunks;
-@@ -3410,7 +3602,7 @@
-       /* Traverse the lists of clean and dirty compressed-only blocks. */
-       for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
--           b = UT_LIST_GET_NEXT(list, b)) {
-+           b = UT_LIST_GET_NEXT(zip_list, b)) {
-               ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
-               ut_a(buf_page_get_io_fix(b) != BUF_IO_WRITE);
-@@ -3420,8 +3612,9 @@
-               }
-       }
-+      mutex_enter(&flush_list_mutex);
-       for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
--           b = UT_LIST_GET_NEXT(list, b)) {
-+           b = UT_LIST_GET_NEXT(flush_list, b)) {
-               ut_ad(b->in_flush_list);
-               switch (buf_page_get_state(b)) {
-@@ -3444,9 +3637,10 @@
-                       break;
-               }
-       }
-+      mutex_exit(&flush_list_mutex);
-       mutex_exit(&buf_pool_zip_mutex);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-       return(fixed_pages_number);
- }
-@@ -3504,7 +3698,11 @@
-       ut_ad(buf_pool);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-+      mutex_enter(&free_list_mutex);
-+      mutex_enter(&buf_pool_mutex);
-+      mutex_enter(&flush_list_mutex);
-       fprintf(file,
-               "Buffer pool size        %lu\n"
-@@ -3607,7 +3805,11 @@
-               buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
-       buf_refresh_io_stats();
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-+      mutex_exit(&free_list_mutex);
-+      mutex_exit(&buf_pool_mutex);
-+      mutex_exit(&flush_list_mutex);
- }
- /**********************************************************************//**
-@@ -3634,7 +3836,7 @@
-       ut_ad(buf_pool);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter(); /* optimistic */
-       chunk = buf_pool->chunks;
-@@ -3651,7 +3853,7 @@
-               }
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit(); /* optimistic */
-       return(TRUE);
- }
-@@ -3667,7 +3869,8 @@
- {
-       ibool   ret;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&buf_pool_mutex);
-       if (buf_pool->n_pend_reads + buf_pool->n_flush[BUF_FLUSH_LRU]
-           + buf_pool->n_flush[BUF_FLUSH_LIST]
-@@ -3677,7 +3880,8 @@
-               ret = TRUE;
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&buf_pool_mutex);
-       return(ret);
- }
-@@ -3692,11 +3896,13 @@
- {
-       ulint   len;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&free_list_mutex);
-       len = UT_LIST_GET_LEN(buf_pool->free);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&free_list_mutex);
-       return(len);
- }
---- a/storage/innodb_plugin/buf/buf0flu.c
-+++ b/storage/innodb_plugin/buf/buf0flu.c
-@@ -102,7 +102,8 @@
-       const ib_rbt_node_t*    c_node;
-       const ib_rbt_node_t*    p_node;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&flush_list_mutex));
-       /* Insert this buffer into the rbt. */
-       c_node = rbt_insert(buf_pool->flush_rbt, &bpage, &bpage);
-@@ -132,7 +133,8 @@
-       ibool   ret = FALSE;
- #endif /* UNIV_DEBUG */
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&flush_list_mutex));
- #ifdef UNIV_DEBUG
-       ret =
- #endif /* UNIV_DEBUG */
-@@ -199,12 +201,14 @@
- buf_flush_init_flush_rbt(void)
- /*==========================*/
- {
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&flush_list_mutex);
-       /* Create red black tree for speedy insertions in flush list. */
-       buf_pool->flush_rbt = rbt_create(sizeof(buf_page_t*),
-                                        buf_flush_block_cmp);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&flush_list_mutex);
- }
- /********************************************************************//**
-@@ -214,7 +218,8 @@
- buf_flush_free_flush_rbt(void)
- /*==========================*/
- {
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&flush_list_mutex);
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-       ut_a(buf_flush_validate_low());
-@@ -223,7 +228,8 @@
-       rbt_free(buf_pool->flush_rbt);
-       buf_pool->flush_rbt = NULL;
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&flush_list_mutex);
- }
- /********************************************************************//**
-@@ -234,7 +240,9 @@
- /*=============================*/
-       buf_block_t*    block)  /*!< in/out: block which is modified */
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&block->mutex));
-+      ut_ad(mutex_own(&flush_list_mutex));
-       ut_ad((UT_LIST_GET_FIRST(buf_pool->flush_list) == NULL)
-             || (UT_LIST_GET_FIRST(buf_pool->flush_list)->oldest_modification
-                 <= block->page.oldest_modification));
-@@ -252,7 +260,7 @@
-       ut_ad(!block->page.in_zip_hash);
-       ut_ad(!block->page.in_flush_list);
-       ut_d(block->page.in_flush_list = TRUE);
--      UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
-+      UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
- #ifdef UNIV_DEBUG_VALGRIND
-       {
-@@ -283,7 +291,9 @@
-       buf_page_t*     prev_b;
-       buf_page_t*     b;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&block->mutex));
-+      ut_ad(mutex_own(&flush_list_mutex));
-       ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-       ut_ad(block->page.in_LRU_list);
-@@ -324,14 +334,14 @@
-                      > block->page.oldest_modification) {
-                       ut_ad(b->in_flush_list);
-                       prev_b = b;
--                      b = UT_LIST_GET_NEXT(list, b);
-+                      b = UT_LIST_GET_NEXT(flush_list, b);
-               }
-       }
-       if (prev_b == NULL) {
--              UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
-+              UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
-       } else {
--              UT_LIST_INSERT_AFTER(list, buf_pool->flush_list,
-+              UT_LIST_INSERT_AFTER(flush_list, buf_pool->flush_list,
-                                    prev_b, &block->page);
-       }
-@@ -352,7 +362,7 @@
-                               buf_page_in_file(bpage) and in the LRU list */
- {
-       //ut_ad(buf_pool_mutex_own());
--      //ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-+      ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-       //ut_ad(bpage->in_LRU_list); /* optimistic use */
-       if (UNIV_LIKELY(bpage->in_LRU_list && buf_page_in_file(bpage))) {
-@@ -387,12 +397,12 @@
-                               buf_page_in_file(bpage) */
-       enum buf_flush  flush_type)/*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
- {
--      ut_a(buf_page_in_file(bpage));
--      ut_ad(buf_pool_mutex_own());
-+      //ut_a(buf_page_in_file(bpage));
-+      //ut_ad(buf_pool_mutex_own()); /*optimistic...*/
-       ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-       ut_ad(flush_type == BUF_FLUSH_LRU || BUF_FLUSH_LIST);
--      if (bpage->oldest_modification != 0
-+      if (buf_page_in_file(bpage) && bpage->oldest_modification != 0
-           && buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
-               ut_ad(bpage->in_flush_list);
-@@ -421,8 +431,11 @@
- /*=============*/
-       buf_page_t*     bpage)  /*!< in: pointer to the block in question */
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-+
-+      mutex_enter(&flush_list_mutex);
-+
-       ut_ad(bpage->in_flush_list);
-       switch (buf_page_get_state(bpage)) {
-@@ -433,17 +446,18 @@
-       case BUF_BLOCK_READY_FOR_USE:
-       case BUF_BLOCK_MEMORY:
-       case BUF_BLOCK_REMOVE_HASH:
-+              mutex_exit(&flush_list_mutex);
-               ut_error;
-               return;
-       case BUF_BLOCK_ZIP_DIRTY:
-               buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);
--              UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
-+              UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-               buf_LRU_insert_zip_clean(bpage);
- #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-               break;
-       case BUF_BLOCK_FILE_PAGE:
--              UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
-+              UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
-               break;
-       }
-@@ -458,8 +472,9 @@
-       bpage->oldest_modification = 0;
--      ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->flush_list,
-+      ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
-                             ut_ad(ut_list_node_313->in_flush_list)));
-+      mutex_exit(&flush_list_mutex);
- }
- /********************************************************************//**
-@@ -476,7 +491,8 @@
-       buf_page_t* prev;
-       buf_page_t* prev_b = NULL;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&flush_list_mutex));
-       ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-@@ -494,18 +510,18 @@
-       because we assert on in_flush_list in comparison function. */
-       ut_d(bpage->in_flush_list = FALSE);
--      prev = UT_LIST_GET_PREV(list, bpage);
--      UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
-+      prev = UT_LIST_GET_PREV(flush_list, bpage);
-+      UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
-       if (prev) {
-               ut_ad(prev->in_flush_list);
-               UT_LIST_INSERT_AFTER(
--                      list,
-+                      flush_list,
-                       buf_pool->flush_list,
-                       prev, dpage);
-       } else {
-               UT_LIST_ADD_FIRST(
--                      list,
-+                      flush_list,
-                       buf_pool->flush_list,
-                       dpage);
-       }
-@@ -979,7 +995,9 @@
-       io_fixed and oldest_modification != 0.  Thus, it cannot be
-       relocated in the buffer pool or removed from flush_list or
-       LRU_list. */
--      ut_ad(!buf_pool_mutex_own());
-+      //ut_ad(!buf_pool_mutex_own());
-+      ut_ad(!mutex_own(&LRU_list_mutex));
-+      ut_ad(!mutex_own(&flush_list_mutex));
-       ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
-       ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);
-       ut_ad(bpage->oldest_modification != 0);
-@@ -1057,7 +1075,7 @@
- /*===============*/
-       buf_block_t*    block)          /*!< in/out: buffer control block */
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-       ut_ad(mutex_own(&block->mutex));
-@@ -1065,8 +1083,11 @@
-               return(FALSE);
-       }
-+      buf_pool_mutex_enter();
-+
-       if (buf_pool->n_flush[BUF_FLUSH_LRU] > 0
-           || buf_pool->init_flush[BUF_FLUSH_LRU]) {
-+              buf_pool_mutex_exit();
-               /* There is already a flush batch of the same type running */
-               return(FALSE);
-       }
-@@ -1139,12 +1160,19 @@
-       ibool           is_uncompressed;
-       ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+#ifdef UNIV_SYNC_DEBUG
-+      ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX)
-+            || rw_lock_own(&page_hash_latch, RW_LOCK_SHARED));
-+#endif
-       ut_ad(buf_page_in_file(bpage));
-       block_mutex = buf_page_get_mutex(bpage);
-       ut_ad(mutex_own(block_mutex));
-+      mutex_enter(&buf_pool_mutex);
-+      rw_lock_s_unlock(&page_hash_latch);
-+
-       ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
-       buf_page_set_io_fix(bpage, BUF_IO_WRITE);
-@@ -1175,7 +1203,8 @@
-               }
-               mutex_exit(block_mutex);
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&buf_pool_mutex);
-               /* Even though bpage is not protected by any mutex at
-               this point, it is safe to access bpage, because it is
-@@ -1212,7 +1241,8 @@
-               immediately. */
-               mutex_exit(block_mutex);
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&buf_pool_mutex);
-               break;
-       default:
-@@ -1277,7 +1307,8 @@
-               high = fil_space_get_size(space);
-       }
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      rw_lock_s_lock(&page_hash_latch);
-       for (i = low; i < high; i++) {
-@@ -1296,11 +1327,9 @@
-               if (flush_type != BUF_FLUSH_LRU
-                   || i == offset
-                   || buf_page_is_old(bpage)) {
--                      mutex_t* block_mutex = buf_page_get_mutex(bpage);
--
--                      mutex_enter(block_mutex);
-+                      mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
--                      if (buf_flush_ready_for_flush(bpage, flush_type)
-+                      if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)
-                           && (i == offset || !bpage->buf_fix_count)) {
-                               /* We only try to flush those
-                               neighbors != offset where the buf fix count is
-@@ -1314,14 +1343,16 @@
-                               ut_ad(!mutex_own(block_mutex));
-                               count++;
--                              buf_pool_mutex_enter();
--                      } else {
-+                              //buf_pool_mutex_enter();
-+                              rw_lock_s_lock(&page_hash_latch);
-+                      } else if (block_mutex) {
-                               mutex_exit(block_mutex);
-                       }
-               }
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_s_unlock(&page_hash_latch);
-       return(count);
- }
-@@ -1352,9 +1383,11 @@
-                                       min_n), otherwise ignored */
- {
-       buf_page_t*     bpage;
-+      buf_page_t*     prev_bpage      = NULL;
-       ulint           page_count      = 0;
-       ulint           space;
-       ulint           offset;
-+      ulint           remaining       = 0;
-       ut_ad((flush_type == BUF_FLUSH_LRU)
-             || (flush_type == BUF_FLUSH_LIST));
-@@ -1362,20 +1395,28 @@
-       ut_ad((flush_type != BUF_FLUSH_LIST)
-             || sync_thread_levels_empty_gen(TRUE));
- #endif /* UNIV_SYNC_DEBUG */
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&buf_pool_mutex);
-       if ((buf_pool->n_flush[flush_type] > 0)
-           || (buf_pool->init_flush[flush_type] == TRUE)) {
-               /* There is already a flush batch of the same type running */
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&buf_pool_mutex);
-               return(ULINT_UNDEFINED);
-       }
-       buf_pool->init_flush[flush_type] = TRUE;
-+      mutex_exit(&buf_pool_mutex);
-+
-+      if (flush_type == BUF_FLUSH_LRU) {
-+              mutex_enter(&LRU_list_mutex);
-+      }
-+
-       for (;;) {
- flush_next:
-               /* If we have flushed enough, leave the loop */
-@@ -1392,7 +1433,13 @@
-               } else {
-                       ut_ad(flush_type == BUF_FLUSH_LIST);
-+                      mutex_enter(&flush_list_mutex);
-+                      remaining = UT_LIST_GET_LEN(buf_pool->flush_list);
-                       bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
-+                      if (bpage) {
-+                              prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
-+                      }
-+                      mutex_exit(&flush_list_mutex);
-                       if (!bpage
-                           || bpage->oldest_modification >= lsn_limit) {
-                               /* We have flushed enough */
-@@ -1409,26 +1456,35 @@
-               function a pointer to a block in the list! */
-               do {
--                      mutex_t*block_mutex = buf_page_get_mutex(bpage);
-+                      mutex_t*block_mutex = buf_page_get_mutex_enter(bpage);
-                       ibool   ready;
--                      ut_a(buf_page_in_file(bpage));
-+                      //ut_a(buf_page_in_file(bpage));
--                      mutex_enter(block_mutex);
--                      ready = buf_flush_ready_for_flush(bpage, flush_type);
--                      mutex_exit(block_mutex);
-+                      if (block_mutex) {
-+                              ready = buf_flush_ready_for_flush(bpage, flush_type);
-+                              mutex_exit(block_mutex);
-+                      } else {
-+                              ready = FALSE;
-+                      }
-                       if (ready) {
-                               space = buf_page_get_space(bpage);
-                               offset = buf_page_get_page_no(bpage);
--                              buf_pool_mutex_exit();
-+                              //buf_pool_mutex_exit();
-+                              if (flush_type == BUF_FLUSH_LRU) {
-+                                      mutex_exit(&LRU_list_mutex);
-+                              }
-                               /* Try to flush also all the neighbors */
-                               page_count += buf_flush_try_neighbors(
-                                       space, offset, flush_type, srv_flush_neighbor_pages);
--                              buf_pool_mutex_enter();
-+                              //buf_pool_mutex_enter();
-+                              if (flush_type == BUF_FLUSH_LRU) {
-+                                      mutex_enter(&LRU_list_mutex);
-+                              }
-                               goto flush_next;
-                       } else if (flush_type == BUF_FLUSH_LRU) {
-@@ -1436,16 +1492,35 @@
-                       } else {
-                               ut_ad(flush_type == BUF_FLUSH_LIST);
--                              bpage = UT_LIST_GET_PREV(list, bpage);
--                              ut_ad(!bpage || bpage->in_flush_list);
-+                              mutex_enter(&flush_list_mutex);
-+                              bpage = UT_LIST_GET_PREV(flush_list, bpage);
-+                              //ut_ad(!bpage || bpage->in_flush_list); /* optimistic */
-+                              if (bpage != prev_bpage) {
-+                                      /* the search may warp.. retrying */
-+                                      bpage = NULL;
-+                              }
-+                              if (bpage) {
-+                                      prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
-+                              }
-+                              mutex_exit(&flush_list_mutex);
-+                              remaining--;
-                       }
-               } while (bpage != NULL);
-+              if (remaining)
-+                      goto flush_next;
-+
-               /* If we could not find anything to flush, leave the loop */
-               break;
-       }
-+      if (flush_type == BUF_FLUSH_LRU) {
-+              mutex_exit(&LRU_list_mutex);
-+      }
-+
-+      mutex_enter(&buf_pool_mutex);
-+
-       buf_pool->init_flush[flush_type] = FALSE;
-       if (buf_pool->n_flush[flush_type] == 0) {
-@@ -1455,7 +1530,8 @@
-               os_event_set(buf_pool->no_flush[flush_type]);
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&buf_pool_mutex);
-       buf_flush_buffered_writes();
-@@ -1516,7 +1592,7 @@
- retry:
-       //buf_pool_mutex_enter();
-       if (have_LRU_mutex)
--              buf_pool_mutex_enter();
-+              mutex_enter(&LRU_list_mutex);
-       n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
-@@ -1533,15 +1609,15 @@
-                       bpage = UT_LIST_GET_LAST(buf_pool->LRU);
-                       continue;
-               }
--              block_mutex = buf_page_get_mutex(bpage);
-+              block_mutex = buf_page_get_mutex_enter(bpage);
--              mutex_enter(block_mutex);
--
--              if (buf_flush_ready_for_replace(bpage)) {
-+              if (block_mutex && buf_flush_ready_for_replace(bpage)) {
-                       n_replaceable++;
-               }
--              mutex_exit(block_mutex);
-+              if (block_mutex) {
-+                      mutex_exit(block_mutex);
-+              }
-               distance++;
-@@ -1550,7 +1626,7 @@
-       //buf_pool_mutex_exit();
-       if (have_LRU_mutex)
--              buf_pool_mutex_exit();
-+              mutex_exit(&LRU_list_mutex);
-       if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN) {
-@@ -1717,7 +1793,7 @@
-       buf_page_t*             bpage;
-       const ib_rbt_node_t*    rnode = NULL;
--      UT_LIST_VALIDATE(list, buf_page_t, buf_pool->flush_list,
-+      UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
-                        ut_ad(ut_list_node_313->in_flush_list));
-       bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-@@ -1732,7 +1808,7 @@
-       while (bpage != NULL) {
-               const ib_uint64_t om = bpage->oldest_modification;
-               ut_ad(bpage->in_flush_list);
--              ut_a(buf_page_in_file(bpage));
-+              //ut_a(buf_page_in_file(bpage)); /* optimistic */
-               ut_a(om > 0);
-               if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) {
-@@ -1744,7 +1820,7 @@
-                       rnode = rbt_next(buf_pool->flush_rbt, rnode);
-               }
--              bpage = UT_LIST_GET_NEXT(list, bpage);
-+              bpage = UT_LIST_GET_NEXT(flush_list, bpage);
-               ut_a(!bpage || om >= bpage->oldest_modification);
-       }
-@@ -1766,11 +1842,13 @@
- {
-       ibool   ret;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&flush_list_mutex);
-       ret = buf_flush_validate_low();
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&flush_list_mutex);
-       return(ret);
- }
---- a/storage/innodb_plugin/buf/buf0lru.c
-+++ b/storage/innodb_plugin/buf/buf0lru.c
-@@ -145,8 +145,9 @@
- void
- buf_LRU_block_free_hashed_page(
- /*===========================*/
--      buf_block_t*    block); /*!< in: block, must contain a file page and
-+      buf_block_t*    block,  /*!< in: block, must contain a file page and
-                               be in a state where it can be freed */
-+      ibool           have_page_hash_mutex);
- /******************************************************************//**
- Determines if the unzip_LRU list should be used for evicting a victim
-@@ -154,16 +155,21 @@
- @return       TRUE if should use unzip_LRU */
- UNIV_INLINE
- ibool
--buf_LRU_evict_from_unzip_LRU(void)
-+buf_LRU_evict_from_unzip_LRU(
-+      ibool           have_LRU_mutex)
- /*==============================*/
- {
-       ulint   io_avg;
-       ulint   unzip_avg;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      if (!have_LRU_mutex)
-+              mutex_enter(&LRU_list_mutex);
-       /* If the unzip_LRU list is empty, we can only use the LRU. */
-       if (UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0) {
-+              if (!have_LRU_mutex)
-+                      mutex_exit(&LRU_list_mutex);
-               return(FALSE);
-       }
-@@ -172,14 +178,20 @@
-       decompressed pages in the buffer pool. */
-       if (UT_LIST_GET_LEN(buf_pool->unzip_LRU)
-           <= UT_LIST_GET_LEN(buf_pool->LRU) / 10) {
-+              if (!have_LRU_mutex)
-+                      mutex_exit(&LRU_list_mutex);
-               return(FALSE);
-       }
-       /* If eviction hasn't started yet, we assume by default
-       that a workload is disk bound. */
-       if (buf_pool->freed_page_clock == 0) {
-+              if (!have_LRU_mutex)
-+                      mutex_exit(&LRU_list_mutex);
-               return(TRUE);
-       }
-+      if (!have_LRU_mutex)
-+              mutex_exit(&LRU_list_mutex);
-       /* Calculate the average over past intervals, and add the values
-       of the current interval. */
-@@ -245,18 +257,25 @@
-       page_arr = ut_malloc(sizeof(ulint)
-                            * BUF_LRU_DROP_SEARCH_HASH_SIZE);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-       num_entries = 0;
- scan_again:
-       bpage = UT_LIST_GET_LAST(buf_pool->LRU);
-       while (bpage != NULL) {
-+              /* bpage->state,space,io_fix,buf_fix_count are protected by block_mutex at XtraDB */
-+              mutex_t*        block_mutex = buf_page_get_mutex_enter(bpage);
-               buf_page_t*     prev_bpage;
-               ibool           is_fixed;
-               prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
-+              if (UNIV_UNLIKELY(!block_mutex)) {
-+                      goto next_page;
-+              }
-+
-               ut_a(buf_page_in_file(bpage));
-               if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
-@@ -265,23 +284,27 @@
-                       /* Compressed pages are never hashed.
-                       Skip blocks of other tablespaces.
-                       Skip I/O-fixed blocks (to be dealt with later). */
-+                      mutex_exit(block_mutex);
- next_page:
-                       bpage = prev_bpage;
-                       continue;
-               }
--              mutex_enter(&((buf_block_t*) bpage)->mutex);
-+              //mutex_enter(&((buf_block_t*) bpage)->mutex);
-               is_fixed = bpage->buf_fix_count > 0
-                       || !((buf_block_t*) bpage)->is_hashed;
--              mutex_exit(&((buf_block_t*) bpage)->mutex);
-+              //mutex_exit(&((buf_block_t*) bpage)->mutex);
-               if (is_fixed) {
-+                      mutex_exit(block_mutex);
-                       goto next_page;
-               }
-               /* Store the page number so that we can drop the hash
-               index in a batch later. */
-               page_arr[num_entries] = bpage->offset;
-+              mutex_exit(block_mutex);
-+
-               ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
-               ++num_entries;
-@@ -291,10 +314,12 @@
-               /* Array full. We release the buf_pool_mutex to
-               obey the latching order. */
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&LRU_list_mutex);
-               buf_LRU_drop_page_hash_batch(id, zip_size, page_arr,
-                                            num_entries);
--              buf_pool_mutex_enter();
-+              //buf_pool_mutex_enter();
-+              mutex_enter(&LRU_list_mutex);
-               num_entries = 0;
-               /* Note that we released the buf_pool mutex above
-@@ -313,13 +338,23 @@
-               /* If, however, bpage has been removed from LRU list
-               to the free list then we should restart the scan.
-               bpage->state is protected by buf_pool mutex. */
-+
-+              /* obtain block_mutex again to avoid race condition of bpage->state */
-+              block_mutex = buf_page_get_mutex_enter(bpage);
-+              if (!block_mutex) {
-+                      goto scan_again;
-+              }
-+
-               if (bpage
-                   && buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
-+                      mutex_exit(block_mutex);
-                       goto scan_again;
-               }
-+              mutex_exit(block_mutex);
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-       /* Drop any remaining batch of search hashed pages. */
-       buf_LRU_drop_page_hash_batch(id, zip_size, page_arr, num_entries);
-@@ -347,7 +382,9 @@
-       buf_LRU_drop_page_hash_for_tablespace(id);
- scan_again:
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-+      rw_lock_x_lock(&page_hash_latch);
-       all_freed = TRUE;
-@@ -377,8 +414,15 @@
-                       all_freed = FALSE;
-                       goto next_page;
-               } else {
--                      block_mutex = buf_page_get_mutex(bpage);
--                      mutex_enter(block_mutex);
-+                      block_mutex = buf_page_get_mutex_enter(bpage);
-+
-+                      if (!block_mutex) {
-+                              /* It may be impossible case...
-+                              Something wrong, so will be scan_again */
-+
-+                              all_freed = FALSE;
-+                              goto next_page;
-+                      }
-                       if (bpage->buf_fix_count > 0) {
-@@ -411,7 +455,9 @@
-                       ulint   page_no;
-                       ulint   zip_size;
--                      buf_pool_mutex_exit();
-+                      //buf_pool_mutex_exit();
-+                      mutex_exit(&LRU_list_mutex);
-+                      rw_lock_x_unlock(&page_hash_latch);
-                       zip_size = buf_page_get_zip_size(bpage);
-                       page_no = buf_page_get_page_no(bpage);
-@@ -435,7 +481,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);
-                       mutex_exit(block_mutex);
-               } else {
-                       /* The block_mutex should have been released
-@@ -448,7 +494,9 @@
-               bpage = prev_bpage;
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-+      rw_lock_x_unlock(&page_hash_latch);
-       if (!all_freed) {
-               os_thread_sleep(20000);
-@@ -468,7 +516,9 @@
- {
-       buf_page_t*     b;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-+      ut_ad(mutex_own(&flush_list_mutex));
-       ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_PAGE);
-       /* Find the first successor of bpage in the LRU list
-@@ -476,17 +526,17 @@
-       b = bpage;
-       do {
-               b = UT_LIST_GET_NEXT(LRU, b);
--      } while (b && buf_page_get_state(b) != BUF_BLOCK_ZIP_PAGE);
-+      } while (b && (buf_page_get_state(b) != BUF_BLOCK_ZIP_PAGE || !b->in_LRU_list));
-       /* Insert bpage before b, i.e., after the predecessor of b. */
-       if (b) {
--              b = UT_LIST_GET_PREV(list, b);
-+              b = UT_LIST_GET_PREV(zip_list, b);
-       }
-       if (b) {
--              UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, bpage);
-+              UT_LIST_INSERT_AFTER(zip_list, buf_pool->zip_clean, b, bpage);
-       } else {
--              UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, bpage);
-+              UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, bpage);
-       }
- }
- #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-@@ -499,16 +549,17 @@
- ibool
- buf_LRU_free_from_unzip_LRU_list(
- /*=============================*/
--      ulint   n_iterations)   /*!< in: how many times this has been called
-+      ulint   n_iterations,   /*!< in: how many times this has been called
-                               repeatedly without result: a high value means
-                               that we should search farther; we will search
-                               n_iterations / 5 of the unzip_LRU list,
-                               or nothing if n_iterations >= 5 */
-+      ibool   have_LRU_mutex)
- {
-       buf_block_t*    block;
-       ulint           distance;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own()); /* optimistic */
-       /* Theoratically it should be much easier to find a victim
-       from unzip_LRU as we can choose even a dirty block (as we'll
-@@ -518,7 +569,7 @@
-       if we have done five iterations so far. */
-       if (UNIV_UNLIKELY(n_iterations >= 5)
--          || !buf_LRU_evict_from_unzip_LRU()) {
-+          || !buf_LRU_evict_from_unzip_LRU(have_LRU_mutex)) {
-               return(FALSE);
-       }
-@@ -526,18 +577,25 @@
-       distance = 100 + (n_iterations
-                         * UT_LIST_GET_LEN(buf_pool->unzip_LRU)) / 5;
-+restart:
-       for (block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
-            UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
-            block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
-               ibool freed;
-+              mutex_enter(&block->mutex);
-+              if (!block->in_unzip_LRU_list || !block->page.in_LRU_list
-+                  || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
-+                      mutex_exit(&block->mutex);
-+                      goto restart;
-+              }
-+
-               ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-               ut_ad(block->in_unzip_LRU_list);
-               ut_ad(block->page.in_LRU_list);
--              mutex_enter(&block->mutex);
--              freed = buf_LRU_free_block(&block->page, FALSE);
-+              freed = buf_LRU_free_block(&block->page, FALSE, have_LRU_mutex);
-               mutex_exit(&block->mutex);
-               if (freed) {
-@@ -555,34 +613,45 @@
- ibool
- buf_LRU_free_from_common_LRU_list(
- /*==============================*/
--      ulint   n_iterations)   /*!< in: how many times this has been called
-+      ulint   n_iterations,   /*!< in: how many times this has been called
-                               repeatedly without result: a high value means
-                               that we should search farther; if
-                               n_iterations < 10, then we search
-                               n_iterations / 10 * buf_pool->curr_size
-                               pages from the end of the LRU list */
-+      ibool   have_LRU_mutex)
- {
-       buf_page_t*     bpage;
-       ulint           distance;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own()); /* optimistic */
-       distance = 100 + (n_iterations * buf_pool->curr_size) / 10;
-+restart:
-       for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
-            UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
-            bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
-               ibool           freed;
-               unsigned        accessed;
--              mutex_t*        block_mutex = buf_page_get_mutex(bpage);
-+              mutex_t*        block_mutex = buf_page_get_mutex_enter(bpage);
-+
-+              if (!block_mutex) {
-+                      goto restart;
-+              }
-+
-+              if (!bpage->in_LRU_list
-+                  || !buf_page_in_file(bpage)) {
-+                      mutex_exit(block_mutex);
-+                      goto restart;
-+              }
-               ut_ad(buf_page_in_file(bpage));
-               ut_ad(bpage->in_LRU_list);
--              mutex_enter(block_mutex);
-               accessed = buf_page_is_accessed(bpage);
--              freed = buf_LRU_free_block(bpage, TRUE);
-+              freed = buf_LRU_free_block(bpage, TRUE, have_LRU_mutex);
-               mutex_exit(block_mutex);
-               if (freed) {
-@@ -616,22 +685,33 @@
-                               n_iterations / 5 of the unzip_LRU list. */
- {
-       ibool   freed = FALSE;
-+      ibool   have_LRU_mutex = FALSE;
--      buf_pool_mutex_enter();
-+      if (UT_LIST_GET_LEN(buf_pool->unzip_LRU))
-+              have_LRU_mutex = TRUE;
--      freed = buf_LRU_free_from_unzip_LRU_list(n_iterations);
-+      /* optimistic search... */
-+      //buf_pool_mutex_enter();
-+      if (have_LRU_mutex)
-+              mutex_enter(&LRU_list_mutex);
-+
-+      freed = buf_LRU_free_from_unzip_LRU_list(n_iterations, have_LRU_mutex);
-       if (!freed) {
--              freed = buf_LRU_free_from_common_LRU_list(n_iterations);
-+              freed = buf_LRU_free_from_common_LRU_list(n_iterations, have_LRU_mutex);
-       }
-+      mutex_enter(&buf_pool_mutex);
-       if (!freed) {
-               buf_pool->LRU_flush_ended = 0;
-       } else if (buf_pool->LRU_flush_ended > 0) {
-               buf_pool->LRU_flush_ended--;
-       }
-+      mutex_exit(&buf_pool_mutex);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      if (have_LRU_mutex)
-+              mutex_exit(&LRU_list_mutex);
-       return(freed);
- }
-@@ -649,18 +729,22 @@
- buf_LRU_try_free_flushed_blocks(void)
- /*=================================*/
- {
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&buf_pool_mutex);
-       while (buf_pool->LRU_flush_ended > 0) {
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&buf_pool_mutex);
-               buf_LRU_search_and_free_block(1);
--              buf_pool_mutex_enter();
-+              //buf_pool_mutex_enter();
-+              mutex_enter(&buf_pool_mutex);
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&buf_pool_mutex);
- }
- /******************************************************************//**
-@@ -675,7 +759,9 @@
- {
-       ibool   ret     = FALSE;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-+      mutex_enter(&free_list_mutex);
-       if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
-           + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 4) {
-@@ -683,7 +769,9 @@
-               ret = TRUE;
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-+      mutex_exit(&free_list_mutex);
-       return(ret);
- }
-@@ -699,9 +787,10 @@
- {
-       buf_block_t*    block;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
--      block = (buf_block_t*) UT_LIST_GET_FIRST(buf_pool->free);
-+      mutex_enter(&free_list_mutex);
-+      block = (buf_block_t*) UT_LIST_GET_LAST(buf_pool->free);
-       if (block) {
-               ut_ad(block->page.in_free_list);
-@@ -709,7 +798,9 @@
-               ut_ad(!block->page.in_flush_list);
-               ut_ad(!block->page.in_LRU_list);
-               ut_a(!buf_page_in_file(&block->page));
--              UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
-+              UT_LIST_REMOVE(free, buf_pool->free, (&block->page));
-+
-+              mutex_exit(&free_list_mutex);
-               mutex_enter(&block->mutex);
-@@ -717,6 +808,8 @@
-               UNIV_MEM_ALLOC(block->frame, UNIV_PAGE_SIZE);
-               mutex_exit(&block->mutex);
-+      } else {
-+              mutex_exit(&free_list_mutex);
-       }
-       return(block);
-@@ -738,7 +831,7 @@
-       ibool           mon_value_was   = FALSE;
-       ibool           started_monitor = FALSE;
- loop:
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-       if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
-           + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 20) {
-@@ -806,7 +899,7 @@
-       /* If there is a block in the free list, take it */
-       block = buf_LRU_get_free_only();
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-       if (block) {
-               memset(&block->page.zip, 0, sizeof block->page.zip);
-@@ -868,18 +961,21 @@
-       os_aio_simulated_wake_handler_threads();
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&buf_pool_mutex);
-       if (buf_pool->LRU_flush_ended > 0) {
-               /* We have written pages in an LRU flush. To make the insert
-               buffer more efficient, we try to move these pages to the free
-               list. */
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&buf_pool_mutex);
-               buf_LRU_try_free_flushed_blocks();
-       } else {
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&buf_pool_mutex);
-       }
-       if (n_iterations > 10) {
-@@ -904,7 +1000,8 @@
-       ulint   new_len;
-       ut_a(buf_pool->LRU_old);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-       ut_ad(buf_LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
-       ut_ad(buf_LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
- #if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
-@@ -969,7 +1066,8 @@
- {
-       buf_page_t*     bpage;
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-       ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN);
-       /* We first initialize all blocks in the LRU list as old and then use
-@@ -1002,13 +1100,14 @@
-       ut_ad(buf_pool);
-       ut_ad(bpage);
-       ut_ad(buf_page_in_file(bpage));
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-       if (buf_page_belongs_to_unzip_LRU(bpage)) {
-               buf_block_t*    block = (buf_block_t*) bpage;
-               ut_ad(block->in_unzip_LRU_list);
--              ut_d(block->in_unzip_LRU_list = FALSE);
-+              block->in_unzip_LRU_list = FALSE;
-               UT_LIST_REMOVE(unzip_LRU, buf_pool->unzip_LRU, block);
-       }
-@@ -1024,7 +1123,8 @@
- {
-       ut_ad(buf_pool);
-       ut_ad(bpage);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-       ut_a(buf_page_in_file(bpage));
-@@ -1099,12 +1199,13 @@
- {
-       ut_ad(buf_pool);
-       ut_ad(block);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-       ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
-       ut_ad(!block->in_unzip_LRU_list);
--      ut_d(block->in_unzip_LRU_list = TRUE);
-+      block->in_unzip_LRU_list = TRUE;
-       if (old) {
-               UT_LIST_ADD_LAST(unzip_LRU, buf_pool->unzip_LRU, block);
-@@ -1123,7 +1224,8 @@
- {
-       ut_ad(buf_pool);
-       ut_ad(bpage);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-       ut_a(buf_page_in_file(bpage));
-@@ -1172,7 +1274,8 @@
- {
-       ut_ad(buf_pool);
-       ut_ad(bpage);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-       ut_a(buf_page_in_file(bpage));
-       ut_ad(!bpage->in_LRU_list);
-@@ -1249,7 +1352,8 @@
- /*=====================*/
-       buf_page_t*     bpage)  /*!< in: control block */
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-       if (bpage->old) {
-               buf_pool->stat.n_pages_made_young++;
-@@ -1288,16 +1392,17 @@
- buf_LRU_free_block(
- /*===============*/
-       buf_page_t*     bpage,  /*!< in: block to be freed */
--      ibool           zip)    /*!< in: TRUE if should remove also the
-+      ibool           zip,    /*!< in: TRUE if should remove also the
-                               compressed page of an uncompressed page */
-+      ibool           have_LRU_mutex)
- {
-       buf_page_t*     b = NULL;
-       mutex_t*        block_mutex = buf_page_get_mutex(bpage);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(mutex_own(block_mutex));
-       ut_ad(buf_page_in_file(bpage));
--      ut_ad(bpage->in_LRU_list);
-+      //ut_ad(bpage->in_LRU_list);
-       ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
- #if UNIV_WORD_SIZE == 4
-       /* On 32-bit systems, there is no padding in buf_page_t.  On
-@@ -1306,7 +1411,7 @@
-       UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
- #endif
--      if (!buf_page_can_relocate(bpage)) {
-+      if (!bpage->in_LRU_list || !block_mutex || !buf_page_can_relocate(bpage)) {
-               /* Do not free buffer-fixed or I/O-fixed blocks. */
-               return(FALSE);
-@@ -1340,7 +1445,7 @@
- alloc:
-               b = buf_page_alloc_descriptor();
-               ut_a(b);
--              memcpy(b, bpage, sizeof *b);
-+              //memcpy(b, bpage, sizeof *b);
-       }
- #ifdef UNIV_DEBUG
-@@ -1351,6 +1456,39 @@
-       }
- #endif /* UNIV_DEBUG */
-+      /* not to break latch order, must re-enter block_mutex */
-+      mutex_exit(block_mutex);
-+
-+      if (!have_LRU_mutex)
-+              mutex_enter(&LRU_list_mutex); /* optimistic */
-+      rw_lock_x_lock(&page_hash_latch);
-+      mutex_enter(block_mutex);
-+
-+      /* recheck states of block */
-+      if (!bpage->in_LRU_list || block_mutex != buf_page_get_mutex(bpage)
-+          || !buf_page_can_relocate(bpage)) {
-+not_freed:
-+              if (b) {
-+                      buf_buddy_free(b, sizeof *b, TRUE);
-+              }
-+              if (!have_LRU_mutex)
-+                      mutex_exit(&LRU_list_mutex);
-+              rw_lock_x_unlock(&page_hash_latch);
-+              return(FALSE);
-+      } else if (zip || !bpage->zip.data) {
-+              if (bpage->oldest_modification)
-+                      goto not_freed;
-+      } else if (bpage->oldest_modification) {
-+              if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
-+                      ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY);
-+                      goto not_freed;
-+              }
-+      }
-+
-+      if (b) {
-+              memcpy(b, bpage, sizeof *b);
-+      }
-+
-       if (buf_LRU_block_remove_hashed_page(bpage, zip)
-           != BUF_BLOCK_ZIP_FREE) {
-               ut_a(bpage->buf_fix_count == 0);
-@@ -1362,6 +1500,10 @@
-                       ut_a(!buf_page_hash_get(bpage->space, bpage->offset));
-+                      while (prev_b && !prev_b->in_LRU_list) {
-+                              prev_b = UT_LIST_GET_PREV(LRU, prev_b);
-+                      }
-+
-                       b->state = b->oldest_modification
-                               ? BUF_BLOCK_ZIP_DIRTY
-                               : BUF_BLOCK_ZIP_PAGE;
-@@ -1437,6 +1579,7 @@
-                               buf_LRU_add_block_low(b, buf_page_is_old(b));
-                       }
-+                      mutex_enter(&flush_list_mutex);
-                       if (b->state == BUF_BLOCK_ZIP_PAGE) {
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-                               buf_LRU_insert_zip_clean(b);
-@@ -1445,6 +1588,7 @@
-                               /* Relocate on buf_pool->flush_list. */
-                               buf_flush_relocate_on_flush_list(bpage, b);
-                       }
-+                      mutex_exit(&flush_list_mutex);
-                       bpage->zip.data = NULL;
-                       page_zip_set_size(&bpage->zip, 0);
-@@ -1456,7 +1600,9 @@
-                       b->io_fix = BUF_IO_READ;
-               }
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&LRU_list_mutex);
-+              rw_lock_x_unlock(&page_hash_latch);
-               mutex_exit(block_mutex);
-               /* Remove possible adaptive hash index on the page.
-@@ -1488,7 +1634,9 @@
-                               : BUF_NO_CHECKSUM_MAGIC);
-               }
--              buf_pool_mutex_enter();
-+              //buf_pool_mutex_enter();
-+              if (have_LRU_mutex)
-+                      mutex_enter(&LRU_list_mutex);
-               mutex_enter(block_mutex);
-               if (b) {
-@@ -1498,13 +1646,17 @@
-                       mutex_exit(&buf_pool_zip_mutex);
-               }
--              buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
-+              buf_LRU_block_free_hashed_page((buf_block_t*) bpage, FALSE);
-       } else {
-               /* The block_mutex should have been released by
-               buf_LRU_block_remove_hashed_page() when it returns
-               BUF_BLOCK_ZIP_FREE. */
-               ut_ad(block_mutex == &buf_pool_zip_mutex);
-               mutex_enter(block_mutex);
-+
-+              if (!have_LRU_mutex)
-+                      mutex_exit(&LRU_list_mutex);
-+              rw_lock_x_unlock(&page_hash_latch);
-       }
-       return(TRUE);
-@@ -1516,12 +1668,13 @@
- void
- buf_LRU_block_free_non_file_page(
- /*=============================*/
--      buf_block_t*    block)  /*!< in: block, must not contain a file page */
-+      buf_block_t*    block,  /*!< in: block, must not contain a file page */
-+      ibool           have_page_hash_mutex)
- {
-       void*   data;
-       ut_ad(block);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(mutex_own(&block->mutex));
-       switch (buf_block_get_state(block)) {
-@@ -1555,15 +1708,17 @@
-       if (data) {
-               block->page.zip.data = NULL;
-               mutex_exit(&block->mutex);
--              buf_pool_mutex_exit_forbid();
--              buf_buddy_free(data, page_zip_get_size(&block->page.zip));
--              buf_pool_mutex_exit_allow();
-+              //buf_pool_mutex_exit_forbid();
-+              buf_buddy_free(data, page_zip_get_size(&block->page.zip), have_page_hash_mutex);
-+              //buf_pool_mutex_exit_allow();
-               mutex_enter(&block->mutex);
-               page_zip_set_size(&block->page.zip, 0);
-       }
--      UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page));
-+      mutex_enter(&free_list_mutex);
-+      UT_LIST_ADD_FIRST(free, buf_pool->free, (&block->page));
-       ut_d(block->page.in_free_list = TRUE);
-+      mutex_exit(&free_list_mutex);
-       UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
- }
-@@ -1590,7 +1745,11 @@
- {
-       const buf_page_t*       hashed_bpage;
-       ut_ad(bpage);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-+#ifdef UNIV_SYNC_DEBUG
-+      ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX));
-+#endif
-       ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-       ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
-@@ -1696,7 +1855,9 @@
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-               mutex_exit(buf_page_get_mutex(bpage));
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&LRU_list_mutex);
-+              rw_lock_x_unlock(&page_hash_latch);
-               buf_print();
-               buf_LRU_print();
-               buf_validate();
-@@ -1720,14 +1881,14 @@
-               ut_a(buf_page_get_zip_size(bpage));
- #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
--              UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
-+              UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, bpage);
- #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-               mutex_exit(&buf_pool_zip_mutex);
--              buf_pool_mutex_exit_forbid();
-+              //buf_pool_mutex_exit_forbid();
-               buf_buddy_free(bpage->zip.data,
--                             page_zip_get_size(&bpage->zip));
--              buf_pool_mutex_exit_allow();
-+                             page_zip_get_size(&bpage->zip), TRUE);
-+              //buf_pool_mutex_exit_allow();
-               buf_page_free_descriptor(bpage);
-               return(BUF_BLOCK_ZIP_FREE);
-@@ -1749,9 +1910,9 @@
-                       ut_ad(!bpage->in_flush_list);
-                       ut_ad(!bpage->in_LRU_list);
-                       mutex_exit(&((buf_block_t*) bpage)->mutex);
--                      buf_pool_mutex_exit_forbid();
--                      buf_buddy_free(data, page_zip_get_size(&bpage->zip));
--                      buf_pool_mutex_exit_allow();
-+                      //buf_pool_mutex_exit_forbid();
-+                      buf_buddy_free(data, page_zip_get_size(&bpage->zip), TRUE);
-+                      //buf_pool_mutex_exit_allow();
-                       mutex_enter(&((buf_block_t*) bpage)->mutex);
-                       page_zip_set_size(&bpage->zip, 0);
-               }
-@@ -1777,15 +1938,16 @@
- void
- buf_LRU_block_free_hashed_page(
- /*===========================*/
--      buf_block_t*    block)  /*!< in: block, must contain a file page and
-+      buf_block_t*    block,  /*!< in: block, must contain a file page and
-                               be in a state where it can be freed */
-+      ibool           have_page_hash_mutex)
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(mutex_own(&block->mutex));
-       buf_block_set_state(block, BUF_BLOCK_MEMORY);
--      buf_LRU_block_free_non_file_page(block);
-+      buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
- }
- /**********************************************************************//**
-@@ -1811,7 +1973,8 @@
-       }
-       if (adjust) {
--              buf_pool_mutex_enter();
-+              //buf_pool_mutex_enter();
-+              mutex_enter(&LRU_list_mutex);
-               if (ratio != buf_LRU_old_ratio) {
-                       buf_LRU_old_ratio = ratio;
-@@ -1822,7 +1985,8 @@
-                       }
-               }
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&LRU_list_mutex);
-       } else {
-               buf_LRU_old_ratio = ratio;
-       }
-@@ -1848,7 +2012,8 @@
-               goto func_exit;
-       }
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&buf_pool_mutex);
-       /* Update the index. */
-       item = &buf_LRU_stat_arr[buf_LRU_stat_arr_ind];
-@@ -1869,7 +2034,8 @@
-       /* Put current entry in the array. */
-       memcpy(item, &cur_stat, sizeof *item);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&buf_pool_mutex);
- func_exit:
-       /* Clear the current entry. */
-@@ -1891,7 +2057,8 @@
-       ulint           new_len;
-       ut_ad(buf_pool);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-       if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
-@@ -1951,16 +2118,22 @@
-       ut_a(buf_pool->LRU_old_len == old_len);
--      UT_LIST_VALIDATE(list, buf_page_t, buf_pool->free,
-+      mutex_exit(&LRU_list_mutex);
-+      mutex_enter(&free_list_mutex);
-+
-+      UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free,
-                        ut_ad(ut_list_node_313->in_free_list));
-       for (bpage = UT_LIST_GET_FIRST(buf_pool->free);
-            bpage != NULL;
--           bpage = UT_LIST_GET_NEXT(list, bpage)) {
-+           bpage = UT_LIST_GET_NEXT(free, bpage)) {
-               ut_a(buf_page_get_state(bpage) == BUF_BLOCK_NOT_USED);
-       }
-+      mutex_exit(&free_list_mutex);
-+      mutex_enter(&LRU_list_mutex);
-+
-       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));
-@@ -1974,7 +2147,8 @@
-               ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
-       return(TRUE);
- }
- #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-@@ -1990,7 +2164,8 @@
-       const buf_page_t*       bpage;
-       ut_ad(buf_pool);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&LRU_list_mutex);
-       bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-@@ -2047,6 +2222,7 @@
-               bpage = UT_LIST_GET_NEXT(LRU, bpage);
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&LRU_list_mutex);
- }
- #endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
---- a/storage/innodb_plugin/buf/buf0rea.c
-+++ b/storage/innodb_plugin/buf/buf0rea.c
-@@ -233,18 +233,22 @@
-               high = fil_space_get_size(space);
-       }
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&buf_pool_mutex);
-       if (buf_pool->n_pend_reads
-           > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&buf_pool_mutex);
-               return(0);
-       }
-+      mutex_exit(&buf_pool_mutex);
-       /* Count how many blocks in the area have been recently accessed,
-       that is, reside near the start of the LRU list. */
-+      rw_lock_s_lock(&page_hash_latch);
-       for (i = low; i < high; i++) {
-               const buf_page_t*       bpage = buf_page_hash_get(space, i);
-@@ -256,13 +260,15 @@
-                       if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
--                              buf_pool_mutex_exit();
-+                              //buf_pool_mutex_exit();
-+                              rw_lock_s_unlock(&page_hash_latch);
-                               goto read_ahead;
-                       }
-               }
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_s_unlock(&page_hash_latch);
-       /* Do nothing */
-       return(0);
-@@ -460,10 +466,12 @@
-       tablespace_version = fil_space_get_version(space);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&buf_pool_mutex);
-       if (high > fil_space_get_size(space)) {
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&buf_pool_mutex);
-               /* The area is not whole, return */
-               return(0);
-@@ -471,10 +479,12 @@
-       if (buf_pool->n_pend_reads
-           > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              mutex_exit(&buf_pool_mutex);
-               return(0);
-       }
-+      mutex_exit(&buf_pool_mutex);
-       /* Check that almost all pages in the area have been accessed; if
-       offset == low, the accesses must be in a descending order, otherwise,
-@@ -493,6 +503,7 @@
-       fail_count = 0;
-+      rw_lock_s_lock(&page_hash_latch);
-       for (i = low; i < high; i++) {
-               bpage = buf_page_hash_get(space, i);
-@@ -520,7 +531,8 @@
-               if (fail_count > threshold) {
-                       /* Too many failures: return */
--                      buf_pool_mutex_exit();
-+                      //buf_pool_mutex_exit();
-+                      rw_lock_s_unlock(&page_hash_latch);
-                       return(0);
-               }
-@@ -535,7 +547,8 @@
-       bpage = buf_page_hash_get(space, offset);
-       if (bpage == NULL) {
--              buf_pool_mutex_exit();
-+              //buf_pool_mutex_exit();
-+              rw_lock_s_unlock(&page_hash_latch);
-               return(0);
-       }
-@@ -561,7 +574,8 @@
-       pred_offset = fil_page_get_prev(frame);
-       succ_offset = fil_page_get_next(frame);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_s_unlock(&page_hash_latch);
-       if ((offset == low) && (succ_offset == offset + 1)) {
---- a/storage/innodb_plugin/handler/i_s.cc
-+++ b/storage/innodb_plugin/handler/i_s.cc
-@@ -2229,7 +2229,8 @@
-       RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&zip_free_mutex);
-       for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
-               buf_buddy_stat_t*       buddy_stat = &buf_buddy_stat[x];
-@@ -2255,7 +2256,8 @@
-               }
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&zip_free_mutex);
-       DBUG_RETURN(status);
- }
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -33,5 +33,6 @@
- {"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
- {"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
- {"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/buf0buddy.h
-+++ b/storage/innodb_plugin/include/buf0buddy.h
-@@ -46,9 +46,10 @@
- /*============*/
-       ulint   size,   /*!< in: compressed page size
-                       (between PAGE_ZIP_MIN_SIZE and UNIV_PAGE_SIZE) */
--      ibool*  lru)    /*!< in: pointer to a variable that will be assigned
-+      ibool*  lru,    /*!< in: pointer to a variable that will be assigned
-                       TRUE if storage was allocated from the LRU list
-                       and buf_pool_mutex was temporarily released */
-+      ibool   have_page_hash_mutex)
-       __attribute__((malloc, nonnull));
- /**********************************************************************//**
- Release a block. */
-@@ -58,7 +59,8 @@
- /*===========*/
-       void*   buf,    /*!< in: block to be freed, must not be
-                       pointed to by the buffer pool */
--      ulint   size)   /*!< in: block size, up to UNIV_PAGE_SIZE */
-+      ulint   size,   /*!< in: block size, up to UNIV_PAGE_SIZE */
-+      ibool   have_page_hash_mutex)
-       __attribute__((nonnull));
- /** Statistics of buddy blocks of a given size. */
---- a/storage/innodb_plugin/include/buf0buddy.ic
-+++ b/storage/innodb_plugin/include/buf0buddy.ic
-@@ -44,9 +44,10 @@
- /*================*/
-       ulint   i,      /*!< in: index of buf_pool->zip_free[],
-                       or BUF_BUDDY_SIZES */
--      ibool*  lru)    /*!< in: pointer to a variable that will be assigned
-+      ibool*  lru,    /*!< in: pointer to a variable that will be assigned
-                       TRUE if storage was allocated from the LRU list
-                       and buf_pool_mutex was temporarily released */
-+      ibool   have_page_hash_mutex)
-       __attribute__((malloc, nonnull));
- /**********************************************************************//**
-@@ -57,8 +58,9 @@
- /*===============*/
-       void*   buf,    /*!< in: block to be freed, must not be
-                       pointed to by the buffer pool */
--      ulint   i)      /*!< in: index of buf_pool->zip_free[],
-+      ulint   i,      /*!< in: index of buf_pool->zip_free[],
-                       or BUF_BUDDY_SIZES */
-+      ibool   have_page_hash_mutex)
-       __attribute__((nonnull));
- /**********************************************************************//**
-@@ -94,16 +96,17 @@
- /*============*/
-       ulint   size,   /*!< in: compressed page size
-                       (between PAGE_ZIP_MIN_SIZE and UNIV_PAGE_SIZE) */
--      ibool*  lru)    /*!< in: pointer to a variable that will be assigned
-+      ibool*  lru,    /*!< in: pointer to a variable that will be assigned
-                       TRUE if storage was allocated from the LRU list
-                       and buf_pool_mutex was temporarily released */
-+      ibool   have_page_hash_mutex)
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(ut_is_2pow(size));
-       ut_ad(size >= PAGE_ZIP_MIN_SIZE);
-       ut_ad(size <= UNIV_PAGE_SIZE);
--      return((byte*) buf_buddy_alloc_low(buf_buddy_get_slot(size), lru));
-+      return((byte*) buf_buddy_alloc_low(buf_buddy_get_slot(size), lru, have_page_hash_mutex));
- }
- /**********************************************************************//**
-@@ -114,14 +117,27 @@
- /*===========*/
-       void*   buf,    /*!< in: block to be freed, must not be
-                       pointed to by the buffer pool */
--      ulint   size)   /*!< in: block size, up to UNIV_PAGE_SIZE */
-+      ulint   size,   /*!< in: block size, up to UNIV_PAGE_SIZE */
-+      ibool   have_page_hash_mutex)
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(ut_is_2pow(size));
-       ut_ad(size >= PAGE_ZIP_MIN_SIZE);
-       ut_ad(size <= UNIV_PAGE_SIZE);
--      buf_buddy_free_low(buf, buf_buddy_get_slot(size));
-+      if (!have_page_hash_mutex) {
-+              mutex_enter(&LRU_list_mutex);
-+              rw_lock_x_lock(&page_hash_latch);
-+      }
-+
-+      mutex_enter(&zip_free_mutex);
-+      buf_buddy_free_low(buf, buf_buddy_get_slot(size), TRUE);
-+      mutex_exit(&zip_free_mutex);
-+
-+      if (!have_page_hash_mutex) {
-+              mutex_exit(&LRU_list_mutex);
-+              rw_lock_x_unlock(&page_hash_latch);
-+      }
- }
- #ifdef UNIV_MATERIALIZE
---- a/storage/innodb_plugin/include/buf0buf.h
-+++ b/storage/innodb_plugin/include/buf0buf.h
-@@ -761,6 +761,15 @@
-       const buf_page_t*       bpage)  /*!< in: pointer to control block */
-       __attribute__((pure));
-+/*************************************************************************
-+Gets the mutex of a block and enter the mutex with consistency. */
-+UNIV_INLINE
-+mutex_t*
-+buf_page_get_mutex_enter(
-+/*=========================*/
-+      const buf_page_t*       bpage)  /*!< in: pointer to control block */
-+      __attribute__((pure));
-+
- /*********************************************************************//**
- Get the flush type of a page.
- @return       flush type */
-@@ -1114,7 +1123,7 @@
-       All these are protected by buf_pool_mutex. */
-       /* @{ */
--      UT_LIST_NODE_T(buf_page_t) list;
-+      /* UT_LIST_NODE_T(buf_page_t) list; */
-                                       /*!< based on state, this is a
-                                       list node, protected only by
-                                       buf_pool_mutex, in one of the
-@@ -1134,6 +1143,10 @@
-                                       BUF_BLOCK_REMOVE_HASH or
-                                       BUF_BLOCK_READY_IN_USE. */
-+      /* resplit for optimistic use */
-+      UT_LIST_NODE_T(buf_page_t) free;
-+      UT_LIST_NODE_T(buf_page_t) flush_list;
-+      UT_LIST_NODE_T(buf_page_t) zip_list; /* zip_clean or zip_free[] */
- #ifdef UNIV_DEBUG
-       ibool           in_flush_list;  /*!< TRUE if in buf_pool->flush_list;
-                                       when buf_pool_mutex is free, the
-@@ -1214,11 +1227,11 @@
-                                       a block is in the unzip_LRU list
-                                       if page.state == BUF_BLOCK_FILE_PAGE
-                                       and page.zip.data != NULL */
--#ifdef UNIV_DEBUG
-+//#ifdef UNIV_DEBUG
-       ibool           in_unzip_LRU_list;/*!< TRUE if the page is in the
-                                       decompressed LRU list;
-                                       used in debugging */
--#endif /* UNIV_DEBUG */
-+//#endif /* UNIV_DEBUG */
-       mutex_t         mutex;          /*!< mutex protecting this block:
-                                       state (also protected by the buffer
-                                       pool mutex), io_fix, buf_fix_count,
-@@ -1498,6 +1511,12 @@
- /** mutex protecting the buffer pool struct and control blocks, except the
- read-write lock in them */
- extern mutex_t        buf_pool_mutex;
-+extern mutex_t        LRU_list_mutex;
-+extern mutex_t        flush_list_mutex;
-+extern rw_lock_t      page_hash_latch;
-+extern mutex_t        free_list_mutex;
-+extern mutex_t        zip_free_mutex;
-+extern mutex_t        zip_hash_mutex;
- /** mutex protecting the control blocks of compressed-only pages
- (of type buf_page_t, not buf_block_t) */
- extern mutex_t        buf_pool_zip_mutex;
-@@ -1509,8 +1528,8 @@
- /** Test if buf_pool_mutex is owned. */
- #define buf_pool_mutex_own() mutex_own(&buf_pool_mutex)
- /** Acquire the buffer pool mutex. */
-+/* the buf_pool_mutex is changed the latch order */
- #define buf_pool_mutex_enter() do {           \
--      ut_ad(!mutex_own(&buf_pool_zip_mutex)); \
-       mutex_enter(&buf_pool_mutex);           \
- } while (0)
---- a/storage/innodb_plugin/include/buf0buf.ic
-+++ b/storage/innodb_plugin/include/buf0buf.ic
-@@ -137,7 +137,9 @@
-       buf_page_t*     bpage;
-       ib_uint64_t     lsn;
--      buf_pool_mutex_enter();
-+try_again:
-+      //buf_pool_mutex_enter();
-+      mutex_enter(&flush_list_mutex);
-       bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
-@@ -146,9 +148,14 @@
-       } else {
-               ut_ad(bpage->in_flush_list);
-               lsn = bpage->oldest_modification;
-+              if (lsn == 0) {
-+                      mutex_exit(&flush_list_mutex);
-+                      goto try_again;
-+              }
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      mutex_exit(&flush_list_mutex);
-       /* The returned answer may be out of date: the flush_list can
-       change after the mutex has been released. */
-@@ -268,7 +275,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. */
--              ut_error;
-+              /* ut_error; */ /* optimistic */
-               break;
-       case BUF_BLOCK_ZIP_PAGE:
-       case BUF_BLOCK_ZIP_DIRTY:
-@@ -311,7 +318,7 @@
- {
-       switch (buf_page_get_state(bpage)) {
-       case BUF_BLOCK_ZIP_FREE:
--              ut_error;
-+              /* ut_error; */ /* optimistic */
-               return(NULL);
-       case BUF_BLOCK_ZIP_PAGE:
-       case BUF_BLOCK_ZIP_DIRTY:
-@@ -321,6 +328,28 @@
-       }
- }
-+/*************************************************************************
-+Gets the mutex of a block and enter the mutex with consistency. */
-+UNIV_INLINE
-+mutex_t*
-+buf_page_get_mutex_enter(
-+/*=========================*/
-+      const buf_page_t*       bpage)  /*!< in: pointer to control block */
-+{
-+      mutex_t*        block_mutex;
-+
-+      while(1) {
-+              block_mutex = buf_page_get_mutex(bpage);
-+              if (!block_mutex)
-+                      return block_mutex;
-+
-+              mutex_enter(block_mutex);
-+              if (block_mutex == buf_page_get_mutex(bpage))
-+                      return block_mutex;
-+              mutex_exit(block_mutex);
-+      }
-+}
-+
- /*********************************************************************//**
- Get the flush type of a page.
- @return       flush type */
-@@ -416,7 +445,7 @@
-       buf_page_t*     bpage,  /*!< in/out: control block */
-       enum buf_io_fix io_fix) /*!< in: io_fix state */
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-       bpage->io_fix = io_fix;
-@@ -444,12 +473,13 @@
- /*==================*/
-       const buf_page_t*       bpage)  /*!< control block being relocated */
- {
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-       ut_ad(buf_page_in_file(bpage));
--      ut_ad(bpage->in_LRU_list);
-+      /* optimistic */
-+      //ut_ad(bpage->in_LRU_list);
--      return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
-+      return(bpage->in_LRU_list && bpage->io_fix == BUF_IO_NONE
-              && bpage->buf_fix_count == 0);
- }
-@@ -463,7 +493,7 @@
-       const buf_page_t*       bpage)  /*!< in: control block */
- {
-       ut_ad(buf_page_in_file(bpage));
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
-       return(bpage->old);
- }
-@@ -478,7 +508,8 @@
-       ibool           old)    /*!< in: old */
- {
-       ut_a(buf_page_in_file(bpage));
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(&LRU_list_mutex));
-       ut_ad(bpage->in_LRU_list);
- #ifdef UNIV_LRU_DEBUG
-@@ -525,7 +556,8 @@
-       ulint           time_ms)        /*!< in: ut_time_ms() */
- {
-       ut_a(buf_page_in_file(bpage));
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+      ut_ad(mutex_own(buf_page_get_mutex(bpage)));
-       if (!bpage->access_time) {
-               /* Make this the time of the first access. */
-@@ -784,17 +816,17 @@
- /*===========*/
-       buf_block_t*    block)  /*!< in, own: block to be freed */
- {
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-       mutex_enter(&block->mutex);
-       ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
--      buf_LRU_block_free_non_file_page(block);
-+      buf_LRU_block_free_non_file_page(block, FALSE);
-       mutex_exit(&block->mutex);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
- }
- #endif /* !UNIV_HOTBACKUP */
-@@ -842,17 +874,17 @@
-                                       page frame */
- {
-       ib_uint64_t     lsn;
--      mutex_t*        block_mutex = buf_page_get_mutex(bpage);
-+      mutex_t*        block_mutex = buf_page_get_mutex_enter(bpage);
--      mutex_enter(block_mutex);
--
--      if (buf_page_in_file(bpage)) {
-+      if (block_mutex && buf_page_in_file(bpage)) {
-               lsn = bpage->newest_modification;
-       } else {
-               lsn = 0;
-       }
--      mutex_exit(block_mutex);
-+      if (block_mutex) {
-+              mutex_exit(block_mutex);
-+      }
-       return(lsn);
- }
-@@ -868,7 +900,7 @@
-       buf_block_t*    block)  /*!< in: block */
- {
- #ifdef UNIV_SYNC_DEBUG
--      ut_ad((buf_pool_mutex_own()
-+      ut_ad((mutex_own(&LRU_list_mutex)
-              && (block->page.buf_fix_count == 0))
-             || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
- #endif /* UNIV_SYNC_DEBUG */
-@@ -947,7 +979,11 @@
-       ulint           fold;
-       ut_ad(buf_pool);
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-+#ifdef UNIV_SYNC_DEBUG
-+      ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX)
-+            || rw_lock_own(&page_hash_latch, RW_LOCK_SHARED));
-+#endif
-       /* Look for the page in the hash table */
-@@ -1002,11 +1038,13 @@
- {
-       const buf_page_t*       bpage;
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-+      rw_lock_s_lock(&page_hash_latch);
-       bpage = buf_page_hash_get(space, offset);
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      rw_lock_s_unlock(&page_hash_latch);
-       return(bpage != NULL);
- }
-@@ -1061,18 +1099,21 @@
-       buf_block_t*    block,          /*!< in: buffer block */
-       ulint           rw_latch,       /*!< in: RW_S_LATCH, RW_X_LATCH,
-                                       RW_NO_LATCH */
--      mtr_t*          mtr)            /*!< in: mtr */
-+      mtr_t*          mtr __attribute__((unused)))            /*!< in: mtr */
- {
-       ut_ad(block);
-       ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-       ut_a(block->page.buf_fix_count > 0);
-+      /* buf_flush_note_modification() should be called before this function. */
-+/*
-       if (rw_latch == RW_X_LATCH && mtr->modifications) {
-               buf_pool_mutex_enter();
-               buf_flush_note_modification(block, mtr);
-               buf_pool_mutex_exit();
-       }
-+*/
-       mutex_enter(&block->mutex);
---- a/storage/innodb_plugin/include/buf0flu.ic
-+++ b/storage/innodb_plugin/include/buf0flu.ic
-@@ -55,13 +55,23 @@
-       buf_block_t*    block,  /*!< in: block which is modified */
-       mtr_t*          mtr)    /*!< in: mtr */
- {
-+      ibool   use_LRU_mutex = FALSE;
-+
-+      if (UT_LIST_GET_LEN(buf_pool->unzip_LRU))
-+              use_LRU_mutex = TRUE;
-+
-+      if (use_LRU_mutex)
-+              mutex_enter(&LRU_list_mutex);
-+
-+      mutex_enter(&block->mutex);
-+
-       ut_ad(block);
-       ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-       ut_ad(block->page.buf_fix_count > 0);
- #ifdef UNIV_SYNC_DEBUG
-       ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
- #endif /* UNIV_SYNC_DEBUG */
--      ut_ad(buf_pool_mutex_own());
-+      //ut_ad(buf_pool_mutex_own());
-       ut_ad(mtr->start_lsn != 0);
-       ut_ad(mtr->modifications);
-@@ -70,16 +80,23 @@
-       block->page.newest_modification = mtr->end_lsn;
-       if (!block->page.oldest_modification) {
-+              mutex_enter(&flush_list_mutex);
-               block->page.oldest_modification = mtr->start_lsn;
-               ut_ad(block->page.oldest_modification != 0);
-               buf_flush_insert_into_flush_list(block);
-+              mutex_exit(&flush_list_mutex);
-       } else {
-               ut_ad(block->page.oldest_modification <= mtr->start_lsn);
-       }
-+      mutex_exit(&block->mutex);
-+
-       ++srv_buf_pool_write_requests;
-+
-+      if (use_LRU_mutex)
-+              mutex_exit(&LRU_list_mutex);
- }
- /********************************************************************//**
-@@ -94,6 +111,16 @@
-       ib_uint64_t     end_lsn)        /*!< in: end lsn of the last mtr in the
-                                       set of mtr's */
- {
-+      ibool   use_LRU_mutex = FALSE;
-+
-+      if(UT_LIST_GET_LEN(buf_pool->unzip_LRU))
-+              use_LRU_mutex = TRUE;
-+
-+      if (use_LRU_mutex)
-+              mutex_enter(&LRU_list_mutex);
-+
-+      mutex_enter(&(block->mutex));
-+
-       ut_ad(block);
-       ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-       ut_ad(block->page.buf_fix_count > 0);
-@@ -101,23 +128,28 @@
-       ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
- #endif /* UNIV_SYNC_DEBUG */
--      buf_pool_mutex_enter();
-+      //buf_pool_mutex_enter();
-       ut_ad(block->page.newest_modification <= end_lsn);
-       block->page.newest_modification = end_lsn;
-       if (!block->page.oldest_modification) {
-+              mutex_enter(&flush_list_mutex);
-               block->page.oldest_modification = start_lsn;
-               ut_ad(block->page.oldest_modification != 0);
-               buf_flush_insert_sorted_into_flush_list(block);
-+              mutex_exit(&flush_list_mutex);
-       } else {
-               ut_ad(block->page.oldest_modification <= start_lsn);
-       }
--      buf_pool_mutex_exit();
-+      //buf_pool_mutex_exit();
-+      if (use_LRU_mutex)
-+              mutex_exit(&LRU_list_mutex);
-+      mutex_exit(&(block->mutex));
- }
- #endif /* !UNIV_HOTBACKUP */
---- a/storage/innodb_plugin/include/buf0lru.h
-+++ b/storage/innodb_plugin/include/buf0lru.h
-@@ -99,8 +99,9 @@
- buf_LRU_free_block(
- /*===============*/
-       buf_page_t*     bpage,  /*!< in: block to be freed */
--      ibool           zip)    /*!< in: TRUE if should remove also the
-+      ibool           zip,    /*!< in: TRUE if should remove also the
-                               compressed page of an uncompressed page */
-+      ibool           have_LRU_mutex)
-       __attribute__((nonnull));
- /******************************************************************//**
- Try to free a replaceable block.
-@@ -142,7 +143,8 @@
- void
- buf_LRU_block_free_non_file_page(
- /*=============================*/
--      buf_block_t*    block); /*!< in: block, must not contain a file page */
-+      buf_block_t*    block,  /*!< in: block, must not contain a file page */
-+      ibool           have_page_hash_mutex);
- /******************************************************************//**
- Adds a block to the LRU list. */
- UNIV_INTERN
---- a/storage/innodb_plugin/include/sync0sync.h
-+++ b/storage/innodb_plugin/include/sync0sync.h
-@@ -489,8 +489,14 @@
-                                       SYNC_SEARCH_SYS, as memory allocation
-                                       can call routines there! Otherwise
-                                       the level is SYNC_MEM_HASH. */
-+#define SYNC_BUF_LRU_LIST     157
-+#define SYNC_BUF_PAGE_HASH    156
-+#define       SYNC_BUF_BLOCK          155
-+#define SYNC_BUF_FREE_LIST    153
-+#define SYNC_BUF_ZIP_FREE     152
-+#define SYNC_BUF_ZIP_HASH     151
- #define       SYNC_BUF_POOL           150
--#define       SYNC_BUF_BLOCK          149
-+#define SYNC_BUF_FLUSH_LIST   149
- #define SYNC_DOUBLEWRITE      140
- #define       SYNC_ANY_LATCH          135
- #define SYNC_THR_LOCAL                133
-@@ -521,7 +527,7 @@
-               os_fast_mutex;  /*!< We use this OS mutex in place of lock_word
-                               when atomic operations are not enabled */
- #endif
--      ulint   waiters;        /*!< This ulint is set to 1 if there are (or
-+      volatile ulint  waiters;        /*!< This ulint is set to 1 if there are (or
-                               may be) threads waiting in the global wait
-                               array for this mutex to be released.
-                               Otherwise, this is 0. */
---- a/storage/innodb_plugin/mtr/mtr0mtr.c
-+++ b/storage/innodb_plugin/mtr/mtr0mtr.c
-@@ -33,6 +33,7 @@
- #include "page0types.h"
- #include "mtr0log.h"
- #include "log0log.h"
-+#include "buf0flu.h"
- #ifndef UNIV_HOTBACKUP
- # include "log0recv.h"
-@@ -105,6 +106,38 @@
-       }
- }
-+UNIV_INLINE
-+void
-+mtr_memo_note_modification_all(
-+/*===========================*/
-+      mtr_t*  mtr)    /* in: mtr */
-+{
-+      mtr_memo_slot_t* slot;
-+      dyn_array_t*    memo;
-+      ulint           offset;
-+
-+      ut_ad(mtr);
-+      ut_ad(mtr->magic_n == MTR_MAGIC_N);
-+      ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
-+                                           commit */
-+      ut_ad(mtr->modifications);
-+
-+      memo = &(mtr->memo);
-+
-+      offset = dyn_array_get_data_size(memo);
-+
-+      while (offset > 0) {
-+              offset -= sizeof(mtr_memo_slot_t);
-+              slot = dyn_array_get_element(memo, offset);
-+
-+              if (UNIV_LIKELY(slot->object != NULL) &&
-+                  slot->type == MTR_MEMO_PAGE_X_FIX) {
-+                      buf_flush_note_modification(
-+                              (buf_block_t*)slot->object, mtr);
-+              }
-+      }
-+}
-+
- /************************************************************//**
- Writes the contents of a mini-transaction log, if any, to the database log. */
- static
-@@ -188,6 +221,8 @@
-       if (write_log) {
-               mtr_log_reserve_and_write(mtr);
-+
-+              mtr_memo_note_modification_all(mtr);
-       }
-       /* We first update the modification info to buffer pages, and only
-@@ -198,11 +233,13 @@
-       required when we insert modified buffer pages in to the flush list
-       which must be sorted on oldest_modification. */
--      mtr_memo_pop_all(mtr);
--
-       if (write_log) {
-               log_release();
-       }
-+
-+      /* All unlocking has been moved here, after log_sys mutex release. */
-+      mtr_memo_pop_all(mtr);
-+
- #endif /* !UNIV_HOTBACKUP */
-       ut_d(mtr->state = MTR_COMMITTED);
-@@ -239,6 +276,12 @@
-               slot = dyn_array_get_element(memo, offset);
-               if ((object == slot->object) && (type == slot->type)) {
-+                      if (mtr->modifications &&
-+                          UNIV_LIKELY(slot->object != NULL) &&
-+                          slot->type == MTR_MEMO_PAGE_X_FIX) {
-+                              buf_flush_note_modification(
-+                                      (buf_block_t*)slot->object, mtr);
-+                      }
-                       mtr_memo_slot_release(mtr, slot);
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -2873,7 +2873,7 @@
-                                       mutex_exit(&(log_sys->mutex));
--                                      buf_pool_mutex_enter();
-+                                      mutex_enter(&flush_list_mutex);
-                                       level = 0;
-                                       bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-@@ -2895,7 +2895,7 @@
-                                               bpl = 0;
-                                       }
--                                      buf_pool_mutex_exit();
-+                                      mutex_exit(&flush_list_mutex);
-                                       if (!srv_use_doublewrite_buf) {
-                                               /* flush is faster than when doublewrite */
---- a/storage/innodb_plugin/sync/sync0sync.c
-+++ b/storage/innodb_plugin/sync/sync0sync.c
-@@ -254,7 +254,7 @@
-       mutex->lock_word = 0;
- #endif
-       mutex->event = os_event_create(NULL);
--      mutex_set_waiters(mutex, 0);
-+      mutex->waiters = 0;
- #ifdef UNIV_DEBUG
-       mutex->magic_n = MUTEX_MAGIC_N;
- #endif /* UNIV_DEBUG */
-@@ -432,6 +432,15 @@
-       mutex_t*        mutex,  /*!< in: mutex */
-       ulint           n)      /*!< in: value to set */
- {
-+#ifdef INNODB_RW_LOCKS_USE_ATOMICS
-+      ut_ad(mutex);
-+
-+      if (n) {
-+              os_compare_and_swap_ulint(&mutex->waiters, 0, 1);
-+      } else {
-+              os_compare_and_swap_ulint(&mutex->waiters, 1, 0);
-+      }
-+#else
-       volatile ulint* ptr;            /* declared volatile to ensure that
-                                       the value is stored to memory */
-       ut_ad(mutex);
-@@ -440,6 +449,7 @@
-       *ptr = n;               /* Here we assume that the write of a single
-                               word in memory is atomic */
-+#endif
- }
- /******************************************************************//**
-@@ -1158,6 +1168,12 @@
-       case SYNC_TRX_SYS_HEADER:
-       case SYNC_FILE_FORMAT_TAG:
-       case SYNC_DOUBLEWRITE:
-+      case SYNC_BUF_LRU_LIST:
-+      case SYNC_BUF_FLUSH_LIST:
-+      case SYNC_BUF_PAGE_HASH:
-+      case SYNC_BUF_FREE_LIST:
-+      case SYNC_BUF_ZIP_FREE:
-+      case SYNC_BUF_ZIP_HASH:
-       case SYNC_BUF_POOL:
-       case SYNC_SEARCH_SYS:
-       case SYNC_SEARCH_SYS_CONF:
-@@ -1186,7 +1202,7 @@
-               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));
--                      ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL));
-+                      ut_a(sync_thread_levels_contain(array, SYNC_BUF_LRU_LIST));
-               }
-               break;
-       case SYNC_REC_LOCK:
diff --git a/mysql-innodb_stats.patch b/mysql-innodb_stats.patch
deleted file mode 100644 (file)
index 7f86351..0000000
+++ /dev/null
@@ -1,1830 +0,0 @@
-# name       : innodb_stats.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/dict/dict0boot.c
-+++ b/storage/innodb_plugin/dict/dict0boot.c
-@@ -263,6 +263,29 @@
-       /* Get the dictionary header */
-       dict_hdr = dict_hdr_get(&mtr);
-+      if (ut_dulint_cmp(mtr_read_dulint(dict_hdr + DICT_HDR_XTRADB_MARK, &mtr),
-+                        DICT_HDR_XTRADB_FLAG) != 0) {
-+              /* not extended yet by XtraDB, need to be extended */
-+              ulint   root_page_no;
-+
-+              root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
-+                                        DICT_HDR_SPACE, 0, DICT_STATS_ID,
-+                                        dict_ind_redundant, &mtr);
-+              if (root_page_no == FIL_NULL) {
-+                      fprintf(stderr, "InnoDB: Warning: failed to create SYS_STATS btr.\n");
-+                      srv_use_sys_stats_table = FALSE;
-+              } else {
-+                      mlog_write_ulint(dict_hdr + DICT_HDR_STATS, root_page_no,
-+                                       MLOG_4BYTES, &mtr);
-+                      mlog_write_dulint(dict_hdr + DICT_HDR_XTRADB_MARK,
-+                                        DICT_HDR_XTRADB_FLAG, &mtr);
-+              }
-+              mtr_commit(&mtr);
-+              /* restart mtr */
-+              mtr_start(&mtr);
-+              dict_hdr = dict_hdr_get(&mtr);
-+      }
-+
-       /* Because we only write new row ids to disk-based data structure
-       (dictionary header) when it is divisible by
-       DICT_HDR_ROW_ID_WRITE_MARGIN, in recovery we will not recover
-@@ -424,7 +447,7 @@
-       table->id = DICT_FIELDS_ID;
-       dict_table_add_to_cache(table, heap);
-       dict_sys->sys_fields = table;
--      mem_heap_free(heap);
-+      mem_heap_empty(heap);
-       index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
-                                     DICT_HDR_SPACE,
-@@ -441,6 +464,45 @@
-                                       FALSE);
-       ut_a(error == DB_SUCCESS);
-+      /*-------------------------*/
-+      table = dict_mem_table_create("SYS_STATS", DICT_HDR_SPACE, 4, 0);
-+      table->n_mysql_handles_opened = 1; /* for pin */
-+
-+      dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
-+      dict_mem_table_add_col(table, heap, "KEY_COLS", DATA_INT, 0, 4);
-+      dict_mem_table_add_col(table, heap, "DIFF_VALS", DATA_BINARY, 0, 0);
-+      dict_mem_table_add_col(table, heap, "NON_NULL_VALS", DATA_BINARY, 0, 0);
-+
-+      /* The '+ 2' below comes from the fields DB_TRX_ID, DB_ROLL_PTR */
-+#if DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2
-+#error "DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2"
-+#endif
-+#if DICT_SYS_STATS_NON_NULL_VALS_FIELD != 3 + 2
-+#error "DICT_SYS_STATS_NON_NULL_VALS_FIELD != 3 + 2"
-+#endif
-+
-+      table->id = DICT_STATS_ID;
-+      dict_table_add_to_cache(table, heap);
-+      dict_sys->sys_stats = table;
-+      mem_heap_empty(heap);
-+
-+      index = dict_mem_index_create("SYS_STATS", "CLUST_IND",
-+                                    DICT_HDR_SPACE,
-+                                    DICT_UNIQUE | DICT_CLUSTERED, 2);
-+
-+      dict_mem_index_add_field(index, "INDEX_ID", 0);
-+      dict_mem_index_add_field(index, "KEY_COLS", 0);
-+
-+      index->id = DICT_STATS_ID;
-+      error = dict_index_add_to_cache(table, index,
-+                                      mtr_read_ulint(dict_hdr
-+                                                     + DICT_HDR_STATS,
-+                                                     MLOG_4BYTES, &mtr),
-+                                      FALSE);
-+      ut_a(error == DB_SUCCESS);
-+
-+      mem_heap_free(heap);
-+
-       mtr_commit(&mtr);
-       /*-------------------------*/
-@@ -454,6 +516,7 @@
-       dict_load_sys_table(dict_sys->sys_columns);
-       dict_load_sys_table(dict_sys->sys_indexes);
-       dict_load_sys_table(dict_sys->sys_fields);
-+      dict_load_sys_table(dict_sys->sys_stats);
-       mutex_exit(&(dict_sys->mutex));
- }
---- a/storage/innodb_plugin/dict/dict0crea.c
-+++ b/storage/innodb_plugin/dict/dict0crea.c
-@@ -508,6 +508,56 @@
- }
- /*****************************************************************//**
-+Based on an index object, this function builds the entry to be inserted
-+in the SYS_STATS system table.
-+@return       the tuple which should be inserted */
-+static
-+dtuple_t*
-+dict_create_sys_stats_tuple(
-+/*========================*/
-+      const dict_index_t*     index,
-+      ulint                   i,
-+      mem_heap_t*             heap)
-+{
-+      dict_table_t*   sys_stats;
-+      dtuple_t*       entry;
-+      dfield_t*       dfield;
-+      byte*           ptr;
-+
-+      ut_ad(index);
-+      ut_ad(heap);
-+
-+      sys_stats = dict_sys->sys_stats;
-+
-+      entry = dtuple_create(heap, 4 + DATA_N_SYS_COLS);
-+
-+      dict_table_copy_types(entry, sys_stats);
-+
-+      /* 0: INDEX_ID -----------------------*/
-+      dfield = dtuple_get_nth_field(entry, 0/*INDEX_ID*/);
-+      ptr = mem_heap_alloc(heap, 8);
-+      mach_write_to_8(ptr, index->id);
-+      dfield_set_data(dfield, ptr, 8);
-+      /* 1: KEY_COLS -----------------------*/
-+      dfield = dtuple_get_nth_field(entry, 1/*KEY_COLS*/);
-+      ptr = mem_heap_alloc(heap, 4);
-+      mach_write_to_4(ptr, i);
-+      dfield_set_data(dfield, ptr, 4);
-+      /* 4: DIFF_VALS ----------------------*/
-+      dfield = dtuple_get_nth_field(entry, 2/*DIFF_VALS*/);
-+      ptr = mem_heap_alloc(heap, 8);
-+      mach_write_to_8(ptr, ut_dulint_zero); /* initial value is 0 */
-+      dfield_set_data(dfield, ptr, 8);
-+      /* 5: NON_NULL_VALS ------------------*/
-+      dfield = dtuple_get_nth_field(entry, 3/*NON_NULL_VALS*/);
-+      ptr = mem_heap_alloc(heap, 8);
-+      mach_write_to_8(ptr, ut_dulint_zero); /* initial value is 0 */
-+      dfield_set_data(dfield, ptr, 8);
-+
-+      return(entry);
-+}
-+
-+/*****************************************************************//**
- Creates the tuple with which the index entry is searched for writing the index
- tree root page number, if such a tree is created.
- @return       the tuple for search */
-@@ -617,6 +667,27 @@
- }
- /***************************************************************//**
-+Builds a row for storing stats to insert.
-+@return DB_SUCCESS */
-+static
-+ulint
-+dict_build_stats_def_step(
-+/*======================*/
-+      ind_node_t*     node)
-+{
-+      dict_index_t*   index;
-+      dtuple_t*       row;
-+
-+      index = node->index;
-+
-+      row = dict_create_sys_stats_tuple(index, node->stats_no, node->heap);
-+
-+      ins_node_set_new_row(node->stats_def, row);
-+
-+      return(DB_SUCCESS);
-+}
-+
-+/***************************************************************//**
- Creates an index tree for the index if it is not a member of a cluster.
- @return       DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- static
-@@ -938,6 +1009,49 @@
-                                         dict_sys->sys_fields, heap);
-       node->field_def->common.parent = node;
-+      if (srv_use_sys_stats_table) {
-+              node->stats_def = ins_node_create(INS_DIRECT,
-+                                                dict_sys->sys_stats, heap);
-+              node->stats_def->common.parent = node;
-+      } else {
-+              node->stats_def = NULL;
-+      }
-+
-+      node->commit_node = commit_node_create(heap);
-+      node->commit_node->common.parent = node;
-+
-+      return(node);
-+}
-+
-+/*********************************************************************//**
-+*/
-+UNIV_INTERN
-+ind_node_t*
-+ind_insert_stats_graph_create(
-+/*==========================*/
-+      dict_index_t*   index,
-+      mem_heap_t*     heap)
-+{
-+      ind_node_t*     node;
-+
-+      node = mem_heap_alloc(heap, sizeof(ind_node_t));
-+
-+      node->common.type = QUE_NODE_INSERT_STATS;
-+
-+      node->index = index;
-+
-+      node->state = INDEX_BUILD_STATS_COLS;
-+      node->page_no = FIL_NULL;
-+      node->heap = mem_heap_create(256);
-+
-+      node->ind_def = NULL;
-+      node->field_def = NULL;
-+
-+      node->stats_def = ins_node_create(INS_DIRECT,
-+                                        dict_sys->sys_stats, heap);
-+      node->stats_def->common.parent = node;
-+      node->stats_no = 0;
-+
-       node->commit_node = commit_node_create(heap);
-       node->commit_node->common.parent = node;
-@@ -1088,6 +1202,7 @@
-               node->state = INDEX_BUILD_FIELD_DEF;
-               node->field_no = 0;
-+              node->stats_no = 0;
-               thr->run_node = node->ind_def;
-@@ -1133,7 +1248,31 @@
-                       goto function_exit;
-               }
--              node->state = INDEX_CREATE_INDEX_TREE;
-+              if (srv_use_sys_stats_table
-+                  && !((node->table->flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY)) {
-+                      node->state = INDEX_BUILD_STATS_COLS;
-+              } else {
-+                      node->state = INDEX_CREATE_INDEX_TREE;
-+              }
-+      }
-+      if (node->state == INDEX_BUILD_STATS_COLS) {
-+              if (node->stats_no <= dict_index_get_n_unique(node->index)) {
-+
-+                      err = dict_build_stats_def_step(node);
-+
-+                      if (err != DB_SUCCESS) {
-+
-+                              goto function_exit;
-+                      }
-+
-+                      node->stats_no++;
-+
-+                      thr->run_node = node->stats_def;
-+
-+                      return(thr);
-+              } else {
-+                      node->state = INDEX_CREATE_INDEX_TREE;
-+              }
-       }
-       if (node->state == INDEX_CREATE_INDEX_TREE) {
-@@ -1185,6 +1324,66 @@
- }
- /****************************************************************//**
-+*/
-+UNIV_INTERN
-+que_thr_t*
-+dict_insert_stats_step(
-+/*===================*/
-+      que_thr_t*      thr)    /*!< in: query thread */
-+{
-+      ind_node_t*     node;
-+      ulint           err     = DB_ERROR;
-+      trx_t*          trx;
-+
-+      ut_ad(thr);
-+
-+      trx = thr_get_trx(thr);
-+
-+      node = thr->run_node;
-+
-+      if (thr->prev_node == que_node_get_parent(node)) {
-+              node->state = INDEX_BUILD_STATS_COLS;
-+      }
-+
-+      if (node->state == INDEX_BUILD_STATS_COLS) {
-+              if (node->stats_no <= dict_index_get_n_unique(node->index)) {
-+
-+                      err = dict_build_stats_def_step(node);
-+
-+                      if (err != DB_SUCCESS) {
-+
-+                              goto function_exit;
-+                      }
-+
-+                      node->stats_no++;
-+
-+                      thr->run_node = node->stats_def;
-+
-+                      return(thr);
-+              } else {
-+                      node->state = INDEX_COMMIT_WORK;
-+              }
-+      }
-+
-+      if (node->state == INDEX_COMMIT_WORK) {
-+
-+              /* do not commit transaction here for now */
-+      }
-+
-+function_exit:
-+      trx->error_state = err;
-+
-+      if (err == DB_SUCCESS) {
-+      } else {
-+              return(NULL);
-+      }
-+
-+      thr->run_node = que_node_get_parent(node);
-+
-+      return(thr);
-+}
-+
-+/****************************************************************//**
- Creates the foreign key constraints system tables inside InnoDB
- at database creation or database start if they are not found or are
- not of the right form.
---- a/storage/innodb_plugin/dict/dict0dict.c
-+++ b/storage/innodb_plugin/dict/dict0dict.c
-@@ -740,7 +740,7 @@
-               print an error message and return without doing
-               anything. */
-               dict_update_statistics(table, TRUE /* only update stats
--                                     if they have not been initialized */);
-+                                     if they have not been initialized */, FALSE);
-       }
-       return(table);
-@@ -4283,6 +4283,313 @@
- }
- /*********************************************************************//**
-+functions to use SYS_STATS system table. */
-+static
-+ibool
-+dict_reload_statistics(
-+/*===================*/
-+      dict_table_t*   table,
-+      ulint*          sum_of_index_sizes)
-+{
-+      dict_index_t*   index;
-+      ulint           size;
-+      mem_heap_t*     heap;
-+
-+      index = dict_table_get_first_index(table);
-+
-+      if (index == NULL) {
-+              /* Table definition is corrupt */
-+
-+              return(FALSE);
-+      }
-+
-+      heap = mem_heap_create(1000);
-+
-+      while (index) {
-+              if (table->is_corrupt) {
-+                      ut_a(srv_pass_corrupt_table);
-+                      mem_heap_free(heap);
-+                      return(FALSE);
-+              }
-+
-+              size = btr_get_size(index, BTR_TOTAL_SIZE);
-+
-+              index->stat_index_size = size;
-+
-+              *sum_of_index_sizes += size;
-+
-+              size = btr_get_size(index, BTR_N_LEAF_PAGES);
-+
-+              if (size == 0) {
-+                      /* The root node of the tree is a leaf */
-+                      size = 1;
-+              }
-+
-+              index->stat_n_leaf_pages = size;
-+
-+/*===========================================*/
-+{
-+      dict_table_t*   sys_stats;
-+      dict_index_t*   sys_index;
-+      btr_pcur_t      pcur;
-+      dtuple_t*       tuple;
-+      dfield_t*       dfield;
-+      ulint           key_cols;
-+      ulint           n_cols;
-+      const rec_t*    rec;
-+      ulint           n_fields;
-+      const byte*     field;
-+      ulint           len;
-+      ib_int64_t*     stat_n_diff_key_vals_tmp;
-+      ib_int64_t*     stat_n_non_null_key_vals_tmp;
-+      byte*           buf;
-+      ulint           i;
-+      mtr_t           mtr;
-+
-+      n_cols = dict_index_get_n_unique(index);
-+      stat_n_diff_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
-+      stat_n_non_null_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
-+
-+      sys_stats = dict_sys->sys_stats;
-+      sys_index = UT_LIST_GET_FIRST(sys_stats->indexes);
-+      ut_a(!dict_table_is_comp(sys_stats));
-+
-+      tuple = dtuple_create(heap, 1);
-+      dfield = dtuple_get_nth_field(tuple, 0);
-+
-+      buf = mem_heap_alloc(heap, 8);
-+      mach_write_to_8(buf, index->id);
-+
-+      dfield_set_data(dfield, buf, 8);
-+      dict_index_copy_types(tuple, sys_index, 1);
-+
-+      mtr_start(&mtr);
-+
-+      btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
-+                                BTR_SEARCH_LEAF, &pcur, &mtr);
-+      for (i = 0; i <= n_cols; i++) {
-+              rec = btr_pcur_get_rec(&pcur);
-+
-+              if (!btr_pcur_is_on_user_rec(&pcur)
-+                  || ut_dulint_cmp(mach_read_from_8(rec_get_nth_field_old(rec, 0, &len)),
-+                                   index->id)) {
-+                      /* not found: even 1 if not found should not be alowed */
-+                      fprintf(stderr, "InnoDB: Warning: stats for %s/%s (%lu/%lu)"
-+                                      " not fonund in SYS_STATS\n",
-+                                      index->table_name, index->name, i, n_cols);
-+                      btr_pcur_close(&pcur);
-+                      mtr_commit(&mtr);
-+                      mem_heap_free(heap);
-+                      return(FALSE);
-+              }
-+
-+              if (rec_get_deleted_flag(rec, 0)) {
-+                      /* don't count */
-+                      i--;
-+                      goto next_rec;
-+              }
-+
-+              n_fields = rec_get_n_fields_old(rec);
-+
-+              field = rec_get_nth_field_old(rec, 1, &len);
-+              ut_a(len == 4);
-+
-+              key_cols = mach_read_from_4(field);
-+
-+              ut_a(i == key_cols);
-+
-+              field = rec_get_nth_field_old(rec, DICT_SYS_STATS_DIFF_VALS_FIELD, &len);
-+              ut_a(len == 8);
-+
-+              stat_n_diff_key_vals_tmp[i] = ut_conv_dulint_to_longlong(mach_read_from_8(field));
-+
-+              if (n_fields > DICT_SYS_STATS_NON_NULL_VALS_FIELD) {
-+                      field = rec_get_nth_field_old(rec, DICT_SYS_STATS_NON_NULL_VALS_FIELD, &len);
-+                      ut_a(len == 8);
-+
-+                      stat_n_non_null_key_vals_tmp[i] = ut_conv_dulint_to_longlong(mach_read_from_8(field));
-+              } else {
-+                      /* not enough fields: should be older */
-+                      fprintf(stderr, "InnoDB: Notice: stats for %s/%s (%lu/%lu)"
-+                                      " in SYS_STATS seems older format. "
-+                                      "Please execute ANALYZE TABLE for it.\n",
-+                                      index->table_name, index->name, i, n_cols);
-+
-+                      stat_n_non_null_key_vals_tmp[i] = ((ib_int64_t)(-1));
-+              }
-+next_rec:
-+              btr_pcur_move_to_next_user_rec(&pcur, &mtr);
-+      }
-+
-+      btr_pcur_close(&pcur);
-+      mtr_commit(&mtr);
-+
-+      for (i = 0; i <= n_cols; i++) {
-+              index->stat_n_diff_key_vals[i] = stat_n_diff_key_vals_tmp[i];
-+              if (stat_n_non_null_key_vals_tmp[i] == ((ib_int64_t)(-1))) {
-+                      /* approximate value */
-+                      index->stat_n_non_null_key_vals[i] = stat_n_diff_key_vals_tmp[n_cols];
-+              } else {
-+                      index->stat_n_non_null_key_vals[i] = stat_n_non_null_key_vals_tmp[i];
-+              }
-+      }
-+}
-+/*===========================================*/
-+
-+              index = dict_table_get_next_index(index);
-+      }
-+
-+      mem_heap_free(heap);
-+      return(TRUE);
-+}
-+
-+static
-+void
-+dict_store_statistics(
-+/*==================*/
-+      dict_table_t*   table)
-+{
-+      dict_index_t*   index;
-+      mem_heap_t*     heap;
-+
-+      index = dict_table_get_first_index(table);
-+
-+      ut_a(index);
-+
-+      heap = mem_heap_create(1000);
-+
-+      while (index) {
-+              if (table->is_corrupt) {
-+                      ut_a(srv_pass_corrupt_table);
-+                      mem_heap_free(heap);
-+                      return;
-+              }
-+
-+/*===========================================*/
-+{
-+      dict_table_t*   sys_stats;
-+      dict_index_t*   sys_index;
-+      btr_pcur_t      pcur;
-+      dtuple_t*       tuple;
-+      dfield_t*       dfield;
-+      ulint           key_cols;
-+      ulint           n_cols;
-+      ulint           rests;
-+      const rec_t*    rec;
-+      ulint           n_fields;
-+      const byte*     field;
-+      ulint           len;
-+      ib_int64_t*     stat_n_diff_key_vals_tmp;
-+      ib_int64_t*     stat_n_non_null_key_vals_tmp;
-+      byte*           buf;
-+      ulint           i;
-+      mtr_t           mtr;
-+
-+      n_cols = dict_index_get_n_unique(index);
-+      stat_n_diff_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
-+      stat_n_non_null_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
-+
-+      for (i = 0; i <= n_cols; i++) {
-+              stat_n_diff_key_vals_tmp[i] = index->stat_n_diff_key_vals[i];
-+              stat_n_non_null_key_vals_tmp[i] = index->stat_n_non_null_key_vals[i];
-+      }
-+
-+      sys_stats = dict_sys->sys_stats;
-+      sys_index = UT_LIST_GET_FIRST(sys_stats->indexes);
-+      ut_a(!dict_table_is_comp(sys_stats));
-+
-+      tuple = dtuple_create(heap, 1);
-+      dfield = dtuple_get_nth_field(tuple, 0);
-+
-+      buf = mem_heap_alloc(heap, 8);
-+      mach_write_to_8(buf, index->id);
-+
-+      dfield_set_data(dfield, buf, 8);
-+      dict_index_copy_types(tuple, sys_index, 1);
-+
-+      mtr_start(&mtr);
-+
-+      btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
-+                                BTR_MODIFY_LEAF, &pcur, &mtr);
-+      rests = n_cols + 1;
-+      for (i = 0; i <= n_cols; i++) {
-+              rec = btr_pcur_get_rec(&pcur);
-+
-+              if (!btr_pcur_is_on_user_rec(&pcur)
-+                  || ut_dulint_cmp(mach_read_from_8(rec_get_nth_field_old(rec, 0, &len)),
-+                                   index->id)) {
-+                      /* not found */
-+
-+
-+                      break;
-+              }
-+
-+              btr_pcur_store_position(&pcur, &mtr);
-+
-+              if (rec_get_deleted_flag(rec, 0)) {
-+                      /* don't count */
-+                      i--;
-+                      goto next_rec;
-+              }
-+
-+              n_fields = rec_get_n_fields_old(rec);
-+
-+              if (n_fields <= DICT_SYS_STATS_NON_NULL_VALS_FIELD) {
-+                      /* not update for the older smaller format */
-+                      fprintf(stderr, "InnoDB: Notice: stats for %s/%s (%lu/%lu)"
-+                                      " in SYS_STATS seems older format. Please ANALYZE TABLE it.\n",
-+                                      index->table_name, index->name, i, n_cols);
-+                      goto next_rec;
-+              }
-+
-+              field = rec_get_nth_field_old(rec, 1, &len);
-+              ut_a(len == 4);
-+
-+              key_cols = mach_read_from_4(field);
-+
-+              field = rec_get_nth_field_old(rec, DICT_SYS_STATS_DIFF_VALS_FIELD, &len);
-+              ut_a(len == 8);
-+
-+              mlog_write_dulint((byte*)field,
-+                              ut_dulint_create((ulint) (stat_n_diff_key_vals_tmp[key_cols] >> 32),
-+                                              (ulint) stat_n_diff_key_vals_tmp[key_cols] & 0xFFFFFFFF),
-+                              &mtr);
-+
-+              field = rec_get_nth_field_old(rec, DICT_SYS_STATS_NON_NULL_VALS_FIELD, &len);
-+              ut_a(len == 8);
-+
-+              mlog_write_dulint((byte*)field,
-+                              ut_dulint_create((ulint) (stat_n_non_null_key_vals_tmp[key_cols] >> 32),
-+                                              (ulint) stat_n_non_null_key_vals_tmp[key_cols] & 0xFFFFFFFF),
-+                              &mtr);
-+
-+              rests--;
-+
-+next_rec:
-+              mtr_commit(&mtr);
-+              mtr_start(&mtr);
-+              btr_pcur_restore_position(BTR_MODIFY_LEAF, &pcur, &mtr);
-+
-+              btr_pcur_move_to_next_user_rec(&pcur, &mtr);
-+      }
-+      btr_pcur_close(&pcur);
-+      mtr_commit(&mtr);
-+
-+      if (rests) {
-+              fprintf(stderr, "InnoDB: Warning: failed to store %lu stats entries"
-+                              " of %s/%s to SYS_STATS system table.\n",
-+                              rests, index->table_name, index->name);
-+      }
-+}
-+/*===========================================*/
-+
-+              index = dict_table_get_next_index(index);
-+      }
-+
-+      mem_heap_free(heap);
-+}
-+
-+/*********************************************************************//**
- Calculates new estimates for table and index statistics. The statistics
- are used in query optimization. */
- UNIV_INTERN
-@@ -4290,10 +4597,11 @@
- dict_update_statistics(
- /*===================*/
-       dict_table_t*   table,          /*!< in/out: table */
--      ibool           only_calc_if_missing_stats)/*!< in: only
-+      ibool           only_calc_if_missing_stats,     /*!< in: only
-                                       update/recalc the stats if they have
-                                       not been initialized yet, otherwise
-                                       do nothing */
-+      ibool           sync)           /*!< in: TRUE if must update SYS_STATS */
- {
-       dict_index_t*   index;
-       ulint           sum_of_index_sizes      = 0;
-@@ -4310,6 +4618,27 @@
-               return;
-       }
-+      if (srv_use_sys_stats_table && !((table->flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY) && !sync) {
-+              dict_table_stats_lock(table, RW_X_LATCH);
-+
-+              /* reload statistics from SYS_STATS table */
-+              if (dict_reload_statistics(table, &sum_of_index_sizes)) {
-+                      /* success */
-+#ifdef UNIV_DEBUG
-+                      fprintf(stderr, "InnoDB: DEBUG: reload_statistics is scceeded for %s.\n",
-+                                      table->name);
-+#endif
-+                      goto end;
-+              }
-+
-+              dict_table_stats_unlock(table, RW_X_LATCH);
-+      }
-+#ifdef UNIV_DEBUG
-+      fprintf(stderr, "InnoDB: DEBUG: update_statistics for %s.\n",
-+                      table->name);
-+#endif
-+      sum_of_index_sizes = 0;
-+
-       /* Find out the sizes of the indexes and how many different values
-       for the key they approximately have */
-@@ -4380,6 +4709,11 @@
-               index = dict_table_get_next_index(index);
-       } while (index);
-+      if (srv_use_sys_stats_table && !((table->flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY)) {
-+              /* store statistics to SYS_STATS table */
-+              dict_store_statistics(table);
-+      }
-+end:
-       index = dict_table_get_first_index(table);
-       table->stat_n_rows = index->stat_n_diff_key_vals[
-@@ -4397,6 +4731,78 @@
-       dict_table_stats_unlock(table, RW_X_LATCH);
- }
-+/*********************************************************************//**
-+*/
-+UNIV_INTERN
-+ibool
-+dict_is_older_statistics(
-+/*=====================*/
-+      dict_index_t*   index)
-+{
-+      mem_heap_t*     heap;
-+      dict_table_t*   sys_stats;
-+      dict_index_t*   sys_index;
-+      btr_pcur_t      pcur;
-+      dtuple_t*       tuple;
-+      dfield_t*       dfield;
-+      const rec_t*    rec;
-+      ulint           n_fields;
-+      ulint           len;
-+      byte*           buf;
-+      mtr_t           mtr;
-+
-+      heap = mem_heap_create(100);
-+
-+      sys_stats = dict_sys->sys_stats;
-+      sys_index = UT_LIST_GET_FIRST(sys_stats->indexes);
-+      ut_a(!dict_table_is_comp(sys_stats));
-+
-+      tuple = dtuple_create(heap, 1);
-+      dfield = dtuple_get_nth_field(tuple, 0);
-+
-+      buf = mem_heap_alloc(heap, 8);
-+      mach_write_to_8(buf, index->id);
-+
-+      dfield_set_data(dfield, buf, 8);
-+      dict_index_copy_types(tuple, sys_index, 1);
-+
-+      mtr_start(&mtr);
-+
-+      btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
-+                                BTR_SEARCH_LEAF, &pcur, &mtr);
-+
-+next_rec:
-+      rec = btr_pcur_get_rec(&pcur);
-+
-+      if (!btr_pcur_is_on_user_rec(&pcur)
-+          || ut_dulint_cmp(mach_read_from_8(rec_get_nth_field_old(rec, 0, &len)),
-+                           index->id)) {
-+              /* not found */
-+              btr_pcur_close(&pcur);
-+              mtr_commit(&mtr);
-+              mem_heap_free(heap);
-+              /* no statistics == not older statistics */
-+              return(FALSE);
-+      }
-+
-+      if (rec_get_deleted_flag(rec, 0)) {
-+              btr_pcur_move_to_next_user_rec(&pcur, &mtr);
-+              goto next_rec;
-+      }
-+
-+      n_fields = rec_get_n_fields_old(rec);
-+
-+      btr_pcur_close(&pcur);
-+      mtr_commit(&mtr);
-+      mem_heap_free(heap);
-+
-+      if (n_fields > DICT_SYS_STATS_NON_NULL_VALS_FIELD) {
-+              return(FALSE);
-+      } else {
-+              return(TRUE);
-+      }
-+}
-+
- /**********************************************************************//**
- Prints info of a foreign key constraint. */
- static
-@@ -4474,7 +4880,7 @@
-       ut_ad(mutex_own(&(dict_sys->mutex)));
--      dict_update_statistics(table, FALSE /* update even if initialized */);
-+      dict_update_statistics(table, FALSE /* update even if initialized */, FALSE);
-       dict_table_stats_lock(table, RW_S_LATCH);
---- a/storage/innodb_plugin/dict/dict0load.c
-+++ b/storage/innodb_plugin/dict/dict0load.c
-@@ -224,7 +224,7 @@
-                       if (dict_table_get_first_index(table)) {
-                               dict_update_statistics(table, FALSE /* update
--                                                     even if initialized */);
-+                                                     even if initialized */, FALSE);
-                       }
-                       dict_table_print_low(table);
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -193,6 +193,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;
-+static my_bool        innobase_use_sys_stats_table            = FALSE;
- static char*  internal_innobase_data_file_path        = NULL;
-@@ -2275,6 +2276,8 @@
-       srv_extra_undoslots = (ibool) innobase_extra_undoslots;
-+      srv_use_sys_stats_table = (ibool) innobase_use_sys_stats_table;
-+
-       /* -------------- Log files ---------------------------*/
-       /* The default dir for log files is the datadir of MySQL */
-@@ -5053,6 +5056,10 @@
-       error = row_insert_for_mysql((byte*) record, prebuilt);
-+#ifdef EXTENDED_FOR_USERSTAT
-+      if (error == DB_SUCCESS) rows_changed++;
-+#endif
-+
-       /* Handle duplicate key errors */
-       if (auto_inc_used) {
-               ulint           err;
-@@ -5397,6 +5404,10 @@
-               }
-       }
-+#ifdef EXTENDED_FOR_USERSTAT
-+      if (error == DB_SUCCESS) rows_changed++;
-+#endif
-+
-       innodb_srv_conc_exit_innodb(trx);
-       error = convert_error_code_to_mysql(error,
-@@ -5458,6 +5469,10 @@
-       error = row_update_for_mysql((byte*) record, prebuilt);
-+#ifdef EXTENDED_FOR_USERSTAT
-+      if (error == DB_SUCCESS) rows_changed++;
-+#endif
-+
-       innodb_srv_conc_exit_innodb(trx);
-       error = convert_error_code_to_mysql(
-@@ -5788,6 +5803,11 @@
-       case DB_SUCCESS:
-               error = 0;
-               table->status = 0;
-+#ifdef EXTENDED_FOR_USERSTAT
-+              rows_read++;
-+              if (active_index < MAX_KEY)
-+                      index_rows_read[active_index]++;
-+#endif
-               break;
-       case DB_RECORD_NOT_FOUND:
-               error = HA_ERR_KEY_NOT_FOUND;
-@@ -6009,6 +6029,11 @@
-       case DB_SUCCESS:
-               error = 0;
-               table->status = 0;
-+#ifdef EXTENDED_FOR_USERSTAT
-+              rows_read++;
-+              if (active_index < MAX_KEY)
-+                      index_rows_read[active_index]++;
-+#endif
-               break;
-       case DB_RECORD_NOT_FOUND:
-               error = HA_ERR_END_OF_FILE;
-@@ -7966,11 +7991,35 @@
-                       /* In sql_show we call with this flag: update
-                       then statistics so that they are up-to-date */
-+                      if (srv_use_sys_stats_table && !((ib_table->flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY)
-+                          && called_from_analyze) {
-+                              /* If the indexes on the table don't have enough rows in SYS_STATS system table, */
-+                              /* they need to be created. */
-+                              dict_index_t*   index;
-+
-+                              prebuilt->trx->op_info = "confirming rows of SYS_STATS to store statistics";
-+
-+                              ut_a(prebuilt->trx->conc_state == TRX_NOT_STARTED);
-+
-+                              for (index = dict_table_get_first_index(ib_table);
-+                                   index != NULL;
-+                                   index = dict_table_get_next_index(index)) {
-+                                      if (dict_is_older_statistics(index)) {
-+                                              row_delete_stats_for_mysql(index, prebuilt->trx);
-+                                              innobase_commit_low(prebuilt->trx);
-+                                      }
-+                                      row_insert_stats_for_mysql(index, prebuilt->trx);
-+                                      innobase_commit_low(prebuilt->trx);
-+                              }
-+
-+                              ut_a(prebuilt->trx->conc_state == TRX_NOT_STARTED);
-+                      }
-+
-                       prebuilt->trx->op_info = "updating table statistics";
-                       dict_update_statistics(ib_table,
-                                              FALSE /* update even if stats
--                                                   are initialized */);
-+                                                   are initialized */, called_from_analyze);
-                       prebuilt->trx->op_info = "returning various info to MySQL";
-               }
-@@ -8055,7 +8104,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. */
--              if (flag & HA_STATUS_NO_LOCK) {
-+              if (flag & HA_STATUS_NO_LOCK || !srv_stats_update_need_lock) {
-                       /* We do not update delete_length if no
-                       locking is requested so the "old" value can
-                       remain. delete_length is initialized to 0 in
-@@ -11288,6 +11337,26 @@
-   "The number of index pages to sample when calculating statistics (default 8)",
-   NULL, NULL, 8, 1, ~0ULL, 0);
-+static MYSQL_SYSVAR_ULONG(stats_auto_update, srv_stats_auto_update,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Enable/Disable InnoDB's auto update statistics of indexes. "
-+  "(except for ANALYZE TABLE command) 0:disable 1:enable",
-+  NULL, NULL, 1, 0, 1, 0);
-+
-+static MYSQL_SYSVAR_ULONG(stats_update_need_lock, srv_stats_update_need_lock,
-+  PLUGIN_VAR_RQCMDARG,
-+  "Enable/Disable InnoDB's update statistics which needs to lock dictionary. "
-+  "e.g. Data_free.",
-+  NULL, NULL, 1, 0, 1, 0);
-+
-+static MYSQL_SYSVAR_BOOL(use_sys_stats_table, innobase_use_sys_stats_table,
-+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-+  "Enable to use SYS_STATS system table to store statistics statically, "
-+  "And avoids to calculate statistics at every first open of the tables. "
-+  "This option may make the opportunities of update statistics less. "
-+  "So you should use ANALYZE TABLE command intentionally.",
-+  NULL, NULL, FALSE);
-+
- static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
-   PLUGIN_VAR_OPCMDARG,
-   "Enable InnoDB adaptive hash index (enabled by default).  "
-@@ -11646,6 +11715,9 @@
-   MYSQL_SYSVAR(overwrite_relay_log_info),
-   MYSQL_SYSVAR(rollback_on_timeout),
-   MYSQL_SYSVAR(stats_on_metadata),
-+  MYSQL_SYSVAR(stats_auto_update),
-+  MYSQL_SYSVAR(stats_update_need_lock),
-+  MYSQL_SYSVAR(use_sys_stats_table),
-   MYSQL_SYSVAR(stats_sample_pages),
-   MYSQL_SYSVAR(adaptive_hash_index),
-   MYSQL_SYSVAR(stats_method),
-@@ -11716,6 +11788,8 @@
- i_s_innodb_cmp_reset,
- i_s_innodb_cmpmem,
- i_s_innodb_cmpmem_reset,
-+i_s_innodb_table_stats,
-+i_s_innodb_index_stats,
- i_s_innodb_admin_command,
- i_s_innodb_patches
- mysql_declare_plugin_end;
---- a/storage/innodb_plugin/handler/i_s.cc
-+++ b/storage/innodb_plugin/handler/i_s.cc
-@@ -45,6 +45,7 @@
- #include "btr0btr.h" /* for btr_page_get_index_id */
- #include "trx0rseg.h" /* for trx_rseg_struct */
- #include "trx0sys.h" /* for trx_sys */
-+#include "dict0dict.h" /* for dict_sys */
- #include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
- }
-@@ -2769,3 +2770,347 @@
-       STRUCT_FLD(system_vars, NULL),
-       STRUCT_FLD(__reserved1, NULL)
- };
-+
-+/***********************************************************************
-+*/
-+static ST_FIELD_INFO  i_s_innodb_table_stats_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "table_schema"),
-+       STRUCT_FLD(field_length,       NAME_LEN),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "table_name"),
-+       STRUCT_FLD(field_length,       NAME_LEN),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "rows"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "clust_size"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "other_size"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "modified"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      END_OF_ST_FIELD_INFO
-+};
-+
-+static ST_FIELD_INFO  i_s_innodb_index_stats_info[] =
-+{
-+      {STRUCT_FLD(field_name,         "table_schema"),
-+       STRUCT_FLD(field_length,       NAME_LEN),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "table_name"),
-+       STRUCT_FLD(field_length,       NAME_LEN),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "index_name"),
-+       STRUCT_FLD(field_length,       NAME_LEN),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "fields"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "row_per_keys"),
-+       STRUCT_FLD(field_length,       256),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_STRING),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        0),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "index_size"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      {STRUCT_FLD(field_name,         "leaf_pages"),
-+       STRUCT_FLD(field_length,       MY_INT64_NUM_DECIMAL_DIGITS),
-+       STRUCT_FLD(field_type,         MYSQL_TYPE_LONGLONG),
-+       STRUCT_FLD(value,              0),
-+       STRUCT_FLD(field_flags,        MY_I_S_UNSIGNED),
-+       STRUCT_FLD(old_name,           ""),
-+       STRUCT_FLD(open_method,        SKIP_OPEN_TABLE)},
-+
-+      END_OF_ST_FIELD_INFO
-+};
-+
-+static
-+int
-+i_s_innodb_table_stats_fill(
-+/*========================*/
-+      THD*            thd,
-+      TABLE_LIST*     tables,
-+      COND*           cond)
-+{
-+      TABLE*  i_s_table       = (TABLE *) tables->table;
-+      int     status  = 0;
-+      dict_table_t*   table;
-+
-+      DBUG_ENTER("i_s_innodb_table_stats_fill");
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+              DBUG_RETURN(0);
-+      }
-+
-+      mutex_enter(&(dict_sys->mutex));
-+
-+      table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
-+
-+      while (table) {
-+              char    buf[NAME_LEN * 2 + 2];
-+              char*   ptr;
-+
-+              if (table->stat_clustered_index_size == 0) {
-+                      table = UT_LIST_GET_NEXT(table_LRU, table);
-+                      continue;
-+              }
-+
-+              buf[NAME_LEN * 2 + 1] = 0;
-+              strncpy(buf, table->name, NAME_LEN * 2 + 1);
-+              ptr = strchr(buf, '/');
-+              if (ptr) {
-+                      *ptr = '\0';
-+                      ++ptr;
-+              } else {
-+                      ptr = buf;
-+              }
-+
-+              field_store_string(i_s_table->field[0], buf);
-+              field_store_string(i_s_table->field[1], ptr);
-+              i_s_table->field[2]->store(table->stat_n_rows);
-+              i_s_table->field[3]->store(table->stat_clustered_index_size);
-+              i_s_table->field[4]->store(table->stat_sum_of_other_index_sizes);
-+              i_s_table->field[5]->store(table->stat_modified_counter);
-+
-+              if (schema_table_store_record(thd, i_s_table)) {
-+                      status = 1;
-+                      break;
-+              }
-+
-+              table = UT_LIST_GET_NEXT(table_LRU, table);
-+      }
-+
-+      mutex_exit(&(dict_sys->mutex));
-+
-+      DBUG_RETURN(status);
-+}
-+
-+static
-+int
-+i_s_innodb_index_stats_fill(
-+/*========================*/
-+      THD*            thd,
-+      TABLE_LIST*     tables,
-+      COND*           cond)
-+{
-+      TABLE*  i_s_table       = (TABLE *) tables->table;
-+      int     status  = 0;
-+      dict_table_t*   table;
-+      dict_index_t*   index;
-+
-+      DBUG_ENTER("i_s_innodb_index_stats_fill");
-+
-+      /* deny access to non-superusers */
-+      if (check_global_access(thd, PROCESS_ACL)) {
-+              DBUG_RETURN(0);
-+      }
-+
-+      mutex_enter(&(dict_sys->mutex));
-+
-+      table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
-+
-+      while (table) {
-+              if (table->stat_clustered_index_size == 0) {
-+                      table = UT_LIST_GET_NEXT(table_LRU, table);
-+                      continue;
-+              }
-+
-+              ib_int64_t      n_rows = table->stat_n_rows;
-+
-+              if (n_rows < 0) {
-+                      n_rows = 0;
-+              }
-+
-+              index = dict_table_get_first_index(table);
-+
-+              while (index) {
-+                      char    buff[256+1];
-+                      char    row_per_keys[256+1];
-+                      char    buf[NAME_LEN * 2 + 2];
-+                      char*   ptr;
-+                      ulint   i;
-+
-+                      buf[NAME_LEN * 2 + 1] = 0;
-+                      strncpy(buf, table->name, NAME_LEN * 2 + 1);
-+                      ptr = strchr(buf, '/');
-+                      if (ptr) {
-+                              *ptr = '\0';
-+                              ++ptr;
-+                      } else {
-+                              ptr = buf;
-+                      }
-+
-+                      field_store_string(i_s_table->field[0], buf);
-+                      field_store_string(i_s_table->field[1], ptr);
-+                      field_store_string(i_s_table->field[2], index->name);
-+                      i_s_table->field[3]->store(index->n_uniq);
-+
-+                      row_per_keys[0] = '\0';
-+
-+                      /* It is remained optimistic operation still for now */
-+                      //dict_index_stat_mutex_enter(index);
-+                      if (index->stat_n_diff_key_vals) {
-+                              for (i = 1; i <= index->n_uniq; i++) {
-+                                      ib_int64_t      rec_per_key;
-+                                      if (index->stat_n_diff_key_vals[i]) {
-+                                              rec_per_key = n_rows / index->stat_n_diff_key_vals[i];
-+                                      } else {
-+                                              rec_per_key = n_rows;
-+                                      }
-+                                      ut_snprintf(buff, 256, (i == index->n_uniq)?"%llu":"%llu, ",
-+                                               rec_per_key);
-+                                      strncat(row_per_keys, buff, 256 - strlen(row_per_keys));
-+                              }
-+                      }
-+                      //dict_index_stat_mutex_exit(index);
-+
-+                      field_store_string(i_s_table->field[4], row_per_keys);
-+
-+                      i_s_table->field[5]->store(index->stat_index_size);
-+                      i_s_table->field[6]->store(index->stat_n_leaf_pages);
-+
-+                      if (schema_table_store_record(thd, i_s_table)) {
-+                              status = 1;
-+                              break;
-+                      }
-+
-+                      index = dict_table_get_next_index(index);
-+              }
-+
-+              if (status == 1) {
-+                      break;
-+              }
-+
-+              table = UT_LIST_GET_NEXT(table_LRU, table);
-+      }
-+
-+      mutex_exit(&(dict_sys->mutex));
-+
-+      DBUG_RETURN(status);
-+}
-+
-+static
-+int
-+i_s_innodb_table_stats_init(
-+/*========================*/
-+      void*   p)
-+{
-+      DBUG_ENTER("i_s_innodb_table_stats_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_table_stats_info;
-+      schema->fill_table = i_s_innodb_table_stats_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+static
-+int
-+i_s_innodb_index_stats_init(
-+/*========================*/
-+      void*   p)
-+{
-+      DBUG_ENTER("i_s_innodb_index_stats_init");
-+      ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
-+
-+      schema->fields_info = i_s_innodb_index_stats_info;
-+      schema->fill_table = i_s_innodb_index_stats_fill;
-+
-+      DBUG_RETURN(0);
-+}
-+
-+UNIV_INTERN struct st_mysql_plugin    i_s_innodb_table_stats =
-+{
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+      STRUCT_FLD(info, &i_s_info),
-+      STRUCT_FLD(name, "INNODB_TABLE_STATS"),
-+      STRUCT_FLD(author, "Percona"),
-+      STRUCT_FLD(descr, "InnoDB table statistics in memory"),
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+      STRUCT_FLD(init, i_s_innodb_table_stats_init),
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+      STRUCT_FLD(status_vars, NULL),
-+      STRUCT_FLD(system_vars, NULL),
-+      STRUCT_FLD(__reserved1, NULL)
-+};
-+
-+UNIV_INTERN struct st_mysql_plugin    i_s_innodb_index_stats =
-+{
-+      STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-+      STRUCT_FLD(info, &i_s_info),
-+      STRUCT_FLD(name, "INNODB_INDEX_STATS"),
-+      STRUCT_FLD(author, "Percona"),
-+      STRUCT_FLD(descr, "InnoDB index statistics in memory"),
-+      STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-+      STRUCT_FLD(init, i_s_innodb_index_stats_init),
-+      STRUCT_FLD(deinit, i_s_common_deinit),
-+      STRUCT_FLD(version, 0x0100 /* 1.0 */),
-+      STRUCT_FLD(status_vars, NULL),
-+      STRUCT_FLD(system_vars, NULL),
-+      STRUCT_FLD(__reserved1, NULL)
-+};
---- a/storage/innodb_plugin/handler/i_s.h
-+++ b/storage/innodb_plugin/handler/i_s.h
-@@ -38,6 +38,8 @@
- extern struct st_mysql_plugin i_s_innodb_cmpmem_reset;
- extern struct st_mysql_plugin i_s_innodb_patches;
- extern struct st_mysql_plugin i_s_innodb_rseg;
-+extern struct st_mysql_plugin i_s_innodb_table_stats;
-+extern struct st_mysql_plugin i_s_innodb_index_stats;
- extern struct st_mysql_plugin i_s_innodb_admin_command;
- #endif /* i_s_h */
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -35,6 +35,7 @@
- {"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
-+{"innodb_stats","Additional features about InnoDB statistics/optimizer","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
---- a/storage/innodb_plugin/include/dict0boot.h
-+++ b/storage/innodb_plugin/include/dict0boot.h
-@@ -101,6 +101,7 @@
- #define DICT_COLUMNS_ID               ut_dulint_create(0, 2)
- #define DICT_INDEXES_ID               ut_dulint_create(0, 3)
- #define DICT_FIELDS_ID                ut_dulint_create(0, 4)
-+#define DICT_STATS_ID         ut_dulint_create(0, 6)
- /* The following is a secondary index on SYS_TABLES */
- #define DICT_TABLE_IDS_ID     ut_dulint_create(0, 5)
-@@ -128,10 +129,13 @@
- #define       DICT_HDR_INDEXES        44      /* Root of the index index tree */
- #define       DICT_HDR_FIELDS         48      /* Root of the index field
-                                       index tree */
-+#define       DICT_HDR_STATS          52      /* Root of the stats tree */
- #define DICT_HDR_FSEG_HEADER  56      /* Segment header for the tablespace
-                                       segment into which the dictionary
-                                       header is created */
-+
-+#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
-@@ -141,11 +145,16 @@
- #define DICT_SYS_INDEXES_TYPE_FIELD    6
- #define DICT_SYS_INDEXES_NAME_FIELD    4
-+#define DICT_SYS_STATS_DIFF_VALS_FIELD         4
-+#define DICT_SYS_STATS_NON_NULL_VALS_FIELD    5
-+
- /* When a row id which is zero modulo this number (which must be a power of
- two) is assigned, the field DICT_HDR_ROW_ID on the dictionary header page is
- updated */
- #define DICT_HDR_ROW_ID_WRITE_MARGIN  256
-+#define DICT_HDR_XTRADB_FLAG          ut_dulint_create(0x58545241UL,0x44425F31UL)     /* "XTRADB_1" */
-+
- #ifndef UNIV_NONINL
- #include "dict0boot.ic"
- #endif
---- a/storage/innodb_plugin/include/dict0crea.h
-+++ b/storage/innodb_plugin/include/dict0crea.h
-@@ -53,6 +53,14 @@
-       dict_index_t*   index,  /*!< in: index to create, built as a memory data
-                               structure */
-       mem_heap_t*     heap);  /*!< in: heap where created */
-+/*********************************************************************//**
-+*/
-+UNIV_INTERN
-+ind_node_t*
-+ind_insert_stats_graph_create(
-+/*==========================*/
-+      dict_index_t*   index,
-+      mem_heap_t*     heap);
- /***********************************************************//**
- Creates a table. This is a high-level function used in SQL execution graphs.
- @return       query thread to run next or NULL */
-@@ -62,6 +70,13 @@
- /*===================*/
-       que_thr_t*      thr);   /*!< in: query thread */
- /***********************************************************//**
-+*/
-+UNIV_INTERN
-+que_thr_t*
-+dict_insert_stats_step(
-+/*===================*/
-+      que_thr_t*      thr);
-+/***********************************************************//**
- Creates an index. This is a high-level function used in SQL execution
- graphs.
- @return       query thread to run next or NULL */
-@@ -170,6 +185,7 @@
-       ins_node_t*     field_def; /* child node which does the inserts of
-                               the field definitions; the row to be inserted
-                               is built by the parent node  */
-+      ins_node_t*     stats_def;
-       commit_node_t*  commit_node;
-                               /* child node which performs a commit after
-                               a successful index creation */
-@@ -180,6 +196,7 @@
-       dict_table_t*   table;  /*!< table which owns the index */
-       dtuple_t*       ind_row;/* index definition row built */
-       ulint           field_no;/* next field definition to insert */
-+      ulint           stats_no;
-       mem_heap_t*     heap;   /*!< memory heap used as auxiliary storage */
- };
-@@ -189,6 +206,7 @@
- #define       INDEX_CREATE_INDEX_TREE 3
- #define       INDEX_COMMIT_WORK       4
- #define       INDEX_ADD_TO_CACHE      5
-+#define       INDEX_BUILD_STATS_COLS  6
- #ifndef UNIV_NONINL
- #include "dict0crea.ic"
---- a/storage/innodb_plugin/include/dict0dict.h
-+++ b/storage/innodb_plugin/include/dict0dict.h
-@@ -1057,10 +1057,18 @@
- dict_update_statistics(
- /*===================*/
-       dict_table_t*   table,          /*!< in/out: table */
--      ibool           only_calc_if_missing_stats);/*!< in: only
-+      ibool           only_calc_if_missing_stats,     /*!< in: only
-                                       update/recalc the stats if they have
-                                       not been initialized yet, otherwise
-                                       do nothing */
-+      ibool           sync);
-+/*********************************************************************//**
-+*/
-+UNIV_INTERN
-+ibool
-+dict_is_older_statistics(
-+/*=====================*/
-+      dict_index_t*   index);
- /********************************************************************//**
- Reserves the dictionary system mutex for MySQL. */
- UNIV_INTERN
-@@ -1175,6 +1183,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 */
-+      dict_table_t*   sys_stats;      /*!< SYS_STATS table */
- };
- #endif /* !UNIV_HOTBACKUP */
---- a/storage/innodb_plugin/include/que0que.h
-+++ b/storage/innodb_plugin/include/que0que.h
-@@ -495,6 +495,8 @@
- #define QUE_NODE_CALL         31
- #define QUE_NODE_EXIT         32
-+#define QUE_NODE_INSERT_STATS 34
-+
- /* Query thread states */
- #define QUE_THR_RUNNING               1
- #define QUE_THR_PROCEDURE_WAIT        2
---- a/storage/innodb_plugin/include/row0mysql.h
-+++ b/storage/innodb_plugin/include/row0mysql.h
-@@ -376,6 +376,22 @@
-                                       then checked for not being too
-                                       large. */
- /*********************************************************************//**
-+*/
-+UNIV_INTERN
-+int
-+row_insert_stats_for_mysql(
-+/*=======================*/
-+      dict_index_t*   index,
-+      trx_t*          trx);
-+/*********************************************************************//**
-+*/
-+UNIV_INTERN
-+int
-+row_delete_stats_for_mysql(
-+/*=======================*/
-+      dict_index_t*   index,
-+      trx_t*          trx);
-+/*********************************************************************//**
- 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.
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -207,6 +207,9 @@
- extern ibool  srv_innodb_status;
- extern unsigned long long     srv_stats_sample_pages;
-+extern ulint  srv_stats_auto_update;
-+extern ulint  srv_stats_update_need_lock;
-+extern ibool  srv_use_sys_stats_table;
- extern ibool  srv_use_doublewrite_buf;
- extern ibool  srv_use_checksums;
---- a/storage/innodb_plugin/que/que0que.c
-+++ b/storage/innodb_plugin/que/que0que.c
-@@ -622,11 +622,21 @@
-               que_graph_free_recursive(cre_ind->ind_def);
-               que_graph_free_recursive(cre_ind->field_def);
-+              if (srv_use_sys_stats_table)
-+                      que_graph_free_recursive(cre_ind->stats_def);
-               que_graph_free_recursive(cre_ind->commit_node);
-               mem_heap_free(cre_ind->heap);
-               break;
-+      case QUE_NODE_INSERT_STATS:
-+              cre_ind = node;
-+
-+              que_graph_free_recursive(cre_ind->stats_def);
-+              que_graph_free_recursive(cre_ind->commit_node);
-+
-+              mem_heap_free(cre_ind->heap);
-+              break;
-       case QUE_NODE_PROC:
-               que_graph_free_stat_list(((proc_node_t*)node)->stat_list);
-@@ -1139,6 +1149,8 @@
-               str = "CREATE TABLE";
-       } else if (type == QUE_NODE_CREATE_INDEX) {
-               str = "CREATE INDEX";
-+      } else if (type == QUE_NODE_INSERT_STATS) {
-+              str = "INSERT TO SYS_STATS";
-       } else if (type == QUE_NODE_FOR) {
-               str = "FOR LOOP";
-       } else if (type == QUE_NODE_RETURN) {
-@@ -1256,6 +1268,8 @@
-               thr = dict_create_table_step(thr);
-       } else if (type == QUE_NODE_CREATE_INDEX) {
-               thr = dict_create_index_step(thr);
-+      } else if (type == QUE_NODE_INSERT_STATS) {
-+              thr = dict_insert_stats_step(thr);
-       } else if (type == QUE_NODE_ROW_PRINTF) {
-               thr = row_printf_step(thr);
-       } else {
---- a/storage/innodb_plugin/row/row0ins.c
-+++ b/storage/innodb_plugin/row/row0ins.c
-@@ -2027,6 +2027,8 @@
-       }
- #ifdef UNIV_DEBUG
-+      if (!srv_use_sys_stats_table
-+          || index != UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes))
-       {
-               page_t* page = btr_cur_get_page(&cursor);
-               rec_t*  first_rec = page_rec_get_next(
---- a/storage/innodb_plugin/row/row0merge.c
-+++ b/storage/innodb_plugin/row/row0merge.c
-@@ -2028,6 +2028,8 @@
-               "UPDATE SYS_INDEXES SET NAME=CONCAT('"
-               TEMP_INDEX_PREFIX_STR "', NAME) WHERE ID = :indexid;\n"
-               "COMMIT WORK;\n"
-+              /* Drop the statistics of the index. */
-+              "DELETE FROM SYS_STATS WHERE INDEX_ID = :indexid;\n"
-               /* Drop the field definitions of the index. */
-               "DELETE FROM SYS_FIELDS WHERE INDEX_ID = :indexid;\n"
-               /* Drop the index definition and the B-tree. */
---- a/storage/innodb_plugin/row/row0mysql.c
-+++ b/storage/innodb_plugin/row/row0mysql.c
-@@ -862,6 +862,9 @@
-       table->stat_modified_counter = counter + 1;
-+      if (!srv_stats_auto_update)
-+              return;
-+
-       /* 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).
-@@ -872,7 +875,7 @@
-           || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) {
-               dict_update_statistics(table, FALSE /* update even if stats
--                                                  are initialized */);
-+                                                  are initialized */, TRUE);
-       }
- }
-@@ -2046,6 +2049,71 @@
- }
- /*********************************************************************//**
-+*/
-+UNIV_INTERN
-+int
-+row_insert_stats_for_mysql(
-+/*=======================*/
-+      dict_index_t*   index,
-+      trx_t*          trx)
-+{
-+      ind_node_t*     node;
-+      mem_heap_t*     heap;
-+      que_thr_t*      thr;
-+      ulint           err;
-+
-+      ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
-+
-+      trx->op_info = "try to insert rows to SYS_STATS";
-+
-+      trx_start_if_not_started(trx);
-+      trx->error_state = DB_SUCCESS;
-+
-+      heap = mem_heap_create(512);
-+
-+      node = ind_insert_stats_graph_create(index, heap);
-+
-+      thr = pars_complete_graph_for_exec(node, trx, heap);
-+
-+      ut_a(thr == que_fork_start_command(que_node_get_parent(thr)));
-+      que_run_threads(thr);
-+
-+      err = trx->error_state;
-+
-+      que_graph_free((que_t*) que_node_get_parent(thr));
-+
-+      trx->op_info = "";
-+
-+      return((int) err);
-+}
-+
-+/*********************************************************************//**
-+*/
-+UNIV_INTERN
-+int
-+row_delete_stats_for_mysql(
-+/*=============================*/
-+      dict_index_t*   index,
-+      trx_t*          trx)
-+{
-+      pars_info_t*    info    = pars_info_create();
-+
-+      trx->op_info = "delete rows from SYS_STATS";
-+
-+      trx_start_if_not_started(trx);
-+      trx->error_state = DB_SUCCESS;
-+
-+      pars_info_add_dulint_literal(info, "indexid", index->id);
-+
-+      return((int) que_eval_sql(info,
-+                                "PROCEDURE DELETE_STATISTICS_PROC () IS\n"
-+                                "BEGIN\n"
-+                                "DELETE FROM SYS_STATS WHERE INDEX_ID = :indexid;\n"
-+                                "END;\n"
-+                                , TRUE, trx));
-+}
-+
-+/*********************************************************************//**
- 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.
-@@ -2976,7 +3044,7 @@
-       dict_table_autoinc_initialize(table, 1);
-       dict_table_autoinc_unlock(table);
-       dict_update_statistics(table, FALSE /* update even if stats are
--                                          initialized */);
-+                                          initialized */, TRUE);
-       trx_commit_for_mysql(trx);
-@@ -3278,6 +3346,8 @@
-                          "       IF (SQL % NOTFOUND) THEN\n"
-                          "               found := 0;\n"
-                          "       ELSE\n"
-+                         "               DELETE FROM SYS_STATS\n"
-+                         "               WHERE INDEX_ID = index_id;\n"
-                          "               DELETE FROM SYS_FIELDS\n"
-                          "               WHERE INDEX_ID = index_id;\n"
-                          "               DELETE FROM SYS_INDEXES\n"
---- a/storage/innodb_plugin/row/row0row.c
-+++ b/storage/innodb_plugin/row/row0row.c
-@@ -374,6 +374,14 @@
-       rec_len = rec_offs_n_fields(offsets);
-+      if (srv_use_sys_stats_table
-+          && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes)) {
-+              if (rec_len < dict_index_get_n_fields(index)) {
-+                      /* the new record should be extended */
-+                      rec_len = dict_index_get_n_fields(index);
-+              }
-+      }
-+
-       entry = dtuple_create(heap, rec_len);
-       dtuple_set_n_fields_cmp(entry,
-@@ -385,6 +393,14 @@
-       for (i = 0; i < rec_len; i++) {
-               dfield = dtuple_get_nth_field(entry, i);
-+
-+              if (srv_use_sys_stats_table
-+                  && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes)
-+                  && i >= rec_offs_n_fields(offsets)) {
-+                      dfield_set_null(dfield);
-+                      continue;
-+              }
-+
-               field = rec_get_nth_field(rec, offsets, i, &len);
-               dfield_set_data(dfield, field, len);
---- a/storage/innodb_plugin/row/row0upd.c
-+++ b/storage/innodb_plugin/row/row0upd.c
-@@ -439,6 +439,12 @@
-                               0);
-               }
-+              if (srv_use_sys_stats_table
-+                  && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes)
-+                  && upd_field->field_no >= rec_offs_n_fields(offsets)) {
-+                      return(TRUE);
-+              }
-+
-               old_len = rec_offs_nth_size(offsets, upd_field->field_no);
-               if (rec_offs_comp(offsets)
-@@ -879,6 +885,18 @@
-       for (i = 0; i < dtuple_get_n_fields(entry); i++) {
-+              if (srv_use_sys_stats_table
-+                  && index == UT_LIST_GET_FIRST(dict_sys->sys_stats->indexes)
-+                  && i >= rec_offs_n_fields(offsets)) {
-+                      dfield = dtuple_get_nth_field(entry, i);
-+
-+                      upd_field = upd_get_nth_field(update, n_diff);
-+                      dfield_copy(&(upd_field->new_val), dfield);
-+                      upd_field_set_field_no(upd_field, i, index, trx);
-+                      n_diff++;
-+                      goto skip_compare;
-+              }
-+
-               data = rec_get_nth_field(rec, offsets, i, &len);
-               dfield = dtuple_get_nth_field(entry, i);
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -386,6 +386,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;
-+UNIV_INTERN ulint     srv_stats_auto_update = 1;
-+UNIV_INTERN ulint     srv_stats_update_need_lock = 1;
-+UNIV_INTERN ibool     srv_use_sys_stats_table = FALSE;
- UNIV_INTERN ibool     srv_use_doublewrite_buf = TRUE;
- UNIV_INTERN ibool     srv_use_checksums = TRUE;
---- a/storage/innodb_plugin/trx/trx0rec.c
-+++ b/storage/innodb_plugin/trx/trx0rec.c
-@@ -665,14 +665,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);
-               }
--              ptr += mach_write_compressed(ptr, upd_get_n_fields(update));
-+              if (srv_use_sys_stats_table
-+                  && 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;
-+
-+                              if (pos >= rec_offs_n_fields(offsets)) {
-+                                      extended++;
-+                              }
-+                      }
-+              }
-+
-+              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/mysql-innodb_swap_builtin_plugin.patch b/mysql-innodb_swap_builtin_plugin.patch
deleted file mode 100644 (file)
index cac1df0..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-# name       : innodb_swap_builtin_plugin.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/mysql-test/include/have_innodb_plugin.inc
-+++ b/mysql-test/include/have_innodb_plugin.inc
-@@ -1,5 +1,5 @@
- --source include/not_embedded.inc
- disable_query_log;
- --require r/true.require
--SELECT (plugin_library LIKE 'ha_innodb_plugin%') AS `TRUE` FROM information_schema.plugins WHERE LOWER(plugin_name) = 'innodb' AND LOWER(plugin_status) = 'active';
-+select (support = 'YES' or support = 'DEFAULT' or support = 'ENABLED') as `TRUE` from information_schema.engines where engine = 'innodb';
- enable_query_log;
---- a/mysql-test/include/read_many_rows.inc
-+++ b/mysql-test/include/read_many_rows.inc
-@@ -112,8 +112,12 @@
- insert into t1 values(1);
- connection con2;
----error 1213
-+#InnoDB Plugin treats this situation as "timeout" not "deadlock"
-+#So, we need to rollback
-+#--error 1213
-+--error 1205
- reap;
-+rollback;
- select @a;
- # check that the whole transaction was rolled back
- select * from t2;
-@@ -134,6 +138,9 @@
- connection con2;
- reap;
-+#InnoDB Plugin treats this situation as "timeout" not "deadlock"
-+#So, we need to rollback
-+rollback;
- select @a,@b;
- # check that the whole transaction was rolled back
- select * from t2;
-@@ -155,6 +162,9 @@
- connection con2;
- reap;
-+#InnoDB Plugin treats this situation as "timeout" not "deadlock"
-+#So, we need to rollback
-+rollback;
- # check that the whole transaction was rolled back
- select * from t2;
---- a/mysql-test/lib/mtr_cases.pm
-+++ b/mysql-test/lib/mtr_cases.pm
-@@ -944,7 +944,7 @@
-     push(@{$tinfo->{'slave_opt'}}, "--loose-federated");
-   }
--  if ( $tinfo->{'innodb_test'} )
-+  if ( $tinfo->{'innodb_test'} || $tinfo->{'innodb_plugin_test'} )
-   {
-     # This is a test that needs innodb
-     if ( $::mysqld_variables{'innodb'} eq "OFF" ||
-@@ -956,36 +956,6 @@
-       return $tinfo;
-     }
-   }
--  elsif ( $tinfo->{'innodb_plugin_test'} )
--  {
--    # This is a test that needs the innodb plugin
--    if (!&find_innodb_plugin)
--    {
--      # innodb plugin is not supported, skip it
--      $tinfo->{'skip'}= 1;
--      $tinfo->{'comment'}= "No innodb plugin support";
--      return $tinfo;
--    }
--
--    my $sep= (IS_WINDOWS) ? ';' : ':';
--    my $plugin_filename= basename($lib_innodb_plugin);
--    my $plugin_list=
--      "innodb=$plugin_filename$sep" .
--      "innodb_trx=$plugin_filename$sep" .
--      "innodb_locks=$plugin_filename$sep" .
--      "innodb_lock_waits=$plugin_filename$sep" .
--      "innodb_cmp=$plugin_filename$sep" .
--      "innodb_cmp_reset=$plugin_filename$sep" .
--      "innodb_cmpmem=$plugin_filename$sep" .
--      "innodb_cmpmem_reset=$plugin_filename";
--
--    foreach my $k ('master_opt', 'slave_opt') 
--    {
--      push(@{$tinfo->{$k}}, '--ignore-builtin-innodb');
--      push(@{$tinfo->{$k}}, '--plugin-dir=' . dirname($lib_innodb_plugin));
--      push(@{$tinfo->{$k}}, "--plugin-load=$plugin_list");
--    }
--  }
-   else
-   {
-     push(@{$tinfo->{'master_opt'}}, "--loose-skip-innodb");
---- a/mysql-test/r/innodb_ignore_builtin.result
-+++ b/mysql-test/r/innodb_ignore_builtin.result
-@@ -1,9 +1,11 @@
- show variables like 'ignore_builtin_innodb';
- Variable_name Value
--ignore_builtin_innodb ON
-+ignore_builtin_innodb OFF
- select PLUGIN_NAME from information_schema.plugins
- where PLUGIN_NAME = "InnoDb";
- PLUGIN_NAME
-+InnoDB
- select ENGINE from information_schema.engines
- where ENGINE = "InnoDB";
- ENGINE
-+InnoDB
---- a/mysql-test/r/read_many_rows_innodb.result
-+++ b/mysql-test/r/read_many_rows_innodb.result
-@@ -64,7 +64,8 @@
- insert into t2 values(123);
- insert into t1 values(1);
- insert into t1 values(1);
--ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-+rollback;
- select @a;
- @a
- NULL
-@@ -77,9 +78,10 @@
- insert into t2 values(123);
- call proc24989();
- insert into t1 values(1);
-+rollback;
- select @a,@b;
- @a    @b
--exception     deadlock
-+exception     NULL
- select * from t2;
- f2
- commit;
-@@ -90,10 +92,9 @@
- call proc24989_2();
- insert into t1 values(1);
- commit;
--exception
--Outer handler
- continued
- continued
-+rollback;
- select * from t2;
- f2
- drop procedure proc24989;
---- a/mysql-test/t/innodb_ignore_builtin-master.opt
-+++ b/mysql-test/t/innodb_ignore_builtin-master.opt
-@@ -1 +1 @@
----ignore_builtin_innodb
-+
---- a/mysql-test/t/innodb_ignore_builtin.test
-+++ b/mysql-test/t/innodb_ignore_builtin.test
-@@ -1,3 +1,7 @@
-+# For Percona Server this test is made a no-op, because ignore-builtin-innodb
-+# is checked at the server startup time and the server aborts with an error
-+# if it is found.  Ideally we would like to test this startup abort itself,
-+# but MTR does not support that.
- #
- # Bug #42610:  Dynamic plugin broken in 5.1.31
- #
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -8207,7 +8207,9 @@
-     thd_startup_options|=OPTION_BIG_TABLES;
-     break;
-   case (int) OPT_IGNORE_BUILTIN_INNODB:
--    opt_ignore_builtin_innodb= 1;
-+    sql_print_error("The option ignore-builtin-innodb is incompatible with "
-+                    "Percona Server with XtraDB");
-+    unireg_abort(1);
-     break;
-   case (int) OPT_ISAM_LOG:
-     opt_myisam_log=1;
---- a/storage/innobase/plug.in
-+++ b/storage/innobase/plug.in
-@@ -1,7 +1,6 @@
- MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine],
-         [Transactional Tables using InnoDB], [max,max-no-ndb])
- MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase])
--MYSQL_PLUGIN_STATIC(innobase,   [libinnobase.a])
- MYSQL_PLUGIN_DYNAMIC(innobase,  [ha_innodb.la])
- MYSQL_PLUGIN_ACTIONS(innobase,  [
-   AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"])
---- a/storage/innodb_plugin/plug.in
-+++ b/storage/innodb_plugin/plug.in
-@@ -19,7 +19,7 @@
- MYSQL_PLUGIN_DIRECTORY(innodb_plugin, [storage/innodb_plugin])
- # Enable if you know what you are doing (trying to link both InnoDB and
- # InnoDB Plugin statically into MySQL does not work).
--#MYSQL_PLUGIN_STATIC(innodb_plugin, [libinnobase.a])
-+MYSQL_PLUGIN_STATIC(innodb_plugin,   [libinnobase.a])
- MYSQL_PLUGIN_DYNAMIC(innodb_plugin,  [ha_innodb_plugin.la])
- MYSQL_PLUGIN_ACTIONS(innodb_plugin,  [
-   AC_CHECK_HEADERS(sched.h)
---- a/mysql-test/mysql-test-run.pl
-+++ b/mysql-test/mysql-test-run.pl
-@@ -157,7 +157,7 @@
- # executables will be used by the test suite.
- our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
--my $DEFAULT_SUITES= "main,binlog,federated,rpl,rpl_ndb,ndb,innodb,innodb_plugin";
-+my $DEFAULT_SUITES= "main,binlog,federated,rpl,rpl_ndb,ndb,innodb_plugin";
- my $opt_suites;
- our $opt_verbose= 0;  # Verbose output, enable with --verbose
diff --git a/mysql-innodb_thread_concurrency_timer_based.patch b/mysql-innodb_thread_concurrency_timer_based.patch
deleted file mode 100644 (file)
index 0e5c789..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-# name       : innodb_thread_concurrency_timer_based.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/storage/innodb_plugin/handler/ha_innodb.cc
-+++ b/storage/innodb_plugin/handler/ha_innodb.cc
-@@ -151,6 +151,7 @@
- static ulong innobase_read_io_threads;
- static ulong innobase_write_io_threads;
-+static my_bool innobase_thread_concurrency_timer_based;
- static long long innobase_buffer_pool_size, innobase_log_file_size;
- /** Percentage of the buffer pool to reserve for 'old' blocks.
-@@ -2343,6 +2344,9 @@
-       srv_n_log_files = (ulint) innobase_log_files_in_group;
-       srv_log_file_size = (ulint) innobase_log_file_size;
-+      srv_thread_concurrency_timer_based =
-+              (ibool) innobase_thread_concurrency_timer_based;
-+
- #ifdef UNIV_LOG_ARCHIVE
-       srv_log_archive_on = (ulint) innobase_log_archive;
- #endif /* UNIV_LOG_ARCHIVE */
-@@ -11202,6 +11206,12 @@
-   "Maximum delay between polling for a spin lock (6 by default)",
-   NULL, NULL, 6L, 0L, ~0L, 0);
-+static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based,
-+  innobase_thread_concurrency_timer_based,
-+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-+  "Use InnoDB timer based concurrency throttling. ",
-+  NULL, NULL, FALSE);
-+
- 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.",
-@@ -11423,6 +11433,7 @@
-   MYSQL_SYSVAR(spin_wait_delay),
-   MYSQL_SYSVAR(table_locks),
-   MYSQL_SYSVAR(thread_concurrency),
-+  MYSQL_SYSVAR(thread_concurrency_timer_based),
-   MYSQL_SYSVAR(thread_sleep_delay),
-   MYSQL_SYSVAR(autoinc_lock_mode),
-   MYSQL_SYSVAR(show_verbose_locks),
---- a/storage/innodb_plugin/handler/innodb_patch_info.h
-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h
-@@ -31,5 +31,6 @@
- {"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
- {"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
-+{"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
- {NULL, NULL, NULL, NULL}
- };
---- a/storage/innodb_plugin/include/srv0srv.h
-+++ b/storage/innodb_plugin/include/srv0srv.h
-@@ -147,6 +147,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;
---- a/storage/innodb_plugin/srv/srv0srv.c
-+++ b/storage/innodb_plugin/srv/srv0srv.c
-@@ -320,6 +320,7 @@
- computer. Bigger computers need bigger values. Value 0 will disable the
- concurrency check. */
-+UNIV_INTERN ibool     srv_thread_concurrency_timer_based = FALSE;
- UNIV_INTERN ulong     srv_thread_concurrency  = 0;
- /* this mutex protects srv_conc data structures */
-@@ -1071,6 +1072,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. */
-+
-+#ifdef HAVE_ATOMIC_BUILTINS
-+static void
-+enter_innodb_with_tickets(trx_t* trx)
-+{
-+      trx->declared_to_be_inside_innodb = TRUE;
-+      trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
-+      return;
-+}
-+
-+static void
-+srv_conc_enter_innodb_timer_based(trx_t* trx)
-+{
-+      lint    conc_n_threads;
-+      ibool   has_yielded = FALSE;
-+      ulint   has_slept = 0;
-+
-+      if (trx->declared_to_be_inside_innodb) {
-+              ut_print_timestamp(stderr);
-+              fputs(
-+"  InnoDB: Error: trying to declare trx to enter InnoDB, but\n"
-+"InnoDB: it already is declared.\n", stderr);
-+              trx_print(stderr, trx, 0);
-+              putc('\n', stderr);
-+      }
-+retry:
-+      if (srv_conc_n_threads < (lint) srv_thread_concurrency) {
-+              conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
-+              if (conc_n_threads <= (lint) srv_thread_concurrency) {
-+                      enter_innodb_with_tickets(trx);
-+                      return;
-+              }
-+              (void) os_atomic_increment_lint(&srv_conc_n_threads, -1);
-+      }
-+      if (!has_yielded)
-+      {
-+              has_yielded = TRUE;
-+              os_thread_yield();
-+              goto retry;
-+      }
-+      if (trx->has_search_latch
-+          || NULL != UT_LIST_GET_FIRST(trx->trx_locks)) {
-+
-+              conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
-+              enter_innodb_with_tickets(trx);
-+              return;
-+      }
-+      if (has_slept < 2)
-+      {
-+              trx->op_info = "sleeping before entering InnoDB";
-+              os_thread_sleep(10000);
-+              trx->op_info = "";
-+              has_slept++;
-+      }
-+      conc_n_threads = os_atomic_increment_lint(&srv_conc_n_threads, 1);
-+      enter_innodb_with_tickets(trx);
-+      return;
-+}
-+
-+static void
-+srv_conc_exit_innodb_timer_based(trx_t* trx)
-+{
-+      (void) os_atomic_increment_lint(&srv_conc_n_threads, -1);
-+      trx->declared_to_be_inside_innodb = FALSE;
-+      trx->n_tickets_to_enter_innodb = 0;
-+      return;
-+}
-+#endif
-+
- UNIV_INTERN
- void
- srv_conc_enter_innodb(
-@@ -1101,6 +1171,13 @@
-               return;
-       }
-+#ifdef HAVE_ATOMIC_BUILTINS
-+      if (srv_thread_concurrency_timer_based) {
-+              srv_conc_enter_innodb_timer_based(trx);
-+              return;
-+      }
-+#endif
-+
-       os_fast_mutex_lock(&srv_conc_mutex);
- retry:
-       if (trx->declared_to_be_inside_innodb) {
-@@ -1244,6 +1321,14 @@
-       }
-       ut_ad(srv_conc_n_threads >= 0);
-+#ifdef HAVE_ATOMIC_BUILTINS
-+      if (srv_thread_concurrency_timer_based) {
-+              (void) os_atomic_increment_lint(&srv_conc_n_threads, 1);
-+              trx->declared_to_be_inside_innodb = TRUE;
-+              trx->n_tickets_to_enter_innodb = 1;
-+              return;
-+      }
-+#endif
-       os_fast_mutex_lock(&srv_conc_mutex);
-@@ -1277,6 +1362,13 @@
-               return;
-       }
-+#ifdef HAVE_ATOMIC_BUILTINS
-+      if (srv_thread_concurrency_timer_based) {
-+              srv_conc_exit_innodb_timer_based(trx);
-+              return;
-+      }
-+#endif
-+
-       os_fast_mutex_lock(&srv_conc_mutex);
-       ut_ad(srv_conc_n_threads > 0);
index 6bd37d4a6f349a04f597f5cb627c0b54d025e504..559ee4b1e2f6d3dae2409ac4c6ee4933573683d0 100644 (file)
  
  noinst_HEADERS =      item.h item_func.h item_sum.h item_cmpfunc.h \
                        item_strfunc.h item_timefunc.h \
---- mysql-5.1.26-rc/config/ac-macros/ssl.m4.orig       2008-07-01 00:35:01.000000000 +0200
-+++ mysql-5.1.26-rc/config/ac-macros/ssl.m4    2008-08-25 19:53:00.258254465 +0200
-@@ -102,7 +102,12 @@
-   #
-   # Try to link with openSSL libs in <location>
-   #
--  openssl_libs="-L$location/lib/ -lssl -lcrypto"
-+  if test "$location" != "/usr"
-+  then
-+  openssl_libs="-L$location/lib -lssl -lcrypto"
-+  else
-+  openssl_libs="-lssl -lcrypto"
-+  fi
-   MYSQL_CHECK_SSL_DIR([$openssl_includes], [$openssl_libs])
-   if test "$mysql_ssl_found" == "no"
 --- mysql-5.1.53/libmysql/Makefile.am~ 2010-11-03 15:40:16.000000000 +0200
 +++ mysql-5.1.53/libmysql/Makefile.am  2010-12-17 11:24:29.593084149 +0200
 @@ -22,7 +22,7 @@
diff --git a/mysql-log_connection_error.patch b/mysql-log_connection_error.patch
deleted file mode 100644 (file)
index 346dafe..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-# name       : log_connection_error.patch
-# introduced : 12
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/mysql-test/r/connect.result
-+++ b/mysql-test/r/connect.result
-@@ -1,3 +1,4 @@
-+set global log_warnings=0;
- drop table if exists t1,t2;
- show tables;
- Tables_in_mysql
-@@ -229,3 +230,4 @@
- # ------------------------------------------------------------------
- # -- End of 5.1 tests
- # ------------------------------------------------------------------
-+set global log_warnings=1;
---- a/mysql-test/t/connect.test
-+++ b/mysql-test/t/connect.test
-@@ -1,3 +1,5 @@
-+set global log_warnings=0;
-+
- # This test is to check various cases of connections
- # with right and wrong password, with and without database
- # Unfortunately the check is incomplete as we can't connect without database
-@@ -328,3 +330,4 @@
- # Wait till all disconnects are completed
- --source include/wait_until_count_sessions.inc
-+set global log_warnings=1;
---- /dev/null
-+++ b/patch_info/log_connection_error.patch
-@@ -0,0 +1,6 @@
-+File=log_connection_error.patch
-+Name=logging abandoned connections
-+Version=1.0
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment=
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -5085,6 +5085,10 @@
-     DBUG_PRINT("error",("Too many connections"));
-     close_connection(thd, ER_CON_COUNT_ERROR, 1);
-+    if (global_system_variables.log_warnings)
-+    {
-+      sql_print_warning("%s", ER(ER_CON_COUNT_ERROR));
-+    }
-     statistic_increment(denied_connections, &LOCK_status);
-     delete thd;
-     DBUG_VOID_RETURN;
-@@ -5472,6 +5476,10 @@
-     if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
-       my_net_init(&thd->net, thd->net.vio))
-     {
-+      if (global_system_variables.log_warnings)
-+      {
-+        sql_print_warning("%s", ER(ER_OUT_OF_RESOURCES));
-+      }
-       close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-       delete thd;
-       continue;
-@@ -5667,6 +5675,10 @@
-                                                    event_conn_closed)) ||
-                         my_net_init(&thd->net, thd->net.vio))
-     {
-+      if (global_system_variables.log_warnings)
-+      {
-+        sql_print_warning("%s", ER(ER_OUT_OF_RESOURCES));
-+      }
-       close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-       errmsg= 0;
-       goto errorconn;
---- /dev/null
-+++ b/mysql-test/r/percona_log_connection_error.result
-@@ -0,0 +1,15 @@
-+SET @old_max_connections = @@max_connections;
-+SET @old_log_warnings = @@log_warnings;
-+SET GLOBAL max_connections=2;
-+SET GLOBAL LOG_WARNINGS = 0;
-+connect(localhost,root,,test,port,socket);
-+ERROR HY000: Too many connections
-+SET GLOBAL LOG_WARNINGS = 1;
-+connect(localhost,root,,test,port,socket);
-+ERROR HY000: Too many connections
-+SET GLOBAL LOG_WARNINGS = 0;
-+connect(localhost,root,,test,port,socket);
-+ERROR HY000: Too many connections
-+SET GLOBAL max_connections = @old_max_connections;
-+SET GLOBAL log_warnings = @old_log_warnings;
-+Occurences: 1
---- /dev/null
-+++ b/mysql-test/t/percona_log_connection_error-master.opt
-@@ -0,0 +1 @@
-+--log-error
---- /dev/null
-+++ b/mysql-test/t/percona_log_connection_error.test
-@@ -0,0 +1,60 @@
-+--source include/not_embedded.inc
-+
-+connect (main,localhost,root,,);
-+connection main;
-+SET @old_max_connections = @@max_connections;
-+SET @old_log_warnings = @@log_warnings;
-+SET GLOBAL max_connections=2;
-+let $port=`SELECT Variable_value FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE Variable_name LIKE 'port'`;
-+let $socket=`SELECT Variable_value FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE Variable_name LIKE 'socket'`;
-+
-+SET GLOBAL LOG_WARNINGS = 0;
-+--connect (conn0,localhost,root,,)
-+connection conn0;
-+replace_result $port port $socket socket;
-+--error 1040
-+--connect(conn1,localhost,root,,)
-+disconnect conn0;
-+SLEEP 0.1; # tsarev: hack, but i don't know (and didn't find) how right
-+
-+connection main;
-+SET GLOBAL LOG_WARNINGS = 1;
-+--connect (conn1,localhost,root,,)
-+replace_result $port port $socket socket;
-+--error 1040
-+--connect (conn0,localhost,root,,)
-+disconnect conn1;
-+SLEEP 0.1; # tsarev: hack, but i don't know (and didn't find) how right
-+
-+connection main;
-+SET GLOBAL LOG_WARNINGS = 0;
-+--connect (conn0,localhost,root,,)
-+replace_result $port port $socket socket;
-+--error 1040
-+--connect(conn1,localhost,root,,)
-+disconnect conn0;
-+SLEEP 0.1; # tsarev: hack, but i don't know (and didn't find) how right
-+
-+connection main;
-+SET GLOBAL max_connections = @old_max_connections;
-+SET GLOBAL log_warnings = @old_log_warnings;
-+let $log_error_= `SELECT @@GLOBAL.log_error`;
-+if(!`select LENGTH('$log_error_')`)
-+{
-+  # MySQL Server on windows is started with --console and thus
-+  # does not know the location of its .err log, use default location
-+  let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
-+}
-+# Assign env variable LOG_ERROR
-+let LOG_ERROR=$log_error_;
-+
-+perl;
-+  my $log_file= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set\n";
-+  open(FILE, "$log_file") or die("Unable to open $log_error: $!\n");
-+  my $count= () = grep(/Too many connections/g,<FILE>);
-+  print "Occurences: $count\n";
-+  close(FILE);
-+  # Clean log error file
-+  open(FILE, '>', $log_file);
-+  close(FILE);
-+EOF
diff --git a/mysql-microsec_process.patch b/mysql-microsec_process.patch
deleted file mode 100644 (file)
index 1189cee..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# name       : microsec_process.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- /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
-+Version=1.0
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment=
-+2010-01
-+Ported to 5.1.42
---- a/sql/sql_show.cc
-+++ b/sql/sql_show.cc
-@@ -1913,7 +1913,8 @@
-   TABLE *table= tables->table;
-   CHARSET_INFO *cs= system_charset_info;
-   char *user;
--  time_t now= my_time(0);
-+  time_t now;
-+  ulonglong now_utime= my_micro_time_and_time(&now);
-   DBUG_ENTER("fill_process_list");
-   user= thd->security_ctx->master_access & PROCESS_ACL ?
-@@ -2018,6 +2019,10 @@
-       }
-       pthread_mutex_unlock(&tmp->LOCK_thd_data);
-+      /* TIME_MS */
-+      table->field[8]->store(((tmp->start_utime ?
-+                               now_utime - tmp->start_utime : 0)/ 1000));
-+
-       if (schema_table_store_record(thd, table))
-       {
-         VOID(pthread_mutex_unlock(&LOCK_thread_count));
-@@ -6758,6 +6763,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},
-+  {"TIME_MS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
-+   0, 0, "Time_ms", SKIP_OPEN_TABLE},
-   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
- };
diff --git a/mysql-microslow.patch b/mysql-microslow.patch
deleted file mode 100644 (file)
index c02227d..0000000
+++ /dev/null
@@ -1,699 +0,0 @@
-diff -r 0b1f42e1aacf sql/event_scheduler.cc
---- a/sql/event_scheduler.cc   Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/event_scheduler.cc   Thu Dec 04 08:55:29 2008 -0800
-@@ -192,6 +192,7 @@
-   thd->client_capabilities|= CLIENT_MULTI_RESULTS;
-   pthread_mutex_lock(&LOCK_thread_count);
-   thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
-+  thd->write_to_slow_log = TRUE;
-   pthread_mutex_unlock(&LOCK_thread_count);
-   /*
-diff -r 0b1f42e1aacf sql/filesort.cc
---- a/sql/filesort.cc  Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/filesort.cc  Thu Dec 04 08:55:29 2008 -0800
-@@ -188,6 +188,7 @@
-   {
-     status_var_increment(thd->status_var.filesort_scan_count);
-   }
-+  thd->query_plan_flags|= QPLAN_FILESORT;
- #ifdef CAN_TRUST_RANGE
-   if (select && select->quick && select->quick->records > 0L)
-   {
-@@ -253,6 +254,7 @@
-   }
-   else
-   {
-+    thd->query_plan_flags|= QPLAN_FILESORT_DISK;
-     if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
-     {
-       x_free(table_sort.buffpek);
-@@ -1202,6 +1204,7 @@
-   DBUG_ENTER("merge_buffers");
-   status_var_increment(current_thd->status_var.filesort_merge_passes);
-+  current_thd->query_plan_fsort_passes++;
-   if (param->not_killable)
-   {
-     killed= &not_killable;
-diff -r 0b1f42e1aacf sql/log.cc
---- a/sql/log.cc       Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/log.cc       Thu Dec 04 08:55:29 2008 -0800
-@@ -963,7 +963,7 @@
-     /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
-     user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
-                              sctx->priv_user ? sctx->priv_user : "", "[",
--                             sctx->user ? sctx->user : "", "] @ ",
-+                             sctx->user ? sctx->user : (thd->slave_thread ? "SQL_SLAVE" : ""), "] @ ",
-                              sctx->host ? sctx->host : "", " [",
-                              sctx->ip ? sctx->ip : "", "]", NullS) -
-                     user_host_buff);
-@@ -985,6 +985,13 @@
-       query= command_name[thd->command].str;
-       query_length= command_name[thd->command].length;
-     }
-+
-+    if (!query_length) 
-+    { 
-+      thd->sent_row_count= thd->examined_row_count= 0; 
-+      thd->query_plan_flags= QPLAN_NONE; 
-+      thd->query_plan_fsort_passes= 0; 
-+    } 
-     for (current_handler= slow_log_handler_list; *current_handler ;)
-       error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
-@@ -2242,16 +2249,31 @@
-       if (my_b_write(&log_file, (uchar*) "\n", 1))
-         tmp_errno= errno;
-     }
-+    
-     /* For slow query log */
-     sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
-     sprintf(lock_time_buff,  "%.6f", ulonglong2double(lock_utime)/1000000.0);
-     if (my_b_printf(&log_file,
--                    "# Query_time: %s  Lock_time: %s"
--                    " Rows_sent: %lu  Rows_examined: %lu\n",
-+                    "# Thread_id: %lu  Schema: %s\n" \
-+                    "# Query_time: %s  Lock_time: %s  Rows_sent: %lu  Rows_examined: %lu\n",
-+                    (ulong) thd->thread_id, (thd->db ? thd->db : ""),
-                     query_time_buff, lock_time_buff,
-                     (ulong) thd->sent_row_count,
-                     (ulong) thd->examined_row_count) == (uint) -1)
-       tmp_errno= errno;
-+     if ((thd->variables.log_slow_verbosity & SLOG_V_QUERY_PLAN) && 
-+         my_b_printf(&log_file, 
-+                     "# QC_Hit: %s  Full_scan: %s  Full_join: %s  Tmp_table: %s  Tmp_table_on_disk: %s\n" \
-+                     "# Filesort: %s  Filesort_on_disk: %s  Merge_passes: %lu\n", 
-+                     ((thd->query_plan_flags & QPLAN_QC) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_FULL_SCAN) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_FULL_JOIN) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_TMP_TABLE) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_TMP_DISK) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_FILESORT) ? "Yes" : "No"), 
-+                     ((thd->query_plan_flags & QPLAN_FILESORT_DISK) ? "Yes" : "No"), 
-+                     thd->query_plan_fsort_passes) == (uint) -1) 
-+       tmp_errno=errno; 
-     if (thd->db && strcmp(thd->db, db))
-     {                                         // Database changed
-       if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
-diff -r 0b1f42e1aacf sql/mysql_priv.h
---- a/sql/mysql_priv.h Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/mysql_priv.h Thu Dec 04 08:55:29 2008 -0800
-@@ -597,6 +597,73 @@
- #define WEEK_FIRST_WEEKDAY   4
- #define STRING_BUFFER_USUAL_SIZE 80
-+
-+/* Slow log */
-+
-+struct msl_opts
-+{
-+  ulong val;
-+  const char *name;
-+};
-+
-+#define SLOG_V_QUERY_PLAN     1 << 1
-+/* ... */
-+#define SLOG_V_INVALID        1 << 31
-+#define SLOG_V_NONE           1 << 0
-+
-+static const struct msl_opts slog_verb[]= 
-+{
-+  /* Basic flags */
-+
-+  { SLOG_V_QUERY_PLAN, "query_plan" },
-+
-+  /* End of baisc flags */
-+
-+  { 0, "" },
-+
-+  /* Complex flags */
-+
-+  { SLOG_V_QUERY_PLAN, "standard" },
-+  { SLOG_V_INVALID, "full" },
-+
-+  /* End of complex flags */
-+
-+  { SLOG_V_INVALID, (char *)0 }
-+};
-+
-+#define QPLAN_NONE            0
-+#define QPLAN_QC              1 << 0
-+#define QPLAN_QC_NO           1 << 1
-+#define QPLAN_FULL_SCAN       1 << 2
-+#define QPLAN_FULL_JOIN       1 << 3
-+#define QPLAN_TMP_TABLE       1 << 4
-+#define QPLAN_TMP_DISK        1 << 5
-+#define QPLAN_FILESORT        1 << 6
-+#define QPLAN_FILESORT_DISK   1 << 7
-+/* ... */
-+#define QPLAN_MAX             1 << 31
-+
-+#define SLOG_F_QC_NO          QPLAN_QC_NO
-+#define SLOG_F_FULL_SCAN      QPLAN_FULL_SCAN
-+#define SLOG_F_FULL_JOIN      QPLAN_FULL_JOIN
-+#define SLOG_F_TMP_TABLE      QPLAN_TMP_TABLE
-+#define SLOG_F_TMP_DISK       QPLAN_TMP_DISK
-+#define SLOG_F_FILESORT       QPLAN_FILESORT
-+#define SLOG_F_FILESORT_DISK  QPLAN_FILESORT_DISK
-+#define SLOG_F_INVALID        1 << 31
-+#define SLOG_F_NONE           0
-+
-+static const struct msl_opts slog_filter[]= 
-+{
-+  { SLOG_F_QC_NO,         "qc_miss" },
-+  { SLOG_F_FULL_SCAN,     "full_scan" },
-+  { SLOG_F_FULL_JOIN,     "full_join" },
-+  { SLOG_F_TMP_TABLE,     "tmp_table" },
-+  { SLOG_F_TMP_DISK,      "tmp_table_on_disk" },
-+  { SLOG_F_FILESORT,      "filesort" },
-+  { SLOG_F_FILESORT_DISK, "filesort_on_disk" },
-+  { SLOG_F_INVALID,       (char *)0 }
-+};
- /*
-   Some defines for exit codes for ::is_equal class functions.
---- mysql-5.1.49/sql/mysqld.cc~        2010-07-24 15:19:16.000000000 +0300
-+++ mysql-5.1.49/sql/mysqld.cc 2010-07-24 15:22:23.181784212 +0300
-@@ -5553,6 +5553,9 @@
-   OPT_SECURE_FILE_PRIV,
-   OPT_MIN_EXAMINED_ROW_LIMIT,
-   OPT_LOG_SLOW_SLAVE_STATEMENTS,
-+  OPT_LOG_SLOW_RATE_LIMIT, 
-+  OPT_LOG_SLOW_VERBOSITY, 
-+  OPT_LOG_SLOW_FILTER, 
- #if defined(ENABLED_DEBUG_SYNC)
-   OPT_DEBUG_SYNC_TIMEOUT,
- #endif /* defined(ENABLED_DEBUG_SYNC) */
-@@ -6819,6 +6819,17 @@
-    "The minimum percentage of warm blocks in key cache.",
-    &dflt_key_cache_var.param_division_limit, NULL, NULL,
-    (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0},
-+  {"log_slow_filter", OPT_LOG_SLOW_FILTER,
-+   "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]",
-+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_F_NONE, 0, 0},
-+  {"log_slow_rate_limit", OPT_LOG_SLOW_RATE_LIMIT,
-+   "Rate limit statement writes to slow log to only those from every (1/log_slow_rate_limit) session.",
-+   (uchar**) &global_system_variables.log_slow_rate_limit,
-+   (uchar**) &max_system_variables.log_slow_rate_limit, 0, GET_ULONG,
-+   REQUIRED_ARG, 1, 1, ~0L, 0, 1L, 0},
-+  {"log_slow_verbosity", OPT_LOG_SLOW_VERBOSITY,
-+   "Choose how verbose the messages to your slow log will be. Multiple flags allowed in a comma-separated string. [microtime, query_plan, innodb]",
-+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_V_NONE, 0, 0},
-   {"long_query_time", OPT_LONG_QUERY_TIME,
-    "Log all queries that have taken more than long_query_time seconds to "
-    "execute. The argument will be treated as a decimal value with "
-@@ -7556,6 +7570,10 @@
-   global_system_variables.old_passwords= 0;
-   global_system_variables.old_alter_table= 0;
-   global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
-+  
-+  global_system_variables.log_slow_verbosity= SLOG_V_NONE; 
-+  global_system_variables.log_slow_filter= SLOG_F_NONE; 
-+  
-   /*
-     Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
-     when collecting index statistics for MyISAM tables.
-@@ -8007,6 +8025,24 @@
-   case OPT_BOOTSTRAP:
-     opt_noacl=opt_bootstrap=1;
-     break;
-+  case OPT_LOG_SLOW_FILTER: 
-+    if ((global_system_variables.log_slow_filter=  
-+          msl_flag_resolve_by_name(slog_filter, argument, 
-+                                   SLOG_F_NONE, SLOG_F_INVALID)) == SLOG_F_INVALID) 
-+    { 
-+      fprintf(stderr,"Invalid argument to log_slow_filter\n"); 
-+      exit(1); 
-+    } 
-+    break; 
-+  case OPT_LOG_SLOW_VERBOSITY: 
-+    if ((global_system_variables.log_slow_verbosity=  
-+         msl_flag_resolve_by_name(slog_verb, argument, 
-+                                  SLOG_V_NONE, SLOG_V_INVALID)) == SLOG_V_INVALID) 
-+    { 
-+      fprintf(stderr,"Invalid argument to log_slow_verbosity\n"); 
-+      exit(1); 
-+    } 
-+    break; 
-   case OPT_SERVER_ID:
-     server_id_supplied = 1;
-     break;
-diff -r 0b1f42e1aacf sql/set_var.cc
---- a/sql/set_var.cc   Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/set_var.cc   Thu Dec 04 08:55:29 2008 -0800
-@@ -336,6 +336,20 @@
-                                             &SV::max_join_size,
-                                             fix_max_join_size);
- #endif
-+static sys_var_thd_ulong  sys_log_slow_rate_limit(&vars, "log_slow_rate_limit", 
-+              &SV::log_slow_rate_limit); 
-+static sys_var_thd_msl_flag sys_log_slow_filter(&vars, "log_slow_filter", 
-+              &SV::log_slow_filter, 
-+                                       SLOG_F_NONE, 
-+                                       SLOG_F_NONE, 
-+                                       SLOG_F_INVALID, 
-+                                       slog_filter); 
-+static sys_var_thd_msl_flag sys_log_slow_verbosity(&vars, "log_slow_verbosity", 
-+              &SV::log_slow_verbosity, 
-+                                       SLOG_V_NONE, 
-+                                       SLOG_V_NONE, 
-+                                       SLOG_V_INVALID, 
-+                                       slog_verb); 
- static sys_var_long_ptr_global
- sys_max_prepared_stmt_count(&vars, "max_prepared_stmt_count",
-                             &max_prepared_stmt_count,
-@@ -3631,6 +3645,192 @@
- #endif
- }
-+/* Slow log stuff */
-+
-+ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len)
-+{
-+  ulong i;
-+  
-+  for (i=0; opts[i].name; i++)
-+  {
-+    if (!my_strnncoll(&my_charset_latin1,
-+                      (const uchar *)name, len,
-+                      (const uchar *)opts[i].name, strlen(opts[i].name)))
-+      return opts[i].val;
-+  }
-+  return opts[i].val;
-+}
-+
-+ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list, 
-+                               const ulong none_val, const ulong invalid_val)
-+{
-+  const char *p, *e;
-+  ulong val= none_val;
-+  
-+  if (!*names_list)
-+    return val;
-+  
-+  for (p= e= names_list; ; e++)
-+  {
-+    ulong i;
-+    
-+    if (*e != ',' && *e)
-+      continue;
-+    for (i=0; opts[i].name; i++)
-+    {
-+      if (!my_strnncoll(&my_charset_latin1,
-+                        (const uchar *)p, e - p,
-+                        (const uchar *)opts[i].name, strlen(opts[i].name)))
-+      {
-+        val= val | opts[i].val;
-+        break;
-+      }
-+    }
-+    if (opts[i].val == invalid_val)
-+      return invalid_val;
-+    if (!*e)
-+      break;
-+    p= e + 1;
-+  }
-+  return val;
-+}
-+
-+const char *msl_option_get_name(const struct msl_opts *opts, ulong val)
-+{
-+  for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
-+  {
-+    if (opts[i].val == val)
-+      return opts[i].name;
-+  }
-+  return "*INVALID*";
-+}
-+
-+char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val)
-+{
-+  uint offset= 0;
-+  
-+  *buf= '\0';
-+  for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
-+  {
-+    if (opts[i].val & val)
-+      offset+= snprintf(buf+offset, STRING_BUFFER_USUAL_SIZE - offset - 1,
-+                        "%s%s", (offset ? "," : ""), opts[i].name);
-+  }
-+  return buf;
-+}
-+
-+/****************************************************************************
-+ Functions to handle log_slow_verbosity
-+****************************************************************************/
-+
-+/* Based upon sys_var::check_enum() */
-+
-+bool sys_var_thd_msl_option::check(THD *thd, set_var *var)
-+{
-+  char buff[STRING_BUFFER_USUAL_SIZE];
-+  String str(buff, sizeof(buff), &my_charset_latin1), *res;
-+
-+  if (var->value->result_type() == STRING_RESULT)
-+  {
-+    ulong verb= this->invalid_val;
-+    if (!(res=var->value->val_str(&str)) ||
-+            (var->save_result.ulong_value=
-+          (ulong) (verb= msl_option_resolve_by_name(this->opts, res->ptr(), res->length()))) == this->invalid_val)
-+      goto err;
-+    return 0;
-+  }
-+
-+err:
-+  my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
-+  return 1;
-+}
-+
-+uchar *sys_var_thd_msl_option::value_ptr(THD *thd, enum_var_type type,
-+                                      LEX_STRING *base)
-+{
-+  ulong val;
-+  val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
-+        thd->variables.*offset);
-+  const char *verbosity= msl_option_get_name(this->opts, val);
-+  return (uchar *) verbosity;
-+}
-+
-+
-+void sys_var_thd_msl_option::set_default(THD *thd, enum_var_type type)
-+{
-+  if (type == OPT_GLOBAL)
-+    global_system_variables.*offset= (ulong) this->default_val;
-+  else
-+    thd->variables.*offset= (ulong) (global_system_variables.*offset);
-+}
-+
-+
-+bool sys_var_thd_msl_option::update(THD *thd, set_var *var)
-+{
-+  if (var->type == OPT_GLOBAL)
-+    global_system_variables.*offset= var->save_result.ulong_value;
-+  else
-+    thd->variables.*offset= var->save_result.ulong_value;
-+  return 0;
-+}
-+
-+/****************************************************************************
-+ Functions to handle log_slow_filter
-+****************************************************************************/
-+  
-+/* Based upon sys_var::check_enum() */
-+
-+bool sys_var_thd_msl_flag::check(THD *thd, set_var *var)
-+{
-+  char buff[2 * STRING_BUFFER_USUAL_SIZE];
-+  String str(buff, sizeof(buff), &my_charset_latin1), *res;
-+
-+  if (var->value->result_type() == STRING_RESULT)
-+  {
-+    ulong filter= this->none_val;
-+    if (!(res=var->value->val_str(&str)) ||
-+       (var->save_result.ulong_value=
-+          (ulong) (filter= msl_flag_resolve_by_name(this->flags, res->ptr(), this->none_val, 
-+                                                    this->invalid_val))) == this->invalid_val)
-+      goto err;
-+    return 0;
-+  }
-+
-+err:
-+  my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
-+  return 1;
-+}
-+
-+uchar *sys_var_thd_msl_flag::value_ptr(THD *thd, enum_var_type type,
-+                                      LEX_STRING *base)
-+{
-+  ulong val;
-+  val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
-+        thd->variables.*offset);
-+  msl_flag_get_name(this->flags, this->flags_string, val);
-+  return (uchar *) this->flags_string;
-+}
-+
-+
-+void sys_var_thd_msl_flag::set_default(THD *thd, enum_var_type type)
-+{
-+  if (type == OPT_GLOBAL)
-+    global_system_variables.*offset= (ulong) this->default_val;
-+  else
-+    thd->variables.*offset= (ulong) (global_system_variables.*offset);
-+}
-+
-+
-+bool sys_var_thd_msl_flag::update(THD *thd, set_var *var)
-+{
-+  if (var->type == OPT_GLOBAL)
-+    global_system_variables.*offset= var->save_result.ulong_value;
-+  else
-+    thd->variables.*offset= var->save_result.ulong_value;
-+  return 0;
-+}
-+
-+
- /****************************************************************************
-  Functions to handle table_type
- ****************************************************************************/
-diff -r 0b1f42e1aacf sql/set_var.h
---- a/sql/set_var.h    Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/set_var.h    Thu Dec 04 08:55:29 2008 -0800
-@@ -1057,6 +1057,68 @@
-   bool update(THD *thd, set_var *var);
- };
-+class sys_var_thd_msl_option :public sys_var_thd
-+{
-+protected:
-+  ulong SV::*offset;
-+  const ulong none_val;
-+  const ulong default_val;
-+  const ulong invalid_val;
-+  const struct msl_opts *opts;
-+public:
-+  sys_var_thd_msl_option(sys_var_chain *chain, const char *name_arg,
-+                         ulong SV::*offset_arg,
-+                         const ulong none_val_arg,
-+                         const ulong default_val_arg,
-+                         const ulong invalid_val_arg,
-+                         const struct msl_opts *opts_arg)
-+    :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
-+     default_val(default_val_arg), invalid_val(invalid_val_arg), 
-+     opts(opts_arg)
-+  { chain_sys_var(chain); }
-+  bool check(THD *thd, set_var *var);
-+  SHOW_TYPE show_type() { return SHOW_CHAR; }
-+  bool check_update_type(Item_result type)
-+  {
-+    return type != STRING_RESULT;             /* Only accept strings */
-+  }
-+  void set_default(THD *thd, enum_var_type type);
-+  bool update(THD *thd, set_var *var);
-+  uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-+};
-+
-+
-+class sys_var_thd_msl_flag :public sys_var_thd
-+{
-+protected:
-+  char flags_string[2 * STRING_BUFFER_USUAL_SIZE];
-+  ulong SV::*offset;
-+  const ulong none_val;
-+  const ulong default_val;
-+  const ulong invalid_val;
-+  const struct msl_opts *flags;
-+public:
-+  sys_var_thd_msl_flag(sys_var_chain *chain, const char *name_arg,
-+                       ulong SV::*offset_arg, 
-+                       const ulong none_val_arg, 
-+                       const ulong default_val_arg, 
-+                       const ulong invalid_val_arg,
-+                       const struct msl_opts *flags_arg)
-+    :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
-+     default_val(default_val_arg), invalid_val(invalid_val_arg), 
-+     flags(flags_arg)
-+  { chain_sys_var(chain); }
-+  bool check(THD *thd, set_var *var);
-+  SHOW_TYPE show_type() { return SHOW_CHAR; }
-+  bool check_update_type(Item_result type)
-+  {
-+    return type != STRING_RESULT;             /* Only accept strings */
-+  }
-+  void set_default(THD *thd, enum_var_type type);
-+  bool update(THD *thd, set_var *var);
-+  uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-+};
-+
- /**
-   Handler for setting the system variable --read-only.
-@@ -1323,3 +1385,10 @@
- bool process_key_caches(process_key_cache_t func);
- void delete_elements(I_List<NAMED_LIST> *list,
-                    void (*free_element)(const char*, uchar*));
-+
-+/* Slow log functions */
-+ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len);
-+ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list, 
-+                               const ulong none_val, const ulong invalid_val);
-+const char *msl_option_get_name(const struct msl_opts *opts, ulong val);
-+char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val);
-diff -r 0b1f42e1aacf sql/slave.cc
---- a/sql/slave.cc     Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/slave.cc     Thu Dec 04 08:55:29 2008 -0800
-@@ -1561,6 +1561,7 @@
-     + MAX_LOG_EVENT_HEADER;  /* note, incr over the global not session var */
-   thd->slave_thread = 1;
-   thd->enable_slow_log= opt_log_slow_slave_statements;
-+  thd->write_to_slow_log= opt_log_slow_slave_statements;
-   set_slave_thread_options(thd);
-   thd->client_capabilities = CLIENT_LOCAL_FILES;
-   pthread_mutex_lock(&LOCK_thread_count);
-diff -r 0b1f42e1aacf sql/sql_cache.cc
---- a/sql/sql_cache.cc Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_cache.cc Thu Dec 04 08:55:29 2008 -0800
-@@ -1465,6 +1465,7 @@
-   thd->limit_found_rows = query->found_rows();
-   thd->status_var.last_query_cost= 0.0;
-+  thd->query_plan_flags|= QPLAN_QC;
-   if (!thd->main_da.is_set())
-     thd->main_da.disable_status();
-@@ -1473,6 +1474,7 @@
- err_unlock:
-   STRUCT_UNLOCK(&structure_guard_mutex);
- err:
-+  thd->query_plan_flags|= QPLAN_QC_NO;
-   DBUG_RETURN(0);                             // Query was not cached
- }
-diff -r 0b1f42e1aacf sql/sql_class.h
---- a/sql/sql_class.h  Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_class.h  Thu Dec 04 08:55:29 2008 -0800
-@@ -396,6 +396,11 @@
-   DATE_TIME_FORMAT *datetime_format;
-   DATE_TIME_FORMAT *time_format;
-   my_bool sysdate_is_now;
-+
-+  ulong log_slow_rate_limit; 
-+  ulong log_slow_filter; 
-+  ulong log_slow_verbosity; 
-+            
- };
-@@ -1339,6 +1344,11 @@
-   
-   thr_lock_type update_lock_default;
-   Delayed_insert *di;
-+
-+  bool       write_to_slow_log; 
-+ 
-+  ulong      query_plan_flags; 
-+  ulong      query_plan_fsort_passes; 
-   /* <> 0 if we are inside of trigger or stored function. */
-   uint in_sub_stmt;
-diff -r 0b1f42e1aacf sql/sql_connect.cc
---- a/sql/sql_connect.cc       Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_connect.cc       Thu Dec 04 08:55:29 2008 -0800
-@@ -1124,6 +1124,15 @@
-     prepare_new_connection_state(thd);
-+    /* 
-+      If rate limiting of slow log writes is enabled, decide whether to log this 
-+      new thread's queries or not. Uses extremely simple algorithm. :) 
-+    */ 
-+    thd->write_to_slow_log= FALSE; 
-+    if (thd->variables.log_slow_rate_limit <= 1 ||  
-+        (thd->thread_id % thd->variables.log_slow_rate_limit) == 0) 
-+         thd->write_to_slow_log= TRUE; 
-+
-     while (!net->error && net->vio != 0 &&
-            !(thd->killed == THD::KILL_CONNECTION))
-     {
-diff -r 0b1f42e1aacf sql/sql_parse.cc
---- a/sql/sql_parse.cc Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_parse.cc Thu Dec 04 08:55:29 2008 -0800
-@@ -1692,6 +1692,27 @@
-   if (unlikely(thd->in_sub_stmt))
-     DBUG_VOID_RETURN;                           // Don't set time for sub stmt
-+  /* Follow the slow log filter configuration. */ 
-+  if (thd->variables.log_slow_filter != SLOG_F_NONE &&  
-+      (!(thd->variables.log_slow_filter & thd->query_plan_flags) || 
-+       ((thd->variables.log_slow_filter & SLOG_F_QC_NO) &&  
-+        (thd->query_plan_flags & QPLAN_QC)))) 
-+    DBUG_VOID_RETURN; 
-+ 
-+  /* 
-+    Low long_query_time value most likely means user is debugging stuff and even  
-+    though some thread's queries are not supposed to be logged b/c of the rate  
-+    limit, if one of them takes long enough (>= 1 second) it will be sensible  
-+    to make an exception and write to slow log anyway. 
-+  */ 
-+  if (thd->write_to_slow_log != TRUE && thd->variables.long_query_time < 1000000 && 
-+      (ulong) (thd->start_utime - thd->utime_after_lock) >= 1000000) 
-+    thd->write_to_slow_log= TRUE; 
-+ 
-+  /* Do not log this thread's queries due to rate limiting. */ 
-+  if (thd->write_to_slow_log != TRUE) 
-+    DBUG_VOID_RETURN; 
-+
-   /*
-     Do not log administrative statements unless the appropriate option is
-     set; do not log into slow log if reading from backup.
-@@ -5773,6 +5794,9 @@
-   thd->total_warn_count=0;                    // Warnings for this query
-   thd->rand_used= 0;
-   thd->sent_row_count= thd->examined_row_count= 0;
-+
-+  thd->query_plan_flags= QPLAN_NONE; 
-+  thd->query_plan_fsort_passes= 0; 
-   /*
-     Because we come here only for start of top-statements, binlog format is
-diff -r 0b1f42e1aacf sql/sql_select.cc
---- a/sql/sql_select.cc        Thu Dec 04 08:55:22 2008 -0800
-+++ b/sql/sql_select.cc        Thu Dec 04 08:55:29 2008 -0800
-@@ -6480,7 +6480,10 @@
-         {
-           join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
-           if (statistics)
-+          {
-             status_var_increment(join->thd->status_var.select_scan_count);
-+            join->thd->query_plan_flags|= QPLAN_FULL_SCAN;
-+          }
-         }
-       }
-       else
-@@ -6494,7 +6497,10 @@
-         {
-           join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
-           if (statistics)
-+          {
-             status_var_increment(join->thd->status_var.select_full_join_count);
-+            join->thd->query_plan_flags|= QPLAN_FULL_JOIN;
-+          }
-         }
-       }
-       if (!table->no_keyread)
-@@ -9638,6 +9644,7 @@
-               (ulong) rows_limit,test(group)));
-   status_var_increment(thd->status_var.created_tmp_tables);
-+  thd->query_plan_flags|= QPLAN_TMP_TABLE;
-   if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
-     temp_pool_slot = bitmap_lock_set_next(&temp_pool);
-@@ -10508,6 +10515,7 @@
-     goto err;
-   }
-   status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
-+  table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
-   share->db_record_offset= 1;
-   DBUG_RETURN(0);
-  err:
diff --git a/mysql-mysql-syslog.patch b/mysql-mysql-syslog.patch
deleted file mode 100644 (file)
index 03f3ea2..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-# name       : mysql-syslog.patch
-# introduced : 12
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/client/client_priv.h
-+++ b/client/client_priv.h
-@@ -93,6 +93,9 @@
-   OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT,
-   OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
-   OPT_WRITE_BINLOG, OPT_DUMP_DATE,
-+#ifndef __WIN__
-+  OPT_SYSLOG,
-+#endif
-   OPT_FIRST_SLAVE,
-   OPT_ALL,
-   OPT_MAX_CLIENT_OPTION
---- a/client/mysql.cc
-+++ b/client/mysql.cc
-@@ -40,6 +40,9 @@
- #include "my_readline.h"
- #include <signal.h>
- #include <violite.h>
-+#ifndef __WIN__
-+#include "syslog.h"
-+#endif
- #if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H)
- #include <locale.h>
-@@ -59,6 +62,8 @@
- /* Version numbers for deprecation messages */
- #define VER_CELOSIA "5.6"
-+#define MAX_SYSLOG_MESSAGE 900
-+
- void* sql_alloc(unsigned size);            // Don't use mysqld alloc for these
- void sql_element_free(void *ptr);
- #include "sql_string.h"
-@@ -149,7 +154,7 @@
-              default_charset_used= 0, opt_secure_auth= 0,
-                default_pager_set= 0, opt_sigint_ignore= 0,
-                show_warnings= 0, executing_query= 0, interrupted_query= 0,
--               ignore_spaces= 0;
-+               ignore_spaces= 0, opt_syslog= 0;
- static my_bool debug_info_flag, debug_check_flag;
- static my_bool column_types_flag;
- static my_bool preserve_comments= 0;
-@@ -204,6 +209,7 @@
- void tee_fputs(const char *s, FILE *file);
- void tee_puts(const char *s, FILE *file);
- void tee_putc(int c, FILE *file);
-+void write_syslog(String *buffer);
- static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
- /* The names of functions that actually do the manipulation. */
- static int get_options(int argc,char **argv);
-@@ -1561,6 +1567,10 @@
-   {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.",
-     &show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG,
-     0, 0, 0, 0, 0, 0},
-+#ifndef __WIN__
-+  {"syslog", OPT_SYSLOG, "Logs all queries to syslog", 0, 0, 0, GET_NO_ARG,
-+   NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
- };
-@@ -1684,6 +1694,11 @@
-                                     opt->name);
- #endif
-     break;
-+#ifndef __WIN__
-+  case OPT_SYSLOG:
-+    opt_syslog = 1;
-+    break;
-+#endif
-   case OPT_SERVER_ARG:
- #ifdef EMBEDDED_LIBRARY
-     /*
-@@ -2064,6 +2079,40 @@
-   DBUG_RETURN((COMMANDS *) 0);
- }
-+void write_syslog(String *line){
-+#ifndef __WIN__
-+  uint length= line->length();
-+  uint chunk_len= min(MAX_SYSLOG_MESSAGE, length);
-+  char *ptr= line->c_ptr_safe();
-+  char buff[MAX_SYSLOG_MESSAGE + 1];
-+
-+  for (;
-+       length;
-+       length-= chunk_len, ptr+= chunk_len, chunk_len= min(MAX_SYSLOG_MESSAGE,
-+                                                           length))
-+  {
-+    char *str;
-+    if (length == chunk_len)
-+      str= ptr;                                 // last chunk => skip copy
-+    else
-+    {
-+      memcpy(buff, ptr, chunk_len);
-+      buff[chunk_len]= '\0';
-+      str= buff;
-+    }
-+    syslog(LOG_INFO,
-+           "SYSTEM_USER:'%s', MYSQL_USER:'%s', CONNECTION_ID:%lu, "
-+           "DB_SERVER:'%s', DB:'%s', QUERY:'%s'",
-+           getenv("SUDO_USER") ? getenv("SUDO_USER") : 
-+           getenv("USER") ? getenv("USER") : "--",
-+           current_user ? current_user : "--",
-+           mysql_thread_id(&mysql),
-+           current_host ? current_host : "--",
-+           current_db ? current_db : "--",
-+           str);
-+  }
-+#endif
-+}
- static bool add_line(String &buffer,char *line,char *in_string,
-                      bool *ml_comment, bool truncated)
-@@ -3039,6 +3088,11 @@
-     fix_history(buffer);
-   }
- #endif
-+#ifndef __WIN__
-+  if (opt_syslog && buffer->length() && connect_flag == CLIENT_INTERACTIVE){
-+    write_syslog(buffer);
-+  }
-+#endif
-   buffer->length(0);
diff --git a/mysql-mysql_dump_ignore_ct.patch b/mysql-mysql_dump_ignore_ct.patch
deleted file mode 100644 (file)
index 0518d5a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-# name       : mysql_dump_ignore_ct.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
-diff -ruN a/client/client_priv.h b/client/client_priv.h
---- a/client/client_priv.h     2010-04-06 23:03:48.000000000 +0900
-+++ b/client/client_priv.h     2010-04-30 19:37:42.000000000 +0900
-@@ -68,6 +68,7 @@
-   OPT_MYSQL_LOCK_DIRECTORY,
-   OPT_USE_THREADS,
-   OPT_IMPORT_USE_THREADS,
-+  OPT_IGNORE_CREATE_ERROR,
-   OPT_MYSQL_NUMBER_OF_QUERY,
-   OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
-   OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
-diff -ruN a/client/mysqldump.c b/client/mysqldump.c
---- a/client/mysqldump.c       2010-04-06 23:03:49.000000000 +0900
-+++ b/client/mysqldump.c       2010-04-30 19:41:20.000000000 +0900
-@@ -98,7 +98,7 @@
-                 opt_complete_insert= 0, opt_drop_database= 0,
-                 opt_replace_into= 0,
-                 opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
--                opt_events= 0,
-+                opt_events= 0, opt_ignore_show_create_table_error=0,
-                 opt_alltspcs=0, opt_notspcs= 0;
- static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
- static ulong opt_max_allowed_packet, opt_net_buffer_length;
-@@ -326,6 +326,9 @@
-   {"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},
-+  {"ignore-create-error", OPT_IGNORE_CREATE_ERROR, "Don't exit on show create table errors.",
-+   (uchar**) &opt_ignore_show_create_table_error, (uchar**) &opt_ignore_show_create_table_error, 0, GET_BOOL,
-+   NO_ARG, 0, 0, 0, 0, 0, 0},
-   {"lines-terminated-by", OPT_LTB, 
-    "Lines in the output file are terminated by the given string.",
-    &lines_terminated, &lines_terminated, 0, GET_STR,
-@@ -2303,13 +2306,21 @@
-       /* Make an sql-file, if path was given iow. option -T was given */
-       char buff[20+FN_REFLEN];
-       MYSQL_FIELD *field;
-+   
-+      my_bool old_ignore_errors=ignore_errors;
-+      //fprintf(stderr, "ignore create table %d\n", opt_ignore_show_create_table_error);
-+      if (opt_ignore_show_create_table_error)
-+         ignore_errors=1;
-       my_snprintf(buff, sizeof(buff), "show create table %s", result_table);
-       if (switch_character_set_results(mysql, "binary") ||
-           mysql_query_with_error_report(mysql, &result, buff) ||
-           switch_character_set_results(mysql, default_charset))
-+      {
-+        ignore_errors=old_ignore_errors;
-         DBUG_RETURN(0);
-+      }
-       if (path)
-       {
diff --git a/mysql-mysql_remove_eol_carret.patch b/mysql-mysql_remove_eol_carret.patch
deleted file mode 100644 (file)
index 2928be0..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# name       : mysql_remove_eol_carret.patch
-# introduced : 11 or before
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/client/client_priv.h
-+++ b/client/client_priv.h
-@@ -98,5 +98,6 @@
- #endif
-   OPT_FIRST_SLAVE,
-   OPT_ALL,
-+  OPT_NO_REMOVE_EOL_CARRET,
-   OPT_MAX_CLIENT_OPTION
- };
---- a/client/mysql.cc
-+++ b/client/mysql.cc
-@@ -143,6 +143,8 @@
- enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
- typedef enum enum_info_type INFO_TYPE;
-+my_bool opt_no_remove_eol_carret=0;
-+
- static MYSQL mysql;                   /* The connection */
- static my_bool ignore_errors=0,wait_flag=0,quick=0,
-                connected=0,opt_raw_data=0,unbuffered=0,output_tables=0,
-@@ -1439,6 +1441,10 @@
-    NO_ARG, 1, 0, 0, 0, 0, 0},  
-   {"skip-line-numbers", 'L', "Don't write line number for errors.", 0, 0, 0, GET_NO_ARG,
-    NO_ARG, 0, 0, 0, 0, 0, 0},
-+  {"no-remove-eol-carret", OPT_NO_REMOVE_EOL_CARRET, "Do not remove \\r before \\n in batch mode", 
-+  (uchar**)&opt_no_remove_eol_carret , (uchar**)&opt_no_remove_eol_carret, 0, 
-+   GET_BOOL,
-+   NO_ARG, 0, 0, 0, 0, 0, 0},
-   {"unbuffered", 'n', "Flush buffer after each query.", &unbuffered,
-    &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-   {"column-names", OPT_COLUMN_NAMES, "Write column names in results.",
---- a/client/readline.cc
-+++ b/client/readline.cc
-@@ -23,6 +23,8 @@
- #include <my_dir.h>
- #include "my_readline.h"
-+extern my_bool opt_no_remove_eol_carret;
-+
- static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,
-                           ulong max_size);
- static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str);
-@@ -57,12 +59,12 @@
- char *batch_readline(LINE_BUFFER *line_buff)
- {
-   char *pos;
--  ulong out_length;
-+  ulong UNINIT_VAR(out_length);
-   if (!(pos=intern_read_line(line_buff, &out_length)))
-     return 0;
-   if (out_length && pos[out_length-1] == '\n')
--    if (--out_length && pos[out_length-1] == '\r')  /* Remove '\n' */
-+    if (--out_length && !opt_no_remove_eol_carret && pos[out_length-1] == '\r')  /* Remove '\n' */
-       out_length--;                                 /* Remove '\r' */
-   line_buff->read_length=out_length;
-   pos[out_length]=0;
---- /dev/null
-+++ b/patch_info/mysql_remove_eol_carret.patch
-@@ -0,0 +1,7 @@
-+File=mysql_remove_eol_carret.patch
-+Name=
-+Version=1.1
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment=Do not remove carret before eol if --no-remove-eol-carret is enabled in MySQL client.
-+Changelog
diff --git a/mysql-optimizer_fix.patch b/mysql-optimizer_fix.patch
deleted file mode 100644 (file)
index b24fa19..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-# name       : optimizer_fix.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- /dev/null
-+++ b/patch_info/optimizer_fix.info
-@@ -0,0 +1,8 @@
-+File=optimizer_fix.patch
-+Name=Unofficial optimizer fixes
-+Version=1.0
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment=
-+2010-01
-+Ported to 5.1.42
---- a/sql/mysql_priv.h
-+++ b/sql/mysql_priv.h
-@@ -2109,6 +2109,7 @@
- extern ulong slave_exec_mode_options;
- extern my_bool opt_readonly, lower_case_file_system;
- extern my_bool opt_userstat_running, opt_thread_statistics;
-+extern my_bool opt_optimizer_fix;
- extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
- extern my_bool opt_secure_auth;
- extern char* opt_secure_file_priv;
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -542,6 +542,7 @@
- #endif /* defined(ENABLED_DEBUG_SYNC) */
- my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
- my_bool opt_userstat_running= 0, opt_thread_statistics= 0;
-+my_bool opt_optimizer_fix= 0;
- /*
-   True if there is at least one per-hour limit for some user, so we should
-   check them before each query (and possibly reset counters when hour is
-@@ -5865,6 +5866,7 @@
-   OPT_SLOW_QUERY_LOG_FILE,
-   OPT_USERSTAT_RUNNING,
-   OPT_THREAD_STATISTICS,
-+  OPT_OPTIMIZER_FIX,
-   OPT_USE_GLOBAL_LONG_QUERY_TIME,
-   OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
-   OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
-@@ -7381,6 +7383,10 @@
-    "Control TABLE_STATISTICS running, when userstat_running is enabled",
-    (uchar**) &opt_thread_statistics, (uchar**) &opt_thread_statistics,
-    0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-+  {"optimizer_fix", OPT_OPTIMIZER_FIX,
-+   "Enable unofficial optimizer fixes.",
-+   (uchar**) &opt_optimizer_fix, (uchar**) &opt_optimizer_fix,
-+   0, GET_BOOL, NO_ARG, 1, 0, 1, 0, 1, 0},
-   {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
-    "Causes updates to non-transactional engines using statement format to be "
-    "written directly to binary log. Before using this option, make sure that "
---- a/sql/opt_range.cc
-+++ b/sql/opt_range.cc
-@@ -695,7 +695,7 @@
- static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
-                                        bool index_read_must_be_used,
-                                        bool update_tbl_stats,
--                                       double read_time);
-+                                       double read_time, ha_rows *estimated_records);
- static
- TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
-                                           double read_time,
-@@ -2200,6 +2200,7 @@
-                                 ha_rows limit, bool force_quick_range)
- {
-   uint idx;
-+  ha_rows estimated_records=0;
-   double scan_time;
-   DBUG_ENTER("SQL_SELECT::test_quick_select");
-   DBUG_PRINT("enter",("keys_to_use: %lu  prev_tables: %lu  const_tables: %lu",
-@@ -2370,12 +2371,17 @@
-         /* Get best 'range' plan and prepare data for making other plans */
-         if ((range_trp= get_key_scans_params(&param, tree, FALSE, TRUE,
--                                             best_read_time)))
-+                                             best_read_time, &estimated_records)))
-         {
-           best_trp= range_trp;
-           best_read_time= best_trp->read_cost;
-         }
-+        if (opt_optimizer_fix && estimated_records)
-+        {
-+          records = estimated_records;
-+        }
-+
-         /*
-           Simultaneous key scans and row deletes on several handler
-           objects are not allowed so don't use ROR-intersection for
-@@ -3726,7 +3732,7 @@
-   {
-     DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map,
-                                         "tree in SEL_IMERGE"););
--    if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE, read_time)))
-+    if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE, read_time, NULL)))
-     {
-       /*
-         One of index scans in this index_merge is more expensive than entire
-@@ -4829,11 +4835,12 @@
- static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
-                                        bool index_read_must_be_used, 
-                                        bool update_tbl_stats,
--                                       double read_time)
-+                                       double read_time, ha_rows *estimated_records)
- {
-   int idx;
-   SEL_ARG **key,**end, **key_to_read= NULL;
-   ha_rows UNINIT_VAR(best_records);              /* protected by key_to_read */
-+  ha_rows min_records= HA_POS_ERROR;
-   TRP_RANGE* read_plan= NULL;
-   bool pk_is_clustered= param->table->file->primary_key_is_clustered();
-   DBUG_ENTER("get_key_scans_params");
-@@ -4904,6 +4911,11 @@
-         key_to_read=  key;
-       }
-+      if (estimated_records && found_records
-+          && min_records > found_records)
-+      {
-+        min_records = found_records;
-+      }
-     }
-   }
-@@ -4926,6 +4938,12 @@
-   else
-     DBUG_PRINT("info", ("No 'range' table read plan found"));
-+  /* minimum number of records (not 0) as estimated number of records */
-+  if (estimated_records && min_records != HA_POS_ERROR)
-+  {
-+    *estimated_records = min_records;
-+  }
-+
-   DBUG_RETURN(read_plan);
- }
---- a/sql/set_var.cc
-+++ b/sql/set_var.cc
-@@ -573,6 +573,8 @@
-                                                    &opt_userstat_running);
- static sys_var_bool_ptr               sys_thread_statistics(&vars, "thread_statistics",
-                                                     &opt_thread_statistics);
-+static sys_var_bool_ptr               sys_optimizer_fix(&vars, "optimizer_fix",
-+                                                &opt_optimizer_fix);
- static sys_var_thd_ulong      sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
-                                              &SV::read_rnd_buff_size);
- static sys_var_thd_ulong      sys_div_precincrement(&vars, "div_precision_increment",
---- a/sql/sql_select.cc
-+++ b/sql/sql_select.cc
-@@ -2605,6 +2605,11 @@
-       table->reginfo.impossible_range=1;
-       DBUG_RETURN(0);
-     }
-+    if (opt_optimizer_fix && error == 0)
-+    {
-+      /* quick select is not effective. but the estimated value is used. */
-+      DBUG_RETURN(select->records);
-+    }
-     DBUG_PRINT("warning",("Couldn't use record count on const keypart"));
-   }
-   DBUG_RETURN(HA_POS_ERROR);                  /* This shouldn't happend */
diff --git a/mysql-profiling_slow.patch b/mysql-profiling_slow.patch
deleted file mode 100644 (file)
index 273937d..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-# name       : profiling_slow.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- /dev/null
-+++ b/mysql-test/r/percona_bug643149.result
-@@ -0,0 +1,21 @@
-+SET @old_slow_query_log_file=@@global.slow_query_log_file;
-+SET GLOBAL slow_query_log=on;
-+SET LOCAL profiling_server=on;
-+SET LOCAL long_query_time=0;
-+SET GLOBAL slow_query_log_file='MYSQLTEST_VARDIR/percona_bug643149_slow.log';;
-+SELECT 1;
-+1
-+1
-+# User@Host: root[root] @ localhost []
-+# Thread_id: X  Schema: test  Last_errno: X  Killed: X
-+# Query_time: X.X  Lock_time: X.X  Rows_sent: X  Rows_examined: X  Rows_affected: X  Rows_read: X
-+# Bytes_sent: X  Tmp_tables: X  Tmp_disk_tables: X  Tmp_table_sizes: X
-+# Profile_starting: X.X Profile_starting_cpu: X.X Profile_Opening_tables: X.X Profile_Opening_tables_cpu: X.X Profile_query_end: X.X Profile_query_end_cpu: X.X Profile_freeing_items: X.X Profile_freeing_items_cpu: X.X Profile_logging_slow_query: X.X Profile_logging_slow_query_cpu: X.X 
-+# Profile_total: X.X Profile_total_cpu: X.X 
-+# User@Host: root[root] @ localhost []
-+# Thread_id: X  Schema: test  Last_errno: X  Killed: X
-+# Query_time: X.X  Lock_time: X.X  Rows_sent: X  Rows_examined: X  Rows_affected: X  Rows_read: X
-+# Bytes_sent: X  Tmp_tables: X  Tmp_disk_tables: X  Tmp_table_sizes: X
-+# Profile_starting: X.X Profile_starting_cpu: X.X Profile_checking_permissions: X.X Profile_checking_permissions_cpu: X.X Profile_Opening_tables: X.X Profile_Opening_tables_cpu: X.X Profile_init: X.X Profile_init_cpu: X.X Profile_optimizing: X.X Profile_optimizing_cpu: X.X Profile_executing: X.X Profile_executing_cpu: X.X Profile_end: X.X Profile_end_cpu: X.X Profile_query_end: X.X Profile_query_end_cpu: X.X Profile_freeing_items: X.X Profile_freeing_items_cpu: X.X Profile_logging_slow_query: X.X Profile_logging_slow_query_cpu: X.X 
-+# Profile_total: X.X Profile_total_cpu: X.X 
-+SET GLOBAL slow_query_log_file=@old_slow_query_log_file;
---- /dev/null
-+++ b/mysql-test/t/percona_bug643149.test
-@@ -0,0 +1,52 @@
-+#
-+# This test suffers from server
-+# Bug#38124 "general_log_file" variable silently unset when using expression
-+# In short:
-+#    SET GLOBAL general_log_file = @<whatever>
-+#    SET GLOBAL slow_query_log = @<whatever>
-+# cause that the value of these server system variables is set to default
-+# instead of the assigned values. There comes no error message or warning.
-+# If this bug is fixed please
-+# 1. try this test with "let $fixed_bug38124 = 0;"
-+# 2. remove all workarounds if 1. was successful.
-+let $fixed_bug38124 = 0;
-+
-+SET @old_slow_query_log_file=@@global.slow_query_log_file;
-+SET GLOBAL slow_query_log=on;
-+SET LOCAL profiling_server=on;
-+SET LOCAL long_query_time=0;
-+
-+let slogfile=$MYSQLTEST_VARDIR/percona_bug643149_slow.log;
-+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-+--eval SET GLOBAL slow_query_log_file='$slogfile';
-+
-+--disable_ps_protocol
-+SELECT 1;
-+--enable_ps_protocol
-+
-+perl;
-+  $slogfile= $ENV{'slogfile'};
-+
-+  open(FILE, "$slogfile") or
-+    die("Unable to read slow query log file $slogfile: $!\n");
-+  while(<FILE>) {
-+    next if (!/^#/);
-+    next if (/^# Time:/);
-+    s/[0-9]+/X/g;
-+    print;
-+  }
-+
-+  close(FILE);
-+  open(FILE, '>', "$slogfile");
-+  close(FILE);
-+EOF
-+
-+SET GLOBAL slow_query_log_file=@old_slow_query_log_file;
-+
-+if(!$fixed_bug38124)
-+{
-+  --disable_query_log
-+  let $my_var = `SELECT @old_slow_query_log_file`;
-+  eval SET @@global.slow_query_log_file = '$my_var';
-+  --enable_query_log
-+}
---- /dev/null
-+++ b/patch_info/profiling_slow.info
-@@ -0,0 +1,9 @@
-+File=profiling_slow.info
-+Name=profiling from SHOW PROFILE to slow.log
-+Version=1.0
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment=
-+Changelog
-+2009-05-18
-+Initial implementation
---- a/sql/log.cc
-+++ b/sql/log.cc
-@@ -2436,6 +2436,11 @@
-           my_b_printf(&log_file,"# No InnoDB statistics available for this query\n") == (uint) -1)
-       tmp_errno= errno;
-     }
-+
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+    thd->profiling.print_current(&log_file);
-+#endif
-+
-     if (thd->db && strcmp(thd->db, db))
-     {                                         // Database changed
-       if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -5809,6 +5809,8 @@
-   OPT_LOG_OUTPUT,
-   OPT_PORT_OPEN_TIMEOUT,
-   OPT_PROFILING,
-+  OPT_PROFILING_SERVER,
-+  OPT_PROFILING_USE_GETRUSAGE,
-   OPT_KEEP_FILES_ON_CREATE,
-   OPT_GENERAL_LOG,
-   OPT_SLOW_LOG,
-@@ -6424,6 +6426,16 @@
-    &global_system_variables.profiling_history_size,
-    &max_system_variables.profiling_history_size,
-    0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
-+  {"profiling_server", OPT_PROFILING_SERVER,
-+   "Enable profiling of all threads",
-+   (uchar**) &global_system_variables.profiling_server,
-+   (uchar**) &max_system_variables.profiling_server, 0, GET_BOOL,
-+   OPT_ARG, 0, 0, 0, 0, 0, 0 },
-+  {"profiling_use_getrusage", OPT_PROFILING_USE_GETRUSAGE,
-+   "Enable getrusage function call for profiling",
-+   (uchar**) &global_system_variables.profiling_use_getrusage,
-+   (uchar**) &max_system_variables.profiling_use_getrusage, 0, GET_BOOL,
-+   OPT_ARG, 0, 0, 0, 0, 0, 0 },
- #endif
-   {"relay-log", OPT_RELAY_LOG,
-    "The location and name to use for relay logs.",
---- a/sql/set_var.cc
-+++ b/sql/set_var.cc
-@@ -860,6 +860,10 @@
-                                       ulonglong(OPTION_PROFILING));
- static sys_var_thd_ulong      sys_profiling_history_size(&vars, "profiling_history_size",
-                                             &SV::profiling_history_size);
-+static sys_var_thd_bool       sys_profiling_server(&vars, "profiling_server",
-+                                            &SV::profiling_server);
-+static sys_var_thd_bool       sys_profiling_use_getrusage(&vars, "profiling_use_getrusage",
-+                                            &SV::profiling_use_getrusage);
- #endif
- /* Local state variables */
---- a/sql/sql_class.h
-+++ b/sql/sql_class.h
-@@ -330,6 +330,8 @@
-   ulong optimizer_switch;
-   ulong preload_buff_size;
-   ulong profiling_history_size;
-+  my_bool profiling_server;
-+  my_bool profiling_use_getrusage;
-   ulong query_cache_type;
-   ulong read_buff_size;
-   ulong read_rnd_buff_size;
---- a/sql/sql_profile.cc
-+++ b/sql/sql_profile.cc
-@@ -225,8 +225,22 @@
- {
-   time_usecs= (double) my_getsystime() / 10.0;  /* 1 sec was 1e7, now is 1e6 */
- #ifdef HAVE_GETRUSAGE
--  getrusage(RUSAGE_SELF, &rusage);
-+  if ((profile->get_profiling())->enabled_getrusage())
-+    getrusage(RUSAGE_SELF, &rusage);
- #endif
-+
-+#ifdef HAVE_CLOCK_GETTIME
-+  struct timespec tp;
-+
-+  if (!(clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+  {
-+    cpu_time_usecs= tp.tv_sec*1000000000.0 + tp.tv_nsec;
-+  } 
-+  else
-+#endif
-+  {
-+    cpu_time_usecs= 0;
-+  }
- }
-@@ -343,7 +357,7 @@
-     finish_current_query();
-   }
--  enabled= (((thd)->options & OPTION_PROFILING) != 0);
-+  enabled= (((thd)->options & OPTION_PROFILING) != 0) || ( thd->variables.profiling_server );
-   if (! enabled) DBUG_VOID_RETURN;
-@@ -381,7 +395,8 @@
-     status_change("ending", NULL, NULL, 0);
-     if ((enabled) &&                                    /* ON at start? */
--        ((thd->options & OPTION_PROFILING) != 0) &&   /* and ON at end? */
-+        (((thd->options & OPTION_PROFILING) != 0) || 
-+          (thd->variables.profiling_server)) &&   /* and ON at end? */
-         (current->query_source != NULL) &&
-         (! current->entries.is_empty()))
-     {
-@@ -482,6 +497,118 @@
-   DBUG_VOID_RETURN;
- }
-+bool PROFILING::enabled_getrusage()
-+{
-+  return thd->variables.profiling_use_getrusage;
-+}
-+
-+/**
-+   For a given profile entry specified by a name and 2 time measurements,
-+   print its normalized name (i.e. with all spaces replaced with underscores)
-+   along with its wall clock and CPU time.
-+*/
-+
-+static void my_b_print_status(IO_CACHE *log_file, const char *status,
-+                              PROF_MEASUREMENT *start, PROF_MEASUREMENT *stop)
-+{
-+  DBUG_ENTER("my_b_print_status");
-+  DBUG_ASSERT(log_file != NULL && status != NULL);
-+  char query_time_buff[22+7];
-+  const char *tmp;
-+
-+  my_b_printf(log_file, "Profile_");
-+  for (tmp= status; *tmp; tmp++)
-+    my_b_write_byte(log_file, *tmp == ' ' ? '_' : *tmp);
-+
-+  snprintf(query_time_buff, sizeof(query_time_buff), "%.6f",
-+           (stop->time_usecs - start->time_usecs) / (1000.0 * 1000));
-+  my_b_printf(log_file, ": %s ", query_time_buff);
-+
-+  my_b_printf(log_file, "Profile_");
-+  for (tmp= status; *tmp; tmp++)
-+    my_b_write_byte(log_file, *tmp == ' ' ? '_' : *tmp);
-+  my_b_printf(log_file, "_cpu: ");
-+
-+  snprintf(query_time_buff, sizeof(query_time_buff), "%.6f",
-+           (stop->cpu_time_usecs - start->cpu_time_usecs) /
-+           (1000.0 * 1000 * 1000));
-+  my_b_printf(log_file, "%s ", query_time_buff);
-+
-+  DBUG_VOID_RETURN;
-+}
-+
-+/**
-+  Print output for current query to file 
-+*/
-+
-+int PROFILING::print_current(IO_CACHE *log_file)
-+{
-+  DBUG_ENTER("PROFILING::print_current");
-+  ulonglong row_number= 0;
-+
-+  QUERY_PROFILE *query;
-+  /* Get current query */
-+  if (current == NULL)
-+  {
-+    DBUG_RETURN(0);
-+  }
-+
-+  query= current;
-+
-+  my_b_printf(log_file, "# ");
-+
-+    void *entry_iterator;
-+    PROF_MEASUREMENT *entry= NULL, *previous= NULL, *first= NULL;
-+    /* ...and for each query, go through all its state-change steps. */
-+    for (entry_iterator= query->entries.new_iterator();
-+         entry_iterator != NULL;
-+         entry_iterator= query->entries.iterator_next(entry_iterator),
-+         previous=entry, row_number++)
-+    {
-+      entry= query->entries.iterator_value(entry_iterator);
-+
-+      /* Skip the first.  We count spans of fence, not fence-posts. */
-+      if (previous == NULL) {first= entry; continue;}
-+
-+      if (thd->lex->sql_command == SQLCOM_SHOW_PROFILE)
-+      {
-+        /*
-+          We got here via a SHOW command.  That means that we stored
-+          information about the query we wish to show and that isn't
-+          in a WHERE clause at a higher level to filter out rows we
-+          wish to exclude.
-+
-+          Because that functionality isn't available in the server yet,
-+          we must filter here, at the wrong level.  Once one can con-
-+          struct where and having conditions at the SQL layer, then this
-+          condition should be ripped out.
-+        */
-+        if (thd->lex->profile_query_id == 0) /* 0 == show final query */
-+        {
-+          if (query != last)
-+            continue;
-+        }
-+        else
-+        {
-+          if (thd->lex->profile_query_id != query->profiling_query_id)
-+            continue;
-+        }
-+      }
-+
-+      my_b_print_status(log_file, previous->status, previous, entry);
-+    }
-+
-+    my_b_write_byte(log_file, '\n');
-+    if ((entry != NULL) && (first != NULL))
-+    {
-+      my_b_printf(log_file, "# ");
-+      my_b_print_status(log_file, "total", first, entry);
-+      my_b_write_byte(log_file, '\n');
-+    }
-+
-+  DBUG_RETURN(0);
-+}
-+
- /**
-   Fill the information schema table, "query_profile", as defined in show.cc .
-   There are two ways to get to this function:  Selecting from the information
-@@ -577,6 +704,8 @@
- #ifdef HAVE_GETRUSAGE
-+      if (enabled_getrusage())
-+      {
-       my_decimal cpu_utime_decimal, cpu_stime_decimal;
-       double2my_decimal(E_DEC_FATAL_ERROR,
-@@ -647,6 +776,7 @@
-       table->field[14]->store((uint32)(entry->rusage.ru_nswap -
-                              previous->rusage.ru_nswap), true);
-       table->field[14]->set_notnull();
-+      }
- #else
-       /* TODO: Add swap info for non-BSD systems */
- #endif
---- a/sql/sql_profile.h
-+++ b/sql/sql_profile.h
-@@ -168,11 +168,15 @@
- */
- class PROF_MEASUREMENT
- {
--private:
--  friend class QUERY_PROFILE;
--  friend class PROFILING;
--
-   QUERY_PROFILE *profile;
-+
-+  char *allocated_status_memory;
-+
-+  void set_label(const char *status_arg, const char *function_arg, 
-+                  const char *file_arg, unsigned int line_arg);
-+  void clean_up();
-+
-+public:
-   char *status;
- #ifdef HAVE_GETRUSAGE
-   struct rusage rusage;
-@@ -183,12 +187,7 @@
-   unsigned int line;
-   double time_usecs;
--  char *allocated_status_memory;
--
--  void set_label(const char *status_arg, const char *function_arg, 
--                  const char *file_arg, unsigned int line_arg);
--  void clean_up();
--  
-+  double cpu_time_usecs;
-   PROF_MEASUREMENT();
-   PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg);
-   PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg,
-@@ -233,6 +232,11 @@
-   /* Show this profile.  This is called by PROFILING. */
-   bool show(uint options);
-+
-+public:
-+
-+  inline PROFILING * get_profiling() { return profiling; };
-+
- };
-@@ -278,9 +282,11 @@
-   /* SHOW PROFILES */
-   bool show_profiles();
-+  bool enabled_getrusage();
-   /* ... from INFORMATION_SCHEMA.PROFILING ... */
-   int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
-+  int print_current(IO_CACHE *log_file);
- };
- #  endif /* HAVE_PROFILING */
diff --git a/mysql-query_cache_enhance.patch b/mysql-query_cache_enhance.patch
deleted file mode 100644 (file)
index 9fa2ffe..0000000
+++ /dev/null
@@ -1,3481 +0,0 @@
-# name       : query_cache_with_comments.patch
-# introduced : 11 or before
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- /dev/null
-+++ b/patch_info/query_cache_enhance.patch
-@@ -0,0 +1,14 @@
-+File=query_cache_enhance.patch
-+Name= query cache Percona's cumulative patch
-+Version=1.0
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment= 1) Add new status - Waiting on query cache mutex (status_wait_query_cache_mutex.patch)
-+         2) Remove comments from query (need for cache hit) (query_cache_with_comments.patch)
-+         3) Totally disable query cache (query_cache_totally_disable.info)
-+2010-05 - First version avaliable (query_cache_with_comments.patch)
-+2010-07 - First version avaliable (status_wait_query_cache_mutex.patch
-+2010-07 - First version avaliable (query_cache_totally_disable.info)
-+2010-07 - Fix crash (query_cache_with_comments.patch)
-+2010-07 - Fix incorrect behavior diff (query_cache_with_comments.patch)
-+2010-09 - Merge patches to one
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -535,6 +535,7 @@
- my_bool opt_log_slow_slave_statements= 0;
- my_bool opt_log_slow_sp_statements= 0;
- my_bool opt_log_slow_timestamp_every= 0;
-+my_bool opt_query_cache_strip_comments = 0;
- my_bool opt_use_global_long_query_time= 0;
- my_bool opt_slow_query_log_microseconds_timestamp= 0;
- my_bool lower_case_file_system= 0;
-@@ -5922,6 +5923,7 @@
-   OPT_THREAD_STATISTICS,
-   OPT_OPTIMIZER_FIX,
-   OPT_SUPPRESS_LOG_WARNING_1592,
-+  OPT_QUERY_CACHE_STRIP_COMMENTS,
-   OPT_USE_GLOBAL_LONG_QUERY_TIME,
-   OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
-   OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
-@@ -6977,6 +6979,10 @@
-   {"use_global_log_slow_control", OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
-     "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]",
-    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_UG_NONE, 0, 0},
-+  {"query_cache_strip_comments", OPT_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",
-+   (uchar**) &opt_query_cache_strip_comments, (uchar**) &opt_query_cache_strip_comments,
-+   0, GET_BOOL, REQUIRED_ARG, 0, 0, 1, 0, 1, 0},
-   {"use_global_long_query_time", OPT_USE_GLOBAL_LONG_QUERY_TIME,
-    "Control always use global long_query_time or local long_query_time.",
-    (uchar**) &opt_use_global_long_query_time, (uchar**) &opt_use_global_long_query_time,
---- a/sql/mysql_priv.h
-+++ b/sql/mysql_priv.h
-@@ -2117,6 +2117,7 @@
- extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements;
- extern my_bool opt_log_slow_sp_statements;
- extern my_bool opt_log_slow_timestamp_every;
-+extern my_bool opt_query_cache_strip_comments;
- extern my_bool opt_use_global_long_query_time;
- extern my_bool opt_slow_query_log_microseconds_timestamp;
- extern my_bool sp_automatic_privileges, opt_noacl;
---- /dev/null
-+++ b/sql/query_strip_comments.h
-@@ -0,0 +1,37 @@
-+#ifndef _SQL_QUERY_STRIPC_COMMENTS_H_
-+#define _SQL_QUERY_STRIPC_COMMENTS_H_
-+#ifdef HAVE_QUERY_CACHE
-+
-+// implemented in sql_cache.cc
-+class QueryStripComments
-+{
-+private:
-+  QueryStripComments(const QueryStripComments&);
-+  QueryStripComments& operator=(const QueryStripComments&);
-+public:
-+  QueryStripComments();
-+  ~QueryStripComments();
-+  void set(const char* a_query, uint a_query_length, uint a_additional_length);
-+  
-+  char* query()        { return buffer; }
-+  uint  query_length() { return length; }
-+private:
-+  void cleanup();
-+private:
-+  char* buffer;
-+  uint  length /*query length, not buffer length*/;
-+  uint  buffer_length;
-+};
-+class QueryStripComments_Backup
-+{
-+public:
-+  QueryStripComments_Backup(THD* a_thd,QueryStripComments* qsc);
-+  ~QueryStripComments_Backup();
-+private:
-+  THD*  thd;
-+  char* query;
-+  uint  length;
-+};
-+
-+#endif // HAVE_QUERY_CACHE
-+#endif // _SQL_QUERY_STRIPC_COMMENTS_H_
---- a/sql/set_var.cc
-+++ b/sql/set_var.cc
-@@ -126,8 +126,10 @@
- static void fix_net_write_timeout(THD *thd, enum_var_type type);
- static void fix_net_retry_count(THD *thd, enum_var_type type);
- static void fix_max_join_size(THD *thd, enum_var_type type);
-+#ifdef HAVE_QUERY_CACHE
- static void fix_query_cache_size(THD *thd, enum_var_type type);
- static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type);
-+#endif
- static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
- static void fix_max_binlog_size(THD *thd, enum_var_type type);
- static void fix_max_relay_log_size(THD *thd, enum_var_type type);
-@@ -583,9 +585,6 @@
-                                               &SV::div_precincrement);
- static sys_var_long_ptr       sys_rpl_recovery_rank(&vars, "rpl_recovery_rank",
-                                             &rpl_recovery_rank);
--static sys_var_long_ptr       sys_query_cache_size(&vars, "query_cache_size",
--                                           &query_cache_size,
--                                           fix_query_cache_size);
- static sys_var_thd_ulong      sys_range_alloc_block_size(&vars, "range_alloc_block_size",
-                                                  &SV::range_alloc_block_size);
-@@ -651,14 +650,20 @@
-                                             NULL);
- #ifdef HAVE_QUERY_CACHE
-+static sys_var_long_ptr       sys_query_cache_size(&vars, "query_cache_size",
-+                                             &query_cache_size,
-+                                             fix_query_cache_size);
- static sys_var_long_ptr       sys_query_cache_limit(&vars, "query_cache_limit",
-                                             &query_cache.query_cache_limit);
--static sys_var_long_ptr        sys_query_cache_min_res_unit(&vars, "query_cache_min_res_unit",
-+static sys_var_long_ptr
-+  sys_query_cache_min_res_unit(&vars, "query_cache_min_res_unit",
-                                                    &query_cache_min_res_unit,
-                                                    fix_query_cache_min_res_unit);
-+static int check_query_cache_type(THD *thd, set_var *var);
- static sys_var_thd_enum       sys_query_cache_type(&vars, "query_cache_type",
-                                            &SV::query_cache_type,
--                                           &query_cache_type_typelib);
-+                                           &query_cache_type_typelib, NULL,
-+                                             check_query_cache_type);
- static sys_var_thd_bool
- sys_query_cache_wlock_invalidate(&vars, "query_cache_wlock_invalidate",
-                                &SV::query_cache_wlock_invalidate);
-@@ -942,6 +947,8 @@
- #ifndef EMBEDDED_LIBRARY
- static sys_var_const_str_ptr    sys_repl_report_host(&vars, "report_host", &report_host);
- static sys_var_const_str_ptr    sys_repl_report_user(&vars, "report_user", &report_user);
-+static sys_var_bool_ptr       sys_query_cache_strip_comments(&vars, "query_cache_strip_comments",
-+                                                       &opt_query_cache_strip_comments);
- static sys_var_const_str_ptr    sys_repl_report_password(&vars, "report_password", &report_password);
- static uchar *slave_get_report_port(THD *thd)
-@@ -1259,10 +1266,9 @@
- {}
- #endif /* HAVE_REPLICATION */
--
-+#ifdef HAVE_QUERY_CACHE
- static void fix_query_cache_size(THD *thd, enum_var_type type)
- {
--#ifdef HAVE_QUERY_CACHE
-   ulong new_cache_size= query_cache.resize(query_cache_size);
-   /*
-@@ -1276,11 +1282,35 @@
-                       query_cache_size, new_cache_size);
-   
-   query_cache_size= new_cache_size;
--#endif
- }
--#ifdef HAVE_QUERY_CACHE
-+/**
-+  Trigger before query_cache_type variable is updated.
-+  @param thd Thread handler
-+  @param var Pointer to the new variable status
-+
-+  @return Status code
-+   @retval 1 Failure
-+   @retval 0 Success
-+*/
-+
-+static int check_query_cache_type(THD *thd, set_var *var)
-+{
-+  /*
-+    Don't allow changes of the query_cache_type if the query cache
-+    is disabled.
-+  */
-+  if (query_cache.is_disabled())
-+  {
-+    my_error(ER_QUERY_CACHE_DISABLED,MYF(0));
-+    return 1;
-+  }
-+
-+  return 0;
-+}
-+
-+
- static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type)
- {
-   query_cache_min_res_unit= 
-@@ -3638,6 +3668,16 @@
-   Functions to handle SET mysql_internal_variable=const_expr
- *****************************************************************************/
-+/**
-+  Verify that the supplied value is correct.
-+
-+  @param thd Thread handler
-+
-+  @return status code
-+    @retval -1 Failure
-+    @retval 0 Success
-+*/
-+
- int set_var::check(THD *thd)
- {
-   if (var->is_readonly())
---- a/sql/sql_cache.cc
-+++ b/sql/sql_cache.cc
-@@ -288,6 +288,7 @@
-          if (and only if) this query has a registered result set writer
-          (thd->net.query_cache_query).
-  4. Query_cache::invalidate
-+    Query_cache::invalidate_locked_for_write
-        - Called from various places to invalidate query cache based on data-
-          base, table and myisam file name. During an on going invalidation
-          the query cache is temporarily disabled.
-@@ -335,6 +336,181 @@
- #include <hash.h>
- #include "../storage/myisammrg/ha_myisammrg.h"
- #include "../storage/myisammrg/myrg_def.h"
-+#include "query_strip_comments.h"
-+
-+QueryStripComments::QueryStripComments()
-+{
-+  buffer = 0;
-+  length = 0;
-+  buffer_length = 0;
-+}
-+QueryStripComments::~QueryStripComments()
-+{
-+  cleanup();
-+}
-+
-+inline bool query_strip_comments_is_white_space(char c)
-+{
-+  return ((' ' == c) || ('\t' == c) || ('\r' == c) || ('\n' ==c ));
-+}
-+void QueryStripComments::set(const char* query, uint query_length, uint additional_length)
-+{
-+  uint new_buffer_length = query_length + additional_length;
-+  if(new_buffer_length > buffer_length)
-+  {
-+    cleanup();
-+    buffer = (char*)my_malloc(new_buffer_length,MYF(0));
-+    memset(buffer,0,new_buffer_length);
-+  }
-+  uint query_position = 0;
-+  uint position = 0;
-+  // Skip whitespaces from begin
-+  while((query_position < query_length) && query_strip_comments_is_white_space(query[query_position]))
-+  {
-+    ++query_position;
-+  }
-+  long int last_space = -1;
-+  while(query_position < query_length)
-+  {
-+    char current = query[query_position];
-+    bool insert_space = false; // insert space to buffer, (IMPORTANT) don't update query_position
-+    switch(current)
-+    {
-+    case '\'':
-+    case '"':
-+      {
-+        buffer[position++] = query[query_position++]; // copy current symbol
-+        while(query_position < query_length)
-+        {
-+          if(current == query[query_position]) // found pair quote
-+          {
-+            break;
-+          }
-+          buffer[position++] = query[query_position++]; // copy current symbol
-+        }
-+        break;
-+      }
-+    case '/':
-+      {
-+        if(((query_position + 2) < query_length) && ('*' == query[query_position+1]) && ('!' != query[query_position+2]))
-+        {
-+          query_position += 2; // skip "/*"
-+          do
-+          {
-+            if('*' == query[query_position] && '/' == query[query_position+1]) // check for "*/"
-+            {
-+              query_position += 2; // skip "*/"
-+              insert_space = true;
-+              break;
-+            }
-+            else
-+            {
-+              ++query_position;
-+            }
-+          }
-+          while(query_position < query_length);
-+          if(!insert_space)
-+          {
-+            continue;
-+          }
-+        }
-+        break;
-+      }
-+    case '-':
-+      {
-+        if(query[query_position+1] == '-')
-+        {
-+          ++query_position; // skip "-", and go to search of "\n"
-+        }
-+        else
-+        {
-+          break;
-+        }
-+      }
-+    case '#':
-+      {
-+        do
-+        {
-+          ++query_position; // skip current symbol (# or -)
-+          if('\n' == query[query_position])  // check for '\n'
-+          {
-+            ++query_position; // skip '\n'
-+            insert_space = true;
-+            break;
-+          }
-+        }
-+        while(query_position < query_length);
-+        if(insert_space)
-+        {
-+          break;
-+        }
-+        else
-+        {
-+          continue;
-+        }
-+      }
-+    default:
-+      if(query_strip_comments_is_white_space(current))
-+      {
-+        insert_space = true;
-+        ++query_position;
-+      }
-+      break; // make gcc happy
-+    }
-+    if(insert_space)
-+    {
-+      if((uint) (last_space + 1) != position)
-+      {
-+        last_space = position;
-+        buffer[position++] = ' ';
-+      }
-+    }
-+    else
-+    {
-+      buffer[position++] = query[query_position++];
-+    }
-+  }
-+  while((0 < position) && query_strip_comments_is_white_space(buffer[position - 1]))
-+  {
-+    --position;
-+  }
-+  buffer[position] = 0;
-+  length = position;
-+}
-+void QueryStripComments::cleanup()
-+{
-+  if(buffer)
-+  {
-+    my_free(buffer,MYF(0));
-+  }
-+  buffer        = 0;
-+  length        = 0;
-+  buffer_length = 0;
-+}
-+QueryStripComments_Backup::QueryStripComments_Backup(THD* a_thd,QueryStripComments* qsc)
-+{
-+  if(opt_query_cache_strip_comments)
-+  {
-+    thd = a_thd;
-+    query = thd->query();
-+    length = thd->query_length();
-+    qsc->set(query,length,thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE);
-+    thd->set_query(qsc->query(),qsc->query_length());
-+  }
-+  else
-+  {
-+    thd = 0;
-+    query = 0;
-+    length = 0;
-+  }
-+}
-+QueryStripComments_Backup::~QueryStripComments_Backup()
-+{
-+  if(thd)
-+  {
-+    thd->set_query(query,length);
-+  }
-+}
- #ifdef EMBEDDED_LIBRARY
- #include "emb_qcache.h"
-@@ -437,7 +613,13 @@
-   bool interrupt= FALSE;
-   DBUG_ENTER("Query_cache::try_lock");
-+  THD *thd = current_thd;
-+  const char* old_proc_info= thd->proc_info;
-+  thd_proc_info(thd,"Waiting on query cache mutex");
-   pthread_mutex_lock(&structure_guard_mutex);
-+  DBUG_EXECUTE_IF("status_wait_query_cache_mutex_sleep", {
-+      sleep(5);
-+    });
-   while (1)
-   {
-     if (m_cache_lock_status == Query_cache::UNLOCKED)
-@@ -485,6 +667,7 @@
-     }
-   }
-   pthread_mutex_unlock(&structure_guard_mutex);
-+  thd->proc_info = old_proc_info;
-   DBUG_RETURN(interrupt);
- }
-@@ -865,11 +1048,14 @@
-   DBUG_EXECUTE_IF("wait_in_query_cache_insert",
-                   debug_wait_for_kill("wait_in_query_cache_insert"); );
-+  if(query_cache.is_disabled())
-+    DBUG_VOID_RETURN;
-+
-   if (query_cache.try_lock())
-     DBUG_VOID_RETURN;
-   Query_cache_block *query_block= (Query_cache_block*)net->query_cache_query;
--  if (!query_block)
-+  if (NULL == query_block)
-   {
-     /*
-       We lost the writer and the currently processed query has been
-@@ -923,6 +1109,9 @@
-   if (net->query_cache_query == 0)
-     DBUG_VOID_RETURN;
-+  if(query_cache.is_disabled())
-+    DBUG_VOID_RETURN;
-+
-   if (query_cache.try_lock())
-     DBUG_VOID_RETURN;
-@@ -1056,6 +1245,7 @@
-    query_cache_limit(query_cache_limit_arg),
-    queries_in_cache(0), hits(0), inserts(0), refused(0),
-    total_blocks(0), lowmem_prunes(0),
-+   m_query_cache_is_disabled(FALSE),
-    min_allocation_unit(ALIGN_SIZE(min_allocation_unit_arg)),
-    min_result_data_size(ALIGN_SIZE(min_result_data_size_arg)),
-    def_query_hash_size(ALIGN_SIZE(def_query_hash_size_arg)),
-@@ -1237,6 +1427,8 @@
-       unlock();
-       DBUG_VOID_RETURN;
-     }
-+    QueryStripComments *query_strip_comments = &(thd->query_strip_comments);
-+    QueryStripComments_Backup backup(thd,query_strip_comments);
-     /* Key is query + database + flag */
-     if (thd->db_length)
-@@ -1407,6 +1599,9 @@
-   Query_cache_block_table *block_table, *block_table_end;
-   ulong tot_length;
-   Query_cache_query_flags flags;
-+  QueryStripComments *query_strip_comments = &(thd->query_strip_comments);
-+  char *sql_backup          = sql;
-+  uint  query_length_backup = query_length;
-   DBUG_ENTER("Query_cache::send_result_to_client");
-   /*
-@@ -1416,8 +1611,8 @@
-     See also a note on double-check locking usage above.
-   */
--  if (thd->locked_tables || thd->variables.query_cache_type == 0 ||
--      query_cache_size == 0)
-+  if (is_disabled() || thd->locked_tables ||
-+      thd->variables.query_cache_type == 0 || query_cache_size == 0)
-     goto err;
-   if (!thd->lex->safe_to_cache_query)
-@@ -1428,6 +1623,87 @@
-   {
-     uint i= 0;
-+    if(opt_query_cache_strip_comments)
-+    {
-+      /* Skip all comments and non-letter symbols */
-+      uint& query_position = i;
-+      char* query = sql;
-+      while(query_position < query_length)
-+      {
-+        bool check = false;
-+        char current = query[query_position];
-+        switch(current)
-+        {
-+        case '/':
-+          if(((query_position + 2) < query_length) && ('*' == query[query_position+1]) && ('!' != query[query_position+2]))
-+          {
-+            query_position += 2; // skip "/*"
-+            do
-+            {
-+              if('*' == query[query_position] && '/' == query[query_position+1]) // check for "*/" (without space)
-+              {
-+                query_position += 2; // skip "*/" (without space)
-+                break;
-+              }
-+              else
-+              {
-+                ++query_position;
-+              }
-+            }
-+            while(query_position < query_length);
-+            continue; // analyze current symbol
-+          }
-+          break;
-+        case '-':
-+          if(query[query_position+1] == '-')
-+          {
-+            ++query_position; // skip "-"
-+          }
-+          else
-+          {
-+            break;
-+          }
-+        case '#':
-+          do
-+          {
-+            ++query_position; // skip current symbol
-+            if('\n' == query[query_position])  // check for '\n'
-+            {
-+              ++query_position; // skip '\n'
-+              break;
-+            }
-+          }
-+          while(query_position < query_length);
-+          continue; // analyze current symbol
-+        case '\r':
-+        case '\n':
-+        case '\t':
-+        case ' ':
-+        case '(':
-+        case ')':
-+          break;
-+        default:
-+          check = true;
-+          break; // make gcc happy
-+        } // switch(current)
-+        if(check)
-+        {
-+          if(query_position + 2 < query_length)
-+          {
-+            // cacheable
-+            break;
-+          }
-+          else
-+          {
-+            DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
-+            goto err;
-+          }
-+        } // if(check)
-+        ++query_position;
-+      } // while(query_position < query_length)
-+    }
-+    else // if(opt_query_cache_strip_comments)
-+    {
-     /*
-       Skip '(' characters in queries like following:
-       (select a from t1) union (select a from t1);
-@@ -1435,6 +1711,7 @@
-     while (sql[i]=='(')
-       i++;
-+    } // if(opt_query_cache_strip_comments)    
-     /*
-       Test if the query is a SELECT
-       (pre-space is removed in dispatch_command).
-@@ -1451,7 +1728,6 @@
-       DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
-       goto err;
-     }
--    
-     if (query_length > 20 && has_no_cache_directive(&sql[i+6]))
-     {
-       /*
-@@ -1483,6 +1759,12 @@
-   DBUG_ASSERT(thd->net.query_cache_query == 0);
-   Query_cache_block *query_block;
-+  if(opt_query_cache_strip_comments)
-+  {
-+    query_strip_comments->set(sql, query_length, thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE);
-+    sql          = query_strip_comments->query();
-+    query_length = query_strip_comments->query_length();
-+  }
-   tot_length= query_length + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE;
-   if (thd->db_length)
-@@ -1549,6 +1831,8 @@
-        (uchar*) &flags, QUERY_CACHE_FLAGS_SIZE);
-   query_block = (Query_cache_block *)  hash_search(&queries, (uchar*) sql,
-                                                  tot_length);
-+  sql          = sql_backup;
-+  query_length = query_length_backup;
-   /* Quick abort on unlocked data */
-   if (query_block == 0 ||
-       query_block->query()->result() == 0 ||
-@@ -1729,6 +2013,8 @@
-                            my_bool using_transactions)
- {
-   DBUG_ENTER("Query_cache::invalidate (table list)");
-+  if (is_disabled())
-+    DBUG_VOID_RETURN;
-   using_transactions= using_transactions &&
-     (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
-@@ -1759,6 +2045,9 @@
- void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
- {
-   DBUG_ENTER("Query_cache::invalidate (changed table list)");
-+  if (is_disabled())
-+    DBUG_VOID_RETURN;
-+
-   THD *thd= current_thd;
-   for (; tables_used; tables_used= tables_used->next)
-   {
-@@ -1784,8 +2073,11 @@
- */
- void Query_cache::invalidate_locked_for_write(TABLE_LIST *tables_used)
- {
--  THD *thd= current_thd;
-   DBUG_ENTER("Query_cache::invalidate_locked_for_write");
-+  if (is_disabled())
-+    DBUG_VOID_RETURN;
-+
-+  THD *thd= current_thd;
-   for (; tables_used; tables_used= tables_used->next_local)
-   {
-     thd_proc_info(thd, "invalidating query cache entries (table)");
-@@ -1806,6 +2098,8 @@
-                            my_bool using_transactions)
- {
-   DBUG_ENTER("Query_cache::invalidate (table)");
-+  if (is_disabled())
-+    DBUG_VOID_RETURN;
-   
-   using_transactions= using_transactions &&
-     (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
-@@ -1823,6 +2117,8 @@
-                            my_bool using_transactions)
- {
-   DBUG_ENTER("Query_cache::invalidate (key)");
-+  if (is_disabled())
-+   DBUG_VOID_RETURN;
-   using_transactions= using_transactions &&
-     (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
-@@ -1841,9 +2137,11 @@
- void Query_cache::invalidate(char *db)
- {
--  bool restart= FALSE;
--  DBUG_ENTER("Query_cache::invalidate (db)");
-+  DBUG_ENTER("Query_cache::invalidate (db)");
-+  if (is_disabled())
-+    DBUG_VOID_RETURN;
-+  bool restart= FALSE;
-   /*
-     Lock the query cache and queue all invalidation attempts to avoid
-     the risk of a race between invalidation, cache inserts and flushes.
-@@ -1928,6 +2226,9 @@
- void Query_cache::flush()
- {
-   DBUG_ENTER("Query_cache::flush");
-+  if (is_disabled())
-+    DBUG_VOID_RETURN;
-+
-   DBUG_EXECUTE_IF("wait_in_query_cache_flush1",
-                   debug_wait_for_kill("wait_in_query_cache_flush1"););
-@@ -1959,6 +2260,9 @@
- {
-   DBUG_ENTER("Query_cache::pack");
-+  if (is_disabled())
-+    DBUG_VOID_RETURN;
-+
-   /*
-     If the entire qc is being invalidated we can bail out early
-     instead of waiting for the lock.
-@@ -2016,6 +2320,15 @@
-   pthread_cond_init(&COND_cache_status_changed, NULL);
-   m_cache_lock_status= Query_cache::UNLOCKED;
-   initialized = 1;
-+  /*
-+    If we explicitly turn off query cache from the command line query cache will
-+    be disabled for the reminder of the server life time. This is because we
-+    want to avoid locking the QC specific mutex if query cache isn't going to
-+    be used.
-+  */
-+  if (global_system_variables.query_cache_type == 0)
-+    query_cache.disable_query_cache();
-+
-   DBUG_VOID_RETURN;
- }
-@@ -4719,3 +5032,4 @@
- #endif /* DBUG_OFF */
- #endif /*HAVE_QUERY_CACHE*/
-+
---- a/sql/sql_class.h
-+++ b/sql/sql_class.h
-@@ -24,7 +24,9 @@
- #include "log.h"
- #include "rpl_tblmap.h"
--
-+#ifdef HAVE_QUERY_CACHE
-+#include "query_strip_comments.h"
-+#endif // HAVE_QUERY_CACHE
- /**
-   An interface that is used to take an action when
-   the locking module notices that a table version has changed
-@@ -672,6 +674,9 @@
-   */
-   LEX_STRING query_string;
-   Server_side_cursor *cursor;
-+#ifdef HAVE_QUERY_CACHE
-+  QueryStripComments query_strip_comments; // see sql_cache.cc
-+#endif //HAVE_QUERY_CACHE
-   inline char *query() { return query_string.str; }
-   inline uint32 query_length() { return query_string.length; }
---- /dev/null
-+++ b/mysql-test/r/query_cache_disabled.result
-@@ -0,0 +1,14 @@
-+SHOW GLOBAL VARIABLES LIKE 'query_cache_type';
-+Variable_name Value
-+query_cache_type      OFF
-+SET GLOBAL query_cache_type=ON;
-+ERROR HY000: Query cache is disabled; restart the server with query_cache_type=1 to enable it
-+SET GLOBAL query_cache_type=DEMAND;
-+ERROR HY000: Query cache is disabled; restart the server with query_cache_type=1 to enable it
-+SET GLOBAL query_cache_type=OFF;
-+ERROR HY000: Query cache is disabled; restart the server with query_cache_type=1 to enable it
-+SET GLOBAL query_cache_size=1024*1024;
-+SHOW GLOBAL VARIABLES LIKE 'query_cache_size';
-+Variable_name Value
-+query_cache_size      1048576
-+SET GLOBAL query_cache_size=0;
---- /dev/null
-+++ b/mysql-test/t/query_cache_disabled-master.opt
-@@ -0,0 +1 @@
-+--query_cache_type=0
---- /dev/null
-+++ b/mysql-test/t/query_cache_disabled.test
-@@ -0,0 +1,15 @@
-+-- source include/have_query_cache.inc
-+#
-+# Bug#38551 query cache can still consume [very little] cpu time even when it is off.
-+#
-+SHOW GLOBAL VARIABLES LIKE 'query_cache_type';
-+--error ER_QUERY_CACHE_DISABLED
-+SET GLOBAL query_cache_type=ON;
-+--error ER_QUERY_CACHE_DISABLED
-+SET GLOBAL query_cache_type=DEMAND;
-+--error ER_QUERY_CACHE_DISABLED
-+SET GLOBAL query_cache_type=OFF;
-+SET GLOBAL query_cache_size=1024*1024;
-+SHOW GLOBAL VARIABLES LIKE 'query_cache_size';
-+SET GLOBAL query_cache_size=0;
-+
---- a/sql/set_var.h
-+++ b/sql/set_var.h
-@@ -521,10 +521,16 @@
-   { chain_sys_var(chain); }
-   bool check(THD *thd, set_var *var)
-   {
--    int ret= 0;
--    if (check_func)
--      ret= (*check_func)(thd, var);
--    return ret ? ret : check_enum(thd, var, enum_names);
-+    /*
-+      check_enum fails if the character representation supplied was wrong
-+      or that the integer value was wrong or missing.
-+    */
-+    if (check_enum(thd, var, enum_names))
-+      return TRUE;
-+    else if ((check_func && (*check_func)(thd, var)))
-+      return TRUE;
-+    else
-+      return FALSE;
-   }
-   bool update(THD *thd, set_var *var);
-   void set_default(THD *thd, enum_var_type type);
---- a/sql/share/errmsg.txt
-+++ b/sql/share/errmsg.txt
-@@ -6213,3 +6213,8 @@
- ER_DEBUG_SYNC_HIT_LIMIT
-   eng "debug sync point hit limit reached"
-   ger "Debug Sync Point Hit Limit erreicht"
-+PADD_QUERY_CACHE_DISABLED 1651
-+  eng "ER_QUERY_CACHE_DISABLED padding to 1651 error"
-+ER_QUERY_CACHE_DISABLED
-+  eng "Query cache is disabled; restart the server with query_cache_type=1 to enable it"
-+
---- a/sql/sql_cache.h
-+++ b/sql/sql_cache.h
-@@ -282,8 +282,11 @@
-   enum Cache_lock_status { UNLOCKED, LOCKED_NO_WAIT, LOCKED };
-   Cache_lock_status m_cache_lock_status;
-+  bool m_query_cache_is_disabled;
-+
-   void free_query_internal(Query_cache_block *point);
-   void invalidate_table_internal(THD *thd, uchar *key, uint32 key_length);
-+  void disable_query_cache(void) { m_query_cache_is_disabled= TRUE; }
- protected:
-   /*
-@@ -426,6 +429,8 @@
-             uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE,
-             uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE);
-+  bool is_disabled(void) { return m_query_cache_is_disabled; }
-+
-   /* initialize cache (mutex) */
-   void init();
-   /* resize query cache (return real query size, 0 if disabled) */
---- /dev/null
-+++ b/mysql-test/include/percona_query_cache_with_comments.inc
-@@ -0,0 +1,95 @@
-+--source include/percona_query_cache_with_comments_clear.inc
-+let $query=/* with comment first */select * from t1;
-+eval $query;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=# with comment first
-+select * from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=-- with comment first
-+select * from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=/* with comment first and "quote" */select * from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=# with comment first and "quote"
-+select * from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=-- with comment first and "quote" 
-+select * from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=
-+    /* with comment and whitespaces first */select * from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query= 
-+    # with comment and whitespaces first
-+select * from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=
-+    -- with comment and whitespaces first
-+select * from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $internal=* internal comment *;
-+
-+let $query=select * /$internal/ from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+let $query=select */$internal/ from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+let $query=select */$internal/from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $internal=* internal comment with "quote" *;
-+
-+let $query=select * /$internal/ from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+let $query=select */$internal/ from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+let $query=select */$internal/from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1
-+;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1 ;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1   ;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1
-+/* comment in the end */;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1
-+/* *\/ */;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1
-+/* comment in the end */
-+;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1 #comment in the end;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1 #comment in the end
-+;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1 -- comment in the end;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select * from t1 -- comment in the end
-+;
-+--source include/percona_query_cache_with_comments_eval.inc
-+
-+let $query=select ' \'  ' from t1;
-+--source include/percona_query_cache_with_comments_eval.inc
---- /dev/null
-+++ b/mysql-test/include/percona_query_cache_with_comments_begin.inc
-@@ -0,0 +1,12 @@
-+-- source include/have_query_cache.inc
-+
-+set GLOBAL query_cache_size=1355776;
-+
-+--disable_warnings
-+drop table if exists t1;
-+--enable_warnings
-+
-+create table t1 (a int not null);
-+insert into t1 values (1),(2),(3);
-+
-+--source include/percona_query_cache_with_comments_clear.inc
---- /dev/null
-+++ b/mysql-test/include/percona_query_cache_with_comments_clear.inc
-@@ -0,0 +1,5 @@
-+# Reset query cache variables.
-+flush query cache; # This crashed in some versions
-+flush query cache; # This crashed in some versions
-+reset query cache;
-+flush status;
---- /dev/null
-+++ b/mysql-test/include/percona_query_cache_with_comments_end.inc
-@@ -0,0 +1,3 @@
-+DROP TABLE t1;
-+SET GLOBAL query_cache_size=default;
-+set global query_cache_strip_comments=OFF;
---- /dev/null
-+++ b/mysql-test/include/percona_query_cache_with_comments_eval.inc
-@@ -0,0 +1,7 @@
-+echo -----------------------------------------------------;
-+echo $query;
-+echo -----------------------------------------------------;
-+--source include/percona_query_cache_with_comments_show.inc
-+eval $query;
-+eval $query;
-+--source include/percona_query_cache_with_comments_show.inc
---- /dev/null
-+++ b/mysql-test/include/percona_query_cache_with_comments_show.inc
-@@ -0,0 +1,8 @@
-+let $show=show status like "Qcache_queries_in_cache";
-+eval $show;
-+let $show=show status like "Qcache_inserts";
-+eval $show;
-+let $show=show status like "Qcache_hits";
-+eval $show;
-+
-+
---- /dev/null
-+++ b/mysql-test/r/percona_query_cache_with_comments.result
-@@ -0,0 +1,866 @@
-+set global query_cache_strip_comments=ON;
-+set GLOBAL query_cache_size=1355776;
-+drop table if exists t1;
-+create table t1 (a int not null);
-+insert into t1 values (1),(2),(3);
-+flush query cache;
-+flush query cache;
-+reset query cache;
-+flush status;
-+flush query cache;
-+flush query cache;
-+reset query cache;
-+flush status;
-+/* with comment first */select * from t1;
-+a
-+1
-+2
-+3
-+-----------------------------------------------------
-+/* with comment first */select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   0
-+/* with comment first */select * from t1;
-+a
-+1
-+2
-+3
-+/* with comment first */select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   2
-+-----------------------------------------------------
-+# with comment first
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   2
-+# with comment first
-+select * from t1;
-+a
-+1
-+2
-+3
-+# with comment first
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   4
-+-----------------------------------------------------
-+-- with comment first
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   4
-+-- with comment first
-+select * from t1;
-+a
-+1
-+2
-+3
-+-- with comment first
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   6
-+-----------------------------------------------------
-+/* with comment first and "quote" */select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   6
-+/* with comment first and "quote" */select * from t1;
-+a
-+1
-+2
-+3
-+/* with comment first and "quote" */select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   8
-+-----------------------------------------------------
-+# with comment first and "quote"
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   8
-+# with comment first and "quote"
-+select * from t1;
-+a
-+1
-+2
-+3
-+# with comment first and "quote"
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   10
-+-----------------------------------------------------
-+-- with comment first and "quote" 
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   10
-+-- with comment first and "quote" 
-+select * from t1;
-+a
-+1
-+2
-+3
-+-- with comment first and "quote" 
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   12
-+-----------------------------------------------------
-+/* with comment and whitespaces first */select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   12
-+/* with comment and whitespaces first */select * from t1;
-+a
-+1
-+2
-+3
-+/* with comment and whitespaces first */select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   14
-+-----------------------------------------------------
-+# with comment and whitespaces first
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   14
-+# with comment and whitespaces first
-+select * from t1;
-+a
-+1
-+2
-+3
-+# with comment and whitespaces first
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   16
-+-----------------------------------------------------
-+-- with comment and whitespaces first
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   16
-+-- with comment and whitespaces first
-+select * from t1;
-+a
-+1
-+2
-+3
-+-- with comment and whitespaces first
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   18
-+-----------------------------------------------------
-+select * /* internal comment */ from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   18
-+select * /* internal comment */ from t1;
-+a
-+1
-+2
-+3
-+select * /* internal comment */ from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   20
-+-----------------------------------------------------
-+select */* internal comment */ from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   20
-+select */* internal comment */ from t1;
-+a
-+1
-+2
-+3
-+select */* internal comment */ from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   22
-+-----------------------------------------------------
-+select */* internal comment */from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   22
-+select */* internal comment */from t1;
-+a
-+1
-+2
-+3
-+select */* internal comment */from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   24
-+-----------------------------------------------------
-+select * /* internal comment with "quote" */ from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   24
-+select * /* internal comment with "quote" */ from t1;
-+a
-+1
-+2
-+3
-+select * /* internal comment with "quote" */ from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   26
-+-----------------------------------------------------
-+select */* internal comment with "quote" */ from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   26
-+select */* internal comment with "quote" */ from t1;
-+a
-+1
-+2
-+3
-+select */* internal comment with "quote" */ from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   28
-+-----------------------------------------------------
-+select */* internal comment with "quote" */from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   28
-+select */* internal comment with "quote" */from t1;
-+a
-+1
-+2
-+3
-+select */* internal comment with "quote" */from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   30
-+-----------------------------------------------------
-+select * from t1
-+
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   30
-+select * from t1
-+;
-+a
-+1
-+2
-+3
-+select * from t1
-+;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   32
-+-----------------------------------------------------
-+select * from t1 
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   32
-+select * from t1 ;
-+a
-+1
-+2
-+3
-+select * from t1 ;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   34
-+-----------------------------------------------------
-+select * from t1      
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   34
-+select * from t1      ;
-+a
-+1
-+2
-+3
-+select * from t1      ;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   36
-+-----------------------------------------------------
-+select * from t1
-+/* comment in the end */
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   36
-+select * from t1
-+/* comment in the end */;
-+a
-+1
-+2
-+3
-+select * from t1
-+/* comment in the end */;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   38
-+-----------------------------------------------------
-+select * from t1
-+/* *\/ */
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   38
-+select * from t1
-+/* *\/ */;
-+a
-+1
-+2
-+3
-+select * from t1
-+/* *\/ */;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   40
-+-----------------------------------------------------
-+select * from t1
-+/* comment in the end */
-+
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   40
-+select * from t1
-+/* comment in the end */
-+;
-+a
-+1
-+2
-+3
-+select * from t1
-+/* comment in the end */
-+;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   42
-+-----------------------------------------------------
-+select * from t1 #comment in the end
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   42
-+select * from t1 #comment in the end;
-+a
-+1
-+2
-+3
-+select * from t1 #comment in the end;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   44
-+-----------------------------------------------------
-+select * from t1 #comment in the end
-+
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   44
-+select * from t1 #comment in the end
-+;
-+a
-+1
-+2
-+3
-+select * from t1 #comment in the end
-+;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   46
-+-----------------------------------------------------
-+select * from t1 -- comment in the end
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   46
-+select * from t1 -- comment in the end;
-+a
-+1
-+2
-+3
-+select * from t1 -- comment in the end;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   48
-+-----------------------------------------------------
-+select * from t1 -- comment in the end
-+
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   48
-+select * from t1 -- comment in the end
-+;
-+a
-+1
-+2
-+3
-+select * from t1 -- comment in the end
-+;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   50
-+-----------------------------------------------------
-+select ' \'  ' from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   50
-+select ' \'  ' from t1;
-+'  
-+ '  
-+ '  
-+ '  
-+select ' \'  ' from t1;
-+'  
-+ '  
-+ '  
-+ '  
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       2
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        2
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   51
-+DROP TABLE t1;
-+SET GLOBAL query_cache_size=default;
-+set global query_cache_strip_comments=OFF;
---- /dev/null
-+++ b/mysql-test/r/percona_query_cache_with_comments_crash.result
-@@ -0,0 +1,21 @@
-+set GLOBAL query_cache_size=1355776;
-+drop table if exists t1;
-+create table t1 (a int not null);
-+insert into t1 values (1),(2),(3);
-+flush query cache;
-+flush query cache;
-+reset query cache;
-+flush status;
-+( select * from t1 );
-+a
-+1
-+2
-+3
-+/*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := REPLACE(REPLACE(@@SQL_MODE, 'ANSI_QUOTES', ''), ',,', ','), @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */;
-+/* only comment */;
-+# only comment
-+;
-+-- only comment
-+;
-+DROP TABLE t1;
-+SET GLOBAL query_cache_size= default;
---- /dev/null
-+++ b/mysql-test/r/percona_query_cache_with_comments_disable.result
-@@ -0,0 +1,865 @@
-+set GLOBAL query_cache_size=1355776;
-+drop table if exists t1;
-+create table t1 (a int not null);
-+insert into t1 values (1),(2),(3);
-+flush query cache;
-+flush query cache;
-+reset query cache;
-+flush status;
-+flush query cache;
-+flush query cache;
-+reset query cache;
-+flush status;
-+/* with comment first */select * from t1;
-+a
-+1
-+2
-+3
-+-----------------------------------------------------
-+/* with comment first */select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   0
-+/* with comment first */select * from t1;
-+a
-+1
-+2
-+3
-+/* with comment first */select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   2
-+-----------------------------------------------------
-+# with comment first
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   2
-+# with comment first
-+select * from t1;
-+a
-+1
-+2
-+3
-+# with comment first
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       2
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        2
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   2
-+-----------------------------------------------------
-+-- with comment first
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       2
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        2
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   2
-+-- with comment first
-+select * from t1;
-+a
-+1
-+2
-+3
-+-- with comment first
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       3
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        3
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   2
-+-----------------------------------------------------
-+/* with comment first and "quote" */select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       3
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        3
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   2
-+/* with comment first and "quote" */select * from t1;
-+a
-+1
-+2
-+3
-+/* with comment first and "quote" */select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       4
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        4
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   3
-+-----------------------------------------------------
-+# with comment first and "quote"
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       4
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        4
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   3
-+# with comment first and "quote"
-+select * from t1;
-+a
-+1
-+2
-+3
-+# with comment first and "quote"
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       5
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        5
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   3
-+-----------------------------------------------------
-+-- with comment first and "quote" 
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       5
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        5
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   3
-+-- with comment first and "quote" 
-+select * from t1;
-+a
-+1
-+2
-+3
-+-- with comment first and "quote" 
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       6
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        6
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   3
-+-----------------------------------------------------
-+/* with comment and whitespaces first */select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       6
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        6
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   3
-+/* with comment and whitespaces first */select * from t1;
-+a
-+1
-+2
-+3
-+/* with comment and whitespaces first */select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       7
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        7
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   4
-+-----------------------------------------------------
-+# with comment and whitespaces first
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       7
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        7
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   4
-+# with comment and whitespaces first
-+select * from t1;
-+a
-+1
-+2
-+3
-+# with comment and whitespaces first
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       8
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        8
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   4
-+-----------------------------------------------------
-+-- with comment and whitespaces first
-+select * from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       8
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        8
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   4
-+-- with comment and whitespaces first
-+select * from t1;
-+a
-+1
-+2
-+3
-+-- with comment and whitespaces first
-+select * from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       9
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        9
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   4
-+-----------------------------------------------------
-+select * /* internal comment */ from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       9
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        9
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   4
-+select * /* internal comment */ from t1;
-+a
-+1
-+2
-+3
-+select * /* internal comment */ from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       10
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        10
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   5
-+-----------------------------------------------------
-+select */* internal comment */ from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       10
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        10
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   5
-+select */* internal comment */ from t1;
-+a
-+1
-+2
-+3
-+select */* internal comment */ from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       11
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        11
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   6
-+-----------------------------------------------------
-+select */* internal comment */from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       11
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        11
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   6
-+select */* internal comment */from t1;
-+a
-+1
-+2
-+3
-+select */* internal comment */from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       12
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        12
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   7
-+-----------------------------------------------------
-+select * /* internal comment with "quote" */ from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       12
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        12
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   7
-+select * /* internal comment with "quote" */ from t1;
-+a
-+1
-+2
-+3
-+select * /* internal comment with "quote" */ from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       13
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        13
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   8
-+-----------------------------------------------------
-+select */* internal comment with "quote" */ from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       13
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        13
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   8
-+select */* internal comment with "quote" */ from t1;
-+a
-+1
-+2
-+3
-+select */* internal comment with "quote" */ from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       14
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        14
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   9
-+-----------------------------------------------------
-+select */* internal comment with "quote" */from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       14
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        14
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   9
-+select */* internal comment with "quote" */from t1;
-+a
-+1
-+2
-+3
-+select */* internal comment with "quote" */from t1;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       15
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        15
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   10
-+-----------------------------------------------------
-+select * from t1
-+
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       15
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        15
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   10
-+select * from t1
-+;
-+a
-+1
-+2
-+3
-+select * from t1
-+;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       16
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        16
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   11
-+-----------------------------------------------------
-+select * from t1 
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       16
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        16
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   11
-+select * from t1 ;
-+a
-+1
-+2
-+3
-+select * from t1 ;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       16
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        16
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   13
-+-----------------------------------------------------
-+select * from t1      
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       16
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        16
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   13
-+select * from t1      ;
-+a
-+1
-+2
-+3
-+select * from t1      ;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       16
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        16
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   15
-+-----------------------------------------------------
-+select * from t1
-+/* comment in the end */
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       16
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        16
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   15
-+select * from t1
-+/* comment in the end */;
-+a
-+1
-+2
-+3
-+select * from t1
-+/* comment in the end */;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       17
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        17
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   16
-+-----------------------------------------------------
-+select * from t1
-+/* *\/ */
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       17
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        17
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   16
-+select * from t1
-+/* *\/ */;
-+a
-+1
-+2
-+3
-+select * from t1
-+/* *\/ */;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       18
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        18
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   17
-+-----------------------------------------------------
-+select * from t1
-+/* comment in the end */
-+
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       18
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        18
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   17
-+select * from t1
-+/* comment in the end */
-+;
-+a
-+1
-+2
-+3
-+select * from t1
-+/* comment in the end */
-+;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       18
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        18
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   19
-+-----------------------------------------------------
-+select * from t1 #comment in the end
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       18
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        18
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   19
-+select * from t1 #comment in the end;
-+a
-+1
-+2
-+3
-+select * from t1 #comment in the end;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       19
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        19
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   20
-+-----------------------------------------------------
-+select * from t1 #comment in the end
-+
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       19
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        19
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   20
-+select * from t1 #comment in the end
-+;
-+a
-+1
-+2
-+3
-+select * from t1 #comment in the end
-+;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       19
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        19
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   22
-+-----------------------------------------------------
-+select * from t1 -- comment in the end
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       19
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        19
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   22
-+select * from t1 -- comment in the end;
-+a
-+1
-+2
-+3
-+select * from t1 -- comment in the end;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       20
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        20
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   23
-+-----------------------------------------------------
-+select * from t1 -- comment in the end
-+
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       20
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        20
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   23
-+select * from t1 -- comment in the end
-+;
-+a
-+1
-+2
-+3
-+select * from t1 -- comment in the end
-+;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       20
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        20
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   25
-+-----------------------------------------------------
-+select ' \'  ' from t1
-+-----------------------------------------------------
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       20
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        20
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   25
-+select ' \'  ' from t1;
-+'  
-+ '  
-+ '  
-+ '  
-+select ' \'  ' from t1;
-+'  
-+ '  
-+ '  
-+ '  
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       21
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        21
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   26
-+DROP TABLE t1;
-+SET GLOBAL query_cache_size=default;
-+set global query_cache_strip_comments=OFF;
---- /dev/null
-+++ b/mysql-test/r/percona_query_cache_with_comments_prepared_statements.result
-@@ -0,0 +1,396 @@
-+set GLOBAL query_cache_size=1355776;
-+flush query cache;
-+flush query cache;
-+reset query cache;
-+flush status;
-+drop table if exists t1;
-+create table t1 (a int not null);
-+insert into t1 values (1),(2),(3);
-+set global query_cache_strip_comments=ON;
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       0
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        0
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   0
-+prepare stmt from '/* with comment */ select * from t1';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   0
-+execute stmt;
-+a
-+1
-+2
-+3
-+execute stmt;
-+a
-+1
-+2
-+3
-+execute stmt;
-+a
-+1
-+2
-+3
-+execute stmt;
-+a
-+1
-+2
-+3
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   5
-+prepare stmt from 'select * from t1';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   6
-+prepare stmt from 'select * /*internal comment*/from t1';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   7
-+prepare stmt from 'select * /*internal comment*/ from t1';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   8
-+prepare stmt from 'select * from t1 /* at the end */';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   9
-+prepare stmt from 'select * from t1 /* with "quote" */';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   10
-+prepare stmt from 'select * from t1 /* with \'quote\' */';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   11
-+prepare stmt from 'select * from t1 # 123
-+';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   12
-+prepare stmt from 'select * from t1 # 123 with "quote"
-+';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   13
-+prepare stmt from 'select * from t1 # 123 with \'quote\'
-+';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   14
-+prepare stmt from 'select * from t1
-+# 123
-+';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   15
-+prepare stmt from '#456
-+select * from t1
-+# 123
-+';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   16
-+prepare stmt from 'select * from t1 -- 123
-+';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   17
-+prepare stmt from 'select * from t1
-+-- 123
-+';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   18
-+prepare stmt from '-- comment in first
-+select * from t1
-+# 123
-+';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       1
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        1
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   19
-+prepare stmt from '(#456(
-+select * from t1
-+# 123(
-+)';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       2
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        2
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   19
-+prepare stmt from '/*test*/(-- comment in first(
-+select * from t1
-+-- 123 asdasd
-+/* test */)';
-+execute stmt;
-+a
-+1
-+2
-+3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       2
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        2
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   20
-+prepare stmt from 'select "test",a from t1';
-+execute stmt;
-+test  a
-+test  1
-+test  2
-+test  3
-+execute stmt;
-+test  a
-+test  1
-+test  2
-+test  3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       3
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        3
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   21
-+prepare stmt from 'select "test /* internal \'comment\' */",a from t1';
-+execute stmt;
-+test /* internal 'comment' */ a
-+test /* internal 'comment' */ 1
-+test /* internal 'comment' */ 2
-+test /* internal 'comment' */ 3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       4
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        4
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   21
-+prepare stmt from 'select "test #internal comment" ,a from t1';
-+execute stmt;
-+test #internal comment        a
-+test #internal comment        1
-+test #internal comment        2
-+test #internal comment        3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       5
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        5
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   21
-+prepare stmt from 'select "test #internal comment" #external comment
-+,a from t1';
-+execute stmt;
-+test #internal comment        a
-+test #internal comment        1
-+test #internal comment        2
-+test #internal comment        3
-+show status like "Qcache_queries_in_cache";
-+Variable_name Value
-+Qcache_queries_in_cache       5
-+show status like "Qcache_inserts";
-+Variable_name Value
-+Qcache_inserts        5
-+show status like "Qcache_hits";
-+Variable_name Value
-+Qcache_hits   22
-+DROP TABLE t1;
-+SET GLOBAL query_cache_size= default;
-+set global query_cache_strip_comments=OFF;
---- /dev/null
-+++ b/mysql-test/r/percona_status_wait_query_cache_mutex.result
-@@ -0,0 +1,27 @@
-+set GLOBAL query_cache_size=1355776;
-+flush query cache;
-+flush query cache;
-+reset query cache;
-+flush status;
-+DROP TABLE IF EXISTS t;
-+CREATE TABLE t(id INT, number INT);
-+INSERT INTO t VALUES (0,1);
-+INSERT INTO t VALUES (1,2);
-+INSERT INTO t VALUES (2,3);
-+SELECT number from t where id > 0;
-+number
-+2
-+3
-+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
-+SELECT number from t where id > 0;
-+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
-+SELECT number from t where id > 0;
-+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
-+SHOW PROCESSLIST;
-+Id    User    Host    db      Command Time    State   Info
-+Id    root    localhost       test    Sleep   Time            NULL
-+Id    root    localhost       test    Query   Time    Waiting on query cache mutex    SELECT number from t where id > 0
-+Id    root    localhost       test    Query   Time    Waiting on query cache mutex    SELECT number from t where id > 0
-+Id    root    localhost       test    Query   Time    NULL    SHOW PROCESSLIST
-+DROP TABLE t;
-+set GLOBAL query_cache_size=0;
---- /dev/null
-+++ b/mysql-test/t/percona_query_cache_with_comments.test
-@@ -0,0 +1,5 @@
-+--disable_ps_protocol
-+set global query_cache_strip_comments=ON;
-+-- source include/percona_query_cache_with_comments_begin.inc
-+-- source include/percona_query_cache_with_comments.inc
-+-- source include/percona_query_cache_with_comments_end.inc
---- /dev/null
-+++ b/mysql-test/t/percona_query_cache_with_comments_crash.test
-@@ -0,0 +1,22 @@
-+-- source include/have_query_cache.inc
-+set GLOBAL query_cache_size=1355776;
-+--disable_warnings
-+drop table if exists t1;
-+--enable_warnings
-+create table t1 (a int not null);
-+insert into t1 values (1),(2),(3);
-+flush query cache; # This crashed in some versions
-+flush query cache; # This crashed in some versions
-+reset query cache;
-+flush status;
-+( select * from t1 );
-+/*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := REPLACE(REPLACE(@@SQL_MODE, 'ANSI_QUOTES', ''), ',,', ','), @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */;
-+/* only comment */;
-+let query=# only comment
-+;
-+eval $query;
-+let query=-- only comment
-+;
-+eval $query;
-+DROP TABLE t1;
-+SET GLOBAL query_cache_size= default;
---- /dev/null
-+++ b/mysql-test/t/percona_query_cache_with_comments_disable.test
-@@ -0,0 +1,3 @@
-+-- source include/percona_query_cache_with_comments_begin.inc
-+-- source include/percona_query_cache_with_comments.inc
-+-- source include/percona_query_cache_with_comments_end.inc
---- /dev/null
-+++ b/mysql-test/t/percona_query_cache_with_comments_prepared_statements.test
-@@ -0,0 +1,208 @@
-+-- source include/have_query_cache.inc
-+
-+set GLOBAL query_cache_size=1355776;
-+
-+# Reset query cache variables.
-+flush query cache; # This crashed in some versions
-+flush query cache; # This crashed in some versions
-+reset query cache;
-+flush status;
-+--disable_warnings
-+drop table if exists t1;
-+--enable_warnings
-+
-+#
-+# First simple test
-+#
-+
-+create table t1 (a int not null);
-+insert into t1 values (1),(2),(3);
-+
-+set global query_cache_strip_comments=ON;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from '/* with comment */ select * from t1';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+execute stmt;
-+execute stmt;
-+execute stmt;
-+execute stmt;
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * /*internal comment*/from t1';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * /*internal comment*/ from t1';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1 /* at the end */';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1 /* with "quote" */';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1 /* with \'quote\' */';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1 # 123
-+';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1 # 123 with "quote"
-+';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1 # 123 with \'quote\'
-+';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1
-+# 123
-+';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from '#456
-+select * from t1
-+# 123
-+';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1 -- 123
-+';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select * from t1
-+-- 123
-+';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from '-- comment in first
-+select * from t1
-+# 123
-+';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from '(#456(
-+select * from t1
-+# 123(
-+)';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from '/*test*/(-- comment in first(
-+select * from t1
-+-- 123 asdasd
-+/* test */)';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select "test",a from t1';
-+execute stmt;
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select "test /* internal \'comment\' */",a from t1';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select "test #internal comment" ,a from t1';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+prepare stmt from 'select "test #internal comment" #external comment
-+,a from t1';
-+execute stmt;
-+
-+show status like "Qcache_queries_in_cache";
-+show status like "Qcache_inserts";
-+show status like "Qcache_hits";
-+
-+DROP TABLE t1;
-+SET GLOBAL query_cache_size= default;
-+set global query_cache_strip_comments=OFF;
---- /dev/null
-+++ b/mysql-test/t/percona_status_wait_query_cache_mutex.test
-@@ -0,0 +1,37 @@
-+--source include/have_query_cache.inc
-+--source include/have_debug.inc
-+set GLOBAL query_cache_size=1355776;
-+--source include/percona_query_cache_with_comments_clear.inc
-+
-+-- disable_warnings
-+DROP TABLE IF EXISTS t;
-+-- enable_warnings
-+CREATE TABLE t(id INT, number INT);
-+INSERT INTO t VALUES (0,1);
-+INSERT INTO t VALUES (1,2);
-+INSERT INTO t VALUES (2,3);
-+SELECT number from t where id > 0;
-+--connect (conn0,localhost,root,,)
-+--connect (conn1,localhost,root,,)
-+--connect (conn2,localhost,root,,)
-+
-+--connection conn0
-+--error 0, ER_UNKNOWN_SYSTEM_VARIABLE
-+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
-+SEND SELECT number from t where id > 0;
-+SLEEP 1.0;
-+
-+--connection conn1
-+--error 0, ER_UNKNOWN_SYSTEM_VARIABLE
-+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
-+SEND SELECT number from t where id > 0;
-+SLEEP 1.0;
-+
-+--connection conn2
-+--error 0, ER_UNKNOWN_SYSTEM_VARIABLE
-+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
-+--replace_column 1 Id 6 Time
-+SHOW PROCESSLIST;
-+
-+DROP TABLE t;
-+set GLOBAL query_cache_size=0;
diff --git a/mysql-remove_fcntl_excessive_calls.patch b/mysql-remove_fcntl_excessive_calls.patch
deleted file mode 100644 (file)
index 32ed1e4..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-# name       : remove_fcntl_excessive_calls.patch
-# introduced : 12
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- /dev/null
-+++ b/patch_info/remove_fcntl_excessive_calls.info
-@@ -0,0 +1,6 @@
-+File=remove_fcntl_excessive_calls.patch
-+Name=remove fcntl excessive calls
-+Version=1.0
-+Author=This is a port of the official fix.
-+License=GPL
-+Comment=
---- a/sql/net_serv.cc
-+++ b/sql/net_serv.cc
-@@ -64,7 +64,7 @@
-   can't normally do this the client should have a bigger max_allowed_packet.
- */
--#if defined(__WIN__) || !defined(MYSQL_SERVER)
-+#if (defined(__WIN__) || !defined(MYSQL_SERVER)) && !defined(NO_ALARM)
-   /* The following is because alarms doesn't work on windows. */
- #define NO_ALARM
- #endif
-@@ -139,7 +139,7 @@
-   if (vio != 0)                                       /* If real connection */
-   {
-     net->fd  = vio_fd(vio);                   /* For perl DBI/DBD */
--#if defined(MYSQL_SERVER) && !defined(__WIN__)
-+#if defined(MYSQL_SERVER) && !defined(__WIN__) && !defined(NO_ALARM)
-     if (!(test_flags & TEST_BLOCKING))
-     {
-       my_bool old_mode;
-@@ -617,7 +617,7 @@
-     if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
-     {
-       my_bool interrupted = vio_should_retry(net->vio);
--#if !defined(__WIN__)
-+#if !defined(NO_ALARM) && !defined(__WIN__)
-       if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
-       {
-         if (!thr_alarm(&alarmed, net->write_timeout, &alarm_buff))
-@@ -673,7 +673,7 @@
-     pos+=length;
-     update_statistics(thd_increment_bytes_sent(length));
-   }
--#ifndef __WIN__
-+#if !defined(NO_ALARM) && !defined(__WIN__)
-  end:
- #endif
- #ifdef HAVE_COMPRESS
-@@ -805,6 +805,7 @@
-     thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
- #else
-   /* Read timeout is set in my_net_set_read_timeout */
-+  DBUG_ASSERT(net_blocking);
- #endif /* NO_ALARM */
-     pos = net->buff + net->where_b;           /* net->packet -4 */
-@@ -819,7 +820,7 @@
-         DBUG_PRINT("info",("vio_read returned %ld  errno: %d",
-                            (long) length, vio_errno(net->vio)));
--#if !defined(__WIN__) || defined(MYSQL_SERVER)
-+#if !defined(NO_ALARM) && (!defined(__WIN__) || defined(MYSQL_SERVER))
-         /*
-           We got an error that there was no data on the socket. We now set up
-           an alarm to not 'read forever', change the socket to non blocking
diff --git a/mysql-response-time-distribution.patch b/mysql-response-time-distribution.patch
deleted file mode 100644 (file)
index a3d4de7..0000000
+++ /dev/null
@@ -1,888 +0,0 @@
-# name       : response-time-distribution.patch
-# introduced : 12
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
-diff -ruN a/include/mysql_com.h b/include/mysql_com.h
---- a/include/mysql_com.h      2010-11-01 08:43:53.000000000 +0000
-+++ b/include/mysql_com.h      2010-11-01 08:52:40.000000000 +0000
-@@ -128,10 +128,11 @@
- #define REFRESH_FAST          32768   /* Intern flag */
- /* RESET (remove all queries) from query cache */
--#define REFRESH_QUERY_CACHE   65536
--#define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */
--#define REFRESH_DES_KEY_FILE  0x40000L
--#define REFRESH_USER_RESOURCES        0x80000L
-+#define REFRESH_QUERY_CACHE        65536
-+#define REFRESH_QUERY_CACHE_FREE    0x20000L /* pack query cache */
-+#define REFRESH_DES_KEY_FILE       0x40000L
-+#define REFRESH_USER_RESOURCES             0x80000L
-+#define REFRESH_QUERY_RESPONSE_TIME 0x100000L /* response time distibution */
- #define CLIENT_LONG_PASSWORD  1       /* new more secure passwords */
- #define CLIENT_FOUND_ROWS     2       /* Found instead of affected rows */
-diff -ruN a/patch_info/response-time-distribution.info b/patch_info/response-time-distribution.info
---- a/patch_info/response-time-distribution.info       1970-01-01 00:00:00.000000000 +0000
-+++ b/patch_info/response-time-distribution.info       2010-11-01 08:52:40.000000000 +0000
-@@ -0,0 +1,9 @@
-+File=response-time-distribution.patch
-+Name=Response time distribution
-+Version=1.0
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment=
-+Changelog
-+2010-07-02 first version avaliable
-+2010-09-15 add column 'total'
-diff -ruN a/sql/Makefile.am b/sql/Makefile.am
---- a/sql/Makefile.am  2010-11-01 08:43:52.000000000 +0000
-+++ b/sql/Makefile.am  2010-11-01 08:52:40.000000000 +0000
-@@ -66,7 +66,7 @@
-                       sql_repl.h slave.h rpl_filter.h rpl_injector.h \
-                       log_event.h rpl_record.h \
-                       log_event_old.h rpl_record_old.h \
--                      sql_sort.h sql_cache.h set_var.h \
-+                      sql_sort.h sql_cache.h set_var.h query_response_time.h \
-                       spatial.h gstream.h client_settings.h tzfile.h \
-                       tztime.h my_decimal.h\
-                       sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
-@@ -89,7 +89,7 @@
-                       sql_string.cc sql_manager.cc sql_map.cc \
-                       mysqld.cc password.c hash_filo.cc hostname.cc \
-                       sql_connect.cc scheduler.cc sql_parse.cc \
--                      set_var.cc sql_yacc.yy \
-+                      set_var.cc query_response_time.cc sql_yacc.yy \
-                       sql_base.cc table.cc sql_select.cc sql_insert.cc \
-                       sql_profile.cc \
-                       sql_prepare.cc sql_error.cc sql_locale.cc \
-diff -ruN a/sql/Makefile.in b/sql/Makefile.in
---- a/sql/Makefile.in  2010-11-01 08:43:52.000000000 +0000
-+++ b/sql/Makefile.in  2010-11-01 08:52:40.000000000 +0000
-@@ -122,7 +122,7 @@
-       sql_string.$(OBJEXT) sql_manager.$(OBJEXT) sql_map.$(OBJEXT) \
-       mysqld.$(OBJEXT) password.$(OBJEXT) hash_filo.$(OBJEXT) \
-       hostname.$(OBJEXT) sql_connect.$(OBJEXT) scheduler.$(OBJEXT) \
--      sql_parse.$(OBJEXT) set_var.$(OBJEXT) sql_yacc.$(OBJEXT) \
-+      sql_parse.$(OBJEXT) set_var.$(OBJEXT) query_response_time.${OBJEXT} sql_yacc.$(OBJEXT) \
-       sql_base.$(OBJEXT) table.$(OBJEXT) sql_select.$(OBJEXT) \
-       sql_insert.$(OBJEXT) sql_profile.$(OBJEXT) \
-       sql_prepare.$(OBJEXT) sql_error.$(OBJEXT) sql_locale.$(OBJEXT) \
-@@ -562,7 +562,7 @@
-                       sql_repl.h slave.h rpl_filter.h rpl_injector.h \
-                       log_event.h rpl_record.h \
-                       log_event_old.h rpl_record_old.h \
--                      sql_sort.h sql_cache.h set_var.h \
-+                      sql_sort.h sql_cache.h set_var.h query_response_time.h \
-                       spatial.h gstream.h client_settings.h tzfile.h \
-                       tztime.h my_decimal.h\
-                       sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
-@@ -585,7 +585,7 @@
-                       sql_string.cc sql_manager.cc sql_map.cc \
-                       mysqld.cc password.c hash_filo.cc hostname.cc \
-                       sql_connect.cc scheduler.cc sql_parse.cc \
--                      set_var.cc sql_yacc.yy \
-+                      set_var.cc query_response_time.cc sql_yacc.yy \
-                       sql_base.cc table.cc sql_select.cc sql_insert.cc \
-                       sql_profile.cc \
-                       sql_prepare.cc sql_error.cc sql_locale.cc \
-@@ -828,6 +828,7 @@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/password.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/procedure.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@
-+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/query_response_time.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/records.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repl_failsafe.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpl_filter.Po@am__quote@
-diff -ruN a/sql/lex.h b/sql/lex.h
---- a/sql/lex.h        2010-11-01 08:43:53.000000000 +0000
-+++ b/sql/lex.h        2010-11-01 08:52:40.000000000 +0000
-@@ -415,6 +415,7 @@
-   { "PURGE",          SYM(PURGE)},
-   { "QUARTER",          SYM(QUARTER_SYM)},
-   { "QUERY",          SYM(QUERY_SYM)},
-+  { "QUERY_RESPONSE_TIME", SYM(QUERY_RESPONSE_TIME_SYM)},
-   { "QUICK",          SYM(QUICK)},
-   { "RANGE",            SYM(RANGE_SYM)},
-   { "READ",           SYM(READ_SYM)},
-diff -ruN a/sql/mysql_priv.h b/sql/mysql_priv.h
---- a/sql/mysql_priv.h 2010-11-01 08:43:57.000000000 +0000
-+++ b/sql/mysql_priv.h 2010-11-01 08:52:40.000000000 +0000
-@@ -2121,6 +2121,11 @@
- extern my_bool opt_query_cache_strip_comments;
- extern my_bool opt_use_global_long_query_time;
- extern my_bool opt_slow_query_log_microseconds_timestamp;
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+extern ulong   opt_query_response_time_range_base;
-+extern my_bool opt_enable_query_response_time_stats;
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+extern SHOW_COMP_OPTION have_response_time_distribution;
- extern my_bool sp_automatic_privileges, opt_noacl;
- extern my_bool opt_old_style_user_limits, trust_function_creators;
- extern uint opt_crash_binlog_innodb;
-diff -ruN a/sql/mysqld.cc b/sql/mysqld.cc
---- a/sql/mysqld.cc    2010-11-01 08:43:57.000000000 +0000
-+++ b/sql/mysqld.cc    2010-11-01 08:52:40.000000000 +0000
-@@ -32,6 +32,7 @@
- #include "rpl_injector.h"
-+#include "query_response_time.h"
- #ifdef HAVE_SYS_PRCTL_H
- #include <sys/prctl.h>
- #endif
-@@ -529,6 +530,10 @@
- my_bool opt_query_cache_strip_comments = 0;
- my_bool opt_use_global_long_query_time= 0;
- my_bool opt_slow_query_log_microseconds_timestamp= 0;
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+ulong   opt_query_response_time_range_base  = QRT_DEFAULT_BASE;
-+my_bool opt_enable_query_response_time_stats= 0;
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
- my_bool lower_case_file_system= 0;
- my_bool opt_large_pages= 0;
- my_bool opt_myisam_use_mmap= 0;
-@@ -679,6 +684,7 @@
- MY_LOCALE *my_default_lc_time_names;
- SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
-+SHOW_COMP_OPTION have_response_time_distribution;
- SHOW_COMP_OPTION have_geometry, have_rtree_keys;
- SHOW_COMP_OPTION have_crypt, have_compress;
- SHOW_COMP_OPTION have_community_features;
-@@ -1389,6 +1395,9 @@
-   free_global_thread_stats();
-   free_global_table_stats();
-   free_global_index_stats();
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  query_response_time_free();
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
- #ifdef HAVE_REPLICATION
-   end_slave_list();
- #endif
-@@ -4103,6 +4112,9 @@
-   init_global_table_stats();
-   init_global_index_stats();
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  query_response_time_init();
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   /* We have to initialize the storage engines before CSV logging */
-   if (ha_init())
-@@ -5916,6 +5928,10 @@
-   OPT_USE_GLOBAL_LONG_QUERY_TIME,
-   OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
-   OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  OPT_QRT_RANGE_BASE,
-+  OPT_ENABLE_QRT_STATS,
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   OPT_IGNORE_BUILTIN_INNODB,
-   OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
-   OPT_DEFAULT_CHARACTER_SET_OLD,
-@@ -6987,6 +7003,23 @@
-    "Use microsecond time's precision in slow query log",
-    (uchar**) &opt_slow_query_log_microseconds_timestamp, (uchar**) &opt_slow_query_log_microseconds_timestamp,
-    0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  {"query_response_time_range_base", OPT_QRT_RANGE_BASE,
-+     "Select base of log for query_response_time ranges. WARNING: variable change affect only after flush",
-+   (uchar**) &opt_query_response_time_range_base, (uchar**) &opt_query_response_time_range_base,
-+   0, GET_ULONG, REQUIRED_ARG, 
-+   /* def_value */  QRT_DEFAULT_BASE,
-+   /* min_value */  2,
-+   /* max_value */  QRT_MAXIMUM_BASE, 
-+   /* sub_size */   0,
-+   /* block_size */ 1,
-+   /* app_type */ 0
-+  },
-+  {"enable_query_response_time_stats", OPT_ENABLE_QRT_STATS,
-+   "Enable or disable query response time statisics collecting",
-+   (uchar**) &opt_enable_query_response_time_stats, (uchar**) &opt_enable_query_response_time_stats,
-+   0, GET_BOOL, REQUIRED_ARG, 0, 0, 1, 0, 1, 0},
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
-    "If set to 1, table names are stored in lowercase on disk and table names "
-    "will be case-insensitive.  Should be set to 2 if you are using a case-"
-@@ -8208,6 +8241,11 @@
- #else
-   have_query_cache=SHOW_OPTION_NO;
- #endif
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  have_response_time_distribution= SHOW_OPTION_YES;
-+#else /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+  have_response_time_distribution= SHOW_OPTION_NO;
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
- #ifdef HAVE_SPATIAL
-   have_geometry=SHOW_OPTION_YES;
- #else
-diff -ruN a/sql/query_response_time.cc b/sql/query_response_time.cc
---- a/sql/query_response_time.cc       1970-01-01 00:00:00.000000000 +0000
-+++ b/sql/query_response_time.cc       2010-11-02 15:34:52.000000000 +0000
-@@ -0,0 +1,369 @@
-+#ifdef __FreeBSD__
-+#include <sys/types.h>
-+#include <machine/atomic.h>
-+#endif // __FreeBSD__
-+#include "my_global.h"
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+#include "mysql_priv.h"
-+#include "mysql_com.h"
-+#include "rpl_tblmap.h"
-+#include "query_response_time.h"
-+
-+#define TIME_STRING_POSITIVE_POWER_LENGTH QRT_TIME_STRING_POSITIVE_POWER_LENGTH
-+#define TIME_STRING_NEGATIVE_POWER_LENGTH 6
-+#define TOTAL_STRING_POSITIVE_POWER_LENGTH QRT_TOTAL_STRING_POSITIVE_POWER_LENGTH
-+#define TOTAL_STRING_NEGATIVE_POWER_LENGTH 6
-+#define MINIMUM_BASE 2
-+#define MAXIMUM_BASE QRT_MAXIMUM_BASE
-+#define POSITIVE_POWER_FILLER QRT_POSITIVE_POWER_FILLER
-+#define NEGATIVE_POWER_FILLER QRT_NEGATIVE_POWER_FILLER
-+#define STRING_OVERFLOW QRT_STRING_OVERFLOW
-+#define TIME_OVERFLOW   QRT_TIME_OVERFLOW
-+#define DEFAULT_BASE    QRT_DEFAULT_BASE
-+
-+#define do_xstr(s) do_str(s)
-+#define do_str(s) #s
-+#define do_format(filler,width) "%" filler width "lld"
-+/*
-+  Format strings for snprintf. Generate from:
-+  POSITIVE_POWER_FILLER and TIME_STRING_POSITIVE_POWER_LENGTH
-+  NEFATIVE_POWER_FILLER and TIME_STRING_NEGATIVE_POWER_LENGTH
-+*/
-+#define TIME_STRING_POSITIVE_POWER_FORMAT do_format(POSITIVE_POWER_FILLER,do_xstr(TIME_STRING_POSITIVE_POWER_LENGTH))
-+#define TIME_STRING_NEGATIVE_POWER_FORMAT do_format(NEGATIVE_POWER_FILLER,do_xstr(TIME_STRING_NEGATIVE_POWER_LENGTH))
-+#define TIME_STRING_FORMAT                  TIME_STRING_POSITIVE_POWER_FORMAT "." TIME_STRING_NEGATIVE_POWER_FORMAT
-+
-+#define TOTAL_STRING_POSITIVE_POWER_FORMAT do_format(POSITIVE_POWER_FILLER,do_xstr(TOTAL_STRING_POSITIVE_POWER_LENGTH))
-+#define TOTAL_STRING_NEGATIVE_POWER_FORMAT do_format(NEGATIVE_POWER_FILLER,do_xstr(TOTAL_STRING_NEGATIVE_POWER_LENGTH))
-+#define TOTAL_STRING_FORMAT                 TOTAL_STRING_POSITIVE_POWER_FORMAT "." TOTAL_STRING_NEGATIVE_POWER_FORMAT
-+
-+#define TIME_STRING_LENGTH    QRT_TIME_STRING_LENGTH
-+#define TIME_STRING_BUFFER_LENGTH     (TIME_STRING_LENGTH + 1 /* '\0' */)
-+
-+#define TOTAL_STRING_LENGTH   QRT_TOTAL_STRING_LENGTH
-+#define TOTAL_STRING_BUFFER_LENGTH    (TOTAL_STRING_LENGTH + 1 /* '\0' */)
-+
-+/*
-+  Calculate length of "log linear"
-+  1)
-+  (MINIMUM_BASE ^ result) <= (10 ^ STRING_POWER_LENGTH) < (MINIMUM_BASE ^ (result + 1))
-+
-+  2)
-+  (MINIMUM_BASE ^ result) <= (10 ^ STRING_POWER_LENGTH)
-+  and
-+  (MINIMUM_BASE ^ (result + 1)) > (10 ^ STRING_POWER_LENGTH)
-+
-+  3)
-+  result     <= LOG(MINIMUM_BASE, 10 ^ STRING_POWER_LENGTH)= STRING_POWER_LENGTH * LOG(MINIMUM_BASE,10)
-+  result + 1 >  LOG(MINIMUM_BASE, 10 ^ STRING_POWER_LENGTH)= STRING_POWER_LENGTH * LOG(MINIMUM_BASE,10)
-+
-+  4) STRING_POWER_LENGTH * LOG(MINIMUM_BASE,10) - 1 < result <= STRING_POWER_LENGTH * LOG(MINIMUM_BASE,10)
-+
-+  MINIMUM_BASE= 2 always, LOG(MINIMUM_BASE,10)= 3.3219280948873626, result= (int)3.3219280948873626 * STRING_POWER_LENGTH
-+
-+  Last counter always use for time overflow
-+*/
-+#define POSITIVE_POWER_COUNT ((int)(3.32192809 * TIME_STRING_POSITIVE_POWER_LENGTH))
-+#define NEGATIVE_POWER_COUNT ((int)(3.32192809 * TIME_STRING_NEGATIVE_POWER_LENGTH))
-+#define OVERALL_POWER_COUNT (NEGATIVE_POWER_COUNT + 1 + POSITIVE_POWER_COUNT)
-+
-+#define MILLION ((unsigned long)1000 * 1000)
-+
-+namespace query_response_time
-+{
-+
-+class utility
-+{
-+public:
-+  utility() : m_base(0)
-+  {
-+    m_max_dec_value= MILLION;
-+    for(int i= 0; TIME_STRING_POSITIVE_POWER_LENGTH > i; ++i)
-+      m_max_dec_value *= 10;
-+    setup(DEFAULT_BASE);
-+  }
-+public:
-+  uint      base()            const { return m_base; }
-+  uint      negative_count()  const { return m_negative_count; }
-+  uint      positive_count()  const { return m_positive_count; }
-+  uint      bound_count()     const { return m_bound_count; }
-+  ulonglong max_dec_value()   const { return m_max_dec_value; }
-+  ulonglong bound(uint index) const { return m_bound[ index ]; }
-+public:
-+  void setup(uint base)
-+  {
-+    if(base != m_base)
-+    {
-+      m_base= base;
-+
-+      const ulonglong million= 1000 * 1000;
-+      ulonglong value= million;
-+      m_negative_count= 0;
-+      while(value > 0)
-+      {
-+      m_negative_count += 1;
-+      value /= m_base;
-+      }
-+      m_negative_count -= 1;
-+
-+      value= million;
-+      m_positive_count= 0;
-+      while(value < m_max_dec_value)
-+      {
-+      m_positive_count += 1;
-+      value *= m_base;
-+      }
-+      m_bound_count= m_negative_count + m_positive_count;
-+
-+      value= million;
-+      for(uint i= 0; i < m_negative_count; ++i)
-+      {
-+      value /= m_base;
-+      m_bound[m_negative_count - i - 1]= value;
-+      }
-+      value= million;
-+      for(uint i= 0; i < m_positive_count;  ++i)
-+      {
-+      m_bound[m_negative_count + i]= value;
-+      value *= m_base;
-+      }
-+    }
-+  }
-+private:
-+  uint      m_base;
-+  uint      m_negative_count;
-+  uint      m_positive_count;
-+  uint      m_bound_count;
-+  ulonglong m_max_dec_value; /* for TIME_STRING_POSITIVE_POWER_LENGTH=7 is 10000000 */
-+  ulonglong m_bound[OVERALL_POWER_COUNT];
-+};
-+
-+void print_time(char* buffer, std::size_t buffer_size, std::size_t string_positive_power_length, const char* format, uint64 value)
-+{
-+  memset(buffer,'X',buffer_size);
-+  buffer[string_positive_power_length]= '.';
-+  ulonglong second=      (value / MILLION);
-+  ulonglong microsecond= (value % MILLION);
-+  int result_length= snprintf(buffer, buffer_size, format, second, microsecond);
-+  if(result_length < 0)
-+  {
-+    assert(sizeof(STRING_OVERFLOW) <= buffer_size);
-+    memcpy(buffer, STRING_OVERFLOW, sizeof(STRING_OVERFLOW));
-+    return;
-+  }
-+  buffer[result_length]= 0;
-+}
-+#ifdef __x86_64__
-+typedef uint64 TimeCounter;
-+void add_time_atomic(TimeCounter* counter, uint64 time)
-+{
-+  __sync_fetch_and_add(counter,time);  
-+}
-+#endif // __x86_64__
-+#ifdef __i386__
-+inline uint32 get_high(uint64 value)
-+{
-+  return ((value >> 32) << 32);
-+}
-+inline uint32 get_low(uint64 value)
-+{
-+  return ((value << 32) >> 32);
-+}
-+#ifdef __FreeBSD__
-+inline bool compare_and_swap(volatile uint32 *target, uint32 old, uint32 new_value)
-+{
-+  return atomic_cmpset_32(target,old,new_value);
-+}
-+#else // __FreeBSD__
-+inline bool compare_and_swap(volatile uint32* target, uint32 old, uint32 new_value)
-+{
-+  return __sync_bool_compare_and_swap(target,old,new_value);
-+}
-+#endif // __FreeBSD__
-+class TimeCounter
-+{
-+public:
-+  TimeCounter& operator=(uint64 time)
-+  {
-+    this->m_high= get_high(time);
-+    this->m_low=  get_low(time);
-+    return *this;
-+  }
-+  operator uint64() const
-+  {
-+    return ((static_cast<uint64>(m_high) << 32) + static_cast<uint64>(m_low));
-+  }
-+  void add(uint64 time)
-+  {
-+    uint32 time_high = get_high(time);
-+    uint32 time_low  = get_low(time);
-+    uint64 time_low64= time_low;
-+    while(true)
-+    {
-+      uint32 old_low= this->m_low;
-+      uint64 old_low64= old_low;
-+
-+      uint64 new_low64= old_low64 + time_low64;
-+      uint32 new_low= (get_low(new_low64));
-+      bool add_high= (get_high(new_low64) != 0);
-+
-+      if(!compare_and_swap(&m_low,old_low,new_low))
-+      {
-+      continue;
-+      }
-+      if(add_high)
-+      {
-+      ++time_high;
-+      }
-+      if(time_high > 0)
-+      {
-+        __sync_fetch_and_add(&m_high,time_high);
-+      }
-+      break;
-+    }
-+  }
-+private:
-+  uint32 m_low;
-+  uint32 m_high;
-+};
-+void add_time_atomic(TimeCounter* counter, uint64 time)
-+{
-+  counter->add(time);
-+}
-+#endif // __i386__
-+
-+class time_collector
-+{
-+public:
-+  time_collector(utility& u) : m_utility(&u)
-+  {
-+  }
-+  uint32 count(uint index) const { return m_count[index]; }
-+  uint64 total(uint index) const { return m_total[index]; }
-+public:
-+  void flush()
-+  {
-+    memset(&m_count,0,sizeof(m_count));
-+    memset((void*)&m_total,0,sizeof(m_total));
-+  }
-+  void collect(uint64 time)
-+  {
-+    bool no_collect= false;
-+    DBUG_EXECUTE_IF("response_time_distribution_log_only_more_300_milliseconds", {   \
-+        no_collect= time < 300 * 1000; \
-+      });
-+    if(no_collect) return;
-+    int i= 0;
-+    for(int count= m_utility->bound_count(); count > i; ++i)
-+    {
-+      if(m_utility->bound(i) > time)
-+      {
-+        __sync_fetch_and_add(&(m_count[i]),(uint32)1);
-+       add_time_atomic(&(m_total[i]),time);
-+        break;
-+      }
-+    }
-+  }
-+private:
-+  utility* m_utility;
-+  uint32   m_count[OVERALL_POWER_COUNT + 1];
-+  TimeCounter m_total[OVERALL_POWER_COUNT + 1];
-+};
-+
-+class collector
-+{
-+public:
-+  collector() : m_time(m_utility)
-+  {
-+    m_utility.setup(DEFAULT_BASE);
-+    m_time.flush();
-+  }
-+public:
-+  void flush()
-+  {
-+    m_utility.setup(opt_query_response_time_range_base);
-+    m_time.flush();
-+  }
-+  int fill(THD* thd, TABLE_LIST *tables, COND *cond)
-+  {
-+    DBUG_ENTER("fill_schema_query_response_time");
-+    TABLE        *table= static_cast<TABLE*>(tables->table);
-+    Field        **fields= table->field;
-+    for(uint i= 0, count= bound_count() + 1 /* with overflow */; count > i; ++i)
-+    {
-+      char time[TIME_STRING_BUFFER_LENGTH];
-+      char total[TOTAL_STRING_BUFFER_LENGTH];
-+      if(i == bound_count())
-+      {        
-+        assert(sizeof(TIME_OVERFLOW) <= TIME_STRING_BUFFER_LENGTH);
-+        assert(sizeof(TIME_OVERFLOW) <= TOTAL_STRING_BUFFER_LENGTH);
-+        memcpy(time,TIME_OVERFLOW,sizeof(TIME_OVERFLOW));
-+        memcpy(total,TIME_OVERFLOW,sizeof(TIME_OVERFLOW));
-+      }
-+      else
-+      {
-+        print_time(time,sizeof(time),TIME_STRING_POSITIVE_POWER_LENGTH,TIME_STRING_FORMAT,this->bound(i));
-+        print_time(total,sizeof(total),TOTAL_STRING_POSITIVE_POWER_LENGTH,TOTAL_STRING_FORMAT,this->total(i));
-+      }
-+      fields[0]->store(time,strlen(time),system_charset_info);
-+      fields[1]->store(this->count(i));
-+      fields[2]->store(total,strlen(total),system_charset_info);
-+      if (schema_table_store_record(thd, table))
-+      {
-+      DBUG_RETURN(1);
-+      }
-+    }
-+    DBUG_RETURN(0);
-+  }
-+  void collect(ulonglong time)
-+  {
-+    m_time.collect(time);
-+  }
-+  uint bound_count() const
-+  {
-+    return m_utility.bound_count();
-+  }
-+  ulonglong bound(uint index)
-+  {
-+    return m_utility.bound(index);
-+  }
-+  ulonglong count(uint index)
-+  {
-+    return m_time.count(index);
-+  }
-+  ulonglong total(uint index)
-+  {
-+    return m_time.total(index);
-+  }
-+private:
-+  utility          m_utility;
-+  time_collector   m_time;
-+};
-+
-+static collector g_collector;
-+
-+} // namespace query_response_time
-+
-+void query_response_time_init()
-+{
-+}
-+
-+void query_response_time_free()
-+{
-+  query_response_time::g_collector.flush();
-+}
-+
-+void query_response_time_flush()
-+{
-+  query_response_time::g_collector.flush();
-+}
-+void query_response_time_collect(ulonglong query_time)
-+{
-+  query_response_time::g_collector.collect(query_time);
-+}
-+
-+int query_response_time_fill(THD* thd, TABLE_LIST *tables, COND *cond)
-+{
-+  return query_response_time::g_collector.fill(thd,tables,cond);
-+}
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-diff -ruN a/sql/query_response_time.h b/sql/query_response_time.h
---- a/sql/query_response_time.h        1970-01-01 00:00:00.000000000 +0000
-+++ b/sql/query_response_time.h        2010-11-01 08:52:40.000000000 +0000
-@@ -0,0 +1,71 @@
-+#ifndef QUERY_RESPONSE_TIME_H
-+#define QUERY_RESPONSE_TIME_H
-+
-+/*
-+  Settings for query response time
-+*/
-+
-+/*
-+  Maximum string length for (10 ^ (-1 * QRT_STRING_NEGATIVE_POWER_LENGTH)) in text representation.
-+  Example: for 6 is 0.000001
-+  Always 2
-+
-+  Maximum string length for (10 ^ (QRT_STRING_POSITIVE_POWER_LENGTH + 1) - 1) in text representation.
-+  Example: for 7 is 9999999.0
-+*/
-+#define QRT_TIME_STRING_POSITIVE_POWER_LENGTH 7
-+#define QRT_TOTAL_STRING_POSITIVE_POWER_LENGTH 7
-+
-+/*
-+  Minimum base for log - ALWAYS 2
-+  Maximum base for log:
-+*/
-+#define QRT_MAXIMUM_BASE 1000
-+
-+/*
-+  Filler for whole number (positive power)
-+  Example: for
-+  QRT_POSITIVE_POWER_FILLER ' '
-+  QRT_POSITIVE_POWER_LENGTH 7
-+  and number 7234 result is:
-+  '   7234'
-+*/
-+#define QRT_POSITIVE_POWER_FILLER " "
-+/*
-+  Filler for fractional number. Similiary to whole number
-+*/
-+#define QRT_NEGATIVE_POWER_FILLER "0"
-+
-+/*
-+  Message if string overflow (string overflow - internal error, this string say about bug in QRT)
-+*/
-+#define QRT_STRING_OVERFLOW "TOO BIG STRING"
-+
-+/*
-+  Message if time too big for statistic collecting (very long query)
-+*/
-+#define QRT_TIME_OVERFLOW "TOO LONG"
-+
-+#define QRT_DEFAULT_BASE 10
-+
-+#define QRT_TIME_STRING_LENGTH                                \
-+  max( (QRT_TIME_STRING_POSITIVE_POWER_LENGTH + 1 /* '.' */ + 6 /*QRT_TIME_STRING_NEGATIVE_POWER_LENGTH*/), \
-+       max( (sizeof(QRT_TIME_OVERFLOW) - 1),          \
-+          (sizeof(QRT_STRING_OVERFLOW) - 1) ) )
-+
-+#define QRT_TOTAL_STRING_LENGTH                               \
-+  max( (QRT_TOTAL_STRING_POSITIVE_POWER_LENGTH + 1 /* '.' */ + 6 /*QRT_TOTAL_STRING_NEGATIVE_POWER_LENGTH*/), \
-+       max( (sizeof(QRT_TIME_OVERFLOW) - 1),          \
-+          (sizeof(QRT_STRING_OVERFLOW) - 1) ) )
-+
-+extern ST_SCHEMA_TABLE query_response_time_table;
-+
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+extern void query_response_time_init   ();
-+extern void query_response_time_free   ();
-+extern void query_response_time_flush  ();
-+extern void query_response_time_collect(ulonglong query_time);
-+extern int  query_response_time_fill   (THD* thd, TABLE_LIST *tables, COND *cond);
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+
-+#endif // QUERY_RESPONSE_TIME_H
-diff -ruN a/sql/set_var.cc b/sql/set_var.cc
---- a/sql/set_var.cc   2010-11-01 08:43:57.000000000 +0000
-+++ b/sql/set_var.cc   2010-11-01 08:52:40.000000000 +0000
-@@ -1017,6 +1017,14 @@
- static sys_var_use_global_long_query_time sys_use_global_long_query_time;
- static sys_var_bool_ptr       sys_slow_query_log_microseconds_timestamp(&vars, "slow_query_log_microseconds_timestamp",
-                                                        &opt_slow_query_log_microseconds_timestamp);
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+static sys_var_bool_ptr       sys_enable_query_response_time_stats(&vars, "enable_query_response_time_stats",
-+                                                       &opt_enable_query_response_time_stats);
-+static sys_var_long_ptr       sys_query_response_time_range_base(&vars, "query_response_time_range_base",
-+                                                     &opt_query_response_time_range_base);
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+static sys_var_have_variable sys_have_response_time_distribution(&vars, "have_response_time_distribution",
-+                                                       &have_response_time_distribution);
- /* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
- static sys_var_log_state sys_var_log_slow(&vars, "log_slow_queries",
-                                           &opt_slow_log, QUERY_LOG_SLOW);
-diff -ruN a/sql/sql_parse.cc b/sql/sql_parse.cc
---- a/sql/sql_parse.cc 2010-11-01 08:43:57.000000000 +0000
-+++ b/sql/sql_parse.cc 2010-11-01 08:52:40.000000000 +0000
-@@ -28,6 +28,7 @@
- #include "events.h"
- #include "sql_trigger.h"
- #include "debug_sync.h"
-+#include "query_response_time.h"
- /**
-   @defgroup Runtime_Environment Runtime Environment
-@@ -1764,23 +1765,37 @@
-     Do not log administrative statements unless the appropriate option is
-     set.
-   */
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  if (opt_enable_query_response_time_stats || thd->enable_slow_log)
-+#else /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   if (thd->enable_slow_log)
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   {
--    ulonglong end_utime_of_query= thd->current_utime();
--    thd_proc_info(thd, "logging slow query");
--
--    if (((end_utime_of_query - thd->utime_after_lock) >
--         thd->variables.long_query_time ||
--         ((thd->server_status &
--           (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
--          opt_log_queries_not_using_indexes &&
--           !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) &&
--        thd->examined_row_count >= thd->variables.min_examined_row_limit)
-+    ulonglong end_utime_of_query   = thd->current_utime();
-+    ulonglong query_execution_time = end_utime_of_query - thd->utime_after_lock;
-+    #ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+    if(opt_enable_query_response_time_stats)
-+    {
-+      query_response_time_collect(query_execution_time);
-+    }
-+    #endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+    if (thd->enable_slow_log)
-     {
-       thd_proc_info(thd, "logging slow query");
--      thd->status_var.long_query_count++;
--      slow_log_print(thd, thd->query(), thd->query_length(), 
--                     end_utime_of_query);
-+
-+      if ((query_execution_time >
-+           thd->variables.long_query_time ||
-+           ((thd->server_status &
-+             (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
-+            opt_log_queries_not_using_indexes &&
-+             !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) &&
-+          thd->examined_row_count >= thd->variables.min_examined_row_limit)
-+      {
-+        thd_proc_info(thd, "logging slow query");
-+        thd->status_var.long_query_count++;
-+        slow_log_print(thd, thd->query(), thd->query_length(), 
-+                       end_utime_of_query);
-+      }
-     }
-   }
-   DBUG_VOID_RETURN;
-@@ -1905,6 +1920,7 @@
-   case SCH_CHARSETS:
-   case SCH_ENGINES:
-   case SCH_COLLATIONS:
-+  case SCH_QUERY_RESPONSE_TIME:
-   case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
-   case SCH_USER_PRIVILEGES:
-   case SCH_SCHEMA_PRIVILEGES:
-@@ -7265,6 +7281,12 @@
-     init_global_index_stats();
-     pthread_mutex_unlock(&LOCK_global_index_stats);
-   }
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  if (options & REFRESH_QUERY_RESPONSE_TIME)
-+  {
-+    query_response_time_flush();
-+  }
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS | REFRESH_THREAD_STATS))
-   {
-     pthread_mutex_lock(&LOCK_global_user_client_stats);
-diff -ruN a/sql/sql_show.cc b/sql/sql_show.cc
---- a/sql/sql_show.cc  2010-11-01 08:43:53.000000000 +0000
-+++ b/sql/sql_show.cc  2010-11-01 08:52:40.000000000 +0000
-@@ -31,6 +31,7 @@
- #include "event_data_objects.h"
- #endif
- #include <my_dir.h>
-+#include "query_response_time.h"
- #include "debug_sync.h"
- #define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
-@@ -7490,6 +7491,13 @@
- */
-+ST_FIELD_INFO query_response_time_fields_info[] =
-+  {
-+    {"time",  QRT_TIME_STRING_LENGTH,      MYSQL_TYPE_STRING,  0, 0,            "", SKIP_OPEN_TABLE },
-+    {"count", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, MY_I_S_UNSIGNED, "", SKIP_OPEN_TABLE },
-+    {"total",  QRT_TIME_STRING_LENGTH,     MYSQL_TYPE_STRING,  0, 0,            "", SKIP_OPEN_TABLE },
-+    {0,       0,                           MYSQL_TYPE_STRING,  0, 0,             0, SKIP_OPEN_TABLE }
-+  };
- ST_SCHEMA_TABLE schema_tables[]=
- {
-   {"CHARACTER_SETS", charsets_fields_info, create_schema_table, 
-@@ -7544,6 +7552,13 @@
-    1, 9, 0, OPEN_TABLE_ONLY},
-   {"ROUTINES", proc_fields_info, create_schema_table, 
-    fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  {"QUERY_RESPONSE_TIME", query_response_time_fields_info, create_schema_table, 
-+   query_response_time_fill, make_old_format, 0, -1, -1, 0, 0},
-+#else /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+  {"QUERY_RESPONSE_TIME", query_response_time_fields_info, create_schema_table, 
-+   0, make_old_format, 0, -1, -1, 0, 0},
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   {"SCHEMATA", schema_fields_info, create_schema_table,
-    fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
-   {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
-diff -ruN a/sql/sql_yacc.yy b/sql/sql_yacc.yy
---- a/sql/sql_yacc.yy  2010-11-01 08:43:53.000000000 +0000
-+++ b/sql/sql_yacc.yy  2010-11-01 08:52:40.000000000 +0000
-@@ -1079,6 +1079,7 @@
- %token  PURGE
- %token  QUARTER_SYM
- %token  QUERY_SYM
-+%token  QUERY_RESPONSE_TIME_SYM
- %token  QUICK
- %token  RANGE_SYM                     /* SQL-2003-R */
- %token  READS_SYM                     /* SQL-2003-R */
-@@ -10396,6 +10397,15 @@
-            if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
-              MYSQL_YYABORT;
-           }
-+        | QUERY_RESPONSE_TIME_SYM wild_and_where
-+        {
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+           LEX *lex= Lex;
-+           lex->sql_command= SQLCOM_SELECT;
-+           if (prepare_schema_table(YYTHD, lex, 0, SCH_QUERY_RESPONSE_TIME))
-+             MYSQL_YYABORT;     
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+        }
-         | CREATE PROCEDURE sp_name
-           {
-             LEX *lex= Lex;
-@@ -10616,6 +10626,12 @@
-           { Lex->type|= REFRESH_TABLE_STATS; }
-         | INDEX_STATS_SYM
-           { Lex->type|= REFRESH_INDEX_STATS; }
-+        | QUERY_RESPONSE_TIME_SYM
-+          { 
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+            Lex->type|= REFRESH_QUERY_RESPONSE_TIME; 
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+          }
-         | MASTER_SYM
-           { Lex->type|= REFRESH_MASTER; }
-         | DES_KEY_FILE
-@@ -11895,6 +11911,7 @@
-         | PROFILES_SYM             {}
-         | QUARTER_SYM              {}
-         | QUERY_SYM                {}
-+        | QUERY_RESPONSE_TIME_SYM  {}
-         | QUICK                    {}
-         | READ_ONLY_SYM            {}
-         | REBUILD_SYM              {}
-diff -ruN a/sql/table.h b/sql/table.h
---- a/sql/table.h      2010-11-01 08:43:53.000000000 +0000
-+++ b/sql/table.h      2010-11-01 08:52:40.000000000 +0000
-@@ -964,6 +964,7 @@
-   SCH_PROFILES,
-   SCH_REFERENTIAL_CONSTRAINTS,
-   SCH_PROCEDURES,
-+  SCH_QUERY_RESPONSE_TIME,
-   SCH_SCHEMATA,
-   SCH_SCHEMA_PRIVILEGES,
-   SCH_SESSION_STATUS,
-diff -ruN a/configure.in b/configure.in
---- a/configure.in     2010-12-07 19:19:42.000000000 +0300
-+++ b/configure.in     2010-12-07 19:21:39.000000000 +0300
-@@ -2687,7 +2687,16 @@
- AC_SUBST(readline_link)
- AC_SUBST(readline_h_ln_cmd)
-+AC_ARG_WITH(response_time_distribution,
-+    AC_HELP_STRING([--without-response_time_distribution],[Disable response_time_distribution feature.]),
-+    [with_response_time_distribution=$withval],
-+    [with_response_time_distribution=yes]
-+)
-+if test "$with_response_time_distribution" = "yes"
-+then
-+  AC_DEFINE([HAVE_RESPONSE_TIME_DISTRIBUTION], [1], [If we want to have response_time_distribution])
-+fi
- # Include man pages, if desired, adapted to the configured parts.
- if test X"$with_man" = Xyes
diff --git a/mysql-show_patches.patch b/mysql-show_patches.patch
deleted file mode 100644 (file)
index 17b8458..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-# name       : show_patches.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- /dev/null
-+++ b/patch_info/show_patches.info
-@@ -0,0 +1,9 @@
-+File=show_patches.patch
-+Name=SHOW PATCHES
-+Version=1.0
-+Author=Jeremy Cole
-+License=N/A
-+Comment=
-+Changelog
-+2010-01
-+Ported to 5.1.42
---- a/sql/Makefile.am
-+++ b/sql/Makefile.am
-@@ -145,7 +145,7 @@
-                       @DEFS@
- BUILT_MAINT_SRC =     sql_yacc.cc sql_yacc.h
--BUILT_SOURCES =               $(BUILT_MAINT_SRC) lex_hash.h link_sources
-+BUILT_SOURCES =               $(BUILT_MAINT_SRC) lex_hash.h patch_info.h link_sources
- EXTRA_DIST =          udf_example.c udf_example.def $(BUILT_MAINT_SRC) \
-                       nt_servc.cc nt_servc.h \
-                       message.mc  message.h message.rc MSG00001.bin \
-@@ -182,6 +182,9 @@
- udf_example_la_SOURCES= udf_example.c
- udf_example_la_LDFLAGS= -module -rpath $(pkglibdir)
-+patch_info.h: patch_info.h.pl
-+      $(PERL) $< > $@
-+
- # We might have some stuff not built in this build, but that we want to install
- install-exec-hook:
-       $(mkinstalldirs) $(DESTDIR)$(libexecdir) $(DESTDIR)$(pkglibdir)
---- a/sql/lex.h
-+++ b/sql/lex.h
-@@ -395,6 +395,7 @@
-   { "PARTITIONING",     SYM(PARTITIONING_SYM)},
-   { "PARTITIONS",       SYM(PARTITIONS_SYM)},
-   { "PASSWORD",               SYM(PASSWORD)},
-+  { "PATCHES",                SYM(PATCHES)},
-   { "PHASE",            SYM(PHASE_SYM)},
-   { "PLUGIN",           SYM(PLUGIN_SYM)},
-   { "PLUGINS",          SYM(PLUGINS_SYM)},
---- a/sql/mysql_priv.h
-+++ b/sql/mysql_priv.h
-@@ -1362,6 +1362,7 @@
- int mysqld_show_status(THD *thd);
- int mysqld_show_variables(THD *thd,const char *wild);
- bool mysqld_show_storage_engines(THD *thd);
-+bool mysqld_show_patches(THD *thd);
- bool mysqld_show_authors(THD *thd);
- bool mysqld_show_contributors(THD *thd);
- bool mysqld_show_privileges(THD *thd);
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -3218,6 +3218,7 @@
-   {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
-   {"show_new_master",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
-   {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
-+  {"show_patches",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PATCHES]), SHOW_LONG_STATUS},
-   {"show_plugins",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
-   {"show_privileges",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]), SHOW_LONG_STATUS},
- #ifndef DBUG_OFF
---- /dev/null
-+++ b/sql/patch_info.h.pl
-@@ -0,0 +1,65 @@
-+use strict;
-+
-+my $patch_info_path = '../patch_info';
-+my $file = '';
-+my $output = '';
-+
-+
-+if (opendir(PATCH_DIR, $patch_info_path))
-+{
-+      while ((my $file = readdir(PATCH_DIR)))
-+      {
-+              open(PATCH_FILE, "<$patch_info_path/$file") || die("Unable to open $patch_info_path/$file ($!)");
-+              my %fields;
-+      
-+              if ($file =~ /^\./)
-+              {
-+                      next;
-+              }       
-+      
-+              while (<PATCH_FILE>)
-+              {
-+                      chomp;
-+      
-+                      my ($key, $value) = split(/\s*=\s*/);
-+                      $fields{lc($key)} = $value;
-+              }
-+      
-+              $output .= "{\"$fields{'file'}\", \"$fields{'name'}\", \"$fields{'version'}\", \"$fields{'author'}\", \"$fields{'license'}\",\"$fields{'comment'}\"},\n"
-+      }
-+}     
-+
-+print <<HEADER;
-+
-+/* Copyright (C) 2002-2006 MySQL AB
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+#ifdef USE_PRAGMA_INTERFACE
-+#pragma interface                     /* gcc class implementation */
-+#endif
-+
-+struct patch {
-+      const char *file;
-+      const char *name;
-+      const char *version;
-+      const char *author;
-+      const char *license;
-+      const char *comment;
-+}patches[] = {
-+$output
-+{NULL, NULL, NULL, NULL, NULL, NULL}
-+};    
-+
-+HEADER
---- a/sql/sp_head.cc
-+++ b/sql/sp_head.cc
-@@ -229,6 +229,7 @@
-   case SQLCOM_SHOW_MASTER_STAT:
-   case SQLCOM_SHOW_NEW_MASTER:
-   case SQLCOM_SHOW_OPEN_TABLES:
-+  case SQLCOM_SHOW_PATCHES:
-   case SQLCOM_SHOW_PRIVILEGES:
-   case SQLCOM_SHOW_PROCESSLIST:
-   case SQLCOM_SHOW_PROC_CODE:
---- a/sql/sql_lex.h
-+++ b/sql/sql_lex.h
-@@ -120,6 +120,7 @@
-   SQLCOM_SHOW_CREATE_TRIGGER,
-   SQLCOM_ALTER_DB_UPGRADE,
-   SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
-+  SQLCOM_SHOW_PATCHES,
-   /*
-     When a command is added here, be sure it's also added in mysqld.cc
---- a/sql/sql_parse.cc
-+++ b/sql/sql_parse.cc
-@@ -3496,6 +3496,9 @@
-   case SQLCOM_SHOW_CONTRIBUTORS:
-     res= mysqld_show_contributors(thd);
-     break;
-+  case SQLCOM_SHOW_PATCHES:
-+    res= mysqld_show_patches(thd);
-+    break;
-   case SQLCOM_SHOW_PRIVILEGES:
-     res= mysqld_show_privileges(thd);
-     break;
---- a/sql/sql_prepare.cc
-+++ b/sql/sql_prepare.cc
-@@ -1950,6 +1950,7 @@
-     */
-   case SQLCOM_SHOW_PROCESSLIST:
-   case SQLCOM_SHOW_STORAGE_ENGINES:
-+  case SQLCOM_SHOW_PATCHES:
-   case SQLCOM_SHOW_PRIVILEGES:
-   case SQLCOM_SHOW_COLUMN_TYPES:
-   case SQLCOM_SHOW_ENGINE_LOGS:
---- a/sql/sql_show.cc
-+++ b/sql/sql_show.cc
-@@ -23,6 +23,7 @@
- #include "sp.h"
- #include "sp_head.h"
- #include "sql_trigger.h"
-+#include "patch_info.h"
- #include "authors.h"
- #include "contributors.h"
- #ifdef HAVE_EVENT_SCHEDULER
-@@ -7313,3 +7314,42 @@
-     status and client connection will be closed.
-   */
- }
-+
-+/***************************************************************************
-+** List patches built into this release
-+***************************************************************************/
-+
-+bool mysqld_show_patches(THD *thd)
-+{
-+  List<Item> field_list;
-+  int i = 0;
-+  Protocol *protocol= thd->protocol;
-+  DBUG_ENTER("mysqld_show_patches");
-+
-+  field_list.push_back(new Item_empty_string("File", 255));
-+  field_list.push_back(new Item_empty_string("Name", 50));
-+  field_list.push_back(new Item_empty_string("Version", 10));
-+  field_list.push_back(new Item_empty_string("Author", 50));
-+  field_list.push_back(new Item_empty_string("License", 50));
-+  field_list.push_back(new Item_empty_string("Comment", 32));
-+
-+  if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+    DBUG_RETURN(TRUE);
-+
-+  for (i = 0; patches[i].file; i++)
-+  {
-+    protocol->prepare_for_resend();
-+    protocol->store(patches[i].file, system_charset_info);
-+    protocol->store(patches[i].name, system_charset_info);
-+    protocol->store(patches[i].version, system_charset_info);
-+    protocol->store(patches[i].author, system_charset_info);
-+    protocol->store(patches[i].license, system_charset_info);
-+    protocol->store(patches[i].comment, system_charset_info);
-+
-+    if (protocol->write())
-+      DBUG_RETURN(TRUE);
-+  }
-+
-+  my_eof(thd);
-+  DBUG_RETURN(FALSE);
-+}
---- a/sql/sql_yacc.yy
-+++ b/sql/sql_yacc.yy
-@@ -1057,6 +1057,7 @@
- %token  PARTITIONS_SYM
- %token  PARTITION_SYM                 /* SQL-2003-R */
- %token  PASSWORD
-+%token  PATCHES
- %token  PHASE_SYM
- %token  PLUGINS_SYM
- %token  PLUGIN_SYM
-@@ -10217,6 +10218,11 @@
-             if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES))
-               MYSQL_YYABORT;
-           }
-+        | PATCHES
-+          {
-+            LEX *lex=Lex;
-+            lex->sql_command= SQLCOM_SHOW_PATCHES;
-+          }
-         | opt_storage ENGINES_SYM
-           {
-             LEX *lex=Lex;
-@@ -11830,6 +11836,7 @@
-         | PARTITIONING_SYM         {}
-         | PARTITIONS_SYM           {}
-         | PASSWORD                 {}
-+        | PATCHES                  {}
-         | PHASE_SYM                {}
-         | PLUGIN_SYM               {}
-         | PLUGINS_SYM              {}
diff --git a/mysql-show_slave_status_nolock.patch b/mysql-show_slave_status_nolock.patch
deleted file mode 100644 (file)
index 1651c8a..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-# name       : show_slave_status_nolock.patch
-# introduced : 12
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- /dev/null
-+++ b/patch_info/show_slave_status_nolock.patch
-@@ -0,0 +1,6 @@
-+File=show_slave_status_nolock.patch
-+Name= SHOW SLAVE STATUS NOLOCK
-+Version=1.0
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment= Implement SHOW SLAVE STATUS without lock (STOP SLAVE lock the same mutex what lock SHOW SLAVE STATUS)
---- a/sql/lex.h
-+++ b/sql/lex.h
-@@ -370,6 +370,7 @@
-   { "NONE",           SYM(NONE_SYM)},
-   { "NOT",            SYM(NOT_SYM)},
-   { "NO_WRITE_TO_BINLOG",  SYM(NO_WRITE_TO_BINLOG)},
-+  { "NOLOCK",           SYM(NOLOCK_SYM)},
-   { "NULL",           SYM(NULL_SYM)},
-   { "NUMERIC",                SYM(NUMERIC_SYM)},
-   { "NVARCHAR",               SYM(NVARCHAR_SYM)},
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -3278,6 +3278,7 @@
-   {"show_profiles",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILES]), SHOW_LONG_STATUS},
-   {"show_slave_hosts",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
-   {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
-+  {"show_slave_status_nolock", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_NOLOCK_STAT]), SHOW_LONG_STATUS},
-   {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
-   {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
-   {"show_table_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS},
---- a/sql/sql_lex.h
-+++ b/sql/sql_lex.h
-@@ -121,7 +121,8 @@
-   SQLCOM_ALTER_DB_UPGRADE, SQLCOM_SHOW_TEMPORARY_TABLES,
-   SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
-   SQLCOM_SHOW_PATCHES,
--
-+  /* SHOW SLAVE STATUS NOLOCK */
-+  SQLCOM_SHOW_SLAVE_NOLOCK_STAT,
-   /*
-     When a command is added here, be sure it's also added in mysqld.cc
-     in "struct show_var_st status_vars[]= {" ...
---- a/sql/sql_parse.cc
-+++ b/sql/sql_parse.cc
-@@ -330,6 +330,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;
-+  sql_command_flags[SQLCOM_SHOW_SLAVE_NOLOCK_STAT]=  CF_STATUS_COMMAND;
-   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;
-@@ -2596,12 +2597,17 @@
-     pthread_mutex_unlock(&LOCK_active_mi);
-     break;
-   }
-+  case SQLCOM_SHOW_SLAVE_NOLOCK_STAT:
-   case SQLCOM_SHOW_SLAVE_STAT:
-   {
-     /* Accept one of two privileges */
-     if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
-       goto error;
--    pthread_mutex_lock(&LOCK_active_mi);
-+    bool do_lock=SQLCOM_SHOW_SLAVE_NOLOCK_STAT != lex->sql_command;
-+    if(do_lock)
-+    {
-+      pthread_mutex_lock(&LOCK_active_mi);
-+    }
-     if (active_mi != NULL)
-     {
-       res = show_master_info(thd, active_mi);
-@@ -2612,7 +2618,19 @@
-                    WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO));
-       my_ok(thd);
-     }
--    pthread_mutex_unlock(&LOCK_active_mi);
-+    if(do_lock)
-+    {
-+      pthread_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:
---- a/sql/sql_yacc.yy
-+++ b/sql/sql_yacc.yy
-@@ -1175,6 +1175,7 @@
- %token  STARTS_SYM
- %token  START_SYM                     /* SQL-2003-R */
- %token  STATUS_SYM
-+%token  NOLOCK_SYM                    /* SHOW SLAVE STATUS NOLOCK */
- %token  STDDEV_SAMP_SYM               /* SQL-2003-N */
- %token  STD_SYM
- %token  STOP_SYM
-@@ -10387,6 +10388,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;
-+          }
-         | CLIENT_STATS_SYM wild_and_where 
-           {
-            LEX *lex= Lex;
---- /dev/null
-+++ b/mysql-test/t/percona_show_slave_status_nolock.test
-@@ -0,0 +1,88 @@
-+--source include/master-slave.inc
-+--source include/have_debug_sync.inc
-+--source include/have_binlog_format_statement.inc
-+
-+--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";
-+SET GLOBAL DEBUG="+d,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;
-+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,68 @@
-+include/master-slave.inc
-+[connection master]
-+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);
-+[slave]
-+SET DEBUG_SYNC='RESET';
-+SET GLOBAL DEBUG="+d,after_mysql_insert";
-+SET GLOBAL DEBUG="+d,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;
-+[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
-+[master]
-+SET DEBUG_SYNC='RESET';
-+[slave]
-+SET GLOBAL DEBUG='';
-+SET DEBUG_SYNC='RESET';
-+DROP TABLE t;
-+include/rpl_end.inc
---- /dev/null
-+++ 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 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;
-+--echo [slave]
-+SET DEBUG_SYNC='now SIGNAL signal.empty';
-+
-+connection slave_nolock;
-+--echo [slave_nolock]
-+send SHOW SLAVE STATUS NOLOCK;
-+
-+connection slave;
-+--let $condition= 'SHOW SLAVE STATUS NOLOCK'
-+--source include/wait_show_condition.inc
-+
-+--disable_warnings
-+SET DEBUG_SYNC='now WAIT_FOR signal.after_show_slave_status TIMEOUT 1';
-+--enable_warnings
-+
-+--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;
-+--echo [slave]
-+SET DEBUG_SYNC='now SIGNAL signal.continue';
-+
-+connection slave_lock;
-+--disable_result_log
-+reap;
-+--enable_result_log
-+
-+connection slave_nolock;
-+--disable_result_log
-+reap;
-+--enable_result_log
-+
-+connection slave;
-+--echo [slave]
-+SET DEBUG_SYNC='now SIGNAL signal.empty';
-+--enable_result_log
-+--echo
---- a/sql/slave.cc
-+++ b/sql/slave.cc
-@@ -1641,6 +1641,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();
-@@ -1649,9 +1650,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.
-     */
--    pthread_mutex_lock(&mi->run_lock);
-+    if (do_lock)
-+    {
-+      pthread_mutex_lock(&mi->run_lock);
-+    }
-     protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin);
--    pthread_mutex_unlock(&mi->run_lock);
-+    if (do_lock)
-+    {
-+      pthread_mutex_unlock(&mi->run_lock);
-+    }
-     pthread_mutex_lock(&mi->data_lock);
-     pthread_mutex_lock(&mi->rli.data_lock);
diff --git a/mysql-show_temp_51.patch b/mysql-show_temp_51.patch
deleted file mode 100644 (file)
index 9fb506f..0000000
+++ /dev/null
@@ -1,622 +0,0 @@
-# name       : show_temp_51.patch
-# introduced : 11 or before
-# maintainer : Yasufumi
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -3259,6 +3259,7 @@
-   {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
-   {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
-   {"show_thread_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_THREAD_STATS]), SHOW_LONG_STATUS},
-+  {"show_temporary_tables",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TEMPORARY_TABLES]), SHOW_LONG_STATUS},
-   {"show_triggers",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
-   {"show_user_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS},
-   {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
---- a/sql/sql_lex.h
-+++ b/sql/sql_lex.h
-@@ -118,7 +118,7 @@
-   SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT,
-   SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_EVENTS,
-   SQLCOM_SHOW_CREATE_TRIGGER,
--  SQLCOM_ALTER_DB_UPGRADE,
-+  SQLCOM_ALTER_DB_UPGRADE, SQLCOM_SHOW_TEMPORARY_TABLES,
-   SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
-   SQLCOM_SHOW_PATCHES,
---- a/sql/sql_parse.cc
-+++ b/sql/sql_parse.cc
-@@ -342,6 +342,9 @@
-    sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
-                                                  CF_SHOW_TABLE_COMMAND |
-                                                  CF_REEXECUTION_FRAGILE);
-+   sql_command_flags[SQLCOM_SHOW_TEMPORARY_TABLES]=       (CF_STATUS_COMMAND |
-+                                                 CF_SHOW_TABLE_COMMAND |
-+                                                 CF_REEXECUTION_FRAGILE);
-   sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
-                                                 CF_SHOW_TABLE_COMMAND |
-                                                 CF_REEXECUTION_FRAGILE);
-@@ -1877,6 +1880,8 @@
-   case SCH_TABLE_NAMES:
-   case SCH_TABLES:
-+  case SCH_TEMPORARY_TABLES:
-+  case SCH_GLOBAL_TEMPORARY_TABLES:
-   case SCH_VIEWS:
-   case SCH_TRIGGERS:
-   case SCH_EVENTS:
-@@ -2376,6 +2381,7 @@
-   }
-   case SQLCOM_SHOW_DATABASES:
-   case SQLCOM_SHOW_TABLES:
-+  case SQLCOM_SHOW_TEMPORARY_TABLES:
-   case SQLCOM_SHOW_TRIGGERS:
-   case SQLCOM_SHOW_TABLE_STATUS:
-   case SQLCOM_SHOW_OPEN_TABLES:
-@@ -5529,6 +5535,8 @@
-   case SCH_TABLE_NAMES:
-   case SCH_TABLES:
-+  case SCH_TEMPORARY_TABLES:
-+  case SCH_GLOBAL_TEMPORARY_TABLES:
-   case SCH_VIEWS:
-   case SCH_TRIGGERS:
-   case SCH_EVENTS:
---- a/sql/sql_show.cc
-+++ b/sql/sql_show.cc
-@@ -3031,6 +3031,7 @@
-     break;
-   case SQLCOM_SHOW_TABLES:
-   case SQLCOM_SHOW_TABLE_STATUS:
-+  case SQLCOM_SHOW_TEMPORARY_TABLES:
-   case SQLCOM_SHOW_TRIGGERS:
-   case SQLCOM_SHOW_EVENTS:
-     thd->make_lex_string(&lookup_field_values->db_value, 
-@@ -3607,6 +3608,231 @@
-   return (uint) OPEN_FULL_TABLE;
- }
-+/**
-+  @brief          Change I_S table item list for SHOW [GLOBAL] TEMPORARY TABLES [FROM/IN db]
-+
-+  @param[in]      thd                      thread handler
-+  @param[in]      schema_table             I_S table
-+
-+  @return         Operation status
-+    @retval       0                        success
-+    @retval       1                        error
-+*/
-+int make_temporary_tables_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+  char tmp[128];
-+  String buffer(tmp,sizeof(tmp), thd->charset());
-+  LEX *lex= thd->lex;
-+  Name_resolution_context *context= &lex->select_lex.context;
-+
-+  if (thd->lex->option_type == OPT_GLOBAL) {
-+    ST_FIELD_INFO *field_info= &schema_table->fields_info[0];
-+    Item_field *field= new Item_field(context, NullS, NullS, field_info->field_name);
-+    if (add_item_to_list(thd, field))
-+      return 1;
-+    field->set_name(field_info->old_name, strlen(field_info->old_name), system_charset_info);
-+  }
-+
-+  ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
-+  buffer.length(0);
-+  buffer.append(field_info->old_name);
-+  buffer.append(lex->select_lex.db);
-+
-+  if (lex->wild && lex->wild->ptr())
-+  {
-+    buffer.append(STRING_WITH_LEN(" ("));
-+    buffer.append(lex->wild->ptr());
-+    buffer.append(')');
-+  }
-+
-+  Item_field *field= new Item_field(context, NullS, NullS, field_info->field_name);    
-+  if (add_item_to_list(thd, field))
-+    return 1;
-+
-+  field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
-+  return 0;
-+}
-+
-+/**
-+  @brief          Fill records for temporary tables by reading info from table object
-+
-+  @param[in]      thd                      thread handler
-+  @param[in]      table                    I_S table
-+  @param[in]      tmp_table                temporary table
-+  @param[in]      db                       database name
-+
-+  @return         Operation status
-+    @retval       0                        success
-+    @retval       1                        error
-+*/
-+
-+static int store_temporary_table_record(THD *thd, TABLE *table, TABLE *tmp_table, const char *db, bool table_name_only)
-+{
-+  CHARSET_INFO *cs= system_charset_info;
-+  DBUG_ENTER("store_temporary_table_record");
-+
-+  if (db && my_strcasecmp(cs, db, tmp_table->s->db.str))
-+    DBUG_RETURN(0);
-+
-+  restore_record(table, s->default_values);
-+
-+  //session_id
-+  table->field[0]->store((longlong) thd->thread_id, TRUE);
-+
-+  //database
-+  table->field[1]->store(tmp_table->s->db.str, tmp_table->s->db.length, cs);
-+
-+  //table
-+  table->field[2]->store(tmp_table->s->table_name.str, tmp_table->s->table_name.length, cs);
-+
-+  if (table_name_only)
-+    DBUG_RETURN(schema_table_store_record(thd, table));
-+
-+  //engine
-+  handler *handle= tmp_table->file;
-+  char *engineType = (char *)(handle ? handle->table_type() : "UNKNOWN");
-+  table->field[3]->store(engineType, strlen(engineType), cs);
-+
-+  //name
-+  if (tmp_table->s->path.str) {
-+    char *p=strstr(tmp_table->s->path.str, "#sql");
-+    int len=tmp_table->s->path.length-(p-tmp_table->s->path.str);
-+    table->field[4]->store(p, min(FN_REFLEN, len), cs);
-+  }
-+
-+  // file stats
-+  handler *file= tmp_table->file;
-+
-+  if (file) {
-+
-+    MYSQL_TIME time;
-+
-+    /**
-+        TODO: InnoDB stat(file) checks file on short names within data dictionary
-+        rather than using full path, because of that, temp files created in
-+        TMPDIR will not have access/create time as it will not find the file
-+
-+        The fix is to patch InnoDB to use full path
-+    */
-+    file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK);
-+
-+    table->field[5]->store((longlong) file->stats.records, TRUE);
-+    table->field[5]->set_notnull();
-+
-+    table->field[6]->store((longlong) file->stats.mean_rec_length, TRUE);
-+    table->field[7]->store((longlong) file->stats.data_file_length, TRUE);
-+    table->field[8]->store((longlong) file->stats.index_file_length, TRUE);
-+    if (file->stats.create_time)
-+    {
-+      thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+                                                (my_time_t) file->stats.create_time);
-+      table->field[9]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+      table->field[9]->set_notnull();
-+    }
-+    if (file->stats.update_time)
-+    {
-+      thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+                                                (my_time_t) file->stats.update_time);
-+      table->field[10]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+      table->field[10]->set_notnull();
-+    }
-+  }
-+
-+  DBUG_RETURN(schema_table_store_record(thd, table));
-+}
-+
-+/**
-+  @brief          Fill I_S tables with global temporary tables
-+
-+  @param[in]      thd                      thread handler
-+  @param[in]      tables                   I_S table
-+  @param[in]      cond                     'WHERE' condition
-+
-+  @return         Operation status
-+    @retval       0                        success
-+    @retval       1                        error
-+*/
-+
-+static int fill_global_temporary_tables(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+  DBUG_ENTER("fill_global_temporary_tables");
-+
-+  pthread_mutex_lock(&LOCK_thread_count);
-+
-+  bool table_names_only= (thd->lex->sql_command == SQLCOM_SHOW_TEMPORARY_TABLES) ? 1 : 0;
-+  I_List_iterator<THD> it(threads);
-+  THD *thd_item;
-+  TABLE *tmp;
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+  Security_context *sctx= thd->security_ctx;
-+  uint db_access;
-+#endif
-+ 
-+  while ((thd_item=it++)) {
-+    pthread_mutex_lock(&thd_item->LOCK_temporary_tables);
-+    for (tmp=thd_item->temporary_tables; tmp; tmp=tmp->next) {
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+      if (test_all_bits(sctx->master_access, DB_ACLS))
-+        db_access=DB_ACLS;
-+      else
-+        db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, tmp->s->db.str, 0) | sctx->master_access);
-+
-+      if (!(db_access & DB_ACLS) && check_grant_db(thd,tmp->s->db.str)) {
-+        //no access for temp tables within this db for user
-+        continue;
-+      }
-+#endif
-+
-+      THD *t= tmp->in_use;
-+      tmp->in_use= thd;
-+
-+      if (store_temporary_table_record(thd_item, tables->table, tmp, thd->lex->select_lex.db, table_names_only)) {
-+        tmp->in_use= t;
-+        pthread_mutex_unlock(&thd_item->LOCK_temporary_tables);
-+        pthread_mutex_unlock(&LOCK_thread_count); 
-+        DBUG_RETURN(1);
-+      }
-+
-+      tmp->in_use= t;
-+    }
-+    pthread_mutex_unlock(&thd_item->LOCK_temporary_tables);
-+  }
-+
-+  pthread_mutex_unlock(&LOCK_thread_count); 
-+  DBUG_RETURN(0);
-+}
-+
-+/**
-+  @brief          Fill I_S tables with session temporary tables
-+
-+  @param[in]      thd                      thread handler
-+  @param[in]      tables                   I_S table
-+  @param[in]      cond                     'WHERE' condition
-+
-+  @return         Operation status
-+    @retval       0                        success
-+    @retval       1                        error
-+*/
-+
-+int fill_temporary_tables(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+  DBUG_ENTER("fill_temporary_tables");
-+
-+  if (thd->lex->option_type == OPT_GLOBAL)
-+    DBUG_RETURN(fill_global_temporary_tables(thd, tables, cond));
-+
-+  bool table_names_only= (thd->lex->sql_command == SQLCOM_SHOW_TEMPORARY_TABLES) ? 1 : 0;
-+  TABLE *tmp;
-+
-+  for (tmp=thd->temporary_tables; tmp; tmp=tmp->next) {
-+    if (store_temporary_table_record(thd, tables->table, tmp, thd->lex->select_lex.db, table_names_only)) {
-+      DBUG_RETURN(1);
-+    }
-+  }
-+  DBUG_RETURN(0);
-+}
- /**
-   @brief          Fill I_S table with data from FRM file only
-@@ -6658,6 +6884,25 @@
-   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
- };
-+ST_FIELD_INFO temporary_table_fields_info[]=
-+{
-+  {"SESSION_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Session", SKIP_OPEN_TABLE},
-+  {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db", SKIP_OPEN_TABLE},
-+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Temp_tables_in_", SKIP_OPEN_TABLE},
-+  {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Engine", OPEN_FRM_ONLY},
-+  {"NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN_TABLE},
-+  {"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+   MY_I_S_UNSIGNED, "Rows", OPEN_FULL_TABLE},
-+  {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 
-+   MY_I_S_UNSIGNED, "Avg Row", OPEN_FULL_TABLE},
-+  {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 
-+   MY_I_S_UNSIGNED, "Data Length", OPEN_FULL_TABLE},
-+  {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 
-+   MY_I_S_UNSIGNED, "Index Size", OPEN_FULL_TABLE},
-+  {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create Time", OPEN_FULL_TABLE},
-+  {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update Time", OPEN_FULL_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
- ST_FIELD_INFO columns_fields_info[]=
- {
-@@ -7318,6 +7563,9 @@
-    fill_schema_files, 0, 0, -1, -1, 0, 0},
-   {"GLOBAL_STATUS", variables_fields_info, create_schema_table,
-    fill_status, make_old_format, 0, 0, -1, 0, 0},
-+  {"GLOBAL_TEMPORARY_TABLES", temporary_table_fields_info, create_schema_table, 
-+   fill_global_temporary_tables, make_temporary_tables_old_format, 0, 2, 3, 0,
-+   OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
-   {"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,
-@@ -7361,6 +7609,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},
-+  {"TEMPORARY_TABLES", temporary_table_fields_info, create_schema_table,
-+   fill_temporary_tables, make_temporary_tables_old_format, 0, 2, 3, 0,
-+   OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
-   {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
-     fill_schema_table_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"THREAD_STATISTICS", thread_stats_fields_info, create_schema_table,
---- a/sql/sql_yacc.yy
-+++ b/sql/sql_yacc.yy
-@@ -10116,6 +10116,15 @@
-              if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES))
-                MYSQL_YYABORT;
-            }
-+         | opt_var_type TEMPORARY TABLES opt_db
-+           {
-+             LEX *lex= Lex;
-+             lex->sql_command= SQLCOM_SHOW_TEMPORARY_TABLES;
-+             lex->option_type= $1;
-+             lex->select_lex.db= $4;
-+             if (prepare_schema_table(YYTHD, lex, 0, SCH_TEMPORARY_TABLES))
-+               MYSQL_YYABORT;
-+           }
-          | opt_full TRIGGERS_SYM opt_db wild_and_where
-            {
-              LEX *lex= Lex;
---- a/sql/table.h
-+++ b/sql/table.h
-@@ -954,6 +954,7 @@
-   SCH_EVENTS,
-   SCH_FILES,
-   SCH_GLOBAL_STATUS,
-+  SCH_GLOBAL_TEMPORARY_TABLES,
-   SCH_GLOBAL_VARIABLES,
-   SCH_KEY_COLUMN_USAGE,
-   SCH_OPEN_TABLES,
-@@ -973,6 +974,7 @@
-   SCH_TABLE_CONSTRAINTS,
-   SCH_TABLE_NAMES,
-   SCH_TABLE_PRIVILEGES,
-+  SCH_TEMPORARY_TABLES,
-   SCH_TABLE_STATS,
-   SCH_THREAD_STATS,
-   SCH_TRIGGERS,
---- a/sql/sql_base.cc
-+++ b/sql/sql_base.cc
-@@ -1459,12 +1459,16 @@
-       (thd->current_stmt_binlog_row_based && thd->variables.binlog_format == BINLOG_FORMAT_ROW))
-   {
-     TABLE *tmp_next;
-+
-+    pthread_mutex_lock(&thd->LOCK_temporary_tables);
-     for (table= thd->temporary_tables; table; table= tmp_next)
-     {
-       tmp_next= table->next;
-       close_temporary(table, 1, 1);
-     }
-     thd->temporary_tables= 0;
-+    pthread_mutex_unlock(&thd->LOCK_temporary_tables);
-+
-     return;
-   }
-@@ -1477,6 +1481,8 @@
-   memcpy(buf, stub, stub_len);
-+  pthread_mutex_lock(&thd->LOCK_temporary_tables);
-+
-   /*
-     Insertion sort of temp tables by pseudo_thread_id to build ordered list
-     of sublists of equal pseudo_thread_id
-@@ -1581,6 +1587,7 @@
-   if (!was_quote_show)
-     thd->options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
-   thd->temporary_tables=0;
-+  pthread_mutex_unlock(&thd->LOCK_temporary_tables);
- }
- /*
-@@ -1883,6 +1890,8 @@
-   if (table->child_l || table->parent)
-     detach_merge_children(table, TRUE);
-+  pthread_mutex_lock(&thd->LOCK_temporary_tables);
-+
-   if (table->prev)
-   {
-     table->prev->next= table->next;
-@@ -1909,6 +1918,9 @@
-     slave_open_temp_tables--;
-   }
-   close_temporary(table, free_share, delete_table);
-+
-+  pthread_mutex_unlock(&thd->LOCK_temporary_tables);
-+
-   DBUG_VOID_RETURN;
- }
-@@ -5626,6 +5638,7 @@
-   if (link_in_list)
-   {
-     /* growing temp list at the head */
-+    pthread_mutex_lock(&thd->LOCK_temporary_tables);
-     tmp_table->next= thd->temporary_tables;
-     if (tmp_table->next)
-       tmp_table->next->prev= tmp_table;
-@@ -5633,6 +5646,7 @@
-     thd->temporary_tables->prev= 0;
-     if (thd->slave_thread)
-       slave_open_temp_tables++;
-+    pthread_mutex_unlock(&thd->LOCK_temporary_tables);
-   }
-   tmp_table->pos_in_table_list= 0;
-   DBUG_PRINT("tmptable", ("opened table: '%s'.'%s' 0x%lx", tmp_table->s->db.str,
---- a/sql/sql_class.cc
-+++ b/sql/sql_class.cc
-@@ -733,6 +733,7 @@
-   active_vio = 0;
- #endif
-   pthread_mutex_init(&LOCK_thd_data, MY_MUTEX_INIT_FAST);
-+  pthread_mutex_init(&LOCK_temporary_tables, MY_MUTEX_INIT_FAST);
-   /* Variables with default values */
-   proc_info="login";
-@@ -1145,6 +1146,7 @@
- #endif
-   mysys_var=0;                                        // Safety (shouldn't be needed)
-   pthread_mutex_destroy(&LOCK_thd_data);
-+  pthread_mutex_destroy(&LOCK_temporary_tables);
- #ifndef DBUG_OFF
-   dbug_sentry= THD_SENTRY_GONE;
- #endif  
---- a/sql/sql_class.h
-+++ b/sql/sql_class.h
-@@ -899,6 +899,11 @@
-   */
-   TABLE *temporary_tables;
-   /**
-+     Protects temporary_tables.
-+  */
-+  pthread_mutex_t LOCK_temporary_tables;
-+
-+  /**
-     List of tables that were opened with HANDLER OPEN and are
-     still in use by this thread.
-   */
---- /dev/null
-+++ b/mysql-test/r/percona_show_temp_tables.result
-@@ -0,0 +1,58 @@
-+drop table if exists t1,t2,t3;
-+drop database if exists showtemp;
-+create database if not exists showtemp;
-+use test;
-+create temporary table t1(id int);
-+create temporary table t2(id int);
-+create temporary table showtemp.t3(id int);
-+insert into t1 values(10),(20),(30),(40);
-+insert into showtemp.t3 values(999);
-+show temporary tables;
-+Temp_tables_in_test
-+t2
-+t1
-+show temporary tables from test;
-+Temp_tables_in_test
-+t2
-+t1
-+show temporary tables in showtemp;
-+Temp_tables_in_showtemp
-+t3
-+select table_schema, table_name, engine, table_rows from Information_schema.temporary_tables;
-+table_schema  table_name      engine  table_rows
-+showtemp      t3      MyISAM  1
-+test  t2      MyISAM  0
-+test  t1      MyISAM  4
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
-+table_schema  table_name      engine  table_rows
-+showtemp      t3      MyISAM  1
-+test  t2      MyISAM  0
-+test  t1      MyISAM  4
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables where table_schema='showtemp';
-+table_schema  table_name      engine  table_rows
-+showtemp      t3      MyISAM  1
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables where table_schema='temp';
-+table_schema  table_name      engine  table_rows
-+drop table if exists showtemp.t2;
-+create temporary table t1(id int);
-+create temporary table showtemp.t2(id int);
-+show temporary tables;
-+Temp_tables_in_test
-+t1
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
-+table_schema  table_name      engine  table_rows
-+showtemp      t2      MyISAM  0
-+test  t1      MyISAM  0
-+showtemp      t3      MyISAM  1
-+test  t2      MyISAM  0
-+test  t1      MyISAM  4
-+drop table showtemp.t2;
-+drop table t1;
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
-+table_schema  table_name      engine  table_rows
-+showtemp      t3      MyISAM  1
-+test  t2      MyISAM  0
-+test  t1      MyISAM  4
-+drop table t1, t2;
-+drop table showtemp.t3;
-+drop database showtemp;
---- /dev/null
-+++ b/mysql-test/t/percona_show_temp_tables.test
-@@ -0,0 +1,65 @@
-+# Uses GRANT commands that usually disabled in embedded server
-+-- source include/not_embedded.inc
-+
-+# Save the initial number of concurrent sessions
-+--source include/count_sessions.inc
-+
-+#
-+# Test of SHOW [GLOBAL] TEMPORARY TABLES [FROM/IN] DB and 
-+# Information_schema.temporary_tables and global_temporary_tables
-+#
-+
-+connect(stcon1,localhost,root,,test);
-+connect(stcon2,localhost,root,,test);
-+
-+connection stcon1;
-+
-+--disable_warnings
-+drop table if exists t1,t2,t3;
-+drop database if exists showtemp;
-+create database if not exists showtemp;
-+--enable_warnings
-+
-+use test;
-+create temporary table t1(id int);
-+create temporary table t2(id int);
-+create temporary table showtemp.t3(id int);
-+insert into t1 values(10),(20),(30),(40);
-+insert into showtemp.t3 values(999);
-+
-+show temporary tables;
-+# "Session" is not same value always. mysql-test cannot test it always.
-+#show global temporary tables;
-+show temporary tables from test;
-+show temporary tables in showtemp;
-+select table_schema, table_name, engine, table_rows from Information_schema.temporary_tables;
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables where table_schema='showtemp';
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables where table_schema='temp';
-+
-+connection stcon2;
-+
-+--disable_warnings
-+drop table if exists showtemp.t2;
-+--enable_warnings
-+create temporary table t1(id int);
-+create temporary table showtemp.t2(id int);
-+show temporary tables;
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
-+drop table showtemp.t2;
-+drop table t1;
-+
-+disconnect stcon2;
-+
-+connection stcon1;
-+select table_schema, table_name, engine, table_rows from Information_schema.global_temporary_tables;
-+
-+drop table t1, t2;
-+drop table showtemp.t3;
-+drop database showtemp;
-+
-+connection default;
-+disconnect stcon1;
-+
-+# Wait till all disconnects are completed
-+--source include/wait_until_count_sessions.inc
diff --git a/mysql-slow_extended.patch b/mysql-slow_extended.patch
deleted file mode 100644 (file)
index cdd802c..0000000
+++ /dev/null
@@ -1,3090 +0,0 @@
-# name       : slow_extended.patch
-# introduced : 11 or before
-# maintainer : Oleg
-#
-#!!! 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
-@@ -696,6 +696,17 @@
- /* Increments the row counter, see THD::row_count */
- void thd_inc_row_count(MYSQL_THD thd);
-+void increment_thd_innodb_stats(MYSQL_THD thd,
-+                    unsigned long long trx_id,
-+                    long io_reads,
-+                    long long io_read,
-+                    long io_reads_wait_timer,
-+                    long lock_que_wait_timer,
-+                    long que_wait_timer,
-+                    long page_access);
-+unsigned long thd_log_slow_verbosity(const MYSQL_THD thd);
-+int thd_opt_slow_log();
-+#define EXTENDED_SLOWLOG
- /**
-   Create a temporary file.
---- a/include/mysql/plugin.h.pp
-+++ b/include/mysql/plugin.h.pp
-@@ -122,6 +122,16 @@
- char *thd_security_context(void* thd, char *buffer, unsigned int length,
-                            unsigned int max_query_len);
- void thd_inc_row_count(void* thd);
-+void increment_thd_innodb_stats(void* thd,
-+                    unsigned long long trx_id,
-+                    long io_reads,
-+                    long long io_read,
-+                    long io_reads_wait_timer,
-+                    long lock_que_wait_timer,
-+                    long que_wait_timer,
-+                    long page_access);
-+unsigned long thd_log_slow_verbosity(const void* thd);
-+int thd_opt_slow_log();
- int mysql_tmpfile(const char *prefix);
- int thd_killed(const void* thd);
- unsigned long thd_get_thread_id(const void* thd);
---- /dev/null
-+++ b/patch_info/slow_extended.info
-@@ -0,0 +1,24 @@
-+File=slow_extended.patch
-+Name=Extended statistics in slow.log (not InnoDB part)
-+Version=1.3
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment=
-+Changelog
-+2008-11-26
-+YK: Fix inefficient determination of trx, Make not to call useless gettimeofday when don't use slow log. Make log_slow_queries dynamic (bool).
-+
-+2008-11-07
-+VT: Moved log_slow_rate_limit in SHOW VARIABLE into right place
-+
-+2008-11
-+Arjen Lentz: Fixups (backward compatibility) by Arjen Lentz <arjen@openquery.com.au>
-+
-+2010-07
-+1) Fix overflow of query time and lock time (Bug 600360) (slow_extended_fix_overflow.patch merged)
-+2) Control global slow feature merged (control_global_slow.patch merged)
-+3) Microseconds in slow query log merged (microseconds_in_slow_query_log.patch merged)
-+4) Now use_global_long_query_time and use_global_log_slow_control are synonims. Add value "all" for use_global_log_slow_control (contol-global_slow-2.patch merged)
-+5) Fix innodb_stats on replication (Bug 600684)
-+6) Change variable types (system/command-line)
-+
---- a/scripts/mysqldumpslow.sh
-+++ b/scripts/mysqldumpslow.sh
-@@ -102,8 +102,8 @@
-     s/^#? Time: \d{6}\s+\d+:\d+:\d+.*\n//;
-     my ($user,$host) = s/^#? User\@Host:\s+(\S+)\s+\@\s+(\S+).*\n// ? ($1,$2) : ('','');
--    s/^# Query_time: ([0-9.]+)\s+Lock_time: ([0-9.]+)\s+Rows_sent: ([0-9.]+).*\n//;
--    my ($t, $l, $r) = ($1, $2, $3);
-+    s/^# Query_time: (\d+(\.\d+)?)  Lock_time: (\d+(\.\d+)?)  Rows_sent: (\d+(\.\d+)?).*\n//;
-+    my ($t, $l, $r)= ($1, $3, $5);
-     $t -= $l unless $opt{l};
-     # remove fluff that mysqld writes to log when it (re)starts:
---- a/sql/event_scheduler.cc
-+++ b/sql/event_scheduler.cc
-@@ -196,6 +196,7 @@
-   thd->client_capabilities|= CLIENT_MULTI_RESULTS;
-   pthread_mutex_lock(&LOCK_thread_count);
-   thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
-+  thd->write_to_slow_log= TRUE;
-   pthread_mutex_unlock(&LOCK_thread_count);
-   /*
---- a/sql/filesort.cc
-+++ b/sql/filesort.cc
-@@ -192,6 +192,7 @@
-   {
-     status_var_increment(thd->status_var.filesort_scan_count);
-   }
-+  thd->query_plan_flags|= QPLAN_FILESORT;
- #ifdef CAN_TRUST_RANGE
-   if (select && select->quick && select->quick->records > 0L)
-   {
-@@ -257,6 +258,7 @@
-   }
-   else
-   {
-+    thd->query_plan_flags|= QPLAN_FILESORT_DISK;
-     if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
-     {
-       x_free(table_sort.buffpek);
-@@ -1205,6 +1207,7 @@
-   DBUG_ENTER("merge_buffers");
-   status_var_increment(current_thd->status_var.filesort_merge_passes);
-+  current_thd->query_plan_fsort_passes++;
-   if (param->not_killable)
-   {
-     killed= &not_killable;
---- a/sql/log.cc
-+++ b/sql/log.cc
-@@ -524,11 +524,13 @@
- */
- bool Log_to_csv_event_handler::
--  log_slow(THD *thd, time_t current_time, time_t query_start_arg,
-+  log_slow(THD *thd, ulonglong current_utime, time_t query_start_arg,
-            const char *user_host, uint user_host_len,
-            ulonglong query_utime, ulonglong lock_utime, bool is_command,
-            const char *sql_text, uint sql_text_len)
- {
-+  time_t current_time= my_time_possible_from_micro(current_utime);
-+
-   TABLE_LIST table_list;
-   TABLE *table;
-   bool result= TRUE;
-@@ -754,14 +756,14 @@
- /** Wrapper around MYSQL_LOG::write() for slow log. */
- bool Log_to_file_event_handler::
--  log_slow(THD *thd, time_t current_time, time_t query_start_arg,
-+  log_slow(THD *thd, ulonglong current_utime, time_t query_start_arg,
-            const char *user_host, uint user_host_len,
-            ulonglong query_utime, ulonglong lock_utime, bool is_command,
-            const char *sql_text, uint sql_text_len)
- {
-   Silence_log_table_errors error_handler;
-   thd->push_internal_handler(&error_handler);
--  bool retval= mysql_slow_log.write(thd, current_time, query_start_arg,
-+  bool retval= mysql_slow_log.write(thd, current_utime, query_start_arg,
-                                     user_host, user_host_len,
-                                     query_utime, lock_utime, is_command,
-                                     sql_text, sql_text_len);
-@@ -987,7 +989,7 @@
-     /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
-     user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
-                              sctx->priv_user ? sctx->priv_user : "", "[",
--                             sctx->user ? sctx->user : "", "] @ ",
-+                             sctx->user ? sctx->user : (thd->slave_thread ? "SQL_SLAVE" : ""), "] @ ",
-                              sctx->host ? sctx->host : "", " [",
-                              sctx->ip ? sctx->ip : "", "]", NullS) -
-                     user_host_buff);
-@@ -995,9 +997,23 @@
-     current_time= my_time_possible_from_micro(current_utime);
-     if (thd->start_utime)
-     {
-+      if(current_utime < thd->start_utime)
-+      {
-+        query_utime= 0;
-+      }
-+      else
-+      {
-       query_utime= (current_utime - thd->start_utime);
-+      }
-+      if(thd->utime_after_lock < thd->start_utime)
-+      {
-+        lock_utime= 0;
-+      }
-+      else
-+      {
-       lock_utime=  (thd->utime_after_lock - thd->start_utime);
-     }
-+    }
-     else
-     {
-       query_utime= lock_utime= 0;
-@@ -1011,7 +1027,7 @@
-     }
-     for (current_handler= slow_log_handler_list; *current_handler ;)
--      error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
-+      error= (*current_handler++)->log_slow(thd, current_utime, thd->start_time,
-                                             user_host_buff, user_host_len,
-                                             query_utime, lock_utime, is_command,
-                                             query, query_length) || error;
-@@ -2282,12 +2298,13 @@
-     TRUE - error occured
- */
--bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
-+bool MYSQL_QUERY_LOG::write(THD *thd, ulonglong current_utime,
-                             time_t query_start_arg, const char *user_host,
-                             uint user_host_len, ulonglong query_utime,
-                             ulonglong lock_utime, bool is_command,
-                             const char *sql_text, uint sql_text_len)
- {
-+  time_t current_time= my_time_possible_from_micro(current_utime);
-   bool error= 0;
-   DBUG_ENTER("MYSQL_QUERY_LOG::write");
-@@ -2309,17 +2326,28 @@
-     if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT))
-     {
--      if (current_time != last_time)
-+      if (opt_log_slow_timestamp_every || current_time != last_time)
-       {
-         last_time= current_time;
-         struct tm start;
-         localtime_r(&current_time, &start);
--
-+      if(opt_slow_query_log_microseconds_timestamp)
-+      {
-+        ulonglong microsecond = current_utime % (1000 * 1000);
-+        buff_len= snprintf(buff, sizeof buff,
-+          "# Time: %02d%02d%02d %2d:%02d:%02d.%010lld\n",
-+            start.tm_year % 100, start.tm_mon + 1,
-+          start.tm_mday, start.tm_hour,
-+          start.tm_min, start.tm_sec,microsecond);
-+      }
-+      else
-+      {
-         buff_len= my_snprintf(buff, sizeof buff,
-                               "# Time: %02d%02d%02d %2d:%02d:%02d\n",
-                               start.tm_year % 100, start.tm_mon + 1,
-                               start.tm_mday, start.tm_hour,
-                               start.tm_min, start.tm_sec);
-+      }
-         /* Note that my_b_write() assumes it knows the length for this */
-         if (my_b_write(&log_file, (uchar*) buff, buff_len))
-@@ -2337,12 +2365,64 @@
-     sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
-     sprintf(lock_time_buff,  "%.6f", ulonglong2double(lock_utime)/1000000.0);
-     if (my_b_printf(&log_file,
--                    "# Query_time: %s  Lock_time: %s"
--                    " Rows_sent: %lu  Rows_examined: %lu\n",
-+                    "# Thread_id: %lu  Schema: %s  Last_errno: %u  Killed: %u\n" \
-+                    "# Query_time: %s  Lock_time: %s  Rows_sent: %lu  Rows_examined: %lu  Rows_affected: %lu  Rows_read: %lu\n"
-+                    "# Bytes_sent: %lu  Tmp_tables: %lu  Tmp_disk_tables: %lu  Tmp_table_sizes: %lu\n",
-+                    (ulong) thd->thread_id, (thd->db ? thd->db : ""),
-+                    thd->last_errno, (uint) thd->killed,
-                     query_time_buff, lock_time_buff,
-                     (ulong) thd->sent_row_count,
--                    (ulong) thd->examined_row_count) == (uint) -1)
-+                    (ulong) thd->examined_row_count,
-+                    ((long) thd->row_count_func > 0 ) ? (ulong) thd->row_count_func : 0,
-+                    thd->row_count - thd->orig_row_count + 1,
-+                    (ulong) (thd->status_var.bytes_sent - thd->bytes_sent_old),
-+                    (ulong) thd->tmp_tables_used,
-+                    (ulong) thd->tmp_tables_disk_used,
-+                    (ulong) thd->tmp_tables_size) == (uint) -1)
-       tmp_errno= errno;
-+    if (thd->innodb_was_used)
-+    {
-+      char buf[20];
-+      snprintf(buf, 20, "%llX", thd->innodb_trx_id);
-+      if (my_b_printf(&log_file,
-+                    "# InnoDB_trx_id: %s\n", buf) == (uint) -1)
-+        tmp_errno=errno;
-+    }
-+    if ((thd->variables.log_slow_verbosity & SLOG_V_QUERY_PLAN) &&
-+         my_b_printf(&log_file,
-+                    "# QC_Hit: %s  Full_scan: %s  Full_join: %s  Tmp_table: %s  Tmp_table_on_disk: %s\n" \
-+                    "# Filesort: %s  Filesort_on_disk: %s  Merge_passes: %lu\n",
-+                    ((thd->query_plan_flags & QPLAN_QC) ? "Yes" : "No"),
-+                    ((thd->query_plan_flags & QPLAN_FULL_SCAN) ? "Yes" : "No"),
-+                    ((thd->query_plan_flags & QPLAN_FULL_JOIN) ? "Yes" : "No"),
-+                    ((thd->query_plan_flags & QPLAN_TMP_TABLE) ? "Yes" : "No"),
-+                    ((thd->query_plan_flags & QPLAN_TMP_DISK) ? "Yes" : "No"),
-+                    ((thd->query_plan_flags & QPLAN_FILESORT) ? "Yes" : "No"),
-+                    ((thd->query_plan_flags & QPLAN_FILESORT_DISK) ? "Yes" : "No"),
-+                    thd->query_plan_fsort_passes) == (uint) -1)
-+      tmp_errno=errno;
-+    if ((thd->variables.log_slow_verbosity & SLOG_V_INNODB) && thd->innodb_was_used)
-+    {
-+      char buf[3][20];
-+      snprintf(buf[0], 20, "%.6f", thd->innodb_io_reads_wait_timer / 1000000.0);
-+      snprintf(buf[1], 20, "%.6f", thd->innodb_lock_que_wait_timer / 1000000.0);
-+      snprintf(buf[2], 20, "%.6f", thd->innodb_innodb_que_wait_timer / 1000000.0);
-+      if (my_b_printf(&log_file,
-+                      "#   InnoDB_IO_r_ops: %lu  InnoDB_IO_r_bytes: %lu  InnoDB_IO_r_wait: %s\n" \
-+                      "#   InnoDB_rec_lock_wait: %s  InnoDB_queue_wait: %s\n" \
-+                      "#   InnoDB_pages_distinct: %lu\n",
-+                      (ulong) thd->innodb_io_reads,
-+                      (ulong) thd->innodb_io_read,
-+                      buf[0], buf[1], buf[2],
-+                      (ulong) thd->innodb_page_access) == (uint) -1)
-+        tmp_errno= errno;
-+    } 
-+    else
-+    {
-+      if ((thd->variables.log_slow_verbosity & SLOG_V_INNODB) &&
-+          my_b_printf(&log_file,"# No InnoDB statistics available for this query\n") == (uint) -1)
-+      tmp_errno= errno;
-+    }
-     if (thd->db && strcmp(thd->db, db))
-     {                                         // Database changed
-       if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
---- a/sql/log.h
-+++ b/sql/log.h
-@@ -213,7 +213,7 @@
-              uint user_host_len, int thread_id,
-              const char *command_type, uint command_type_len,
-              const char *sql_text, uint sql_text_len);
--  bool write(THD *thd, time_t current_time, time_t query_start_arg,
-+  bool write(THD *thd, ulonglong current_utime, time_t query_start_arg,
-              const char *user_host, uint user_host_len,
-              ulonglong query_utime, ulonglong lock_utime, bool is_command,
-              const char *sql_text, uint sql_text_len);
-@@ -427,7 +427,7 @@
-   virtual bool init()= 0;
-   virtual void cleanup()= 0;
--  virtual bool log_slow(THD *thd, time_t current_time,
-+  virtual bool log_slow(THD *thd, ulonglong current_utime,
-                         time_t query_start_arg, const char *user_host,
-                         uint user_host_len, ulonglong query_utime,
-                         ulonglong lock_utime, bool is_command,
-@@ -456,7 +456,7 @@
-   virtual bool init();
-   virtual void cleanup();
--  virtual bool log_slow(THD *thd, time_t current_time,
-+  virtual bool log_slow(THD *thd, ulonglong current_utime,
-                         time_t query_start_arg, const char *user_host,
-                         uint user_host_len, ulonglong query_utime,
-                         ulonglong lock_utime, bool is_command,
-@@ -488,7 +488,7 @@
-   virtual bool init();
-   virtual void cleanup();
--  virtual bool log_slow(THD *thd, time_t current_time,
-+  virtual bool log_slow(THD *thd, ulonglong current_utime,
-                         time_t query_start_arg, const char *user_host,
-                         uint user_host_len, ulonglong query_utime,
-                         ulonglong lock_utime, bool is_command,
---- a/sql/log_event.cc
-+++ b/sql/log_event.cc
-@@ -2368,6 +2368,15 @@
-       start+= host.length;
-     }
-   }
-+#ifndef DBUG_OFF
-+  if (thd && thd->variables.query_exec_time > 0)
-+  {
-+    *start++= Q_QUERY_EXEC_TIME;;
-+    int8store(start, thd->variables.query_exec_time);
-+    start+= 8;
-+  }
-+#endif
-+
-   /*
-     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
-@@ -2797,6 +2806,17 @@
-       data_written= master_data_written= uint4korr(pos);
-       pos+= 4;
-       break;
-+#if !defined(DBUG_OFF) && !defined(MYSQL_CLIENT)
-+    case Q_QUERY_EXEC_TIME:
-+    {
-+      THD *thd= current_thd;
-+      CHECK_SPACE(pos, end, 8);
-+      if (thd)
-+        thd->variables.query_exec_time= uint8korr(pos);
-+      pos+= 8;
-+      break;
-+    }
-+#endif
-     case Q_INVOKER:
-     {
-       CHECK_SPACE(pos, end, 1);
-@@ -3097,6 +3117,7 @@
-   LEX_STRING new_db;
-   int expected_error,actual_error= 0;
-   HA_CREATE_INFO db_options;
-+  bool process_log_slow_statement= false;
-   /*
-     Colleagues: please never free(thd->catalog) in MySQL. This would
-@@ -3278,19 +3299,7 @@
-       /* Execute the query (note that we bypass dispatch_command()) */
-       const char* found_semicolon= NULL;
-       mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
--      log_slow_statement(thd);
--
--      /*
--        Resetting the enable_slow_log thd variable.
--
--        We need to reset it back to the opt_log_slow_slave_statements
--        value after the statement execution (and slow logging
--        is done). It might have changed if the statement was an
--        admin statement (in which case, down in mysql_parse execution
--        thd->enable_slow_log is set to the value of
--        opt_log_slow_admin_statements).
--      */
--      thd->enable_slow_log= opt_log_slow_slave_statements;
-+      process_log_slow_statement= true;
-     }
-     else
-     {
-@@ -3435,11 +3444,27 @@
-     don't suffer from these assignments to 0 as DROP TEMPORARY
-     TABLE uses the db.table syntax.
-   */
-+  close_thread_tables(thd);      
-+  if(process_log_slow_statement)
-+  {
-+      log_slow_statement(thd);
-+
-+      /*
-+        Resetting the enable_slow_log thd variable.
-+
-+        We need to reset it back to the opt_log_slow_slave_statements
-+        value after the statement execution (and slow logging
-+        is done). It might have changed if the statement was an
-+        admin statement (in which case, down in mysql_parse execution
-+        thd->enable_slow_log is set to the value of
-+        opt_log_slow_admin_statements).
-+      */
-+      thd->enable_slow_log= opt_log_slow_slave_statements;
-+  }
-   thd->catalog= 0;
-   thd->set_db(NULL, 0);                 /* will free the current database */
-   thd->set_query(NULL, 0);
-   DBUG_PRINT("info", ("end: query= 0"));
--  close_thread_tables(thd);      
-   /*
-     As a disk space optimization, future masters will not log an event for
-     LAST_INSERT_ID() if that function returned 0 (and thus they will be able
---- a/sql/mysql_priv.h
-+++ b/sql/mysql_priv.h
-@@ -640,6 +640,106 @@
- #define STRING_BUFFER_USUAL_SIZE 80
-+/* Slow log */
-+
-+struct msl_opts
-+{
-+  ulong val;
-+  const char *name;
-+};
-+
-+/* use global log slow control */
-+#define SLOG_UG_NONE                        (1UL << 0)
-+#define SLOG_UG_LOG_SLOW_FILTER             (1UL << 1)
-+#define SLOG_UG_LOG_SLOW_RATE_LIMIT         (1UL << 2)
-+#define SLOG_UG_LOG_SLOW_VERBOSITY          (1UL << 3)
-+#define SLOG_UG_LONG_QUERY_TIME             (1UL << 4)
-+#define SLOG_UG_MIN_EXAMINED_ROW_LIMIT      (1UL << 5)
-+#define SLOG_UG_ALL                         SLOG_UG_LOG_SLOW_FILTER | SLOG_UG_LOG_SLOW_RATE_LIMIT | SLOG_UG_LOG_SLOW_VERBOSITY | SLOG_UG_LONG_QUERY_TIME | SLOG_UG_MIN_EXAMINED_ROW_LIMIT
-+/* ... */
-+#define SLOG_UG_INVALID                     1##UL << 31
-+
-+static const struct msl_opts slog_use_global[]=
-+  {
-+    /* Basic flags */
-+    { SLOG_UG_NONE                      , "none" },
-+    { SLOG_UG_LOG_SLOW_FILTER           , "log_slow_filter" },
-+    { SLOG_UG_LOG_SLOW_RATE_LIMIT       , "log_slow_rate_limit" },
-+    { SLOG_UG_LOG_SLOW_VERBOSITY        , "log_slow_verbosity" },
-+    { SLOG_UG_LONG_QUERY_TIME           , "long_query_time" },
-+    { SLOG_UG_MIN_EXAMINED_ROW_LIMIT    , "min_examined_row_limit" },
-+    /* ... */
-+    { 0, "" },
-+    /* Complex flags */
-+    { SLOG_UG_ALL                       , "all" },
-+    /* ... */
-+    { SLOG_UG_INVALID                   , (char*)0 }
-+  };
-+
-+#define SLOG_V_MICROTIME      1 << 0
-+#define SLOG_V_QUERY_PLAN     1 << 1
-+#define SLOG_V_INNODB         1 << 2
-+/* ... */
-+#define SLOG_V_INVALID        1##UL << 31
-+#define SLOG_V_NONE           SLOG_V_MICROTIME
-+
-+static const struct msl_opts slog_verb[]= 
-+{
-+  /* Basic flags */
-+
-+  { SLOG_V_MICROTIME, "microtime" },
-+  { SLOG_V_QUERY_PLAN, "query_plan" },
-+  { SLOG_V_INNODB, "innodb" },
-+
-+  /* End of baisc flags */
-+
-+  { 0, "" },
-+
-+  /* Complex flags */
-+
-+  { SLOG_V_MICROTIME, "minimal" },
-+  { SLOG_V_MICROTIME|SLOG_V_QUERY_PLAN, "standard" },
-+  { SLOG_V_MICROTIME|SLOG_V_QUERY_PLAN|SLOG_V_INNODB, "full" },
-+
-+  /* End of complex flags */
-+
-+  { SLOG_V_INVALID, (char *)0 }
-+};
-+
-+#define QPLAN_NONE            0
-+#define QPLAN_QC              1 << 0
-+#define QPLAN_QC_NO           1 << 1
-+#define QPLAN_FULL_SCAN       1 << 2
-+#define QPLAN_FULL_JOIN       1 << 3
-+#define QPLAN_TMP_TABLE       1 << 4
-+#define QPLAN_TMP_DISK        1 << 5
-+#define QPLAN_FILESORT        1 << 6
-+#define QPLAN_FILESORT_DISK   1 << 7
-+/* ... */
-+#define QPLAN_MAX             1 << 31
-+
-+#define SLOG_F_QC_NO          QPLAN_QC_NO
-+#define SLOG_F_FULL_SCAN      QPLAN_FULL_SCAN
-+#define SLOG_F_FULL_JOIN      QPLAN_FULL_JOIN
-+#define SLOG_F_TMP_TABLE      QPLAN_TMP_TABLE
-+#define SLOG_F_TMP_DISK       QPLAN_TMP_DISK
-+#define SLOG_F_FILESORT       QPLAN_FILESORT
-+#define SLOG_F_FILESORT_DISK  QPLAN_FILESORT_DISK
-+#define SLOG_F_INVALID        1##UL << 31
-+#define SLOG_F_NONE           0
-+
-+static const struct msl_opts slog_filter[]= 
-+{
-+  { SLOG_F_QC_NO,         "qc_miss" },
-+  { SLOG_F_FULL_SCAN,     "full_scan" },
-+  { SLOG_F_FULL_JOIN,     "full_join" },
-+  { SLOG_F_TMP_TABLE,     "tmp_table" },
-+  { SLOG_F_TMP_DISK,      "tmp_table_on_disk" },
-+  { SLOG_F_FILESORT,      "filesort" },
-+  { SLOG_F_FILESORT_DISK, "filesort_on_disk" },
-+  { SLOG_F_INVALID,       (char *)0 }
-+};
-+
- /*
-   Some defines for exit codes for ::is_equal class functions.
- */
-@@ -2001,6 +2101,10 @@
- extern my_bool opt_secure_auth;
- extern char* opt_secure_file_priv;
- extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements;
-+extern my_bool opt_log_slow_sp_statements;
-+extern my_bool opt_log_slow_timestamp_every;
-+extern my_bool opt_use_global_long_query_time;
-+extern my_bool opt_slow_query_log_microseconds_timestamp;
- extern my_bool sp_automatic_privileges, opt_noacl;
- extern my_bool opt_old_style_user_limits, trust_function_creators;
- extern uint opt_crash_binlog_innodb;
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -443,6 +443,7 @@
- static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
- static I_List<THD> thread_cache;
- static double long_query_time;
-+static double query_exec_time;
- static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
-@@ -528,6 +529,10 @@
- char* opt_secure_file_priv= 0;
- my_bool opt_log_slow_admin_statements= 0;
- my_bool opt_log_slow_slave_statements= 0;
-+my_bool opt_log_slow_sp_statements= 0;
-+my_bool opt_log_slow_timestamp_every= 0;
-+my_bool opt_use_global_long_query_time= 0;
-+my_bool opt_slow_query_log_microseconds_timestamp= 0;
- my_bool lower_case_file_system= 0;
- my_bool opt_large_pages= 0;
- my_bool opt_myisam_use_mmap= 0;
-@@ -5811,7 +5816,13 @@
-   OPT_INNODB_ROLLBACK_ON_TIMEOUT,
-   OPT_SECURE_FILE_PRIV,
-   OPT_MIN_EXAMINED_ROW_LIMIT,
-+  OPT_QUERY_EXEC_TIME,
-   OPT_LOG_SLOW_SLAVE_STATEMENTS,
-+  OPT_LOG_SLOW_RATE_LIMIT,
-+  OPT_LOG_SLOW_VERBOSITY,
-+  OPT_LOG_SLOW_FILTER,
-+  OPT_LOG_SLOW_SP_STATEMENTS,
-+  OPT_LOG_SLOW_TIMESTAMP_EVERY,
- #if defined(ENABLED_DEBUG_SYNC)
-   OPT_DEBUG_SYNC_TIMEOUT,
- #endif /* defined(ENABLED_DEBUG_SYNC) */
-@@ -5819,6 +5830,9 @@
-   OPT_SLAVE_EXEC_MODE,
-   OPT_GENERAL_LOG_FILE,
-   OPT_SLOW_QUERY_LOG_FILE,
-+  OPT_USE_GLOBAL_LONG_QUERY_TIME,
-+  OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
-+  OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
-   OPT_IGNORE_BUILTIN_INNODB,
-   OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
-   OPT_DEFAULT_CHARACTER_SET_OLD,
-@@ -6839,6 +6853,36 @@
-    "microsecond precision.",
-    &long_query_time, &long_query_time, 0, GET_DOUBLE,
-    REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
-+  {"log_slow_filter", OPT_LOG_SLOW_FILTER,
-+    "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]",
-+    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_F_NONE, 0, 0},
-+  {"log_slow_rate_limit", OPT_LOG_SLOW_RATE_LIMIT,
-+    "Rate limit statement writes to slow log to only those from every (1/log_slow_rate_limit) session.",
-+    (uchar**) &global_system_variables.log_slow_rate_limit,
-+    (uchar**) &max_system_variables.log_slow_rate_limit, 0, GET_ULONG,
-+    REQUIRED_ARG, 1, 1, LONG_MAX, 0, 1L, 0},
-+  {"log_slow_verbosity", OPT_LOG_SLOW_VERBOSITY,
-+    "Choose how verbose the messages to your slow log will be. Multiple flags allowed in a comma-separated string. [microtime, query_plan, innodb]",
-+    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_V_MICROTIME, 0, 0},
-+  {"log_slow_sp_statements", OPT_LOG_SLOW_SP_STATEMENTS,
-+   "Log slow statements executed by stored procedure to the slow log if it is open.",
-+   (uchar**) &opt_log_slow_sp_statements, (uchar**) &opt_log_slow_sp_statements,
-+   0, GET_BOOL, OPT_ARG, 1, 0, 1, 0, 1, 0},
-+  {"log_slow_timestamp_every", OPT_LOG_SLOW_TIMESTAMP_EVERY,
-+   "Timestamp is printed for all records of the slow log even if they are same time.",
-+   (uchar**) &opt_log_slow_timestamp_every, (uchar**) &opt_log_slow_timestamp_every,
-+   0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
-+  {"use_global_log_slow_control", OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
-+    "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]",
-+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_UG_NONE, 0, 0},
-+  {"use_global_long_query_time", OPT_USE_GLOBAL_LONG_QUERY_TIME,
-+   "Control always use global long_query_time or local long_query_time.",
-+   (uchar**) &opt_use_global_long_query_time, (uchar**) &opt_use_global_long_query_time,
-+   0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
-+  {"slow_query_log_microseconds_timestamp", OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
-+   "Use microsecond time's precision in slow query log",
-+   (uchar**) &opt_slow_query_log_microseconds_timestamp, (uchar**) &opt_slow_query_log_microseconds_timestamp,
-+   0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
-   {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
-    "If set to 1, table names are stored in lowercase on disk and table names "
-    "will be case-insensitive.  Should be set to 2 if you are using a case-"
-@@ -7076,6 +7120,13 @@
-    "is the plugin library in plugin_dir.",
-    &opt_plugin_load, &opt_plugin_load, 0,
-    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#ifndef DBUG_OFF
-+  {"query_exec_time", OPT_QUERY_EXEC_TIME,
-+   "Pretend queries take this many seconds. When 0 (the default) use the "
-+   "actual execution time. Used only for debugging.",
-+   &query_exec_time, &query_exec_time, 0, GET_DOUBLE,
-+   REQUIRED_ARG, 0, 0, LONG_TIMEOUT, 0, 0, 0},
-+#endif
-   {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
-    "The size of the buffer that is allocated when preloading indexes.",
-    &global_system_variables.preload_buff_size,
-@@ -7991,6 +8042,10 @@
-   global_system_variables.old_passwords= 0;
-   global_system_variables.old_alter_table= 0;
-   global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
-+
-+  global_system_variables.log_slow_verbosity= SLOG_V_MICROTIME;
-+  global_system_variables.use_global_log_slow_control= SLOG_UG_NONE;
-+  global_system_variables.log_slow_filter= SLOG_F_NONE;
-   /*
-     Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
-     when collecting index statistics for MyISAM tables.
-@@ -8494,6 +8549,44 @@
-   case OPT_BOOTSTRAP:
-     opt_noacl=opt_bootstrap=1;
-     break;
-+  case OPT_LOG_SLOW_FILTER:
-+    if ((global_system_variables.log_slow_filter= 
-+          msl_flag_resolve_by_name(slog_filter, argument,
-+                                   SLOG_F_NONE, SLOG_F_INVALID)) == SLOG_F_INVALID)
-+    {
-+      fprintf(stderr,"Invalid argument in log_slow_filter: %s\n", argument);
-+      exit(1);
-+    }
-+    break;
-+  case OPT_LOG_SLOW_VERBOSITY:
-+    if ((global_system_variables.log_slow_verbosity= 
-+         msl_flag_resolve_by_name(slog_verb, argument,
-+                                  SLOG_V_NONE, SLOG_V_INVALID)) == SLOG_V_INVALID)
-+    {
-+      fprintf(stderr,"Invalid argument in log_slow_verbosity: %s\n", argument);
-+      exit(1);
-+    }
-+    break;
-+  case OPT_USE_GLOBAL_LONG_QUERY_TIME:
-+    use_global_long_query_time_update(opt_use_global_long_query_time);
-+    break;
-+  case OPT_USE_GLOBAL_LOG_SLOW_CONTROL:
-+    {
-+      ulong &v= global_system_variables.use_global_log_slow_control;
-+      v= msl_flag_resolve_by_name(slog_use_global, argument, SLOG_UG_NONE, SLOG_UG_INVALID);
-+      if (v != SLOG_UG_NONE)
-+      {
-+        v&= ~SLOG_UG_NONE;
-+      }
-+      if (v == SLOG_UG_INVALID)
-+      {
-+        fprintf(stderr,"Invalid argument in use_global_log_slow_control: %s\n", argument);
-+        exit(1);
-+      }
-+      use_global_long_query_time_update
-+        (global_system_variables.use_global_log_slow_control & SLOG_UG_LONG_QUERY_TIME);
-+      break;
-+    }
-   case OPT_SERVER_ID:
-     server_id_supplied = 1;
-     break;
---- a/sql/set_var.cc
-+++ b/sql/set_var.cc
-@@ -164,6 +164,74 @@
- static sys_var_chain vars = { NULL, NULL };
-+void use_global_long_query_time_update(bool enable)
-+{
-+  ulong &log_slow_control= global_system_variables.use_global_log_slow_control;
-+  opt_use_global_long_query_time= enable;
-+  if (enable)
-+    log_slow_control|= SLOG_UG_LONG_QUERY_TIME;
-+  else
-+    log_slow_control&= ~SLOG_UG_LONG_QUERY_TIME;
-+  log_slow_control&= ~SLOG_UG_NONE;
-+  if (log_slow_control == 0)
-+    log_slow_control= SLOG_UG_NONE;
-+}
-+
-+class sys_var_use_global_long_query_time : public sys_var_bool_ptr
-+{
-+public:
-+  sys_var_use_global_long_query_time()
-+    :sys_var_bool_ptr(&vars,"use_global_long_query_time",&opt_use_global_long_query_time)
-+  {
-+    chain_sys_var(&vars);
-+  }
-+  virtual bool update(THD *thd, set_var *var)
-+  {
-+    bool result = sys_var_bool_ptr::update(thd,var);
-+    sync();
-+    return result;
-+  }
-+  virtual void set_default(THD *thd, enum_var_type type)
-+  {
-+    sys_var_bool_ptr::set_default(thd,type);
-+    sync();
-+  }
-+private:
-+  void sync()
-+  {
-+    use_global_long_query_time_update(opt_use_global_long_query_time);    
-+  }
-+};
-+class sys_var_use_global_log_slow_control : public sys_var_thd_msl_flag_correct_none
-+{
-+ public:
-+  sys_var_use_global_log_slow_control() : sys_var_thd_msl_flag_correct_none(
-+                                                               &vars
-+                                                               ,"use_global_log_slow_control"
-+                                                               ,&SV::use_global_log_slow_control
-+                                                               ,SLOG_UG_NONE,SLOG_UG_NONE,SLOG_UG_INVALID
-+                                                               ,slog_use_global)
-+    {
-+    }
-+  virtual bool update(THD *thd, set_var *var)
-+  {
-+    bool result = sys_var_thd_msl_flag_correct_none::update(thd,var);
-+    sync();
-+    return result;
-+  }
-+  virtual void set_default(THD *thd, enum_var_type type)
-+  {
-+    sys_var_thd_msl_flag_correct_none::set_default(thd,type);
-+    sync();
-+  }
-+private:
-+  void sync()
-+  {
-+    ulong const &variable= global_system_variables.use_global_log_slow_control;
-+    use_global_long_query_time_update((variable & SLOG_UG_LONG_QUERY_TIME));
-+  }
-+};
-+
- static sys_var_thd_ulong
- sys_auto_increment_increment(&vars, "auto_increment_increment",
-                              &SV::auto_increment_increment, NULL, NULL,
-@@ -903,6 +971,37 @@
-                                       QUERY_LOG_GENERAL);
- static sys_var_log_state sys_var_slow_query_log(&vars, "slow_query_log", &opt_slow_log,
-                                          QUERY_LOG_SLOW);
-+static sys_var_thd_ulong      sys_log_slow_rate_limit(&vars, "log_slow_rate_limit",
-+                                            &SV::log_slow_rate_limit);
-+static sys_var_thd_msl_flag   sys_log_slow_filter(&vars, "log_slow_filter",
-+                                      &SV::log_slow_filter,
-+                                       SLOG_F_NONE,
-+                                       SLOG_F_NONE,
-+                                       SLOG_F_INVALID,
-+                                       slog_filter);
-+static sys_var_thd_msl_flag   sys_log_slow_verbosity(&vars, "log_slow_verbosity",
-+                                      &SV::log_slow_verbosity,
-+                                       SLOG_V_NONE,
-+                                       SLOG_V_MICROTIME,
-+                                       SLOG_V_INVALID,
-+                                       slog_verb);
-+static sys_var_use_global_log_slow_control sys_use_global_log_slow_control;
-+static sys_var_bool_ptr       sys_log_slow_admin_statements(&vars, "log_slow_admin_statements",
-+                                                            &opt_log_slow_admin_statements);
-+static sys_var_bool_ptr       sys_log_slow_slave_statements(&vars, "log_slow_slave_statements",
-+                                                            &opt_log_slow_slave_statements);
-+static sys_var_bool_ptr       sys_log_slow_sp_statements(&vars, "log_slow_sp_statements",
-+                                                         &opt_log_slow_sp_statements);
-+static sys_var_bool_ptr       sys_log_slow_timestamp_every(&vars, "log_slow_timestamp_every",
-+                                                           &opt_log_slow_timestamp_every);
-+static sys_var_use_global_long_query_time sys_use_global_long_query_time;
-+static sys_var_bool_ptr       sys_slow_query_log_microseconds_timestamp(&vars, "slow_query_log_microseconds_timestamp",
-+                                                       &opt_slow_query_log_microseconds_timestamp);
-+#ifndef DBUG_OFF
-+static sys_var_microseconds sys_var_query_exec_time(&vars, "query_exec_time",
-+                                                    &SV::query_exec_time,
-+                                                    sys_var::SESSION_VARIABLE_IN_BINLOG);
-+#endif
- /* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
- static sys_var_log_state sys_var_log_slow(&vars, "log_slow_queries",
-                                           &opt_slow_log, QUERY_LOG_SLOW);
-@@ -3713,6 +3812,203 @@
- #endif
- }
-+/* Slow log stuff */
-+
-+ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len)
-+{
-+  ulong i;
-+  
-+  for (i=0; opts[i].name; i++)
-+  {
-+    if (!my_strnncoll(&my_charset_latin1,
-+                      (const uchar *)name, len,
-+                      (const uchar *)opts[i].name, strlen(opts[i].name)))
-+      return opts[i].val;
-+  }
-+  return opts[i].val;
-+}
-+
-+ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list, 
-+                               const ulong none_val, const ulong invalid_val)
-+{
-+  const char *p, *e;
-+  ulong val= none_val;
-+  
-+  if (!*names_list)
-+    return val;
-+  
-+  for (p= e= names_list; ; e++)
-+  {
-+    ulong i;
-+    
-+    if (*e != ',' && *e)
-+      continue;
-+    for (i=0; opts[i].name; i++)
-+    {
-+      if (!my_strnncoll(&my_charset_latin1,
-+                        (const uchar *)p, e - p,
-+                        (const uchar *)opts[i].name, strlen(opts[i].name)))
-+      {
-+        val= val | opts[i].val;
-+        break;
-+      }
-+    }
-+    if (opts[i].val == invalid_val)
-+      return invalid_val;
-+    if (!*e)
-+      break;
-+    p= e + 1;
-+  }
-+  return val;
-+}
-+
-+const char *msl_option_get_name(const struct msl_opts *opts, ulong val)
-+{
-+  for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
-+  {
-+    if (opts[i].val == val)
-+      return opts[i].name;
-+  }
-+  return "*INVALID*";
-+}
-+
-+char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val)
-+{
-+  uint offset= 0;
-+  
-+  *buf= '\0';
-+  for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
-+  {
-+    if (opts[i].val & val)
-+      offset+= snprintf(buf+offset, STRING_BUFFER_USUAL_SIZE - offset - 1,
-+                        "%s%s", (offset ? "," : ""), opts[i].name);
-+  }
-+  return buf;
-+}
-+
-+/****************************************************************************
-+ Functions to handle log_slow_verbosity
-+****************************************************************************/
-+
-+/* Based upon sys_var::check_enum() */
-+
-+bool sys_var_thd_msl_option::check(THD *thd, set_var *var)
-+{
-+  char buff[STRING_BUFFER_USUAL_SIZE];
-+  String str(buff, sizeof(buff), &my_charset_latin1), *res;
-+
-+  if (var->value->result_type() == STRING_RESULT)
-+  {
-+    ulong verb= this->invalid_val;
-+    if (!(res=var->value->val_str(&str)) ||
-+             (var->save_result.ulong_value=
-+          (ulong) (verb= msl_option_resolve_by_name(this->opts, res->ptr(), res->length()))) == this->invalid_val)
-+      goto err;
-+    return 0;
-+  }
-+
-+err:
-+  my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
-+  return 1;
-+}
-+
-+uchar *sys_var_thd_msl_option::value_ptr(THD *thd, enum_var_type type,
-+                                       LEX_STRING *base)
-+{
-+  ulong val;
-+  val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
-+        thd->variables.*offset);
-+  const char *verbosity= msl_option_get_name(this->opts, val);
-+  return (uchar *) verbosity;
-+}
-+
-+
-+void sys_var_thd_msl_option::set_default(THD *thd, enum_var_type type)
-+{
-+  if (type == OPT_GLOBAL)
-+    global_system_variables.*offset= (ulong) this->default_val;
-+  else
-+    thd->variables.*offset= (ulong) (global_system_variables.*offset);
-+}
-+
-+
-+bool sys_var_thd_msl_option::update(THD *thd, set_var *var)
-+{
-+  if (var->type == OPT_GLOBAL)
-+    global_system_variables.*offset= var->save_result.ulong_value;
-+  else
-+    thd->variables.*offset= var->save_result.ulong_value;
-+  return 0;
-+}
-+
-+/****************************************************************************
-+ Functions to handle log_slow_filter
-+****************************************************************************/
-+  
-+/* Based upon sys_var::check_enum() */
-+
-+bool sys_var_thd_msl_flag::check(THD *thd, set_var *var)
-+{
-+  char buff[2 * STRING_BUFFER_USUAL_SIZE];
-+  String str(buff, sizeof(buff), &my_charset_latin1), *res;
-+
-+  if (var->value->result_type() == STRING_RESULT)
-+  {
-+    ulong filter= this->none_val;
-+    if (!(res=var->value->val_str(&str)) ||
-+        (var->save_result.ulong_value=
-+          (ulong) (filter= msl_flag_resolve_by_name(this->flags, res->ptr(), this->none_val, 
-+                                                    this->invalid_val))) == this->invalid_val)
-+      goto err;
-+    return 0;
-+  }
-+
-+err:
-+  my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
-+  return 1;
-+}
-+
-+uchar *sys_var_thd_msl_flag::value_ptr(THD *thd, enum_var_type type,
-+                                       LEX_STRING *base)
-+{
-+  ulong val;
-+  val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
-+        thd->variables.*offset);
-+  msl_flag_get_name(this->flags, this->flags_string, val);
-+  return (uchar *) this->flags_string;
-+}
-+
-+
-+void sys_var_thd_msl_flag::set_default(THD *thd, enum_var_type type)
-+{
-+  if (type == OPT_GLOBAL)
-+    global_system_variables.*offset= (ulong) this->default_val;
-+  else
-+    thd->variables.*offset= (ulong) (global_system_variables.*offset);
-+}
-+
-+
-+bool sys_var_thd_msl_flag::update(THD *thd, set_var *var)
-+{
-+  if (var->type == OPT_GLOBAL)
-+    global_system_variables.*offset= var->save_result.ulong_value;
-+  else
-+    thd->variables.*offset= var->save_result.ulong_value;
-+  return 0;
-+}
-+bool sys_var_thd_msl_flag_correct_none::update(THD *thd, set_var *var)
-+{
-+  ulong result = var->save_result.ulong_value;
-+  if (result != none_val)
-+    result = result & (~none_val);
-+  if (var->type == OPT_GLOBAL)
-+    global_system_variables.*offset = result;
-+  else
-+    thd->variables.*offset = result;
-+  return 0;
-+}
-+
-+
- /****************************************************************************
-  Functions to handle table_type
- ****************************************************************************/
---- a/sql/set_var.h
-+++ b/sql/set_var.h
-@@ -569,6 +569,82 @@
- };
-+extern void use_global_long_query_time_update(bool enable);
-+
-+class sys_var_thd_msl_option :public sys_var_thd
-+{
-+protected:
-+  ulong SV::*offset;
-+  const ulong none_val;
-+  const ulong default_val;
-+  const ulong invalid_val;
-+  const struct msl_opts *opts;
-+public:
-+  sys_var_thd_msl_option(sys_var_chain *chain, const char *name_arg, ulong SV::*offset_arg,
-+                         const ulong none_val_arg,
-+                         const ulong default_val_arg,
-+                         const ulong invalid_val_arg,
-+                         const struct msl_opts *opts_arg)
-+    :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
-+     default_val(default_val_arg), invalid_val(invalid_val_arg), 
-+     opts(opts_arg)
-+  { chain_sys_var(chain); }
-+  bool check(THD *thd, set_var *var);
-+  SHOW_TYPE show_type() { return SHOW_CHAR; }
-+  bool check_update_type(Item_result type)
-+  {
-+    return type != STRING_RESULT;              /* Only accept strings */
-+  }
-+  void set_default(THD *thd, enum_var_type type);
-+  bool update(THD *thd, set_var *var);
-+  uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-+};
-+
-+
-+class sys_var_thd_msl_flag :public sys_var_thd
-+{
-+protected:
-+  char flags_string[2 * STRING_BUFFER_USUAL_SIZE];
-+  ulong SV::*offset;
-+  const ulong none_val;
-+  const ulong default_val;
-+  const ulong invalid_val;
-+  const struct msl_opts *flags;
-+public:
-+  sys_var_thd_msl_flag(sys_var_chain *chain, const char *name_arg, ulong SV::*offset_arg, 
-+                       const ulong none_val_arg, 
-+                       const ulong default_val_arg, 
-+                       const ulong invalid_val_arg,
-+                       const struct msl_opts *flags_arg)
-+    :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
-+     default_val(default_val_arg), invalid_val(invalid_val_arg), 
-+     flags(flags_arg)
-+  { chain_sys_var(chain); }
-+  bool check(THD *thd, set_var *var);
-+  SHOW_TYPE show_type() { return SHOW_CHAR; }
-+  bool check_update_type(Item_result type)
-+  {
-+    return type != STRING_RESULT;              /* Only accept strings */
-+  }
-+  void set_default(THD *thd, enum_var_type type);
-+  bool update(THD *thd, set_var *var);
-+  uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-+};
-+
-+class sys_var_thd_msl_flag_correct_none : public sys_var_thd_msl_flag
-+{
-+ public:
-+  sys_var_thd_msl_flag_correct_none(sys_var_chain *chain, const char *name_arg, ulong SV::*offset_arg,
-+                                  const ulong none_val_arg,
-+                                  const ulong default_val_arg,
-+                                  const ulong invalid_val_arg,
-+                                  const struct msl_opts *flags_arg)
-+    : sys_var_thd_msl_flag(chain,name_arg,offset_arg,none_val_arg,default_val_arg,invalid_val_arg,flags_arg)
-+    {
-+    }
-+  virtual bool update(THD *thd, set_var *var);
-+};
-+
- class sys_var_thd_storage_engine :public sys_var_thd
- {
- protected:
-@@ -1178,8 +1254,9 @@
-   ulonglong SV::*offset;
- public:
-   sys_var_microseconds(sys_var_chain *chain, const char *name_arg,
--                       ulonglong SV::*offset_arg):
--    sys_var_thd(name_arg), offset(offset_arg)
-+                       ulonglong SV::*offset_arg,
-+                       Binlog_status_enum binlog_status= NOT_IN_BINLOG):
-+  sys_var_thd(name_arg, NULL, binlog_status), offset(offset_arg)
-   { chain_sys_var(chain); }
-   bool check(THD *thd, set_var *var) {return 0;}
-   bool update(THD *thd, set_var *var);
-@@ -1470,3 +1547,10 @@
- bool process_key_caches(process_key_cache_t func);
- void delete_elements(I_List<NAMED_LIST> *list,
-                    void (*free_element)(const char*, uchar*));
-+
-+/* Slow log functions */
-+ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len);
-+ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list, 
-+                               const ulong none_val, const ulong invalid_val);
-+const char *msl_option_get_name(const struct msl_opts *opts, ulong val);
-+char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val);
---- a/sql/slave.cc
-+++ b/sql/slave.cc
-@@ -1836,6 +1836,7 @@
-     + MAX_LOG_EVENT_HEADER;  /* note, incr over the global not session var */
-   thd->slave_thread = 1;
-   thd->enable_slow_log= opt_log_slow_slave_statements;
-+  thd->write_to_slow_log= opt_log_slow_slave_statements;
-   set_slave_thread_options(thd);
-   thd->client_capabilities = CLIENT_LOCAL_FILES;
-   pthread_mutex_lock(&LOCK_thread_count);
---- a/sql/sp_head.cc
-+++ b/sql/sp_head.cc
-@@ -1989,7 +1989,7 @@
-     DBUG_PRINT("info",(" %.*s: eval args done", (int) m_name.length, 
-                        m_name.str));
-   }
--  if (!(m_flags & LOG_SLOW_STATEMENTS) && thd->enable_slow_log)
-+  if (!(m_flags & LOG_SLOW_STATEMENTS || opt_log_slow_sp_statements) && thd->enable_slow_log)
-   {
-     DBUG_PRINT("info", ("Disabling slow log for the execution"));
-     save_enable_slow_log= true;
---- a/sql/sql_cache.cc
-+++ b/sql/sql_cache.cc
-@@ -1706,6 +1706,7 @@
-   thd->limit_found_rows = query->found_rows();
-   thd->status_var.last_query_cost= 0.0;
-+  thd->query_plan_flags|= QPLAN_QC;
-   if (!thd->main_da.is_set())
-     thd->main_da.disable_status();
-@@ -1715,6 +1716,7 @@
- err_unlock:
-   unlock();
- err:
-+  thd->query_plan_flags|= QPLAN_QC_NO;
-   DBUG_RETURN(0);                             // Query was not cached
- }
---- a/sql/sql_class.cc
-+++ b/sql/sql_class.cc
-@@ -342,6 +342,37 @@
-   thd->row_count++;
- }
-+extern "C"
-+void increment_thd_innodb_stats(THD* thd,
-+                                unsigned long long trx_id,
-+                                long io_reads,
-+                                long long  io_read,
-+                                long      io_reads_wait_timer,
-+                                long      lock_que_wait_timer,
-+                                long      que_wait_timer,
-+                                long      page_access)
-+{
-+  thd->innodb_was_used=               TRUE;
-+  thd->innodb_trx_id=                 trx_id;
-+  thd->innodb_io_reads+=              io_reads;
-+  thd->innodb_io_read+=               io_read;
-+  thd->innodb_io_reads_wait_timer+=   io_reads_wait_timer;
-+  thd->innodb_lock_que_wait_timer+=   lock_que_wait_timer;
-+  thd->innodb_innodb_que_wait_timer+= que_wait_timer;
-+  thd->innodb_page_access+=           page_access;
-+}
-+
-+extern "C"
-+unsigned long thd_log_slow_verbosity(const THD *thd)
-+{
-+  return (unsigned long) thd->variables.log_slow_verbosity;
-+}
-+
-+extern "C"
-+int thd_opt_slow_log()
-+{
-+  return (int) opt_slow_log;
-+}
- /**
-   Dumps a text description of a thread, its security context
-@@ -761,6 +792,8 @@
- bool THD::handle_error(uint sql_errno, const char *message,
-                        MYSQL_ERROR::enum_warning_level level)
- {
-+  last_errno = sql_errno;
-+
-   for (Internal_error_handler *error_handler= m_internal_handler;
-        error_handler;
-        error_handler= error_handler->m_prev_internal_handler)
-@@ -881,6 +914,8 @@
-   /* Initialize the Debug Sync Facility. See debug_sync.cc. */
-   debug_sync_init_thread(this);
- #endif /* defined(ENABLED_DEBUG_SYNC) */
-+
-+  clear_slow_extended();
- }
-@@ -3187,8 +3222,6 @@
-   backup->in_sub_stmt=     in_sub_stmt;
-   backup->enable_slow_log= enable_slow_log;
-   backup->limit_found_rows= limit_found_rows;
--  backup->examined_row_count= examined_row_count;
--  backup->sent_row_count=   sent_row_count;
-   backup->cuted_fields=     cuted_fields;
-   backup->client_capabilities= client_capabilities;
-   backup->savepoints= transaction.savepoints;
-@@ -3196,6 +3229,7 @@
-     first_successful_insert_id_in_prev_stmt;
-   backup->first_successful_insert_id_in_cur_stmt= 
-     first_successful_insert_id_in_cur_stmt;
-+  reset_sub_statement_state_slow_extended(backup);
-   if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
-       !current_stmt_binlog_row_based)
-@@ -3210,13 +3244,75 @@
-   /* Disable result sets */
-   client_capabilities &= ~CLIENT_MULTI_RESULTS;
-   in_sub_stmt|= new_state;
--  examined_row_count= 0;
--  sent_row_count= 0;
-   cuted_fields= 0;
-   transaction.savepoints= 0;
-   first_successful_insert_id_in_cur_stmt= 0;
- }
-+void THD::clear_slow_extended()
-+{
-+  DBUG_ENTER("THD::clear_slow_extended");
-+  sent_row_count=               0;
-+  orig_row_count=               row_count;
-+  examined_row_count=           0;
-+  bytes_sent_old=               status_var.bytes_sent;
-+  tmp_tables_used=              0;
-+  tmp_tables_disk_used=         0;
-+  tmp_tables_size=              0;
-+  innodb_was_used=              FALSE;
-+  innodb_trx_id=                0;
-+  innodb_io_reads=              0;
-+  innodb_io_read=               0;
-+  innodb_io_reads_wait_timer=   0;
-+  innodb_lock_que_wait_timer=   0;
-+  innodb_innodb_que_wait_timer= 0;
-+  innodb_page_access=           0;
-+  query_plan_flags=             QPLAN_NONE;
-+  query_plan_fsort_passes=      0;
-+  last_errno=                   0;
-+  DBUG_VOID_RETURN;
-+}
-+
-+void THD::reset_sub_statement_state_slow_extended(Sub_statement_state *backup)
-+{
-+  DBUG_ENTER("THD::reset_sub_statement_state_slow_extended");
-+  backup->sent_row_count=               sent_row_count;
-+  backup->examined_row_count=           examined_row_count;
-+  backup->tmp_tables_used=              tmp_tables_used;
-+  backup->tmp_tables_disk_used=         tmp_tables_disk_used;
-+  backup->tmp_tables_size=              tmp_tables_size;
-+  backup->innodb_was_used=              innodb_was_used;
-+  backup->innodb_io_reads=              innodb_io_reads;
-+  backup->innodb_io_read=               innodb_io_read;
-+  backup->innodb_io_reads_wait_timer=   innodb_io_reads_wait_timer;
-+  backup->innodb_lock_que_wait_timer=   innodb_lock_que_wait_timer;
-+  backup->innodb_innodb_que_wait_timer= innodb_innodb_que_wait_timer;
-+  backup->innodb_page_access=           innodb_page_access;
-+  backup->query_plan_flags=             query_plan_flags;
-+  backup->query_plan_fsort_passes=      query_plan_fsort_passes;
-+  clear_slow_extended();
-+  DBUG_VOID_RETURN;
-+}
-+
-+void THD::restore_sub_statement_state_slow_extended(const Sub_statement_state *backup)
-+{
-+  DBUG_ENTER("THD::restore_sub_statement_state_slow_extended");
-+  sent_row_count=                backup->sent_row_count;
-+  examined_row_count+=           backup->examined_row_count;
-+  tmp_tables_used+=              backup->tmp_tables_used;
-+  tmp_tables_disk_used+=         backup->tmp_tables_disk_used;
-+  tmp_tables_size+=              backup->tmp_tables_size;
-+  innodb_was_used=               (innodb_was_used || backup->innodb_was_used);
-+  innodb_io_reads+=              backup->innodb_io_reads;
-+  innodb_io_read+=               backup->innodb_io_read;
-+  innodb_io_reads_wait_timer+=   backup->innodb_io_reads_wait_timer;
-+  innodb_lock_que_wait_timer+=   backup->innodb_lock_que_wait_timer;
-+  innodb_innodb_que_wait_timer+= backup->innodb_innodb_que_wait_timer;
-+  innodb_page_access+=           backup->innodb_page_access;
-+  query_plan_flags|=             backup->query_plan_flags;
-+  query_plan_fsort_passes+=      backup->query_plan_fsort_passes;
-+  DBUG_VOID_RETURN;
-+}
- void THD::restore_sub_statement_state(Sub_statement_state *backup)
- {
-@@ -3257,7 +3353,6 @@
-   first_successful_insert_id_in_cur_stmt= 
-     backup->first_successful_insert_id_in_cur_stmt;
-   limit_found_rows= backup->limit_found_rows;
--  sent_row_count=   backup->sent_row_count;
-   client_capabilities= backup->client_capabilities;
-   /*
-     If we've left sub-statement mode, reset the fatal error flag.
-@@ -3275,8 +3370,8 @@
-     The following is added to the old values as we are interested in the
-     total complexity of the query
-   */
--  examined_row_count+= backup->examined_row_count;
-   cuted_fields+=       backup->cuted_fields;
-+  restore_sub_statement_state_slow_extended(backup);
-   DBUG_VOID_RETURN;
- }
---- a/sql/sql_class.h
-+++ b/sql/sql_class.h
-@@ -404,6 +404,21 @@
-   DATE_TIME_FORMAT *datetime_format;
-   DATE_TIME_FORMAT *time_format;
-   my_bool sysdate_is_now;
-+
-+#ifndef DBUG_OFF
-+  ulonglong query_exec_time;
-+#endif
-+  ulong log_slow_rate_limit;
-+  ulong log_slow_filter;
-+  ulong log_slow_verbosity;
-+  ulong use_global_log_slow_control;
-+
-+  ulong      innodb_io_reads;
-+  ulonglong  innodb_io_read;
-+  ulong      innodb_io_reads_wait_timer;
-+  ulong      innodb_lock_que_wait_timer;
-+  ulong      innodb_innodb_que_wait_timer;
-+  ulong      innodb_page_access;
- };
-@@ -1000,6 +1015,24 @@
-   uint in_sub_stmt;
-   bool enable_slow_log;
-   bool last_insert_id_used;
-+
-+  /*** Following variables used in slow_extended.patch ***/
-+  ulong      tmp_tables_used;
-+  ulong      tmp_tables_disk_used;
-+  ulonglong  tmp_tables_size;
-+
-+  bool       innodb_was_used;
-+  ulong      innodb_io_reads;
-+  ulonglong  innodb_io_read;
-+  ulong      innodb_io_reads_wait_timer;
-+  ulong      innodb_lock_que_wait_timer;
-+  ulong      innodb_innodb_que_wait_timer;
-+  ulong      innodb_page_access;
-+
-+  ulong      query_plan_flags;
-+  ulong      query_plan_fsort_passes;
-+  /*** The variables above used in slow_extended.patch ***/
-+
-   SAVEPOINT *savepoints;
-   enum enum_check_fields count_cuted_fields;
- };
-@@ -1427,6 +1460,77 @@
-   thr_lock_type update_lock_default;
-   Delayed_insert *di;
-+  /*** Following variables used in slow_extended.patch ***/
-+  /*
-+    Variable write_to_slow_log:
-+     1) initialized in
-+       * sql_connect.cc (log_slow_rate_limit support)
-+       * slave.cc       (log_slow_slave_statements support)
-+     2) The variable is initialized on the thread startup and remains
-+        constant afterwards.  This will change when 
-+        LP #712396 ("log_slow_slave_statements not work on replication 
-+        threads without RESTART") is implemented.
-+     3) An implementation of LP #688646 ("Make query sampling possible 
-+        by query") should use it.
-+  */
-+  bool       write_to_slow_log;
-+  /*
-+    Variable bytes_send_old saves value of thd->status_var.bytes_sent
-+    before query execution.
-+  */
-+  ulonglong  bytes_sent_old;
-+  /*
-+    Original row_count value at the start of query execution
-+    (used by the slow_extended patch).
-+  */
-+  ulong      orig_row_count;
-+  /*
-+    Variables tmp_tables_*** collect statistics about usage of temporary tables
-+  */
-+  ulong      tmp_tables_used;
-+  ulong      tmp_tables_disk_used;
-+  ulonglong  tmp_tables_size;
-+  /*
-+    Variable innodb_was_used shows used or not InnoDB engine in current query.
-+  */
-+  bool       innodb_was_used;
-+  /*
-+    Following Variables innodb_*** (is |should be) different from
-+    default values only if (innodb_was_used==TRUE)
-+  */
-+  ulonglong  innodb_trx_id;
-+  ulong      innodb_io_reads;
-+  ulonglong  innodb_io_read;
-+  ulong      innodb_io_reads_wait_timer;
-+  ulong      innodb_lock_que_wait_timer;
-+  ulong      innodb_innodb_que_wait_timer;
-+  ulong      innodb_page_access;
-+
-+  /*
-+    Variable query_plan_flags collects information about query plan entites
-+    used on query execution.
-+  */
-+  ulong      query_plan_flags;
-+  /*
-+    Variable query_plan_fsort_passes collects information about file sort passes
-+    acquired during query execution.
-+  */
-+  ulong      query_plan_fsort_passes;
-+  /*
-+    Query can generate several errors/warnings during execution
-+    (see THD::handle_condition comment in sql_class.h)
-+    Variable last_errno contains the last error/warning acquired during
-+    query execution.
-+  */
-+  uint       last_errno;
-+  /*** The variables above used in slow_extended.patch ***/
-+
-+  /*** Following methods used in slow_extended.patch ***/
-+  void clear_slow_extended();
-+  void reset_sub_statement_state_slow_extended(Sub_statement_state *backup);
-+  void restore_sub_statement_state_slow_extended(const Sub_statement_state *backup);
-+  /*** The methods above used in slow_extended.patch ***/
-+
-   /* <> 0 if we are inside of trigger or stored function. */
-   uint in_sub_stmt;
-   /* TRUE when the current top has SQL_LOG_BIN ON */
---- a/sql/sql_connect.cc
-+++ b/sql/sql_connect.cc
-@@ -1421,6 +1421,15 @@
-     if (login_connection(thd))
-       goto end_thread;
-+    /* 
-+      If rate limiting of slow log writes is enabled, decide whether to log this 
-+      new thread's queries or not. Uses extremely simple algorithm. :) 
-+    */ 
-+    thd->write_to_slow_log= FALSE; 
-+    if (thd->variables.log_slow_rate_limit <= 1 ||  
-+        (thd->thread_id % thd->variables.log_slow_rate_limit) == 0) 
-+         thd->write_to_slow_log= TRUE; 
-+
-     prepare_new_connection_state(thd);
-     while (!net->error && net->vio != 0 &&
---- a/sql/sql_parse.cc
-+++ b/sql/sql_parse.cc
-@@ -48,6 +48,7 @@
- static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
- static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
-+static inline ulonglong get_query_exec_time(THD *thd, ulonglong cur_utime);
- const char *any_db="*any*";   // Special symbol for check_access
-@@ -1001,6 +1002,7 @@
-     the slow log only if opt_log_slow_admin_statements is set.
-   */
-   thd->enable_slow_log= TRUE;
-+  thd->clear_slow_extended();
-   thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
-   thd->set_time();
-   if (!thd->is_valid_time())
-@@ -1702,6 +1704,50 @@
-   DBUG_RETURN(error);
- }
-+/**
-+   Calculate execution time for the current query.
-+
-+   For debug builds, check the session value of query_exec_time
-+   and if it is not zero, return it instead of the actual execution time.
-+
-+   SET queries are ignored so that statements changing query_exec_time are not
-+   affected by themselves.
-+
-+   @param thd              thread handle
-+   @param lex              current relative time in microseconds
-+
-+   @return                 time in microseconds from utime_after_lock
-+*/
-+
-+static inline ulonglong get_query_exec_time(THD *thd, ulonglong cur_utime)
-+{
-+#ifndef DBUG_OFF
-+  if (thd->variables.query_exec_time)
-+    return thd->lex->sql_command != SQLCOM_SET_OPTION ?
-+      thd->variables.query_exec_time : 0;
-+#endif
-+
-+  return cur_utime - thd->utime_after_lock;
-+}
-+
-+
-+static inline void copy_global_to_session(THD *thd, ulong flag,
-+                                          const ulong *val)
-+{
-+  my_ptrdiff_t offset = ((char *)val - (char *)&global_system_variables);
-+  if (global_system_variables.use_global_log_slow_control & flag)
-+    *(ulong *)((char *) &thd->variables + offset) = *val;
-+}
-+
-+
-+static inline void copy_global_to_session(THD *thd, ulong flag,
-+                                          const ulonglong *val)
-+{
-+  my_ptrdiff_t offset = ((char *)val - (char *)&global_system_variables);
-+  if (global_system_variables.use_global_log_slow_control & flag)
-+    *(ulonglong *)((char *) &thd->variables + offset) = *val;
-+}
-+
- void log_slow_statement(THD *thd)
- {
-@@ -1715,17 +1761,51 @@
-   if (unlikely(thd->in_sub_stmt))
-     DBUG_VOID_RETURN;                           // Don't set time for sub stmt
-+  /* Follow the slow log filter configuration. */
-+  if (thd->variables.log_slow_filter != SLOG_F_NONE &&
-+      (!(thd->variables.log_slow_filter & thd->query_plan_flags) ||
-+       ((thd->variables.log_slow_filter & SLOG_F_QC_NO) &&
-+        (thd->query_plan_flags & QPLAN_QC))))
-+    DBUG_VOID_RETURN;
-+
-+  ulonglong end_utime_of_query= thd->current_utime();
-+  ulonglong query_exec_time= get_query_exec_time(thd, end_utime_of_query);
-+
-+  /*
-+    Low long_query_time value most likely means user is debugging stuff and even
-+    though some thread's queries are not supposed to be logged b/c of the rate
-+    limit, if one of them takes long enough (>= 1 second) it will be sensible
-+    to make an exception and write to slow log anyway.
-+  */
-+
-+  /* use_global_log_slow_control */
-+  system_variables const &g= global_system_variables;
-+  copy_global_to_session(thd, SLOG_UG_LOG_SLOW_FILTER,
-+                         &g.log_slow_filter);
-+  copy_global_to_session(thd, SLOG_UG_LOG_SLOW_RATE_LIMIT,
-+                         &g.log_slow_rate_limit);
-+  copy_global_to_session(thd, SLOG_UG_LOG_SLOW_VERBOSITY,
-+                         &g.log_slow_verbosity);
-+  copy_global_to_session(thd, SLOG_UG_LONG_QUERY_TIME,
-+                         &g.long_query_time);
-+  copy_global_to_session(thd, SLOG_UG_MIN_EXAMINED_ROW_LIMIT,
-+                         &g.min_examined_row_limit);
-+
-+  /* Do not log this thread's queries due to rate limiting. */
-+  if (thd->write_to_slow_log != TRUE
-+      && (thd->variables.long_query_time >= 1000000
-+          || (ulong) query_exec_time < 1000000))
-+    DBUG_VOID_RETURN;
-+
-   /*
-     Do not log administrative statements unless the appropriate option is
-     set.
-   */
-   if (thd->enable_slow_log)
-   {
--    ulonglong end_utime_of_query= thd->current_utime();
-     thd_proc_info(thd, "logging slow query");
--    if (((end_utime_of_query - thd->utime_after_lock) >
--         thd->variables.long_query_time ||
-+    if (((query_exec_time > thd->variables.long_query_time) ||
-          ((thd->server_status &
-            (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
-           opt_log_queries_not_using_indexes &&
-@@ -5827,7 +5907,8 @@
-   thd->main_da.reset_diagnostics_area();
-   thd->total_warn_count=0;                    // Warnings for this query
-   thd->rand_used= 0;
--  thd->sent_row_count= thd->examined_row_count= 0;
-+
-+  thd->clear_slow_extended();
-   /*
-     Because we come here only for start of top-statements, binlog format is
---- a/sql/sql_select.cc
-+++ b/sql/sql_select.cc
-@@ -6798,7 +6798,10 @@
-         {
-           join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
-           if (statistics)
-+            {
-             status_var_increment(join->thd->status_var.select_scan_count);
-+              join->thd->query_plan_flags|= QPLAN_FULL_SCAN;
-+            }
-         }
-       }
-       else
-@@ -6812,7 +6815,10 @@
-         {
-           join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
-           if (statistics)
-+            {
-             status_var_increment(join->thd->status_var.select_full_join_count);
-+              join->thd->query_plan_flags|= QPLAN_FULL_JOIN;
-+            }
-         }
-       }
-       if (!table->no_keyread)
-@@ -10016,6 +10022,7 @@
-               (ulong) rows_limit,test(group)));
-   status_var_increment(thd->status_var.created_tmp_tables);
-+  thd->query_plan_flags|= QPLAN_TMP_TABLE;
-   if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
-     temp_pool_slot = bitmap_lock_set_next(&temp_pool);
-@@ -10897,6 +10904,7 @@
-     goto err;
-   }
-   status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
-+  table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
-   share->db_record_offset= 1;
-   DBUG_RETURN(0);
-  err:
-@@ -10915,6 +10923,14 @@
-   save_proc_info=thd->proc_info;
-   thd_proc_info(thd, "removing tmp table");
-+  thd->tmp_tables_used++;
-+  if (entry->file)
-+  {
-+    thd->tmp_tables_size += entry->file->stats.data_file_length;
-+    if (entry->file->ht->db_type != DB_TYPE_HEAP)
-+      thd->tmp_tables_disk_used++;
-+  }
-+
-   // Release latches since this can take a long time
-   ha_release_temporary_latches(thd);
---- a/sql/sql_show.cc
-+++ b/sql/sql_show.cc
-@@ -1971,8 +1971,17 @@
-         table->field[4]->store(command_name[tmp->command].str,
-                                command_name[tmp->command].length, cs);
-       /* MYSQL_TIME */
--      table->field[5]->store((longlong)(tmp->start_time ?
--                                      now - tmp->start_time : 0), FALSE);
-+      longlong value_in_time_column= 0;
-+      if(tmp->start_time)
-+      {
-+        value_in_time_column = (now - tmp->start_time);
-+        if(value_in_time_column > now)
-+        {
-+          value_in_time_column= 0;
-+        }
-+      }
-+      table->field[5]->store(value_in_time_column, FALSE);
-+
-       /* STATE */
- #ifndef EMBEDDED_LIBRARY
-       val= (char*) (tmp->locked ? "Locked" :
---- /dev/null
-+++ b/mysql-test/include/log_grep.inc
-@@ -0,0 +1,17 @@
-+--disable_query_log
-+--echo [log_grep.inc] file: $log_file pattern: $grep_pattern
-+perl;
-+  $log_file=           $ENV{'log_file'};
-+  $log_file_full_path= $ENV{'log_file_full_path'};
-+  $grep_pattern=       $ENV{'grep_pattern'};
-+
-+  open(FILE, "$log_file_full_path") 
-+    or die("Cannot open file $log_file_full_path: $!\n");
-+
-+  $lines = 0;
-+  while(<FILE>) {
-+    $lines++ if (/$grep_pattern/);
-+  }
-+  close(FILE);
-+  print "[log_grep.inc] lines:   $lines\n";
-+EOF
---- /dev/null
-+++ b/mysql-test/include/log_start.inc
-@@ -0,0 +1,16 @@
-+--let slow_query_log_file_old=`SELECT Variable_value FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE Variable_name = 'slow_query_log_file';`
-+--let slow_query_log_old=`SELECT Variable_value FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE Variable_name = 'slow_query_log';`
-+--disable_query_log
-+--let log_file_full_path = $MYSQLTEST_VARDIR/$log_file
-+SET GLOBAL slow_query_log=0;
-+perl;
-+  $log_file_full_path= $ENV{'log_file_full_path'};
-+  unlink $log_file_full_path;
-+  open(FILE, '>', $log_file_full_path)
-+    or die "Cannot create log file $log_file_full_path, reason: $!";
-+  close(FILE);
-+EOF
-+--echo [log_start.inc] $log_file
-+EVAL SET GLOBAL slow_query_log_file="$log_file_full_path";
-+SET GLOBAL slow_query_log=1;
-+--enable_query_log
---- /dev/null
-+++ b/mysql-test/include/log_stop.inc
-@@ -0,0 +1,7 @@
-+--disable_query_log
-+FLUSH LOGS;
-+SET GLOBAL slow_query_log=0;
-+--echo [log_stop.inc] $log_file
-+EVAL SET GLOBAL slow_query_log_file= "$slow_query_log_file_old";
-+EVAL SET GLOBAL slow_query_log=      $slow_query_log_old ;
-+--enable_query_log
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_filter-cl.result
-@@ -0,0 +1,6 @@
-+SHOW VARIABLES LIKE 'log_slow_filter';
-+Variable_name Value
-+log_slow_filter       full_join
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_filter';
-+Variable_name Value
-+log_slow_filter       full_join
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_filter.result
-@@ -0,0 +1,15 @@
-+CREATE TABLE t(id INT PRIMARY KEY);
-+INSERT INTO t VALUES(1);
-+INSERT INTO t VALUES(2);
-+INSERT INTO t VALUES(3);
-+SET long_query_time=1;
-+SET log_slow_filter=full_join;
-+[log_start.inc] percona.slow_extended.log_slow_filter
-+SET query_exec_time = 1.1;
-+SELECT * FROM t AS t1, t AS t2;
-+SET query_exec_time = default;
-+[log_stop.inc] percona.slow_extended.log_slow_filter
-+SET log_slow_filter=default;
-+SET long_query_time=default;
-+[log_grep.inc] file: percona.slow_extended.log_slow_filter pattern: Query_time
-+[log_grep.inc] lines:   1
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_slave_statements-cl.result
-@@ -0,0 +1,6 @@
-+SHOW VARIABLES LIKE 'log_slow_slave_statements';
-+Variable_name Value
-+log_slow_slave_statements     ON
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_slave_statements';
-+Variable_name Value
-+log_slow_slave_statements     ON
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_slave_statements-innodb.result
-@@ -0,0 +1,18 @@
-+include/master-slave.inc
-+[connection master]
-+DROP TABLE IF EXISTS t;
-+CREATE TABLE t(id INT,data CHAR(30)) ENGINE=InnoDB;
-+INSERT INTO t VALUES
-+(1,"aaaaabbbbbcccccdddddeeeeefffff"),
-+(2,"aaaaabbbbbcccccdddddeeeeefffff"),
-+(3,"aaaaabbbbbcccccdddddeeeeefffff"),
-+(4,"aaaaabbbbbcccccdddddeeeeefffff"),
-+(5,"aaaaabbbbbcccccdddddeeeeefffff");
-+INSERT INTO t SELECT t2.id,t2.data from t as t1, t as t2;
-+INSERT INTO t SELECT t2.id,t2.data from t as t1, t as t2;
-+include/rpl_restart_server.inc [server_number=1]
-+[log_start.inc] percona.slow_extended.log_slow_slave_statements-innodb
-+[log_stop.inc] percona.slow_extended.log_slow_slave_statements-innodb
-+[log_grep.inc] file: percona.slow_extended.log_slow_slave_statements-innodb pattern: InnoDB_IO_r_ops
-+[log_grep.inc] lines:   1
-+include/rpl_end.inc
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_slave_statements.result
-@@ -0,0 +1,46 @@
-+include/master-slave.inc
-+[connection master]
-+DROP TABLE IF EXISTS t;
-+CREATE TABLE t(id INT);
-+[log_start.inc] percona.slow_extended.log_slow_slave_statements
-+LINE 1
-+LOG_SLOW_SLAVE_STATAMENTS is OFF
-+LOG_SLOW_SLAVE_STATEMENTS=1
-+LOG_SLOW_SLAVE_STATAMENTS is ON
-+LINE 2
-+include/restart_slave.inc
-+LOG_SLOW_SLAVE_STATAMENTS is ON
-+LINE 3
-+LOG_SLOW_SLAVE_STATAMENTS is ON
-+LOG_SLOW_SLAVE_STATEMENTS=0
-+LOG_SLOW_SLAVE_STATAMENTS is OFF
-+LINE 4
-+include/restart_slave.inc
-+LOG_SLOW_SLAVE_STATAMENTS is OFF
-+LINE 5
-+LOG_SLOW_SLAVE_STATAMENTS is OFF
-+LOG_SLOW_SLAVE_STATEMENTS=1
-+LOG_SLOW_SLAVE_STATAMENTS is ON
-+LINE 6
-+include/restart_slave.inc
-+LOG_SLOW_SLAVE_STATAMENTS is ON
-+LINE 7
-+[log_stop.inc] percona.slow_extended.log_slow_slave_statements
-+SET GLOBAL log_slow_slave_statements=default;
-+[log_grep.inc] file: percona.slow_extended.log_slow_slave_statements pattern: INSERT INTO t VALUES \(1\)
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.log_slow_slave_statements pattern: INSERT INTO t VALUES \(2\)
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.log_slow_slave_statements pattern: INSERT INTO t VALUES \(3\)
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.log_slow_slave_statements pattern: INSERT INTO t VALUES \(4\)
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.log_slow_slave_statements pattern: INSERT INTO t VALUES \(5\)
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.log_slow_slave_statements pattern: INSERT INTO t VALUES \(6\)
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.log_slow_slave_statements pattern: INSERT INTO t VALUES \(7\)
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.log_slow_slave_statements pattern: INSERT INTO t VALUES \(8\)
-+[log_grep.inc] lines:   0
-+include/rpl_end.inc
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_sp_statements-cl.result
-@@ -0,0 +1,6 @@
-+SHOW VARIABLES LIKE 'log_slow_sp_statements';
-+Variable_name Value
-+log_slow_sp_statements        ON
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_sp_statements';
-+Variable_name Value
-+log_slow_sp_statements        ON
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_sp_statements.result
-@@ -0,0 +1,22 @@
-+SET long_query_time=1;
-+SET GLOBAL log_slow_sp_statements=1;
-+[log_start.inc] percona.slow_extended.log_slow_sp_statements
-+CREATE PROCEDURE test_f()
-+BEGIN
-+SET SESSION query_exec_time=1.1; SELECT 1;
-+SET SESSION query_exec_time=2.1; SELECT 1;
-+SET SESSION query_exec_time=3.1; SELECT 1;
-+SET SESSION query_exec_time=default;
-+END^
-+CALL test_f();
-+1
-+1
-+1
-+1
-+1
-+1
-+[log_stop.inc] percona.slow_extended.log_slow_sp_statements
-+SET GLOBAL log_slow_sp_statements=default;
-+SET long_query_time=default;
-+[log_grep.inc] file: percona.slow_extended.log_slow_sp_statements pattern: Query_time
-+[log_grep.inc] lines:   3
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_timestamp_every-cl.result
-@@ -0,0 +1,6 @@
-+SHOW VARIABLES LIKE 'log_slow_timestamp_every';
-+Variable_name Value
-+log_slow_timestamp_every      ON
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_timestamp_every';
-+Variable_name Value
-+log_slow_timestamp_every      ON
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_timestamp_every.result
-@@ -0,0 +1,39 @@
-+SET long_query_time=2;
-+SET GLOBAL log_slow_timestamp_every=1;
-+[log_start.inc] percona.slow_extended.log_slow_timestamp_every
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SELECT 2;
-+2
-+2
-+SELECT 3;
-+3
-+3
-+SET GLOBAL log_slow_timestamp_every=0;
-+SELECT 1;
-+1
-+1
-+SELECT 2;
-+2
-+2
-+SELECT 3;
-+3
-+3
-+SET GLOBAL log_slow_timestamp_every=1;
-+SELECT 1;
-+1
-+1
-+SELECT 2;
-+2
-+2
-+SELECT 3;
-+3
-+3
-+SET SESSION query_exec_time = default;
-+[log_stop.inc] percona.slow_extended.log_slow_timestamp_every
-+SET GLOBAL log_slow_timestamp_every=default;
-+SET long_query_time=default;
-+[log_grep.inc] file: percona.slow_extended.log_slow_timestamp_every pattern: # Time: [0-9]+[ ]+[0-9]+:[0-9]+:[0-9]+
-+[log_grep.inc] lines:   6
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_verbosity-cl.result
-@@ -0,0 +1,6 @@
-+SHOW VARIABLES LIKE 'log_slow_verbosity';
-+Variable_name Value
-+log_slow_verbosity    microtime,query_plan,innodb
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_verbosity';
-+Variable_name Value
-+log_slow_verbosity    microtime,query_plan,innodb
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_verbosity.result
-@@ -0,0 +1,16 @@
-+SET SESSION long_query_time=1;
-+[log_start.inc] percona.slow_extended.log_slow_verbosity
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION log_slow_verbosity=innodb;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=default;
-+[log_stop.inc] percona.slow_extended.log_slow_verbosity
-+SET log_slow_verbosity='';
-+SET long_query_time=default;
-+[log_grep.inc] file: percona.slow_extended.log_slow_verbosity pattern: No InnoDB statistics available for this query
-+[log_grep.inc] lines:   1
---- /dev/null
-+++ b/mysql-test/r/percona_long_query_time.result
-@@ -0,0 +1,33 @@
-+SET long_query_time=2;
-+[log_start.inc] percona.slow_extended.long_query_time
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET long_query_time=4;
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=default;
-+SET long_query_time=2;
-+[log_stop.inc] percona.slow_extended.long_query_time
-+SET long_query_time=default;
-+[log_grep.inc] file: percona.slow_extended.long_query_time pattern: Query_time
-+[log_grep.inc] lines:   3
---- /dev/null
-+++ b/mysql-test/r/percona_min_examined_row_limit.result
-@@ -0,0 +1,34 @@
-+drop table if exists t;
-+create table t(id INT PRIMARY KEY);
-+insert into t values(1);
-+insert into t values(2);
-+insert into t values(3);
-+SET GLOBAL long_query_time=2;
-+SET GLOBAL use_global_log_slow_control='long_query_time,min_examined_row_limit';
-+[log_start.inc] percona.slow_extended.min_examined_row_limit
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET GLOBAL min_examined_row_limit=5;
-+SELECT * FROM t AS t1, t AS t2;
-+id    id
-+1     1
-+2     1
-+3     1
-+1     2
-+2     2
-+3     2
-+1     3
-+2     3
-+3     3
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=default;
-+[log_stop.inc] percona.slow_extended.min_examined_row_limit
-+SET GLOBAL min_examined_row_limit=default;
-+SET GLOBAL use_global_log_slow_control='';
-+SET GLOBAL long_query_time=default;
-+[log_grep.inc] file: percona.slow_extended.min_examined_row_limit pattern: Query_time
-+[log_grep.inc] lines:   1
---- /dev/null
-+++ b/mysql-test/r/percona_slow_query_log_microseconds_timestamp-cl.result
-@@ -0,0 +1,6 @@
-+SHOW VARIABLES LIKE 'slow_query_log_microseconds_timestamp';
-+Variable_name Value
-+slow_query_log_microseconds_timestamp ON
-+SHOW GLOBAL VARIABLES LIKE 'slow_query_log_microseconds_timestamp';
-+Variable_name Value
-+slow_query_log_microseconds_timestamp ON
---- /dev/null
-+++ b/mysql-test/r/percona_slow_query_log_microseconds_timestamp.result
-@@ -0,0 +1,18 @@
-+SET long_query_time=2;
-+[log_start.inc] percona.slow_extended.slow_query_log_microseconds_timestamp
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET GLOBAL slow_query_log_microseconds_timestamp=1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=default;
-+[log_stop.inc] percona.slow_extended.slow_query_log_microseconds_timestamp
-+SET GLOBAL slow_query_log_microseconds_timestamp=default;
-+SET long_query_time=default;
-+[log_grep.inc] file: percona.slow_extended.slow_query_log_microseconds_timestamp pattern: # Time: [0-9]+[ ]+[0-9]+:[0-9]+:[0-9]+.[0-9]+
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.slow_query_log_microseconds_timestamp pattern: # Time: [0-9]+[ ]+[0-9]+:[0-9]+:[0-9]+
-+[log_grep.inc] lines:   2
---- /dev/null
-+++ b/mysql-test/r/percona_use_global_log_slow_control-cl.result
-@@ -0,0 +1,6 @@
-+SHOW VARIABLES LIKE 'use_global_log_slow_control';
-+Variable_name Value
-+use_global_log_slow_control   log_slow_verbosity,long_query_time
-+SHOW GLOBAL VARIABLES LIKE 'use_global_log_slow_control';
-+Variable_name Value
-+use_global_log_slow_control   log_slow_verbosity,long_query_time
---- /dev/null
-+++ b/mysql-test/r/percona_use_global_log_slow_control.result
-@@ -0,0 +1,18 @@
-+SET GLOBAL long_query_time=1;
-+[log_start.inc] percona.slow_extended.use_global_log_slow_control
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET GLOBAL log_slow_verbosity=innodb;
-+SET GLOBAL use_global_log_slow_control="log_slow_verbosity,long_query_time";
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=default;
-+[log_stop.inc] percona.slow_extended.use_global_log_slow_control
-+SET GLOBAL use_global_log_slow_control='';
-+SET GLOBAL log_slow_verbosity='';
-+SET GLOBAL long_query_time=default;
-+[log_grep.inc] file: percona.slow_extended.use_global_log_slow_control pattern: No InnoDB statistics available for this query
-+[log_grep.inc] lines:   1
---- /dev/null
-+++ b/mysql-test/r/percona_use_global_long_query_time.result
-@@ -0,0 +1,34 @@
-+[log_start.inc] percona.slow_extended.use_global_long_query_time
-+SET long_query_time=2;
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET GLOBAL long_query_time=4;
-+SET GLOBAL use_global_long_query_time=1;
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0;
-+[log_stop.inc] percona.slow_extended.use_global_long_query_time
-+SET GLOBAL long_query_time=default;
-+SET GLOBAL use_global_long_query_time=0;
-+[log_grep.inc] file: percona.slow_extended.use_global_long_query_time pattern: Query_time
-+[log_grep.inc] lines:   3
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_filter-cl-master.opt
-@@ -0,0 +1 @@
-+--log_slow_filter=full_join
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_filter-cl.test
-@@ -0,0 +1,2 @@
-+SHOW VARIABLES LIKE 'log_slow_filter';
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_filter';
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_filter.test
-@@ -0,0 +1,26 @@
-+--source include/have_debug.inc
-+
-+CREATE TABLE t(id INT PRIMARY KEY);
-+INSERT INTO t VALUES(1);
-+INSERT INTO t VALUES(2);
-+INSERT INTO t VALUES(3);
-+
-+SET long_query_time=1;
-+SET log_slow_filter=full_join;
-+--let log_file=percona.slow_extended.log_slow_filter
-+--source include/log_start.inc
-+
-+SET query_exec_time = 1.1;
-+--disable_result_log
-+SELECT * FROM t AS t1, t AS t2;
-+--enable_result_log
-+SET query_exec_time = default;
-+
-+--source include/log_stop.inc
-+SET log_slow_filter=default;
-+SET long_query_time=default;
-+
-+--let grep_pattern = Query_time
-+--source include/log_grep.inc
-+
-+DROP TABLE t;
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_slave_statements-cl-master.opt
-@@ -0,0 +1 @@
-+--log_slow_slave_statements
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_slave_statements-cl.test
-@@ -0,0 +1,3 @@
-+SHOW VARIABLES LIKE 'log_slow_slave_statements';
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_slave_statements';
-+
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_slave_statements-innodb-slave.opt
-@@ -0,0 +1 @@
-+--long_query_time=0 --log_slow_slave_statements --log_slow_verbosity=innodb
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_slave_statements-innodb.test
-@@ -0,0 +1,48 @@
-+--source include/have_binlog_format_statement.inc
-+--source include/master-slave.inc
-+--source include/have_innodb.inc
-+--let log_file=percona.slow_extended.log_slow_slave_statements-innodb
-+
-+connection master;
-+-- disable_warnings
-+DROP TABLE IF EXISTS t;
-+-- enable_warnings
-+
-+CREATE TABLE t(id INT,data CHAR(30)) ENGINE=InnoDB;
-+INSERT INTO t VALUES
-+(1,"aaaaabbbbbcccccdddddeeeeefffff"),
-+(2,"aaaaabbbbbcccccdddddeeeeefffff"),
-+(3,"aaaaabbbbbcccccdddddeeeeefffff"),
-+(4,"aaaaabbbbbcccccdddddeeeeefffff"),
-+(5,"aaaaabbbbbcccccdddddeeeeefffff");
-+INSERT INTO t SELECT t2.id,t2.data from t as t1, t as t2;
-+INSERT INTO t SELECT t2.id,t2.data from t as t1, t as t2;
-+sync_slave_with_master;
-+
-+--let rpl_server_number=1
-+--source include/rpl_restart_server.inc
-+
-+connection slave;
-+--source include/log_start.inc
-+
-+--disable_query_log
-+--disable_result_log
-+
-+connection master;
-+INSERT INTO t SELECT t.id,t.data from t;
-+sync_slave_with_master;
-+
-+connection slave;
-+--source include/log_stop.inc
-+
-+--enable_query_log
-+--enable_result_log
-+
-+--let grep_pattern =  InnoDB_IO_r_ops
-+--source include/log_grep.inc
-+
-+connection master;
-+DROP TABLE t;
-+sync_slave_with_master;
-+
-+--source include/rpl_end.inc
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_slave_statements-slave.opt
-@@ -0,0 +1 @@
-+--long_query_time=0
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_slave_statements.test
-@@ -0,0 +1,119 @@
-+-- source include/have_binlog_format_statement.inc
-+-- source include/master-slave.inc
-+--let log_file=percona.slow_extended.log_slow_slave_statements
-+--let show=SELECT Variable_value FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE Variable_name LIKE 'log_slow_slave_statements';
-+
-+connection master;
-+-- disable_warnings
-+DROP TABLE IF EXISTS t;
-+-- enable_warnings
-+
-+CREATE TABLE t(id INT);
-+sync_slave_with_master;
-+
-+connection slave;
-+--source include/log_start.inc
-+
-+--disable_query_log
-+--disable_result_log
-+
-+--echo LINE 1
-+connection master;
-+INSERT INTO t VALUES (1);
-+sync_slave_with_master;
-+
-+connection slave;
-+--let value=`$show`
-+--echo LOG_SLOW_SLAVE_STATAMENTS is $value
-+--echo LOG_SLOW_SLAVE_STATEMENTS=1
-+SET GLOBAL log_slow_slave_statements=1;
-+--let value=`$show`
-+--echo LOG_SLOW_SLAVE_STATAMENTS is $value
-+
-+--echo LINE 2
-+connection master;
-+INSERT INTO t VALUES (2);
-+sync_slave_with_master;
-+
-+--source include/restart_slave_sql.inc
-+
-+connection slave;
-+--let value=`$show`
-+--echo LOG_SLOW_SLAVE_STATAMENTS is $value
-+
-+--echo LINE 3
-+connection master;
-+INSERT INTO t VALUES (3);
-+sync_slave_with_master;
-+
-+connection slave;
-+--let value=`$show`
-+--echo LOG_SLOW_SLAVE_STATAMENTS is $value
-+--echo LOG_SLOW_SLAVE_STATEMENTS=0
-+SET GLOBAL log_slow_slave_statements=0;
-+--let value=`$show`
-+--echo LOG_SLOW_SLAVE_STATAMENTS is $value
-+
-+--echo LINE 4
-+connection master;
-+INSERT INTO t VALUES (4);
-+sync_slave_with_master;
-+
-+--source include/restart_slave_sql.inc
-+
-+connection slave;
-+--let value=`$show`
-+--echo LOG_SLOW_SLAVE_STATAMENTS is $value
-+
-+--echo LINE 5
-+connection master;
-+INSERT INTO t VALUES (5);
-+sync_slave_with_master;
-+
-+connection slave;
-+--let value=`$show`
-+--echo LOG_SLOW_SLAVE_STATAMENTS is $value
-+--echo LOG_SLOW_SLAVE_STATEMENTS=1
-+SET GLOBAL log_slow_slave_statements=1;
-+--let value=`$show`
-+--echo LOG_SLOW_SLAVE_STATAMENTS is $value
-+
-+--echo LINE 6
-+connection master;
-+INSERT INTO t VALUES (6);
-+sync_slave_with_master;
-+
-+--source include/restart_slave_sql.inc
-+
-+connection slave;
-+--let value=`$show`
-+--echo LOG_SLOW_SLAVE_STATAMENTS is $value
-+
-+--echo LINE 7
-+connection master;
-+INSERT INTO t VALUES (7);
-+sync_slave_with_master;
-+
-+--enable_query_log
-+--enable_result_log
-+
-+connection slave;
-+--source include/log_stop.inc
-+SET GLOBAL log_slow_slave_statements=default;
-+
-+connection slave;
-+--let i=1
-+--let k=8
-+while($k)
-+{
-+--let grep_pattern= INSERT INTO t VALUES \($i\)
-+--source include/log_grep.inc
-+  inc $i;
-+  dec $k;
-+}
-+
-+connection master;
-+DROP TABLE t;
-+sync_slave_with_master;
-+
-+--source include/rpl_end.inc
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_sp_statements-cl-master.opt
-@@ -0,0 +1 @@
-+--log_slow_sp_statements
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_sp_statements-cl.test
-@@ -0,0 +1,2 @@
-+SHOW VARIABLES LIKE 'log_slow_sp_statements';
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_sp_statements';
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_sp_statements.test
-@@ -0,0 +1,27 @@
-+--source include/have_debug.inc
-+
-+SET long_query_time=1;
-+SET GLOBAL log_slow_sp_statements=1;
-+--let log_file=percona.slow_extended.log_slow_sp_statements
-+--source include/log_start.inc
-+
-+delimiter ^;
-+CREATE PROCEDURE test_f()
-+BEGIN
-+  SET SESSION query_exec_time=1.1; SELECT 1;
-+  SET SESSION query_exec_time=2.1; SELECT 1;
-+  SET SESSION query_exec_time=3.1; SELECT 1;
-+  SET SESSION query_exec_time=default;
-+END^
-+delimiter ;^  
-+
-+CALL test_f();
-+
-+--source include/log_stop.inc
-+SET GLOBAL log_slow_sp_statements=default;
-+SET long_query_time=default;
-+
-+--let grep_pattern = Query_time
-+--source include/log_grep.inc
-+
-+DROP PROCEDURE test_f;
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_timestamp_every-cl-master.opt
-@@ -0,0 +1 @@
-+--log_slow_timestamp_every
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_timestamp_every-cl.test
-@@ -0,0 +1,2 @@
-+SHOW VARIABLES LIKE 'log_slow_timestamp_every';
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_timestamp_every';
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_timestamp_every.test
-@@ -0,0 +1,33 @@
-+--source include/have_debug.inc
-+
-+SET long_query_time=2;
-+SET GLOBAL log_slow_timestamp_every=1;
-+--let log_file=percona.slow_extended.log_slow_timestamp_every
-+--source include/log_start.inc
-+
-+SET SESSION query_exec_time=2.1;
-+
-+SELECT 1;
-+SELECT 2;
-+SELECT 3;
-+
-+SET GLOBAL log_slow_timestamp_every=0;
-+
-+SELECT 1;
-+SELECT 2;
-+SELECT 3;
-+
-+SET GLOBAL log_slow_timestamp_every=1;
-+
-+SELECT 1;
-+SELECT 2;
-+SELECT 3;
-+
-+SET SESSION query_exec_time = default;
-+
-+--source include/log_stop.inc
-+SET GLOBAL log_slow_timestamp_every=default;
-+SET long_query_time=default;
-+
-+--let grep_pattern =  # Time: [0-9]+[ ]+[0-9]+:[0-9]+:[0-9]+
-+--source include/log_grep.inc
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_verbosity-cl-master.opt
-@@ -0,0 +1 @@
-+--log_slow_verbosity="full"
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_verbosity-cl.test
-@@ -0,0 +1,2 @@
-+SHOW VARIABLES LIKE 'log_slow_verbosity';
-+SHOW GLOBAL VARIABLES LIKE 'log_slow_verbosity';
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_verbosity.test
-@@ -0,0 +1,19 @@
-+--source include/have_innodb.inc
-+--source include/have_debug.inc
-+
-+SET SESSION long_query_time=1;
-+--let log_file=percona.slow_extended.log_slow_verbosity
-+--source include/log_start.inc
-+
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+SET SESSION log_slow_verbosity=innodb; 
-+SELECT 1;
-+SET SESSION query_exec_time=default;
-+
-+--source include/log_stop.inc
-+SET log_slow_verbosity='';
-+SET long_query_time=default;
-+
-+--let grep_pattern = No InnoDB statistics available for this query
-+--source include/log_grep.inc
---- /dev/null
-+++ b/mysql-test/t/percona_long_query_time.test
-@@ -0,0 +1,25 @@
-+--source include/have_debug.inc
-+
-+SET long_query_time=2;
-+--let log_file=percona.slow_extended.long_query_time
-+--source include/log_start.inc
-+
-+SET SESSION query_exec_time=1.1; SELECT 1;
-+SET SESSION query_exec_time=3.1; SELECT 1;
-+SET SESSION query_exec_time=5.1; SELECT 1;
-+
-+SET long_query_time=4;
-+
-+SET SESSION query_exec_time=1.1; SELECT 1;
-+SET SESSION query_exec_time=3.1; SELECT 1;
-+SET SESSION query_exec_time=5.1; SELECT 1;
-+
-+SET SESSION query_exec_time=default;
-+
-+SET long_query_time=2;
-+
-+--source include/log_stop.inc
-+SET long_query_time=default;
-+
-+--let grep_pattern = Query_time
-+--source include/log_grep.inc
---- /dev/null
-+++ b/mysql-test/t/percona_min_examined_row_limit.test
-@@ -0,0 +1,35 @@
-+--source include/have_debug.inc
-+
-+--disable_warnings
-+drop table if exists t;
-+--enable_warnings
-+
-+create table t(id INT PRIMARY KEY);
-+insert into t values(1);
-+insert into t values(2);
-+insert into t values(3);
-+
-+SET GLOBAL long_query_time=2;
-+SET GLOBAL use_global_log_slow_control='long_query_time,min_examined_row_limit';
-+--let log_file=percona.slow_extended.min_examined_row_limit
-+--source include/log_start.inc
-+
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+
-+SET GLOBAL min_examined_row_limit=5;
-+
-+SELECT * FROM t AS t1, t AS t2;
-+SELECT 1;
-+
-+SET SESSION query_exec_time=default;
-+
-+--source include/log_stop.inc
-+SET GLOBAL min_examined_row_limit=default;
-+SET GLOBAL use_global_log_slow_control='';
-+SET GLOBAL long_query_time=default;
-+
-+--let grep_pattern = Query_time
-+--source include/log_grep.inc
-+
-+DROP TABLE t;
---- /dev/null
-+++ b/mysql-test/t/percona_slow_query_log_microseconds_timestamp-cl-master.opt
-@@ -0,0 +1 @@
-+--slow_query_log_microseconds_timestamp
---- /dev/null
-+++ b/mysql-test/t/percona_slow_query_log_microseconds_timestamp-cl.test
-@@ -0,0 +1,2 @@
-+SHOW VARIABLES LIKE 'slow_query_log_microseconds_timestamp';
-+SHOW GLOBAL VARIABLES LIKE 'slow_query_log_microseconds_timestamp';
---- /dev/null
-+++ b/mysql-test/t/percona_slow_query_log_microseconds_timestamp-master.opt
-@@ -0,0 +1 @@
-+--log_slow_timestamp_every
---- /dev/null
-+++ b/mysql-test/t/percona_slow_query_log_microseconds_timestamp.test
-@@ -0,0 +1,25 @@
-+--source include/have_debug.inc
-+
-+SET long_query_time=2;
-+--let log_file=percona.slow_extended.slow_query_log_microseconds_timestamp
-+--source include/log_start.inc
-+
-+SET SESSION query_exec_time=2.1;
-+
-+SELECT 1;
-+
-+SET GLOBAL slow_query_log_microseconds_timestamp=1;
-+
-+SELECT 1;
-+
-+SET SESSION query_exec_time=default;
-+
-+--source include/log_stop.inc
-+SET GLOBAL slow_query_log_microseconds_timestamp=default;
-+SET long_query_time=default;
-+
-+--let grep_pattern = # Time: [0-9]+[ ]+[0-9]+:[0-9]+:[0-9]+.[0-9]+
-+--source include/log_grep.inc
-+
-+--let grep_pattern =  # Time: [0-9]+[ ]+[0-9]+:[0-9]+:[0-9]+
-+--source include/log_grep.inc
---- /dev/null
-+++ b/mysql-test/t/percona_use_global_log_slow_control-cl-master.opt
-@@ -0,0 +1 @@
-+--use_global_log_slow_control="log_slow_verbosity,long_query_time"
---- /dev/null
-+++ b/mysql-test/t/percona_use_global_log_slow_control-cl.test
-@@ -0,0 +1,2 @@
-+SHOW VARIABLES LIKE 'use_global_log_slow_control';
-+SHOW GLOBAL VARIABLES LIKE 'use_global_log_slow_control';
---- /dev/null
-+++ b/mysql-test/t/percona_use_global_log_slow_control.test
-@@ -0,0 +1,28 @@
-+--source include/have_debug.inc
-+--source include/have_innodb.inc
-+
-+SET GLOBAL long_query_time=1;
-+
-+--let log_file=percona.slow_extended.use_global_log_slow_control
-+--source include/log_start.inc
-+
-+SET SESSION query_exec_time=1.1;
-+
-+SELECT 1;
-+
-+SET GLOBAL log_slow_verbosity=innodb;
-+SET GLOBAL use_global_log_slow_control="log_slow_verbosity,long_query_time";
-+
-+SELECT 1;
-+
-+SET SESSION query_exec_time=default;
-+
-+--source include/log_stop.inc
-+
-+SET GLOBAL use_global_log_slow_control='';
-+SET GLOBAL log_slow_verbosity='';
-+SET GLOBAL long_query_time=default;
-+
-+--let grep_pattern = No InnoDB statistics available for this query
-+--source include/log_grep.inc
-+
---- /dev/null
-+++ b/mysql-test/t/percona_use_global_long_query_time.test
-@@ -0,0 +1,27 @@
-+--source include/have_debug.inc
-+
-+--let log_file=percona.slow_extended.use_global_long_query_time
-+--source include/log_start.inc
-+
-+SET long_query_time=2;
-+
-+SET SESSION query_exec_time=1.1; SELECT 1;
-+SET SESSION query_exec_time=3.1; SELECT 1;
-+SET SESSION query_exec_time=5.1; SELECT 1;
-+
-+SET GLOBAL long_query_time=4;
-+SET GLOBAL use_global_long_query_time=1;
-+
-+SET SESSION query_exec_time=1.1; SELECT 1;
-+SET SESSION query_exec_time=3.1; SELECT 1;
-+SET SESSION query_exec_time=5.1; SELECT 1;
-+
-+SET SESSION query_exec_time=0;
-+
-+--source include/log_stop.inc
-+
-+SET GLOBAL long_query_time=default;
-+SET GLOBAL use_global_long_query_time=0;
-+
-+--let grep_pattern = Query_time
-+--source include/log_grep.inc
---- a/sql/log_event.h
-+++ b/sql/log_event.h
-@@ -338,6 +338,10 @@
- #define Q_INVOKER 11
-+#ifndef DBUG_OFF
-+#define Q_QUERY_EXEC_TIME 250
-+#endif
-+
- /* Intvar event post-header */
- /* Intvar event data */
---- /dev/null
-+++ b/mysql-test/r/percona_log_slow_admin_statements.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/t/percona_log_slow_admin_statements.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/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("ignoring option '--log-slow-admin-statements' due to invalid value '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
---- /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/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_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.cnf
-@@ -0,0 +1,2 @@
-+[mysqld.1]
-+log-slow-admin-statements=foo
---- /dev/null
-+++ b/mysql-test/t/percona_log_slow_admin_statements-config_foo.test
-@@ -0,0 +1,3 @@
-+call mtr.add_suppression("ignoring option '--log-slow-admin-statements' due to invalid value 'foo'");
-+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.cnf
-@@ -0,0 +1,2 @@
-+[mysqld.1]
-+log-slow-admin-statements=true
---- /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/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.cnf
-@@ -0,0 +1,2 @@
-+[mysqld.1]
-+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';
---- /dev/null
-+++ b/mysql-test/t/percona_slow_extended_error_on_quit.test
-@@ -0,0 +1,87 @@
-+################################################################################
-+# Current test check following attributes:                                     #
-+# 1) "Last_errno"                                                              #
-+# 2) "Rows_{sent,examined|affected|read}                                       #
-+# 3) Bytes_sent                                                                #
-+# 4) Tmp_{tables|dist_tables|table_size}                                       #
-+# 5) InnoDB statistic counters                                                 #
-+# in Slow Query Log                                                            #
-+# for administrative command "Quit"                                            #
-+#                                                                              #
-+# See Launchpad Bug #716210                                                    #
-+################################################################################
-+
-+--source include/have_innodb.inc
-+
-+################################################################################
-+--let log_file=percona.slow_extended.error_on_quit
-+--let wait_condition=SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST;
-+################################################################################
-+
-+--disable_warnings
-+DROP TABLE IF EXISTS t;
-+--enable_warnings
-+CREATE TABLE t(a INT) engine=InnoDB;
-+INSERT INTO t VALUES(0),(1),(2),(3),(4);
-+
-+################################################################################
-+--source include/log_start.inc
-+
-+--connect(additional,localhost,root,,)
-+--connection additional
-+
-+  SET log_slow_verbosity=innodb;
-+  SET long_query_time= 0;
-+
-+--disable_result_log
-+--error ER_TABLE_EXISTS_ERROR
-+  CREATE TABLE t(a INT) engine=InnoDB;
-+--enable_result_log
-+
-+--connection default
-+--echo # Disconnecting (passing to Slow Query Log "# administrative command: Quit")
-+--disconnect additional
-+--source include/wait_condition.inc
-+--source include/log_stop.inc
-+--source include/percona_slow_extended_error_on_quit.inc
-+################################################################################
-+--source include/log_start.inc
-+
-+--connect(additional,localhost,root,,)
-+--connection additional
-+
-+  SET log_slow_verbosity=innodb;
-+  SET long_query_time= 0;
-+
-+--disable_result_log
-+  INSERT INTO t SELECT * FROM t ORDER BY RAND();
-+--enable_result_log
-+
-+--connection default
-+--echo # Disconnecting (passing to Slow Query Log "# administrative command: Quit")
-+--disconnect additional
-+--source include/wait_condition.inc
-+--source include/log_stop.inc
-+--source include/percona_slow_extended_error_on_quit.inc
-+################################################################################
-+--source include/log_start.inc
-+
-+--connect(additional,localhost,root,,)
-+--connection additional
-+
-+  SET log_slow_verbosity=innodb;
-+  SET long_query_time= 0;
-+
-+--disable_result_log
-+  SELECT * FROM t;
-+--enable_result_log
-+
-+--connection default
-+--echo # Disconnecting (passing to Slow Query Log "# administrative command: Quit")
-+--disconnect additional
-+--source include/wait_condition.inc
-+--source include/log_stop.inc
-+--source include/percona_slow_extended_error_on_quit.inc
-+################################################################################
-+
-+DROP TABLE t;
---- /dev/null
-+++ b/mysql-test/r/percona_slow_extended_error_on_quit.result
-@@ -0,0 +1,171 @@
-+DROP TABLE IF EXISTS t;
-+CREATE TABLE t(a INT) engine=InnoDB;
-+INSERT INTO t VALUES(0),(1),(2),(3),(4);
-+[log_start.inc] percona.slow_extended.error_on_quit
-+SET log_slow_verbosity=innodb;
-+SET long_query_time= 0;
-+CREATE TABLE t(a INT) engine=InnoDB;
-+# Disconnecting (passing to Slow Query Log "# administrative command: Quit")
-+[log_stop.inc] percona.slow_extended.error_on_quit
-+################################################################################
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: CREATE
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: INSERT
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: SELECT
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Quit
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Last_errno: [^0]+
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Last_errno: 0
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_sent: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_sent: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_examined: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_examined: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_affected: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_affected: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_read: [^0]+
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_read: 0
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Bytes_sent: [^0]+
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Bytes_sent: 0
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_tables: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_tables: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_disk_tables: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_disk_tables: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_table_sizes: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_table_sizes: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: # No InnoDB statistics available for this query
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: # InnoDB_trx_id: 
-+[log_grep.inc] lines:   0
-+################################################################################
-+[log_start.inc] percona.slow_extended.error_on_quit
-+SET log_slow_verbosity=innodb;
-+SET long_query_time= 0;
-+INSERT INTO t SELECT * FROM t ORDER BY RAND();
-+# Disconnecting (passing to Slow Query Log "# administrative command: Quit")
-+[log_stop.inc] percona.slow_extended.error_on_quit
-+################################################################################
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: CREATE
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: INSERT
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: SELECT
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Quit
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Last_errno: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Last_errno: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_sent: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_sent: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_examined: [^0]+
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_examined: 0
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_affected: [^0]+
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_affected: 0
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_read: [^0]+
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_read: 0
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Bytes_sent: [^0]+
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Bytes_sent: 0
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_tables: [^0]+
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_tables: 0
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_disk_tables: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_disk_tables: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_table_sizes: [^0]+
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_table_sizes: 0
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: # No InnoDB statistics available for this query
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: # InnoDB_trx_id: 
-+[log_grep.inc] lines:   1
-+################################################################################
-+[log_start.inc] percona.slow_extended.error_on_quit
-+SET log_slow_verbosity=innodb;
-+SET long_query_time= 0;
-+SELECT * FROM t;
-+# Disconnecting (passing to Slow Query Log "# administrative command: Quit")
-+[log_stop.inc] percona.slow_extended.error_on_quit
-+################################################################################
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: CREATE
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: INSERT
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: SELECT
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Quit
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Last_errno: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Last_errno: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_sent: [^0]+
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_sent: 0
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_examined: [^0]+
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_examined: 0
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_affected: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_affected: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_read: [^0]+
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Rows_read: 0
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Bytes_sent: [^0]+
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Bytes_sent: 0
-+[log_grep.inc] lines:   1
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_tables: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_tables: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_disk_tables: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_disk_tables: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_table_sizes: [^0]+
-+[log_grep.inc] lines:   0
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: Tmp_table_sizes: 0
-+[log_grep.inc] lines:   3
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: # No InnoDB statistics available for this query
-+[log_grep.inc] lines:   2
-+[log_grep.inc] file: percona.slow_extended.error_on_quit pattern: # InnoDB_trx_id: 
-+[log_grep.inc] lines:   1
-+################################################################################
---- /dev/null
-+++ b/mysql-test/include/percona_slow_extended_error_on_quit.inc
-@@ -0,0 +1,50 @@
-+--echo ################################################################################
-+--let grep_pattern=CREATE
-+--source include/log_grep.inc
-+--let grep_pattern=INSERT
-+--source include/log_grep.inc
-+--let grep_pattern=SELECT
-+--source include/log_grep.inc
-+--let grep_pattern=Quit
-+--source include/log_grep.inc
-+--let grep_pattern=Last_errno: [^0]+
-+--source include/log_grep.inc
-+--let grep_pattern=Last_errno: 0
-+--source include/log_grep.inc
-+--let grep_pattern=Rows_sent: [^0]+
-+--source include/log_grep.inc
-+--let grep_pattern=Rows_sent: 0
-+--source include/log_grep.inc
-+--let grep_pattern=Rows_examined: [^0]+
-+--source include/log_grep.inc
-+--let grep_pattern=Rows_examined: 0
-+--source include/log_grep.inc
-+--let grep_pattern=Rows_affected: [^0]+
-+--source include/log_grep.inc
-+--let grep_pattern=Rows_affected: 0
-+--source include/log_grep.inc
-+--let grep_pattern=Rows_read: [^0]+
-+--source include/log_grep.inc
-+--let grep_pattern=Rows_read: 0
-+--source include/log_grep.inc
-+--let grep_pattern=Bytes_sent: [^0]+
-+--source include/log_grep.inc
-+--let grep_pattern=Bytes_sent: 0
-+--source include/log_grep.inc
-+--let grep_pattern=Tmp_tables: [^0]+
-+--source include/log_grep.inc
-+--let grep_pattern=Tmp_tables: 0
-+--source include/log_grep.inc
-+--let grep_pattern=Tmp_disk_tables: [^0]+
-+--source include/log_grep.inc
-+--let grep_pattern=Tmp_disk_tables: 0
-+--source include/log_grep.inc
-+--let grep_pattern=Tmp_table_sizes: [^0]+
-+--source include/log_grep.inc
-+--let grep_pattern=Tmp_table_sizes: 0
-+--source include/log_grep.inc
-+--let grep_pattern=# No InnoDB statistics available for this query
-+--source include/log_grep.inc
-+--let grep_pattern=# InnoDB_trx_id: 
-+--source include/log_grep.inc
-+--echo ################################################################################
diff --git a/mysql-split_buf_pool_mutex_fixed_optimistic_safe.patch b/mysql-split_buf_pool_mutex_fixed_optimistic_safe.patch
deleted file mode 100644 (file)
index ef673d9..0000000
+++ /dev/null
@@ -1,1281 +0,0 @@
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/buf/buf0buf.c mysql-5.1.29-rc/storage/innobase/buf/buf0buf.c
---- mysql-5.1.29-rc_orig/storage/innobase/buf/buf0buf.c        2008-10-12 06:54:12.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/buf/buf0buf.c     2008-11-18 15:44:00.000000000 +0900
-@@ -596,6 +596,15 @@
-       ---------------------------- */
-       mutex_create(&buf_pool->mutex, SYNC_BUF_POOL);
-+      mutex_create(&(buf_pool->flush_list_mutex), SYNC_NO_ORDER_CHECK);
-+      mutex_create(&(buf_pool->LRU_mutex), SYNC_NO_ORDER_CHECK);
-+      mutex_create(&(buf_pool->free_mutex), SYNC_NO_ORDER_CHECK);
-+      mutex_create(&(buf_pool->hash_mutex), SYNC_NO_ORDER_CHECK);
-+
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       mutex_enter(&(buf_pool->mutex));
-       if (srv_use_awe) {
-@@ -773,6 +782,10 @@
-               block->in_free_list = TRUE;
-       }
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       mutex_exit(&(buf_pool->mutex));
-       if (srv_use_adaptive_hash_indexes) {
-@@ -905,12 +918,12 @@
-       if (buf_block_peek_if_too_old(block)) {
--              mutex_enter(&buf_pool->mutex);
-+              mutex_enter(&(buf_pool->LRU_mutex));
-               /* There has been freeing activity in the LRU list:
-               best to move to the head of the LRU list */
-               buf_LRU_make_block_young(block);
--              mutex_exit(&buf_pool->mutex);
-+              mutex_exit(&(buf_pool->LRU_mutex));
-       }
- }
-@@ -926,7 +939,7 @@
- {
-       buf_block_t*    block;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-       block = buf_block_align(frame);
-@@ -934,7 +947,7 @@
-       buf_LRU_make_block_young(block);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
- }
- /************************************************************************
-@@ -945,7 +958,7 @@
- /*===========*/
-       buf_block_t*    block)  /* in, own: block to be freed */
- {
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       mutex_enter(&block->mutex);
-@@ -955,7 +968,7 @@
-       mutex_exit(&block->mutex);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
- }
- /*************************************************************************
-@@ -996,11 +1009,11 @@
- {
-       buf_block_t*    block;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(block);
- }
-@@ -1017,7 +1030,7 @@
- {
-       buf_block_t*    block;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1025,7 +1038,7 @@
-               block->check_index_page_at_flush = FALSE;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
- }
- /************************************************************************
-@@ -1044,7 +1057,7 @@
-       buf_block_t*    block;
-       ibool           is_hashed;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1054,7 +1067,7 @@
-               is_hashed = block->is_hashed;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(is_hashed);
- }
-@@ -1096,7 +1109,7 @@
- {
-       buf_block_t*    block;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1104,7 +1117,7 @@
-               block->file_page_was_freed = TRUE;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(block);
- }
-@@ -1125,7 +1138,7 @@
- {
-       buf_block_t*    block;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      mutex_enter_fast(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1133,7 +1146,7 @@
-               block->file_page_was_freed = FALSE;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(block);
- }
-@@ -1174,26 +1187,33 @@
-       buf_pool->n_page_gets++;
- loop:
-       block = NULL;
--      mutex_enter_fast(&(buf_pool->mutex));
-+      // mutex_enter_fast(&(buf_pool->mutex));
-       if (guess) {
-               block = buf_block_align(guess);
-+              mutex_enter(&block->mutex);
-               if ((offset != block->offset) || (space != block->space)
-                   || (block->state != BUF_BLOCK_FILE_PAGE)) {
-+                      mutex_exit(&block->mutex);
-                       block = NULL;
-               }
-       }
-       if (block == NULL) {
-+              mutex_enter_fast(&(buf_pool->hash_mutex));
-               block = buf_page_hash_get(space, offset);
-+              if(block) {
-+                      mutex_enter(&block->mutex);
-+              }
-+              mutex_exit(&(buf_pool->hash_mutex));
-       }
-       if (block == NULL) {
-               /* Page not in buf_pool: needs to be read from file */
--              mutex_exit(&(buf_pool->mutex));
-+              // mutex_exit(&(buf_pool->mutex));
-               if (mode == BUF_GET_IF_IN_POOL) {
-@@ -1212,7 +1232,7 @@
-               goto loop;
-       }
--      mutex_enter(&block->mutex);
-+      // mutex_enter(&block->mutex);
-       ut_a(block->state == BUF_BLOCK_FILE_PAGE);
-@@ -1224,7 +1244,7 @@
-               if (mode == BUF_GET_IF_IN_POOL) {
-                       /* The page is only being read to buffer */
--                      mutex_exit(&buf_pool->mutex);
-+                      // mutex_exit(&buf_pool->mutex);
-                       mutex_exit(&block->mutex);
-                       return(NULL);
-@@ -1241,7 +1261,9 @@
-               LRU list and we must put it to awe_LRU_free_mapped list once
-               mapped to a frame */
-+              mutex_enter_fast(&(buf_pool->mutex));
-               buf_awe_map_page_to_frame(block, TRUE);
-+              mutex_exit(&buf_pool->mutex);
-       }
- #ifdef UNIV_SYNC_DEBUG
-@@ -1249,7 +1271,7 @@
- #else
-       buf_block_buf_fix_inc(block);
- #endif
--      mutex_exit(&buf_pool->mutex);
-+      // mutex_exit(&buf_pool->mutex);
-       /* Check if this is the first access to the page */
-@@ -1747,7 +1769,8 @@
-       ut_a(block);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       mutex_enter(&block->mutex);
-       if (fil_tablespace_deleted_or_being_deleted_in_mem(
-@@ -1763,7 +1786,8 @@
-               already in buf_pool, return */
-               mutex_exit(&block->mutex);
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->LRU_mutex));
-+              mutex_exit(&(buf_pool->hash_mutex));
-               buf_block_free(block);
-@@ -1778,10 +1802,14 @@
-       ut_ad(block);
-       buf_page_init(space, offset, block);
-+      mutex_exit(&(buf_pool->hash_mutex));
-       /* The block must be put to the LRU list, to the old blocks */
-       buf_LRU_add_block(block, TRUE);         /* TRUE == to old blocks */
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+
-+      mutex_enter(&(buf_pool->mutex)); /* for consistency about aio */
-       block->io_fix = BUF_IO_READ;
-@@ -1830,7 +1858,8 @@
-       free_block = buf_LRU_get_free_block();
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-@@ -1841,7 +1870,8 @@
-               block->file_page_was_freed = FALSE;
-               /* Page can be found in buf_pool */
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->LRU_mutex));
-+              mutex_exit(&(buf_pool->hash_mutex));
-               buf_block_free(free_block);
-@@ -1864,6 +1894,7 @@
-       mutex_enter(&block->mutex);
-       buf_page_init(space, offset, block);
-+      mutex_exit(&(buf_pool->hash_mutex));
-       /* The block must be put to the LRU list */
-       buf_LRU_add_block(block, FALSE);
-@@ -1875,7 +1906,7 @@
- #endif
-       buf_pool->n_pages_created++;
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-       mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
-@@ -1889,7 +1920,7 @@
-       ibuf_merge_or_delete_for_page(NULL, space, offset, TRUE);
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
-       frame = block->frame;
-@@ -1928,6 +1959,7 @@
-       buf_block_t*    block)  /* in: pointer to the block in question */
- {
-       ulint           io_type;
-+      ulint           flush_type;
-       ut_ad(block);
-@@ -2040,9 +2072,6 @@
-               }
-       }
--      mutex_enter(&(buf_pool->mutex));
--      mutex_enter(&block->mutex);
--
- #ifdef UNIV_IBUF_DEBUG
-       ut_a(ibuf_count_get(block->space, block->offset) == 0);
- #endif
-@@ -2051,9 +2080,12 @@
-       removes the newest lock debug record, without checking the thread
-       id. */
--      block->io_fix = 0;
--
-       if (io_type == BUF_IO_READ) {
-+              mutex_enter(&block->mutex);
-+              mutex_enter(&(buf_pool->mutex));
-+
-+              block->io_fix = 0;
-+
-               /* NOTE that the call to ibuf may have moved the ownership of
-               the x-latch to this OS thread: do not let this confuse you in
-               debugging! */
-@@ -2064,6 +2096,8 @@
-               rw_lock_x_unlock_gen(&(block->lock), BUF_IO_READ);
-+              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&block->mutex);
- #ifdef UNIV_DEBUG
-               if (buf_debug_prints) {
-                       fputs("Has read ", stderr);
-@@ -2072,15 +2106,33 @@
-       } else {
-               ut_ad(io_type == BUF_IO_WRITE);
-+              flush_type = block->flush_type;
-+              if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
-+                      mutex_enter(&(buf_pool->LRU_mutex));
-+              }
-+              mutex_enter(&(buf_pool->flush_list_mutex));
-+              mutex_enter(&block->mutex);
-+              mutex_enter(&(buf_pool->mutex));
-+
-+              block->io_fix = 0;
-+
-               /* Write means a flush operation: call the completion
-               routine in the flush system */
-               buf_flush_write_complete(block);
-+              mutex_exit(&(buf_pool->flush_list_mutex));
-+              if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
-+                      mutex_exit(&(buf_pool->LRU_mutex));
-+              }
-+
-               rw_lock_s_unlock_gen(&(block->lock), BUF_IO_WRITE);
-               buf_pool->n_pages_written++;
-+              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&block->mutex);
-+
- #ifdef UNIV_DEBUG
-               if (buf_debug_prints) {
-                       fputs("Has written ", stderr);
-@@ -2088,9 +2140,6 @@
- #endif /* UNIV_DEBUG */
-       }
--      mutex_exit(&block->mutex);
--      mutex_exit(&(buf_pool->mutex));
--
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints) {
-               fprintf(stderr, "page space %lu page no %lu\n",
-@@ -2118,11 +2167,11 @@
-               freed = buf_LRU_search_and_free_block(100);
-       }
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-       ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
- }
- #ifdef UNIV_DEBUG
-@@ -2142,10 +2191,22 @@
-       ulint           n_flush         = 0;
-       ulint           n_free          = 0;
-       ulint           n_page          = 0;
-+      ulint           n_single_flush_tmp      = 0;
-+      ulint           n_lru_flush_tmp         = 0;
-+      ulint           n_list_flush_tmp        = 0;
-       ut_ad(buf_pool);
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-+
-       mutex_enter(&(buf_pool->mutex));
-+      n_single_flush_tmp = buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE];
-+      n_list_flush_tmp = buf_pool->n_flush[BUF_FLUSH_LIST];
-+      n_lru_flush_tmp = buf_pool->n_flush[BUF_FLUSH_LRU];
-+      mutex_exit(&(buf_pool->mutex));
-       for (i = 0; i < buf_pool->curr_size; i++) {
-@@ -2216,11 +2277,14 @@
-       }
-       ut_a(UT_LIST_GET_LEN(buf_pool->flush_list) == n_flush);
--      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);
--
--      mutex_exit(&(buf_pool->mutex));
-+      ut_a(n_single_flush_tmp == n_single_flush);
-+      ut_a(n_list_flush_tmp == n_list_flush);
-+      ut_a(n_lru_flush_tmp == n_lru_flush);
-+      
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       ut_a(buf_LRU_validate());
-       ut_a(buf_flush_validate());
-@@ -2252,7 +2316,9 @@
-       index_ids = mem_alloc(sizeof(dulint) * size);
-       counts = mem_alloc(sizeof(ulint) * size);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       fprintf(stderr,
-               "buf_pool size %lu\n"
-@@ -2305,7 +2371,9 @@
-               }
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       for (i = 0; i < n_found; i++) {
-               index = dict_index_get_if_in_cache(index_ids[i]);
-@@ -2339,8 +2407,6 @@
-       ulint           i;
-       ulint           fixed_pages_number = 0;
--      mutex_enter(&(buf_pool->mutex));
--
-       for (i = 0; i < buf_pool->curr_size; i++) {
-               block = buf_pool_get_nth_block(buf_pool, i);
-@@ -2356,7 +2422,6 @@
-               }
-       }
--      mutex_exit(&(buf_pool->mutex));
-       return(fixed_pages_number);
- }
-@@ -2385,7 +2450,9 @@
- {
-       ulint   ratio;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       ratio = (100 * UT_LIST_GET_LEN(buf_pool->flush_list))
-               / (1 + UT_LIST_GET_LEN(buf_pool->LRU)
-@@ -2393,7 +2460,9 @@
-       /* 1 + is there to avoid division by zero */
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       return(ratio);
- }
-@@ -2413,6 +2482,9 @@
-       ut_ad(buf_pool);
-       size = buf_pool->curr_size;
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       mutex_enter(&(buf_pool->mutex));
-       if (srv_use_awe) {
-@@ -2487,6 +2559,9 @@
-       buf_pool->n_pages_written_old = buf_pool->n_pages_written;
-       buf_pool->n_pages_awe_remapped_old = buf_pool->n_pages_awe_remapped;
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       mutex_exit(&(buf_pool->mutex));
- }
-@@ -2517,8 +2592,6 @@
-       ut_ad(buf_pool);
--      mutex_enter(&(buf_pool->mutex));
--
-       for (i = 0; i < buf_pool->curr_size; i++) {
-               block = buf_pool_get_nth_block(buf_pool, i);
-@@ -2540,8 +2613,6 @@
-               mutex_exit(&block->mutex);
-       }
--      mutex_exit(&(buf_pool->mutex));
--
-       return(TRUE);
- }
-@@ -2580,11 +2651,11 @@
- {
-       ulint   len;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       len = UT_LIST_GET_LEN(buf_pool->free);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       return(len);
- }
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/buf/buf0flu.c mysql-5.1.29-rc/storage/innobase/buf/buf0flu.c
---- mysql-5.1.29-rc_orig/storage/innobase/buf/buf0flu.c        2008-10-12 06:54:12.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/buf/buf0flu.c     2008-11-18 15:26:07.000000000 +0900
-@@ -109,13 +109,15 @@
-       ut_ad(mutex_own(&(buf_pool->mutex)));
-       ut_ad(mutex_own(&block->mutex));
-       if (block->state != BUF_BLOCK_FILE_PAGE) {
-+              /* It is permited not to own LRU_mutex..  */
-+/*
-               ut_print_timestamp(stderr);
-               fprintf(stderr,
-                       "  InnoDB: Error: buffer block state %lu"
-                       " in the LRU list!\n",
-                       (ulong)block->state);
-               ut_print_buf(stderr, block, sizeof(buf_block_t));
--
-+*/
-               return(FALSE);
-       }
-@@ -546,18 +548,20 @@
-       ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST
-             || flush_type == BUF_FLUSH_SINGLE_PAGE);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-       ut_a(!block || block->state == BUF_BLOCK_FILE_PAGE);
-       if (!block) {
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->hash_mutex));
-               return(0);
-       }
-       mutex_enter(&block->mutex);
-+      mutex_enter(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       if (flush_type == BUF_FLUSH_LIST
-           && buf_flush_ready_for_flush(block, flush_type)) {
-@@ -755,7 +759,7 @@
-               high = fil_space_get_size(space);
-       }
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       for (i = low; i < high; i++) {
-@@ -789,7 +793,7 @@
-                               mutex_exit(&block->mutex);
--                              mutex_exit(&(buf_pool->mutex));
-+                              mutex_exit(&(buf_pool->hash_mutex));
-                               /* Note: as we release the buf_pool mutex
-                               above, in buf_flush_try_page we cannot be sure
-@@ -800,14 +804,14 @@
-                               count += buf_flush_try_page(space, i,
-                                                           flush_type);
--                              mutex_enter(&(buf_pool->mutex));
-+                              mutex_enter(&(buf_pool->hash_mutex));
-                       } else {
-                               mutex_exit(&block->mutex);
-                       }
-               }
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       return(count);
- }
-@@ -863,6 +867,13 @@
-       (buf_pool->init_flush)[flush_type] = TRUE;
-+      mutex_exit(&(buf_pool->mutex));
-+
-+      if (flush_type == BUF_FLUSH_LRU) {
-+              mutex_enter(&(buf_pool->LRU_mutex));
-+      }
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+
-       for (;;) {
-               /* If we have flushed enough, leave the loop */
-               if (page_count >= min_n) {
-@@ -908,7 +919,10 @@
-                               offset = block->offset;
-                               mutex_exit(&block->mutex);
--                              mutex_exit(&(buf_pool->mutex));
-+                              if (flush_type == BUF_FLUSH_LRU) {
-+                                      mutex_exit(&(buf_pool->LRU_mutex));
-+                              }
-+                              mutex_exit(&(buf_pool->flush_list_mutex));
-                               old_page_count = page_count;
-@@ -920,7 +934,10 @@
-                               flush_type, offset,
-                               page_count - old_page_count); */
--                              mutex_enter(&(buf_pool->mutex));
-+                              if (flush_type == BUF_FLUSH_LRU) {
-+                                      mutex_enter(&(buf_pool->LRU_mutex));
-+                              }
-+                              mutex_enter(&(buf_pool->flush_list_mutex));
-                       } else if (flush_type == BUF_FLUSH_LRU) {
-@@ -943,6 +960,13 @@
-               }
-       }
-+      if (flush_type == BUF_FLUSH_LRU) {
-+              mutex_exit(&(buf_pool->LRU_mutex));
-+      }
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+
-+      mutex_enter(&(buf_pool->mutex));
-+
-       (buf_pool->init_flush)[flush_type] = FALSE;
-       if ((buf_pool->n_flush[flush_type] == 0)
-@@ -1001,10 +1025,14 @@
-       ulint           n_replaceable;
-       ulint           distance        = 0;
--      mutex_enter(&(buf_pool->mutex));
-+      /* optimistic search... */
-+      //mutex_enter(&(buf_pool->LRU_mutex));
-+      //mutex_enter(&(buf_pool->free_mutex));
-       n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
-+      //mutex_exit(&(buf_pool->free_mutex));
-+
-       block = UT_LIST_GET_LAST(buf_pool->LRU);
-       while ((block != NULL)
-@@ -1025,7 +1053,7 @@
-               block = UT_LIST_GET_PREV(LRU, block);
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      //mutex_exit(&(buf_pool->LRU_mutex));
-       if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN) {
-@@ -1044,8 +1072,9 @@
- immediately, without waiting. */
- void
--buf_flush_free_margin(void)
-+buf_flush_free_margin(
- /*=======================*/
-+      ibool   wait)
- {
-       ulint   n_to_flush;
-       ulint   n_flushed;
-@@ -1055,7 +1084,7 @@
-       if (n_to_flush > 0) {
-               n_flushed = buf_flush_batch(BUF_FLUSH_LRU, n_to_flush,
-                                           ut_dulint_zero);
--              if (n_flushed == ULINT_UNDEFINED) {
-+              if (wait && n_flushed == ULINT_UNDEFINED) {
-                       /* There was an LRU type flush batch already running;
-                       let us wait for it to end */
-@@ -1105,11 +1134,11 @@
- {
-       ibool   ret;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-       ret = buf_flush_validate_low();
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-       return(ret);
- }
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/buf/buf0lru.c mysql-5.1.29-rc/storage/innobase/buf/buf0lru.c
---- mysql-5.1.29-rc_orig/storage/innobase/buf/buf0lru.c        2008-10-12 06:54:12.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/buf/buf0lru.c     2008-11-18 15:09:58.000000000 +0900
-@@ -79,7 +79,10 @@
-       ibool           all_freed;
- scan_again:
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-+      mutex_enter(&(buf_pool->hash_mutex));
-       all_freed = TRUE;
-@@ -119,7 +122,10 @@
-                               mutex_exit(&block->mutex);
--                              mutex_exit(&(buf_pool->mutex));
-+                              mutex_exit(&(buf_pool->LRU_mutex));
-+                              mutex_exit(&(buf_pool->flush_list_mutex));
-+                              mutex_exit(&(buf_pool->free_mutex));
-+                              mutex_exit(&(buf_pool->hash_mutex));
-                               /* Note that the following call will acquire
-                               an S-latch on the page */
-@@ -149,7 +155,10 @@
-               block = prev_block;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       if (!all_freed) {
-               os_thread_sleep(20000);
-@@ -172,14 +181,14 @@
-       ulint           len;
-       ulint           limit;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-       len = UT_LIST_GET_LEN(buf_pool->LRU);
-       if (len < BUF_LRU_OLD_MIN_LEN) {
-               /* The LRU list is too short to do read-ahead */
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->LRU_mutex));
-               return(0);
-       }
-@@ -188,7 +197,7 @@
-       limit = block->LRU_position - len / BUF_LRU_INITIAL_RATIO;
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-       return(limit);
- }
-@@ -212,13 +221,15 @@
-       ulint           distance = 0;
-       ibool           freed;
--      mutex_enter(&(buf_pool->mutex));
-+      /* optimistic search... */
-+      //mutex_enter(&(buf_pool->LRU_mutex));
-+retry:
-       freed = FALSE;
-       block = UT_LIST_GET_LAST(buf_pool->LRU);
-       while (block != NULL) {
--              ut_a(block->in_LRU_list);
-+              //ut_a(block->in_LRU_list); /* optimistic */
-               mutex_enter(&block->mutex);
-@@ -234,9 +245,17 @@
-                       }
- #endif /* UNIV_DEBUG */
-+                      mutex_exit(&block->mutex);
-+
-+                      mutex_enter(&(buf_pool->LRU_mutex));/* optimistic */
-+
-+                      mutex_enter(&(buf_pool->hash_mutex));
-+                      mutex_enter(&block->mutex);
-+                      if(block->in_LRU_list && buf_flush_ready_for_replace(block)) {
-                       buf_LRU_block_remove_hashed_page(block);
-+                      mutex_exit(&(buf_pool->hash_mutex));
--                      mutex_exit(&(buf_pool->mutex));
-+                      mutex_exit(&(buf_pool->LRU_mutex));
-                       mutex_exit(&block->mutex);
-                       /* Remove possible adaptive hash index built on the
-@@ -257,14 +276,25 @@
-                       ut_a(block->buf_fix_count == 0);
--                      mutex_enter(&(buf_pool->mutex));
-+                      mutex_enter(&(buf_pool->free_mutex));
-                       mutex_enter(&block->mutex);
-                       buf_LRU_block_free_hashed_page(block);
-                       freed = TRUE;
-+                      mutex_exit(&(buf_pool->free_mutex));
-                       mutex_exit(&block->mutex);
-                       break;
-+                      } else { /* someone may interrupt...??? */
-+                      mutex_exit(&(buf_pool->LRU_mutex));/* optimistic */
-+
-+                      mutex_exit(&(buf_pool->hash_mutex));
-+
-+                      if (!(block->in_LRU_list)) {
-+                              mutex_exit(&block->mutex);
-+                              goto retry;
-+                      }
-+                      }
-               }
-               mutex_exit(&block->mutex);
-@@ -275,13 +305,21 @@
-               if (!freed && n_iterations <= 10
-                   && distance > 100 + (n_iterations * buf_pool->curr_size)
-                   / 10) {
--                      buf_pool->LRU_flush_ended = 0;
-+                      mutex_enter(&(buf_pool->mutex));
-+                      buf_pool->LRU_flush_ended = 0;
-                       mutex_exit(&(buf_pool->mutex));
-+                      //mutex_exit(&(buf_pool->LRU_mutex));
-+
-                       return(FALSE);
-               }
-       }
-+      if (!freed) {
-+              //mutex_exit(&(buf_pool->LRU_mutex));
-+      }
-+
-+      mutex_enter(&(buf_pool->mutex));
-       if (buf_pool->LRU_flush_ended > 0) {
-               buf_pool->LRU_flush_ended--;
-       }
-@@ -333,7 +371,8 @@
- {
-       ibool   ret     = FALSE;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-       if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
-           + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
-@@ -341,7 +380,8 @@
-               ret = TRUE;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       return(ret);
- }
-@@ -364,7 +404,7 @@
-       ibool           mon_value_was   = FALSE;
-       ibool           started_monitor = FALSE;
- loop:
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->free_mutex)); /* LRU info:optimistic */
-       if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
-           + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 20) {
-@@ -461,7 +501,7 @@
-               mutex_exit(&block->mutex);
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->free_mutex));
-               if (started_monitor) {
-                       srv_print_innodb_monitor = mon_value_was;
-@@ -473,7 +513,7 @@
-       /* If no block was in the free list, search from the end of the LRU
-       list and try to free a block there */
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       freed = buf_LRU_search_and_free_block(n_iterations);
-@@ -517,7 +557,7 @@
-       /* No free block was found: try to flush the LRU list */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(TRUE);
-       ++srv_buf_pool_wait_free;
-       os_aio_simulated_wake_handler_threads();
-@@ -988,7 +1028,7 @@
-       ulint           LRU_pos;
-       ut_ad(buf_pool);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-       if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
-@@ -1033,6 +1073,9 @@
-               ut_a(buf_pool->LRU_old_len == old_len);
-       }
-+      mutex_exit(&(buf_pool->LRU_mutex));
-+      mutex_enter(&(buf_pool->free_mutex));
-+
-       UT_LIST_VALIDATE(free, buf_block_t, buf_pool->free);
-       block = UT_LIST_GET_FIRST(buf_pool->free);
-@@ -1043,7 +1086,7 @@
-               block = UT_LIST_GET_NEXT(free, block);
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->free_mutex));
-       return(TRUE);
- }
-@@ -1059,7 +1102,7 @@
-       ulint           len;
-       ut_ad(buf_pool);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->LRU_mutex));
-       fprintf(stderr, "Pool ulint clock %lu\n",
-               (ulong) buf_pool->ulint_clock);
-@@ -1105,6 +1148,6 @@
-               }
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->LRU_mutex));
- }
- #endif /* UNIV_DEBUG */
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/buf/buf0rea.c mysql-5.1.29-rc/storage/innobase/buf/buf0rea.c
---- mysql-5.1.29-rc_orig/storage/innobase/buf/buf0rea.c        2008-10-12 06:54:12.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/buf/buf0rea.c     2008-11-18 15:28:13.000000000 +0900
-@@ -219,10 +219,12 @@
-               return(0);
-       }
-+      mutex_exit(&(buf_pool->mutex));
-       /* Count how many blocks in the area have been recently accessed,
-       that is, reside near the start of the LRU list. */
-+      mutex_enter(&(buf_pool->hash_mutex));
-       for (i = low; i < high; i++) {
-               block = buf_page_hash_get(space, i);
-@@ -233,8 +235,9 @@
-                       recent_blocks++;
-               }
-       }
-+      mutex_exit(&(buf_pool->hash_mutex));
--      mutex_exit(&(buf_pool->mutex));
-+      // mutex_exit(&(buf_pool->mutex));
-       if (recent_blocks < BUF_READ_AHEAD_RANDOM_THRESHOLD) {
-               /* Do nothing */
-@@ -334,7 +337,7 @@
-       }
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
-       return(count + count2);
- }
-@@ -432,6 +435,7 @@
-               return(0);
-       }
-+      mutex_exit(&(buf_pool->mutex));
-       /* Check that almost all pages in the area have been accessed; if
-       offset == low, the accesses must be in a descending order, otherwise,
-@@ -445,6 +449,7 @@
-       fail_count = 0;
-+      mutex_enter(&(buf_pool->hash_mutex));
-       for (i = low; i < high; i++) {
-               block = buf_page_hash_get(space, i);
-@@ -462,12 +467,13 @@
-                       pred_block = block;
-               }
-       }
-+      mutex_exit(&(buf_pool->hash_mutex));
-       if (fail_count > BUF_READ_AHEAD_LINEAR_AREA
-           - BUF_READ_AHEAD_LINEAR_THRESHOLD) {
-               /* Too many failures: return */
--              mutex_exit(&(buf_pool->mutex));
-+              //mutex_exit(&(buf_pool->mutex));
-               return(0);
-       }
-@@ -475,10 +481,11 @@
-       /* If we got this far, we know that enough pages in the area have
-       been accessed in the right order: linear read-ahead can be sensible */
-+      mutex_enter(&(buf_pool->hash_mutex));
-       block = buf_page_hash_get(space, offset);
-       if (block == NULL) {
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&(buf_pool->hash_mutex));
-               return(0);
-       }
-@@ -494,7 +501,7 @@
-       pred_offset = fil_page_get_prev(frame);
-       succ_offset = fil_page_get_next(frame);
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->hash_mutex));
-       if ((offset == low) && (succ_offset == offset + 1)) {
-@@ -573,7 +580,7 @@
-       os_aio_simulated_wake_handler_threads();
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints && (count > 0)) {
-@@ -639,7 +646,7 @@
-       os_aio_simulated_wake_handler_threads();
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints) {
-@@ -716,7 +723,7 @@
-       os_aio_simulated_wake_handler_threads();
-       /* Flush pages from the end of the LRU list if necessary */
--      buf_flush_free_margin();
-+      buf_flush_free_margin(FALSE);
- #ifdef UNIV_DEBUG
-       if (buf_debug_prints) {
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/buf0buf.h mysql-5.1.29-rc/storage/innobase/include/buf0buf.h
---- mysql-5.1.29-rc_orig/storage/innobase/include/buf0buf.h    2008-10-12 06:54:13.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/buf0buf.h 2008-11-18 15:09:58.000000000 +0900
-@@ -926,6 +926,7 @@
-                                       currently always the same as
-                                       max_size */
-       hash_table_t*   page_hash;      /* hash table of the file pages */
-+      mutex_t         hash_mutex;
-       ulint           n_pend_reads;   /* number of pending read operations */
-@@ -958,6 +959,7 @@
-       UT_LIST_BASE_NODE_T(buf_block_t) flush_list;
-                                       /* base node of the modified block
-                                       list */
-+      mutex_t         flush_list_mutex;
-       ibool           init_flush[BUF_FLUSH_LIST + 1];
-                                       /* this is TRUE when a flush of the
-                                       given type is being initialized */
-@@ -991,8 +993,10 @@
-                                       in the case of AWE, at the start are
-                                       always free blocks for which the
-                                       physical memory is mapped to a frame */
-+      mutex_t         free_mutex;
-       UT_LIST_BASE_NODE_T(buf_block_t) LRU;
-                                       /* base node of the LRU list */
-+      mutex_t         LRU_mutex;
-       buf_block_t*    LRU_old;        /* pointer to the about 3/8 oldest
-                                       blocks in the LRU list; NULL if LRU
-                                       length less than BUF_LRU_OLD_MIN_LEN */
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/buf0buf.ic mysql-5.1.29-rc/storage/innobase/include/buf0buf.ic
---- mysql-5.1.29-rc_orig/storage/innobase/include/buf0buf.ic   2008-10-12 06:54:13.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/buf0buf.ic        2008-11-18 15:09:58.000000000 +0900
-@@ -104,7 +104,7 @@
-       buf_block_t*    block;
-       dulint          lsn;
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-       block = UT_LIST_GET_LAST(buf_pool->flush_list);
-@@ -114,7 +114,7 @@
-               lsn = block->oldest_modification;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
-       return(lsn);
- }
-@@ -388,18 +388,18 @@
-                               /* out: TRUE if io going on */
-       buf_block_t*    block)  /* in: buf_pool block, must be bufferfixed */
- {
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&block->mutex);
-       ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
-       ut_ad(block->buf_fix_count > 0);
-       if (block->io_fix != 0) {
--              mutex_exit(&(buf_pool->mutex));
-+              mutex_exit(&block->mutex);
-               return(TRUE);
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&block->mutex);
-       return(FALSE);
- }
-@@ -421,7 +421,7 @@
-       block = buf_block_align(frame);
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&block->mutex);
-       if (block->state == BUF_BLOCK_FILE_PAGE) {
-               lsn = block->newest_modification;
-@@ -429,7 +429,7 @@
-               lsn = ut_dulint_zero;
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&block->mutex);
-       return(lsn);
- }
-@@ -624,9 +624,9 @@
-       ut_a(block->buf_fix_count > 0);
-       if (rw_latch == RW_X_LATCH && mtr->modifications) {
--              mutex_enter(&buf_pool->mutex);
-+              mutex_enter(&buf_pool->flush_list_mutex);
-               buf_flush_note_modification(block, mtr);
--              mutex_exit(&buf_pool->mutex);
-+              mutex_exit(&buf_pool->flush_list_mutex);
-       }
-       mutex_enter(&block->mutex);
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/buf0flu.h mysql-5.1.29-rc/storage/innobase/include/buf0flu.h
---- mysql-5.1.29-rc_orig/storage/innobase/include/buf0flu.h    2008-10-12 06:54:13.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/buf0flu.h 2008-11-18 15:09:58.000000000 +0900
-@@ -26,8 +26,9 @@
- a margin of replaceable pages there. */
- void
--buf_flush_free_margin(void);
-+buf_flush_free_margin(
- /*=======================*/
-+      ibool   wait);
- /************************************************************************
- Initializes a page for writing to the tablespace. */
-diff -ruN mysql-5.1.29-rc_orig/storage/innobase/include/buf0flu.ic mysql-5.1.29-rc/storage/innobase/include/buf0flu.ic
---- mysql-5.1.29-rc_orig/storage/innobase/include/buf0flu.ic   2008-10-12 06:54:13.000000000 +0900
-+++ mysql-5.1.29-rc/storage/innobase/include/buf0flu.ic        2008-11-18 15:09:58.000000000 +0900
-@@ -84,7 +84,7 @@
-       ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
- #endif /* UNIV_SYNC_DEBUG */
--      mutex_enter(&(buf_pool->mutex));
-+      mutex_enter(&(buf_pool->flush_list_mutex));
-       ut_ad(ut_dulint_cmp(block->newest_modification, end_lsn) <= 0);
-@@ -102,5 +102,5 @@
-                                   start_lsn) <= 0);
-       }
--      mutex_exit(&(buf_pool->mutex));
-+      mutex_exit(&(buf_pool->flush_list_mutex));
- }
-diff -ruN mysql-5.1.29-rc_orig/patch_info/split_buf_pool_mutex_fixed_optimistic_safe.info mysql-5.1.29-rc/patch_info/split_buf_pool_mutex_fixed_optimistic_safe.info
---- /dev/null  1970-01-01 09:00:00.000000000 +0900
-+++ mysql-5.1.29-rc/patch_info/split_buf_pool_mutex_fixed_optimistic_safe.info 2008-11-18 15:09:58.000000000 +0900
-@@ -0,0 +1,6 @@
-+File=split_buf_pool_mutex_fixed_optimistic_safe.patch
-+Name=InnoDB patch to fix buffer pool scalability
-+Version=1.0
-+Author=Yasufumi Kinoshita
-+License=BSD
-+Comment=
diff --git a/mysql-sql_no_fcache.patch b/mysql-sql_no_fcache.patch
deleted file mode 100644 (file)
index 8da2050..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-# name       : sql_no_fcache.patch
-# introduced : 12
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/client/mysqldump.c
-+++ b/client/mysqldump.c
-@@ -136,6 +136,8 @@
- #endif
- static uint opt_protocol= 0;
-+static my_bool server_supports_sql_no_fcache= FALSE;
-+
- /*
- Dynamic_string wrapper functions. In this file use these
- wrappers, they will terminate the process if there is
-@@ -1521,6 +1523,17 @@
-     /* Don't switch charsets for 4.1 and earlier.  (bug#34192). */
-     server_supports_switching_charsets= FALSE;
-   } 
-+  
-+  /* Check to see if we support SQL_NO_FCACHE on this server. */ 
-+  if (mysql_query(mysql, "SELECT SQL_NO_FCACHE NOW()") == 0)
-+  {
-+    MYSQL_RES *res = mysql_store_result(mysql);
-+    if (res)
-+    {
-+      mysql_free_result(res);
-+    }
-+    server_supports_sql_no_fcache= TRUE;
-+  }
-   /*
-     As we're going to set SQL_MODE, it would be lost on reconnect, so we
-     cannot reconnect.
-@@ -3184,7 +3197,12 @@
-     /* now build the query string */
--    dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '");
-+    dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ ");
-+    if (server_supports_sql_no_fcache)
-+    {
-+      dynstr_append_checked(&query_string, "/*!50084 SQL_NO_FCACHE */ ");
-+    }
-+    dynstr_append_checked(&query_string, "* INTO OUTFILE '");
-     dynstr_append_checked(&query_string, filename);
-     dynstr_append_checked(&query_string, "'");
-@@ -3234,7 +3252,12 @@
-       check_io(md_result_file);
-     }
-     
--    dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
-+    dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ ");
-+    if (server_supports_sql_no_fcache)
-+    {
-+      dynstr_append_checked(&query_string, "/*!50084 SQL_NO_FCACHE */ ");
-+    }
-+    dynstr_append_checked(&query_string, "* FROM ");
-     dynstr_append_checked(&query_string, result_table);
-     if (where)
---- /dev/null
-+++ b/include/flashcache_ioctl.h
-@@ -0,0 +1,53 @@
-+/****************************************************************************
-+ *  flashcache_ioctl.h
-+ *  FlashCache: Device mapper target for block-level disk caching
-+ *
-+ *  Copyright 2010 Facebook, Inc.
-+ *  Author: Mohan Srinivasan (mohan@facebook.com)
-+ *
-+ *  Based on DM-Cache:
-+ *   Copyright (C) International Business Machines Corp., 2006
-+ *   Author: Ming Zhao (mingzhao@ufl.edu)
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; under version 2 of the License.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-+ ****************************************************************************/
-+
-+#ifndef FLASHCACHE_IOCTL_H
-+#define FLASHCACHE_IOCTL_H
-+
-+#include <linux/types.h>
-+
-+#define FLASHCACHE_IOCTL 0xfe
-+
-+enum {
-+       FLASHCACHEADDNCPID_CMD=200,
-+       FLASHCACHEDELNCPID_CMD,
-+       FLASHCACHEDELNCALL_CMD,
-+       FLASHCACHEADDWHITELIST_CMD,
-+       FLASHCACHEDELWHITELIST_CMD,
-+       FLASHCACHEDELWHITELISTALL_CMD,
-+};
-+
-+#define FLASHCACHEADDNCPID     _IOW(FLASHCACHE_IOCTL, FLASHCACHEADDNCPID_CMD, pid_t)
-+#define FLASHCACHEDELNCPID     _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELNCPID_CMD, pid_t)
-+#define FLASHCACHEDELNCALL     _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELNCALL_CMD, pid_t)
-+
-+#define FLASHCACHEADDBLACKLIST         FLASHCACHEADDNCPID
-+#define FLASHCACHEDELBLACKLIST         FLASHCACHEDELNCPID
-+#define FLASHCACHEDELALLBLACKLIST      FLASHCACHEDELNCALL
-+
-+#define FLASHCACHEADDWHITELIST         _IOW(FLASHCACHE_IOCTL, FLASHCACHEADDWHITELIST_CMD, pid_t)
-+#define FLASHCACHEDELWHITELIST         _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELWHITELIST_CMD, pid_t)
-+#define FLASHCACHEDELALLWHITELIST      _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELWHITELISTALL_CMD, pid_t)
-+
-+#endif
---- a/mysql-test/r/mysqldump.result
-+++ b/mysql-test/r/mysqldump.result
-@@ -1832,7 +1832,7 @@
- # Bug#21288 mysqldump segmentation fault when using --where
- #
- create table t1 (a int);
--mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064)
-+mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ /*!50084 SQL_NO_FCACHE */ * FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064)
- mysqldump: Got error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 when retrieving data from server
- /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
---- /dev/null
-+++ b/patch_info/sql_no_fcache.info
-@@ -0,0 +1,6 @@
-+File=sql_no_fcache.patch
-+Name=Support for flashcache including the SQL_NO_FCACHE option that prevents blocks from being cached during a query.
-+Version=1.0
-+Author=Facebook
-+License=GPL
-+Comment=
---- a/sql/lex.h
-+++ b/sql/lex.h
-@@ -503,6 +503,7 @@
-   { "SQL_CACHE",        SYM(SQL_CACHE_SYM)},
-   { "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS)},
-   { "SQL_NO_CACHE",   SYM(SQL_NO_CACHE_SYM)},
-+  { "SQL_NO_FCACHE",   SYM(SQL_NO_FCACHE_SYM)},
-   { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT)},
-   { "SQL_THREAD",     SYM(SQL_THREAD)},
-   { "SQL_TSI_FRAC_SECOND", SYM(FRAC_SECOND_SYM)},
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -46,6 +46,11 @@
- #define OPT_NDB_SHM_DEFAULT 0
- #endif
- #endif
-+#if defined(__linux__)
-+#include <mntent.h>
-+#include <sys/statfs.h>
-+#include "flashcache_ioctl.h"
-+#endif//__linux__
- #ifndef DEFAULT_SKIP_THREAD_PRIORITY
- #define DEFAULT_SKIP_THREAD_PRIORITY 0
-@@ -608,6 +613,11 @@
- ulong max_long_data_size;
- uint  max_user_connections= 0;
- ulonglong denied_connections = 0;
-+
-+/* flashcache */
-+int cachedev_fd;
-+my_bool cachedev_enabled= FALSE;
-+
- /**
-   Limit of the total number of prepared statements in the server.
-   Is necessary to protect the server against out-of-memory attacks.
-@@ -4412,6 +4422,97 @@
- }
- #endif//DBUG_OFF
-+#if defined(__linux__)
-+/*
-+ * Auto detect if we support flash cache on the host system.
-+ * This needs to be called before we setuid away from root
-+ * to avoid permission problems on opening the device node.
-+ */
-+static void init_cachedev(void)
-+{
-+  struct statfs stfs_data_home_dir;
-+  struct statfs stfs;
-+  struct mntent *ent;
-+  pid_t pid = getpid();
-+  FILE *mounts;
-+  const char *error_message= NULL;
-+
-+  // disabled by default
-+  cachedev_fd = -1;
-+  cachedev_enabled= FALSE;
-+
-+  if (!mysql_data_home)
-+  {
-+    error_message= "mysql_data_home not set";
-+    goto epilogue;
-+  }
-+
-+  if (statfs(mysql_data_home, &stfs_data_home_dir) < 0)
-+  {
-+    error_message= "statfs failed";
-+    goto epilogue;
-+  }
-+
-+  mounts = setmntent("/etc/mtab", "r");
-+  if (mounts == NULL)
-+  {
-+    error_message= "setmntent failed";
-+    goto epilogue;
-+  }
-+
-+  while ((ent = getmntent(mounts)) != NULL)
-+  {
-+    if (statfs(ent->mnt_dir, &stfs) < 0)
-+      continue;
-+    if (memcmp(&stfs.f_fsid, &stfs_data_home_dir.f_fsid, sizeof(fsid_t)) == 0)
-+      break;
-+  }
-+  endmntent(mounts);
-+
-+  if (ent == NULL)
-+  {
-+    error_message= "getmntent loop failed";
-+    goto epilogue;
-+  }
-+
-+  cachedev_fd = open(ent->mnt_fsname, O_RDONLY);
-+  if (cachedev_fd < 0)
-+  {
-+    error_message= "open flash device failed";
-+    goto epilogue;
-+  }
-+
-+  /* cleanup previous whitelistings */
-+  if (ioctl(cachedev_fd, FLASHCACHEDELALLWHITELIST, &pid) < 0)
-+  {
-+    close(cachedev_fd);
-+    cachedev_fd = -1;
-+    error_message= "ioctl failed";
-+  } else {
-+    ioctl(cachedev_fd, FLASHCACHEADDWHITELIST, &pid);
-+  }
-+
-+epilogue:
-+  sql_print_information("Flashcache bypass: %s",
-+      (cachedev_fd > 0) ? "enabled" : "disabled");
-+  if (error_message)
-+    sql_print_information("Flashcache setup error is : %s\n", error_message);
-+  else
-+    cachedev_enabled= TRUE;
-+
-+}
-+
-+static void cleanup_cachedev(void)
-+{
-+  pid_t pid = getpid();
-+
-+  if (cachedev_enabled) {
-+    ioctl(cachedev_fd, FLASHCACHEDELWHITELIST, &pid);
-+    close(cachedev_fd);
-+    cachedev_fd = -1;
-+  }
-+}
-+#endif//__linux__
- #ifdef __WIN__
- int win_main(int argc, char **argv)
-@@ -4516,6 +4617,10 @@
-   test_lc_time_sz();
- #endif
-+#if defined(__linux__)
-+  init_cachedev();
-+#endif//__linux__
-+
-   /*
-     We have enough space for fiddling with the argv, continue
-   */
-@@ -4717,6 +4822,10 @@
-   clean_up_mutexes();
-   my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
-+#if defined(__linux__)
-+  cleanup_cachedev();
-+#endif//__linux__
-+
-   exit(0);
-   return(0);                                  /* purecov: deadcode */
- }
-@@ -7890,6 +7999,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},
-+  {"Flashcache_enabled",       (char*) &cachedev_enabled,       SHOW_BOOL },
-   {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_NOFLUSH},
-   {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
-   {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
---- a/sql/mysql_priv.h
-+++ b/sql/mysql_priv.h
-@@ -825,6 +825,8 @@
- */
- extern ulong server_id, concurrency;
-+/* flashcache */
-+extern int cachedev_fd;
- typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
-                                       uint key_length,
---- a/sql/sql_lex.cc
-+++ b/sql/sql_lex.cc
-@@ -308,6 +308,7 @@
-   lex->describe= 0;
-   lex->subqueries= FALSE;
-   lex->context_analysis_only= 0;
-+  lex->disable_flashcache= FALSE;
-   lex->derived_tables= 0;
-   lex->lock_option= TL_READ;
-   lex->safe_to_cache_query= 1;
---- a/sql/sql_lex.h
-+++ b/sql/sql_lex.h
-@@ -1730,6 +1730,7 @@
-   uint8 context_analysis_only;
-   bool safe_to_cache_query;
-+  bool disable_flashcache;
-   bool subqueries, ignore;
-   st_parsing_options parsing_options;
-   Alter_info alter_info;
---- a/sql/sql_select.cc
-+++ b/sql/sql_select.cc
-@@ -37,6 +37,12 @@
- #include <hash.h>
- #include <ft_global.h>
-+#include <sys/syscall.h>
-+#include <sys/ioctl.h>
-+#if defined(__linux__)
-+#include "flashcache_ioctl.h"
-+#endif//__linux__
-+
- const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
-                             "MAYBE_REF","ALL","range","index","fulltext",
-                             "ref_or_null","unique_subquery","index_subquery",
-@@ -239,9 +245,20 @@
-                    ulong setup_tables_done_option)
- {
-   bool res;
-+#if defined(__linux__)
-+  pid_t pid;
-+#endif
-   register SELECT_LEX *select_lex = &lex->select_lex;
-   DBUG_ENTER("handle_select");
-+#if defined(__linux__)
-+  if(lex->disable_flashcache && cachedev_fd > 0)
-+  {
-+    pid = syscall(SYS_gettid);
-+    ioctl(cachedev_fd, FLASHCACHEADDNCPID, &pid);
-+  }
-+#endif//__linux__
-+ 
-   if (select_lex->master_unit()->is_union() || 
-       select_lex->master_unit()->fake_select_lex)
-     res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
-@@ -274,6 +291,12 @@
-   if (unlikely(res))
-     result->abort();
-+#if defined(__linux__)
-+  if (lex->disable_flashcache && cachedev_fd > 0)
-+  {
-+    ioctl(cachedev_fd, FLASHCACHEDELNCPID, &pid);
-+  }
-+#endif//__linux__ 
-   DBUG_RETURN(res);
- }
---- a/sql/sql_yacc.yy
-+++ b/sql/sql_yacc.yy
-@@ -1166,6 +1166,7 @@
- %token  SQL_CACHE_SYM
- %token  SQL_CALC_FOUND_ROWS
- %token  SQL_NO_CACHE_SYM
-+%token  SQL_NO_FCACHE_SYM
- %token  SQL_SMALL_RESULT
- %token  SQL_SYM                       /* SQL-2003-R */
- %token  SQL_THREAD
-@@ -6757,6 +6758,10 @@
-             Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE;
-             Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE;
-           }
-+      | SQL_NO_FCACHE_SYM
-+        {
-+          Lex->disable_flashcache= TRUE;
-+        }
-         | SQL_CACHE_SYM
-           {
-             /*
---- /dev/null
-+++ b/mysql-test/r/percona_sql_no_fcache.result
-@@ -0,0 +1,12 @@
-+drop table if exists t1;
-+create table t (a int not null);
-+insert into t values (1),(2),(3);
-+SELECT SQL_NO_FCACHE SLEEP(0);
-+SLEEP(0)
-+0
-+SELECT /*!40001 SQL_NO_CACHE */ /*!50084 SQL_NO_FCACHE */ * FROM t;
-+a
-+1
-+2
-+3
-+DROP TABLE t;
---- /dev/null
-+++ b/mysql-test/t/percona_sql_no_fcache.test
-@@ -0,0 +1,11 @@
-+--disable_warnings
-+drop table if exists t1;
-+--enable_warnings
-+
-+create table t (a int not null);
-+insert into t values (1),(2),(3);
-+
-+SELECT SQL_NO_FCACHE SLEEP(0);
-+SELECT /*!40001 SQL_NO_CACHE */ /*!50084 SQL_NO_FCACHE */ * FROM t;
-+
-+DROP TABLE t;
diff --git a/mysql-suppress_log_warning_1592.patch b/mysql-suppress_log_warning_1592.patch
deleted file mode 100644 (file)
index 34cdfb1..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-# name       : suppress_log_warning_1592.patch
-# introduced : 11 or before
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/sql/mysql_priv.h
-+++ b/sql/mysql_priv.h
-@@ -2110,6 +2110,7 @@
- extern my_bool opt_readonly, lower_case_file_system;
- extern my_bool opt_userstat_running, opt_thread_statistics;
- extern my_bool opt_optimizer_fix;
-+extern my_bool opt_suppress_log_warning_1592;
- extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
- extern my_bool opt_secure_auth;
- extern char* opt_secure_file_priv;
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -543,6 +543,7 @@
- my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
- my_bool opt_userstat_running= 0, opt_thread_statistics= 0;
- my_bool opt_optimizer_fix= 0;
-+my_bool opt_suppress_log_warning_1592= 0;
- /*
-   True if there is at least one per-hour limit for some user, so we should
-   check them before each query (and possibly reset counters when hour is
-@@ -5868,6 +5869,7 @@
-   OPT_USERSTAT_RUNNING,
-   OPT_THREAD_STATISTICS,
-   OPT_OPTIMIZER_FIX,
-+  OPT_SUPPRESS_LOG_WARNING_1592,
-   OPT_USE_GLOBAL_LONG_QUERY_TIME,
-   OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
-   OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
-@@ -7388,6 +7390,10 @@
-    "Enable unofficial optimizer fixes.",
-    (uchar**) &opt_optimizer_fix, (uchar**) &opt_optimizer_fix,
-    0, GET_BOOL, NO_ARG, 1, 0, 1, 0, 1, 0},
-+  {"suppress_log_warning_1592", OPT_SUPPRESS_LOG_WARNING_1592,
-+   "suppress warning about unsafe statements for binary logging",
-+   (uchar**) &opt_suppress_log_warning_1592, (uchar**) &opt_suppress_log_warning_1592,
-+   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-   {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
-    "Causes updates to non-transactional engines using statement format to be "
-    "written directly to binary log. Before using this option, make sure that "
---- a/sql/set_var.cc
-+++ b/sql/set_var.cc
-@@ -575,6 +575,8 @@
-                                                     &opt_thread_statistics);
- static sys_var_bool_ptr               sys_optimizer_fix(&vars, "optimizer_fix",
-                                                 &opt_optimizer_fix);
-+static sys_var_bool_ptr               sys_suppress_log_warning_1592(&vars, "suppress_log_warning_1592",
-+                                                            &opt_suppress_log_warning_1592);
- static sys_var_thd_ulong      sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
-                                              &SV::read_rnd_buff_size);
- static sys_var_thd_ulong      sys_div_precincrement(&vars, "div_precision_increment",
---- a/sql/sql_class.cc
-+++ b/sql/sql_class.cc
-@@ -4141,6 +4141,7 @@
-                  ER_BINLOG_UNSAFE_STATEMENT,
-                  ER(ER_BINLOG_UNSAFE_STATEMENT));
-     if (global_system_variables.log_warnings &&
-+        !opt_suppress_log_warning_1592 &&
-         !(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
-     {
-       sql_print_warning("%s Statement: %.*s",
---- /dev/null
-+++ b/mysql-test/r/percona_suppress_log_warning_1592.result
-@@ -0,0 +1,28 @@
-+SET @old_log_warnings = @@log_warnings;
-+SET @old_suppress_log_warning_1592 = @@suppress_log_warning_1592;
-+DROP TABLE IF EXISTS t1;
-+CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(20));
-+SET GLOBAL SUPPRESS_LOG_WARNING_1592 = 0;
-+SET GLOBAL LOG_WARNINGS = 0;
-+INSERT INTO t1 VALUES(UUID(), 'suppress_1592');
-+Warnings:
-+Note  1592    Statement may not be safe to log in statement format.
-+SET GLOBAL LOG_WARNINGS = 1;
-+INSERT INTO t1 VALUES(UUID(), 'suppress_1592');
-+Warnings:
-+Note  1592    Statement may not be safe to log in statement format.
-+SET GLOBAL SUPPRESS_LOG_WARNING_1592 = 1;
-+SET GLOBAL LOG_WARNINGS = 0;
-+INSERT INTO t1 VALUES(UUID(), 'suppress_1592');
-+Warnings:
-+Note  1592    Statement may not be safe to log in statement format.
-+SET GLOBAL LOG_WARNINGS = 1;
-+INSERT INTO t1 VALUES(UUID(), 'suppress_1592');
-+Warnings:
-+Note  1592    Statement may not be safe to log in statement format.
-+DROP TABLE t1;
-+SET GLOBAL log_warnings = @old_log_warnings;
-+SET GLOBAL suppress_log_warning_1592 = @old_suppress_log_warning_1592;
-+# Count the number of times the "Unsafe" message was printed
-+# to the error log.
-+Occurrences: 1
---- /dev/null
-+++ b/mysql-test/t/percona_suppress_log_warning_1592-master.opt
-@@ -0,0 +1 @@
-+--log-error
---- /dev/null
-+++ b/mysql-test/t/percona_suppress_log_warning_1592.test
-@@ -0,0 +1,49 @@
-+-- source include/have_log_bin.inc
-+-- source include/have_binlog_format_statement.inc
-+
-+SET @old_log_warnings = @@log_warnings;
-+SET @old_suppress_log_warning_1592 = @@suppress_log_warning_1592;
-+
-+--disable_warnings
-+DROP TABLE IF EXISTS t1;
-+--enable_warnings
-+CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(20));
-+SET GLOBAL SUPPRESS_LOG_WARNING_1592 = 0;
-+SET GLOBAL LOG_WARNINGS = 0;
-+INSERT INTO t1 VALUES(UUID(), 'suppress_1592');
-+SET GLOBAL LOG_WARNINGS = 1;
-+INSERT INTO t1 VALUES(UUID(), 'suppress_1592');
-+SET GLOBAL SUPPRESS_LOG_WARNING_1592 = 1;
-+SET GLOBAL LOG_WARNINGS = 0;
-+INSERT INTO t1 VALUES(UUID(), 'suppress_1592');
-+SET GLOBAL LOG_WARNINGS = 1;
-+INSERT INTO t1 VALUES(UUID(), 'suppress_1592');
-+DROP TABLE t1;
-+
-+SET GLOBAL log_warnings = @old_log_warnings;
-+SET GLOBAL suppress_log_warning_1592 = @old_suppress_log_warning_1592;
-+
-+let $log_error_= `SELECT @@GLOBAL.log_error`;
-+if(!`select LENGTH('$log_error_')`)
-+{
-+  # MySQL Server on windows is started with --console and thus
-+  # does not know the location of its .err log, use default location
-+  let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
-+}
-+# Assign env variable LOG_ERROR
-+let LOG_ERROR=$log_error_;
-+
-+--echo # Count the number of times the "Unsafe" message was printed
-+--echo # to the error log.
-+
-+perl;
-+  use strict;
-+  my $log_error= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set";
-+  open(FILE, "$log_error") or die("Unable to open $log_error: $!\n");
-+  my $count = () = grep(/suppress_1592/g,<FILE>);
-+  print "Occurrences: $count\n";
-+  close(FILE);
-+  # Clean error log file
-+  open(FILE, '>', "$log_error");
-+  close(FILE);
-+EOF
index 9bdc823b06a45d496b24bf736681cfe3e3a3879c..ee42c8233b8793ffa4aee5d7929eb54d2f8485ad 100644 (file)
@@ -1,9 +1,8 @@
-diff -ur mysql-5.1.22-rc.org/scripts/mysql_system_tables_data.sql mysql-5.1.22-rc/scripts/mysql_system_tables_data.sql
---- mysql-5.1.22-rc.org/scripts/mysql_system_tables_data.sql   2007-09-24 12:29:43.000000000 +0200
-+++ mysql-5.1.22-rc/scripts/mysql_system_tables_data.sql       2007-11-24 20:22:08.360937978 +0100
-@@ -7,23 +7,16 @@
- -- containing "@current_hostname" are filtered out by mysql_install_db.
- set @current_hostname= @@hostname;
+--- Percona-Server-5.1.70-rel14.8/scripts/mysql_system_tables_data.sql 2013-06-06 22:46:49.000000000 +0300
++++ mysql-5.1.71/scripts/mysql_system_tables_data.sql  2013-08-08 17:05:37.885379684 +0300
+@@ -28,23 +28,20 @@
+ SET @get_hostname= @@hostname;
+ SELECT REPLACE((SELECT REPLACE(@get_hostname,'_','\_')),'%','\%') INTO @current_hostname;
  
 -
 --- Fill "db" table with default grants for anyone to
@@ -15,20 +14,23 @@ diff -ur mysql-5.1.22-rc.org/scripts/mysql_system_tables_data.sql mysql-5.1.22-r
 -DROP TABLE tmp_db;
 -
 -
- -- Fill "users" table with default users allowing root access
- -- from local machine if "users" table didn't exist before
+ -- Fill "user" table with default users allowing root access
+ -- from local machine if "user" table didn't exist before
  CREATE TEMPORARY TABLE tmp_user LIKE user;
- set @current_hostname= @@hostname;
 -INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
 -REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0 FROM dual WHERE LOWER( @current_hostname) != 'localhost';
 -REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
++
 +INSERT INTO tmp_user VALUES ('localhost','mysql','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
 +REPLACE INTO tmp_user SELECT @current_hostname,'mysql','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0 FROM dual WHERE LOWER( @current_hostname) != 'localhost';
 +REPLACE INTO tmp_user VALUES ('127.0.0.1','mysql','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
++
 +INSERT INTO tmp_user VALUES ('localhost','mysql_sysadmin','','N','N','N','N','N','N','Y','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','','','',0,0,0,0);
 +REPLACE INTO tmp_user SELECT @current_hostname,'mysql_sysadmin','','N','N','N','N','N','N','Y','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','','','',0,0,0,0 FROM dual WHERE LOWER( @current_hostname) != 'localhost';
 +REPLACE INTO tmp_user VALUES ('127.0.0.1','mysql_sysadmin','','N','N','N','N','N','N','Y','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','','','',0,0,0,0);
++
  INSERT INTO tmp_user (host,user) VALUES ('localhost','');
  INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE LOWER(@current_hostname ) != 'localhost';
++
  INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0;
-
+ DROP TABLE tmp_user;
diff --git a/mysql-userstat.patch b/mysql-userstat.patch
deleted file mode 100644 (file)
index 749fbf1..0000000
+++ /dev/null
@@ -1,3453 +0,0 @@
-# name       : userstat.patch
-# introduced : 11 or before
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/configure.in
-+++ b/configure.in
-@@ -2059,7 +2059,7 @@
-   realpath rename rint rwlock_init setupterm \
-   shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \
-   sighold sigset sigthreadmask port_create sleep \
--  snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
-+  snprintf socket strsep stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \
-   strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
-   posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd printstack \
-   fedisableexcept)
-@@ -2067,6 +2067,9 @@
- #
- #
- #
-+# The following change can be safely null-merged to 5.5
-+# since configure.cmake in 5.5 does the same check
-+AC_SEARCH_LIBS(clock_gettime, rt, LIBRT="-lrt")
- case "$target" in
-  *-*-aix4* | *-*-sco*)
-       # (grr) aix 4.3 has a stub for clock_gettime, (returning ENOSYS)
-@@ -2754,7 +2757,7 @@
- fi
- sql_client_dirs="$sql_client_dirs client"
--CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
-+CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $LIBRT $STATIC_NSS_FLAGS"
- AC_SUBST(CLIENT_LIBS)
- AC_SUBST(CLIENT_THREAD_LIBS)
---- a/include/mysql/plugin.h
-+++ b/include/mysql/plugin.h
-@@ -707,6 +707,9 @@
- unsigned long thd_log_slow_verbosity(const MYSQL_THD thd);
- int thd_opt_slow_log();
- #define EXTENDED_SLOWLOG
-+
-+#define EXTENDED_FOR_USERSTAT
-+
- /**
-   Create a temporary file.
---- a/include/mysql_com.h
-+++ b/include/mysql_com.h
-@@ -29,6 +29,7 @@
- #define SERVER_VERSION_LENGTH 60
- #define SQLSTATE_LENGTH 5
-+#define LIST_PROCESS_HOST_LEN 64
- /*
-   USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
-@@ -115,6 +116,12 @@
-                                          thread */
- #define REFRESH_MASTER          128     /* Remove all bin logs in the index
-                                          and truncate the index */
-+#define REFRESH_TABLE_STATS     256     /* Refresh table stats hash table */
-+#define REFRESH_INDEX_STATS     512     /* Refresh index stats hash table */
-+#define REFRESH_USER_STATS      1024    /* Refresh user stats hash table */
-+#define REFRESH_SLOW_QUERY_LOG  2048    /* Flush slow query log and rotate*/
-+#define REFRESH_CLIENT_STATS    4096    /* Refresh client stats hash table */
-+#define REFRESH_THREAD_STATS    8192    /* Refresh thread stats hash table */
- /* The following can't be set with mysql_refresh() */
- #define REFRESH_READ_LOCK     16384   /* Lock tables for read */
---- /dev/null
-+++ b/patch_info/userstats.info
-@@ -0,0 +1,11 @@
-+File=userstats.patch
-+Name=SHOW USER/TABLE/INDEX statistics
-+Version=V2
-+Author=Google
-+License=GPL
-+Comment=Added INFORMATION_SCHEMA.*_STATISTICS
-+2008-12-01
-+YK: fix behavior for prepared statements
-+
-+2008-11-26
-+YK: add switch variable "userstat_running" to control INFORMATION_SCHEMA.*_STATISTICS (default:OFF)
---- a/sql/handler.cc
-+++ b/sql/handler.cc
-@@ -1198,6 +1198,8 @@
-         goto end;
-       }
-     DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
-+    if (is_real_trans)
-+      thd->diff_commit_trans++;
- end:
-     if (rw_trans)
-       start_waiting_global_read_lock(thd);
-@@ -1328,6 +1330,8 @@
-   /* Always cleanup. Even if there nht==0. There may be savepoints. */
-   if (is_real_trans)
-     thd->transaction.cleanup();
-+
-+  thd->diff_rollback_trans++;
- #endif /* USING_TRANSACTIONS */
-   if (all)
-     thd->transaction_rollback_request= FALSE;
-@@ -1767,6 +1771,7 @@
-     ha_info->reset(); /* keep it conveniently zero-filled */
-   }
-   trans->ha_list= sv->ha_list;
-+  thd->diff_rollback_trans++;
-   DBUG_RETURN(error);
- }
-@@ -2134,6 +2139,8 @@
-       dup_ref=ref+ALIGN_SIZE(ref_length);
-     cached_table_flags= table_flags();
-   }
-+  rows_read = rows_changed = 0;
-+  memset(index_rows_read, 0, sizeof(index_rows_read));
-   DBUG_RETURN(error);
- }
-@@ -3597,6 +3604,111 @@
-   return;
- }
-+// Updates the global table stats with the TABLE this handler represents.
-+void handler::update_global_table_stats() {
-+  if (!opt_userstat_running) {
-+    rows_read = rows_changed = 0;
-+    return;
-+  }
-+
-+  if (!rows_read && !rows_changed) return;  // Nothing to update.
-+  // table_cache_key is db_name + '\0' + table_name + '\0'.
-+  if (!table->s || !table->s->table_cache_key.str || !table->s->table_name.str) return;
-+
-+  TABLE_STATS* table_stats;
-+  char key[NAME_LEN * 2 + 2];
-+  // [db] + '.' + [table]
-+  sprintf(key, "%s.%s", table->s->table_cache_key.str, table->s->table_name.str);
-+
-+  pthread_mutex_lock(&LOCK_global_table_stats);
-+  // Gets the global table stats, creating one if necessary.
-+  if (!(table_stats = (TABLE_STATS*)hash_search(&global_table_stats,
-+                                                (uchar*)key,
-+                                                strlen(key)))) {
-+    if (!(table_stats = ((TABLE_STATS*)
-+                         my_malloc(sizeof(TABLE_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
-+      // Out of memory.
-+      sql_print_error("Allocating table stats failed.");
-+      goto end;
-+    }
-+    strncpy(table_stats->table, key, sizeof(table_stats->table));
-+    table_stats->rows_read = 0;
-+    table_stats->rows_changed = 0;
-+    table_stats->rows_changed_x_indexes = 0;
-+    table_stats->engine_type = (int) ht->db_type;
-+
-+    if (my_hash_insert(&global_table_stats, (uchar*)table_stats)) {
-+      // Out of memory.
-+      sql_print_error("Inserting table stats failed.");
-+      my_free((char*)table_stats, 0);
-+      goto end;
-+    }
-+  }
-+  // Updates the global table stats.
-+  table_stats->rows_read += rows_read;
-+  table_stats->rows_changed += rows_changed;
-+  table_stats->rows_changed_x_indexes +=
-+      rows_changed * (table->s->keys ? table->s->keys : 1);
-+  current_thd->diff_total_read_rows += rows_read;
-+  rows_read = rows_changed = 0;
-+end:
-+  pthread_mutex_unlock(&LOCK_global_table_stats);
-+}
-+
-+// Updates the global index stats with this handler's accumulated index reads.
-+void handler::update_global_index_stats() {
-+  // table_cache_key is db_name + '\0' + table_name + '\0'.
-+  if (!table->s || !table->s->table_cache_key.str || !table->s->table_name.str) return;
-+
-+  if (!opt_userstat_running) {
-+    for (uint x = 0; x < table->s->keys; x++) {
-+      index_rows_read[x] = 0;
-+    }
-+    return;
-+  }
-+
-+  for (uint x = 0; x < table->s->keys; x++) {
-+    if (index_rows_read[x]) {
-+      // Rows were read using this index.
-+      KEY* key_info = &table->key_info[x];
-+
-+      if (!key_info->name) continue;
-+
-+      INDEX_STATS* index_stats;
-+      char key[NAME_LEN * 3 + 3];
-+      // [db] + '.' + [table] + '.' + [index]
-+      sprintf(key, "%s.%s.%s",  table->s->table_cache_key.str,
-+              table->s->table_name.str, key_info->name);
-+
-+      pthread_mutex_lock(&LOCK_global_index_stats);
-+      // Gets the global index stats, creating one if necessary.
-+      if (!(index_stats = (INDEX_STATS*)hash_search(&global_index_stats,
-+                                                    (uchar*)key,
-+                                                    strlen(key)))) {
-+        if (!(index_stats = ((INDEX_STATS*)
-+                             my_malloc(sizeof(INDEX_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
-+          // Out of memory.
-+          sql_print_error("Allocating index stats failed.");
-+          goto end;
-+        }
-+        strncpy(index_stats->index, key, sizeof(index_stats->index));
-+        index_stats->rows_read = 0;
-+
-+        if (my_hash_insert(&global_index_stats, (uchar*)index_stats)) {
-+          // Out of memory.
-+          sql_print_error("Inserting index stats failed.");
-+          my_free((char*)index_stats, 0);
-+          goto end;
-+        }
-+      }
-+      // Updates the global index stats.
-+      index_stats->rows_read += index_rows_read[x];
-+      index_rows_read[x] = 0;
-+end:
-+      pthread_mutex_unlock(&LOCK_global_index_stats);
-+    }
-+  }
-+}
- /****************************************************************************
- ** Some general functions that isn't in the handler class
---- a/sql/handler.h
-+++ b/sql/handler.h
-@@ -31,6 +31,10 @@
- #define USING_TRANSACTIONS
-+#if MAX_KEY > 128
-+#error MAX_KEY is too large.  Values up to 128 are supported.
-+#endif
-+
- // the following is for checking tables
- #define HA_ADMIN_ALREADY_DONE   1
-@@ -1122,6 +1126,9 @@
-   bool locked;
-   bool implicit_emptied;                /* Can be !=0 only if HEAP */
-   const COND *pushed_cond;
-+  ulonglong rows_read;
-+  ulonglong rows_changed;
-+  ulonglong index_rows_read[MAX_KEY];
-   /**
-     next_insert_id is the next value which should be inserted into the
-     auto_increment column: in a inserting-multi-row statement (like INSERT
-@@ -1159,9 +1166,11 @@
-     ref_length(sizeof(my_off_t)),
-     ft_handler(0), inited(NONE),
-     locked(FALSE), implicit_emptied(0),
--    pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
-+    pushed_cond(0), rows_read(0), rows_changed(0), next_insert_id(0), insert_id_for_cur_row(0),
-     auto_inc_intervals_count(0)
--    {}
-+    {
-+      memset(index_rows_read, 0, sizeof(index_rows_read));
-+    }
-   virtual ~handler(void)
-   {
-     DBUG_ASSERT(locked == FALSE);
-@@ -1285,6 +1294,8 @@
-   {
-     table= table_arg;
-     table_share= share;
-+    rows_read = rows_changed = 0;
-+    memset(index_rows_read, 0, sizeof(index_rows_read));
-   }
-   virtual double scan_time()
-   { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
-@@ -1629,6 +1640,8 @@
-   virtual bool is_crashed() const  { return 0; }
-   virtual bool auto_repair() const { return 0; }
-+  void update_global_table_stats();
-+  void update_global_index_stats();
- #define CHF_CREATE_FLAG 0
- #define CHF_DELETE_FLAG 1
---- a/sql/lex.h
-+++ b/sql/lex.h
-@@ -109,6 +109,7 @@
-   { "CHECKSUM",               SYM(CHECKSUM_SYM)},
-   { "CIPHER",         SYM(CIPHER_SYM)},
-   { "CLIENT",         SYM(CLIENT_SYM)},
-+  { "CLIENT_STATISTICS",      SYM(CLIENT_STATS_SYM)},
-   { "CLOSE",          SYM(CLOSE_SYM)},
-   { "COALESCE",               SYM(COALESCE)},
-   { "CODE",             SYM(CODE_SYM)},
-@@ -248,6 +249,7 @@
-   { "IN",             SYM(IN_SYM)},
-   { "INDEX",          SYM(INDEX_SYM)},
-   { "INDEXES",                SYM(INDEXES)},
-+  { "INDEX_STATISTICS",       SYM(INDEX_STATS_SYM)},
-   { "INFILE",         SYM(INFILE)},
-   { "INITIAL_SIZE",   SYM(INITIAL_SIZE_SYM)},
-   { "INNER",          SYM(INNER_SYM)},
-@@ -481,6 +483,7 @@
-   { "SIGNED",         SYM(SIGNED_SYM)},
-   { "SIMPLE",         SYM(SIMPLE_SYM)},
-   { "SLAVE",            SYM(SLAVE)},
-+  { "SLOW",             SYM(SLOW_SYM)},
-   { "SNAPSHOT",         SYM(SNAPSHOT_SYM)},
-   { "SMALLINT",               SYM(SMALLINT)},
-   { "SOCKET",         SYM(SOCKET_SYM)},
-@@ -530,12 +533,14 @@
-   { "TABLES",         SYM(TABLES)},
-   { "TABLESPACE",             SYM(TABLESPACE)},
-   { "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)},
-+  { "TABLE_STATISTICS",       SYM(TABLE_STATS_SYM)},
-   { "TEMPORARY",      SYM(TEMPORARY)},
-   { "TEMPTABLE",      SYM(TEMPTABLE_SYM)},
-   { "TERMINATED",     SYM(TERMINATED)},
-   { "TEXT",           SYM(TEXT_SYM)},
-   { "THAN",             SYM(THAN_SYM)},
-   { "THEN",           SYM(THEN_SYM)},
-+  { "THREAD_STATISTICS",      SYM(THREAD_STATS_SYM)},
-   { "TIME",           SYM(TIME_SYM)},
-   { "TIMESTAMP",      SYM(TIMESTAMP)},
-   { "TIMESTAMPADD",     SYM(TIMESTAMP_ADD)},
-@@ -571,6 +576,7 @@
-   { "USE",            SYM(USE_SYM)},
-   { "USER",           SYM(USER)},
-   { "USER_RESOURCES", SYM(RESOURCES)},
-+  { "USER_STATISTICS",        SYM(USER_STATS_SYM)},
-   { "USE_FRM",                SYM(USE_FRM)},
-   { "USING",          SYM(USING)},
-   { "UTC_DATE",         SYM(UTC_DATE_SYM)},
---- a/sql/log.cc
-+++ b/sql/log.cc
-@@ -826,6 +826,13 @@
-     mysql_slow_log.reopen_file();
- }
-+void Log_to_file_event_handler::flush_slow_log()
-+{
-+  /* reopen slow log file */
-+  if (opt_slow_log)
-+    mysql_slow_log.reopen_file();
-+}
-+
- /*
-   Log error with all enabled log event handlers
-@@ -937,6 +944,21 @@
-   return rc;
- }
-+bool LOGGER::flush_slow_log(THD *thd)
-+{
-+  /*
-+    Now we lock logger, as nobody should be able to use logging routines while
-+    log tables are closed
-+  */
-+  logger.lock_exclusive();
-+
-+  /* reopen log files */
-+  file_log_handler->flush_slow_log();
-+
-+  /* end of log flush */
-+  logger.unlock();
-+  return 0;
-+}
- /*
-   Log slow query with all enabled log event handlers
-@@ -4571,6 +4593,8 @@
-                              thd->first_successful_insert_id_in_prev_stmt_for_binlog);
-           if (e.write(file))
-             goto err;
-+          if (file == &log_file)
-+            thd->binlog_bytes_written += e.data_written;
-         }
-         if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
-         {
-@@ -4582,12 +4606,16 @@
-                              minimum());
-           if (e.write(file))
-             goto err;
-+          if (file == &log_file)
-+            thd->binlog_bytes_written += e.data_written;
-         }
-         if (thd->rand_used)
-         {
-           Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
-           if (e.write(file))
-             goto err;
-+          if (file == &log_file)
-+            thd->binlog_bytes_written += e.data_written;
-         }
-         if (thd->user_var_events.elements)
-         {
-@@ -4603,6 +4631,8 @@
-                                  user_var_event->charset_number);
-             if (e.write(file))
-               goto err;
-+            if (file == &log_file)
-+              thd->binlog_bytes_written += e.data_written;
-           }
-         }
-       }
-@@ -4615,6 +4645,8 @@
-     if (event_info->write(file) || 
-         DBUG_EVALUATE_IF("injecting_fault_writing", 1, 0))
-       goto err;
-+    if (file == &log_file)
-+      thd->binlog_bytes_written += event_info->data_written;
-     if (file == &log_file) // we are writing to the real log (disk)
-     {
-@@ -4785,7 +4817,7 @@
-     be reset as a READ_CACHE to be able to read the contents from it.
-  */
--int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
-+int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache, bool lock_log, bool sync_log)
- {
-   Mutex_sentry sentry(lock_log ? &LOCK_log : NULL);
-@@ -4833,6 +4865,7 @@
-       /* write the first half of the split header */
-       if (my_b_write(&log_file, header, carry))
-         return ER_ERROR_ON_WRITE;
-+      thd->binlog_bytes_written += carry;
-       /*
-         copy fixed second half of header to cache so the correct
-@@ -4901,6 +4934,7 @@
-     /* Write data to the binary log file */
-     if (my_b_write(&log_file, cache->read_pos, length))
-       return ER_ERROR_ON_WRITE;
-+    thd->binlog_bytes_written += length;
-     cache->read_pos=cache->read_end;          // Mark buffer used up
-   } while ((length= my_b_fill(cache)));
-@@ -5027,21 +5061,24 @@
-       */
-       if (qinfo.write(&log_file))
-         goto err;
-+      thd->binlog_bytes_written += qinfo.data_written;
-       DBUG_EXECUTE_IF("crash_before_writing_xid",
-                       {
--                        if ((write_error= write_cache(cache, false, true)))
-+                        if ((write_error= write_cache(thd, cache, false, true)))
-                           DBUG_PRINT("info", ("error writing binlog cache: %d",
-                                                write_error));
-                         DBUG_PRINT("info", ("crashing before writing xid"));
-                         DBUG_SUICIDE();
-                       });
--      if ((write_error= write_cache(cache, false, false)))
-+      if ((write_error= write_cache(thd, cache, false, false)))
-         goto err;
-       if (commit_event && commit_event->write(&log_file))
-         goto err;
-+      if (commit_event)
-+        thd->binlog_bytes_written += commit_event->data_written;
-       if (incident && write_incident(thd, FALSE))
-         goto err;
---- a/sql/log.h
-+++ b/sql/log.h
-@@ -363,7 +363,7 @@
-   bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
-   bool write_incident(THD *thd, bool lock);
--  int  write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
-+  int  write_cache(THD *thd, IO_CACHE *cache, bool lock_log, bool flush_and_sync);
-   void set_write_error(THD *thd);
-   bool check_write_error(THD *thd);
-@@ -501,6 +501,7 @@
-                            const char *sql_text, uint sql_text_len,
-                            CHARSET_INFO *client_cs);
-   void flush();
-+  void flush_slow_log();
-   void init_pthread_objects();
-   MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
-   MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; }
-@@ -545,6 +546,7 @@
-   void init_base();
-   void init_log_tables();
-   bool flush_logs(THD *thd);
-+  bool flush_slow_log(THD *thd);
-   /* Perform basic logger cleanup. this will leave e.g. error log open. */
-   void cleanup_base();
-   /* Free memory. Nothing could be logged after this function is called */
---- a/sql/mysql_priv.h
-+++ b/sql/mysql_priv.h
-@@ -1174,7 +1174,17 @@
- bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
- void init_max_user_conn(void);
- void init_update_queries(void);
-+void init_global_user_stats(void);
-+void init_global_table_stats(void);
-+void init_global_index_stats(void);
-+void init_global_client_stats(void);
-+void init_global_thread_stats(void);
- void free_max_user_conn(void);
-+void free_global_user_stats(void);
-+void free_global_table_stats(void);
-+void free_global_index_stats(void);
-+void free_global_client_stats(void);
-+void free_global_thread_stats(void);
- pthread_handler_t handle_bootstrap(void *arg);
- int mysql_execute_command(THD *thd);
- bool do_command(THD *thd);
-@@ -2043,6 +2053,7 @@
- extern ulong max_connect_errors, connect_timeout;
- extern ulong slave_net_timeout, slave_trans_retries;
- extern uint max_user_connections;
-+extern ulonglong denied_connections;
- extern ulong what_to_log,flush_time;
- extern ulong query_buff_size;
- extern ulong max_prepared_stmt_count, prepared_stmt_count;
-@@ -2097,6 +2108,7 @@
- extern my_bool opt_slave_compressed_protocol, use_temp_pool;
- extern ulong slave_exec_mode_options;
- extern my_bool opt_readonly, lower_case_file_system;
-+extern my_bool opt_userstat_running, opt_thread_statistics;
- extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
- extern my_bool opt_secure_auth;
- extern char* opt_secure_file_priv;
-@@ -2165,6 +2177,15 @@
- extern struct system_variables max_system_variables;
- extern struct system_status_var global_status_var;
- extern struct rand_struct sql_rand;
-+extern HASH global_user_stats;
-+extern HASH global_client_stats;
-+extern HASH global_thread_stats;
-+extern pthread_mutex_t LOCK_global_user_client_stats;
-+extern HASH global_table_stats;
-+extern pthread_mutex_t LOCK_global_table_stats;
-+extern HASH global_index_stats;
-+extern pthread_mutex_t LOCK_global_index_stats;
-+extern pthread_mutex_t LOCK_stats;
- extern const char *opt_date_time_formats[];
- extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -541,6 +541,7 @@
- uint    opt_debug_sync_timeout= 0;
- #endif /* defined(ENABLED_DEBUG_SYNC) */
- my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
-+my_bool opt_userstat_running= 0, opt_thread_statistics= 0;
- /*
-   True if there is at least one per-hour limit for some user, so we should
-   check them before each query (and possibly reset counters when hour is
-@@ -594,6 +595,7 @@
- */
- ulong max_long_data_size;
- uint  max_user_connections= 0;
-+ulonglong denied_connections = 0;
- /**
-   Limit of the total number of prepared statements in the server.
-   Is necessary to protect the server against out-of-memory attacks.
-@@ -695,6 +697,10 @@
-               LOCK_global_system_variables,
-               LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
-                 LOCK_connection_count;
-+pthread_mutex_t LOCK_stats;
-+pthread_mutex_t LOCK_global_user_client_stats;
-+pthread_mutex_t LOCK_global_table_stats;
-+pthread_mutex_t LOCK_global_index_stats;
- /**
-   The below lock protects access to two global server variables:
-   max_prepared_stmt_count and prepared_stmt_count. These variables
-@@ -1380,6 +1386,11 @@
-   x_free(opt_secure_file_priv);
-   bitmap_free(&temp_pool);
-   free_max_user_conn();
-+  free_global_user_stats();
-+  free_global_client_stats();
-+  free_global_thread_stats();
-+  free_global_table_stats();
-+  free_global_index_stats();
- #ifdef HAVE_REPLICATION
-   end_slave_list();
- #endif
-@@ -1496,6 +1507,10 @@
-   (void) pthread_cond_destroy(&COND_thread_cache);
-   (void) pthread_cond_destroy(&COND_flush_thread_cache);
-   (void) pthread_cond_destroy(&COND_manager);
-+  (void) pthread_mutex_destroy(&LOCK_stats);
-+  (void) pthread_mutex_destroy(&LOCK_global_user_client_stats);
-+  (void) pthread_mutex_destroy(&LOCK_global_table_stats);
-+  (void) pthread_mutex_destroy(&LOCK_global_index_stats);
- }
- #endif /*EMBEDDED_LIBRARY*/
-@@ -3198,6 +3213,7 @@
-   {"show_binlog_events",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
-   {"show_binlogs",         (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
-   {"show_charsets",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
-+  {"show_client_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CLIENT_STATS]), SHOW_LONG_STATUS},
-   {"show_collations",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
-   {"show_column_types",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS},
-   {"show_contributors",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS},
-@@ -3219,6 +3235,7 @@
- #endif
-   {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
-   {"show_grants",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
-+  {"show_index_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_INDEX_STATS]), SHOW_LONG_STATUS},
-   {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
-   {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
-   {"show_new_master",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
-@@ -3237,9 +3254,12 @@
-   {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
-   {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
-   {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
-+  {"show_table_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS},
-   {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
-   {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
-+  {"show_thread_statistics",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_THREAD_STATS]), SHOW_LONG_STATUS},
-   {"show_triggers",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
-+  {"show_user_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS},
-   {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
-   {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
-   {"slave_start",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
-@@ -3683,6 +3703,10 @@
- #endif
-   (void) pthread_mutex_init(&LOCK_server_started, MY_MUTEX_INIT_FAST);
-   (void) pthread_cond_init(&COND_server_started,NULL);
-+  (void) pthread_mutex_init(&LOCK_stats, MY_MUTEX_INIT_FAST);
-+  (void) pthread_mutex_init(&LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST);
-+  (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
-+  (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
-   sp_cache_init();
- #ifdef HAVE_EVENT_SCHEDULER
-   Events::init_mutexes();
-@@ -4084,6 +4108,9 @@
-   if (!errmesg[0][0])
-     unireg_abort(1);
-+  init_global_table_stats();
-+  init_global_index_stats();
-+
-   /* We have to initialize the storage engines before CSV logging */
-   if (ha_init())
-   {
-@@ -4230,6 +4257,9 @@
-   init_max_user_conn();
-   init_update_queries();
-+  init_global_user_stats();
-+  init_global_client_stats();
-+  init_global_thread_stats();
-   DBUG_RETURN(0);
- }
-@@ -5047,6 +5077,7 @@
-     DBUG_PRINT("error",("Too many connections"));
-     close_connection(thd, ER_CON_COUNT_ERROR, 1);
-+    statistic_increment(denied_connections, &LOCK_status);
-     delete thd;
-     DBUG_VOID_RETURN;
-   }
-@@ -5832,6 +5863,8 @@
-   OPT_SLAVE_EXEC_MODE,
-   OPT_GENERAL_LOG_FILE,
-   OPT_SLOW_QUERY_LOG_FILE,
-+  OPT_USERSTAT_RUNNING,
-+  OPT_THREAD_STATISTICS,
-   OPT_USE_GLOBAL_LONG_QUERY_TIME,
-   OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
-   OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
-@@ -7340,6 +7373,14 @@
-    &max_system_variables.net_wait_timeout, 0, GET_ULONG,
-    REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
-    0, 1, 0},
-+  {"userstat_running", OPT_USERSTAT_RUNNING,
-+   "Control USER_STATISTICS, CLIENT_STATISTICS, THREAD_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS running",
-+   (uchar**) &opt_userstat_running, (uchar**) &opt_userstat_running,
-+   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-+  {"thread_statistics", OPT_THREAD_STATISTICS,
-+   "Control TABLE_STATISTICS running, when userstat_running is enabled",
-+   (uchar**) &opt_thread_statistics, (uchar**) &opt_thread_statistics,
-+   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-   {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
-    "Causes updates to non-transactional engines using statement format to be "
-    "written directly to binary log. Before using this option, make sure that "
---- a/sql/set_var.cc
-+++ b/sql/set_var.cc
-@@ -569,6 +569,10 @@
- static sys_var_thd_ulong      sys_read_buff_size(&vars, "read_buffer_size",
-                                          &SV::read_buff_size);
- static sys_var_opt_readonly   sys_readonly(&vars, "read_only", &opt_readonly);
-+static sys_var_bool_ptr               sys_userstat_running(&vars, "userstat_running",
-+                                                   &opt_userstat_running);
-+static sys_var_bool_ptr               sys_thread_statistics(&vars, "thread_statistics",
-+                                                    &opt_thread_statistics);
- static sys_var_thd_ulong      sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
-                                              &SV::read_rnd_buff_size);
- static sys_var_thd_ulong      sys_div_precincrement(&vars, "div_precision_increment",
---- a/sql/sql_base.cc
-+++ b/sql/sql_base.cc
-@@ -1382,6 +1382,12 @@
-   DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str,
-                         table->s->table_name.str, (long) table));
-+  if(table->file)
-+  {
-+    table->file->update_global_table_stats();
-+    table->file->update_global_index_stats();
-+  }
-+
-   *table_ptr=table->next;
-   /*
-     When closing a MERGE parent or child table, detach the children first.
-@@ -1922,6 +1928,8 @@
-   DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
-                           table->s->db.str, table->s->table_name.str));
-+  table->file->update_global_table_stats();
-+  table->file->update_global_index_stats();
-   free_io_cache(table);
-   closefrm(table, 0);
-   if (delete_table)
---- a/sql/sql_class.cc
-+++ b/sql/sql_class.cc
-@@ -706,6 +706,13 @@
-   mysys_var=0;
-   binlog_evt_union.do_union= FALSE;
-   enable_slow_log= 0;
-+  busy_time = 0;
-+  cpu_time = 0;
-+  bytes_received = 0;
-+  bytes_sent = 0;
-+  binlog_bytes_written = 0;
-+  updated_row_count = 0;
-+  sent_row_count_2 = 0;
- #ifndef DBUG_OFF
-   dbug_sentry=THD_SENTRY_MAGIC;
- #endif
-@@ -909,6 +916,7 @@
-   reset_current_stmt_binlog_row_based();
-   bzero((char *) &status_var, sizeof(status_var));
-   sql_log_bin_toplevel= options & OPTION_BIN_LOG;
-+  reset_stats();
- #if defined(ENABLED_DEBUG_SYNC)
-   /* Initialize the Debug Sync Facility. See debug_sync.cc. */
-@@ -916,6 +924,84 @@
- #endif /* defined(ENABLED_DEBUG_SYNC) */
- }
-+// Resets stats in a THD.
-+void THD::reset_stats(void) {
-+  current_connect_time = time(NULL);
-+  last_global_update_time = current_connect_time;
-+  reset_diff_stats();
-+}
-+
-+// Resets the 'diff' stats, which are used to update global stats.
-+void THD::reset_diff_stats(void) {
-+  diff_total_busy_time = 0;
-+  diff_total_cpu_time = 0;
-+  diff_total_bytes_received = 0;
-+  diff_total_bytes_sent = 0;
-+  diff_total_binlog_bytes_written = 0;
-+  diff_total_sent_rows = 0;
-+  diff_total_updated_rows = 0;
-+  diff_total_read_rows = 0;
-+  diff_select_commands = 0;
-+  diff_update_commands = 0;
-+  diff_other_commands = 0;
-+  diff_commit_trans = 0;
-+  diff_rollback_trans = 0;
-+  diff_denied_connections = 0;
-+  diff_lost_connections = 0;
-+  diff_access_denied_errors = 0;
-+  diff_empty_queries = 0;
-+}
-+
-+// Updates 'diff' stats of a THD.
-+void THD::update_stats(bool ran_command) {
-+  if (opt_userstat_running) {
-+  diff_total_busy_time += busy_time;
-+  diff_total_cpu_time += cpu_time;
-+  diff_total_bytes_received += bytes_received;
-+  diff_total_bytes_sent += bytes_sent;
-+  diff_total_binlog_bytes_written += binlog_bytes_written;
-+  diff_total_sent_rows += sent_row_count_2;
-+  diff_total_updated_rows += updated_row_count;
-+  // diff_total_read_rows is updated in handler.cc.
-+
-+  if (ran_command) {
-+    // The replication thread has the COM_CONNECT command.
-+    if ((old_command == COM_QUERY || command == COM_CONNECT) &&
-+        (lex->sql_command >= 0 && lex->sql_command < SQLCOM_END)) {
-+      // A SQL query.
-+      if (lex->sql_command == SQLCOM_SELECT) {
-+        diff_select_commands++;
-+        if (!sent_row_count_2)
-+          diff_empty_queries++;
-+      } else if (! sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) {
-+        // 'SHOW ' commands become SQLCOM_SELECT.
-+        diff_other_commands++;
-+        // 'SHOW ' commands shouldn't inflate total sent row count.
-+        diff_total_sent_rows -= sent_row_count_2;
-+      } else if (is_update_query(lex->sql_command)) {
-+        diff_update_commands++;
-+      } else {
-+        diff_other_commands++;
-+      }
-+    }
-+  }
-+  // diff_commit_trans is updated in handler.cc.
-+  // diff_rollback_trans is updated in handler.cc.
-+  // diff_denied_connections is updated in sql_parse.cc.
-+  // diff_lost_connections is updated in sql_parse.cc.
-+  // diff_access_denied_errors is updated in sql_parse.cc.
-+
-+  /* reset counters to zero to avoid double-counting since values
-+     are already store in diff_total_*. */
-+  }
-+  busy_time = 0;
-+  cpu_time = 0;
-+  bytes_received = 0;
-+  bytes_sent = 0;
-+  binlog_bytes_written = 0;
-+  updated_row_count = 0;
-+  sent_row_count_2 = 0;
-+}
- /*
-   Init THD for query processing.
-@@ -1566,6 +1652,32 @@
- }
- #endif
-+char *THD::get_client_host_port(THD *client)
-+{
-+  Security_context *client_sctx= client->security_ctx;
-+  char *client_host= NULL;
-+
-+  if (client->peer_port && (client_sctx->host || client_sctx->ip) &&
-+      security_ctx->host_or_ip[0])
-+  {
-+    if ((client_host= (char *) this->alloc(LIST_PROCESS_HOST_LEN+1)))
-+      my_snprintf((char *) client_host, LIST_PROCESS_HOST_LEN,
-+                  "%s:%u", client_sctx->host_or_ip, client->peer_port);
-+  }
-+  else
-+    client_host= this->strdup(client_sctx->host_or_ip[0] ?
-+                              client_sctx->host_or_ip :
-+                              client_sctx->host ? client_sctx->host : "");
-+
-+  return client_host;
-+}
-+
-+const char *get_client_host(THD *client)
-+{
-+  return client->security_ctx->host_or_ip[0] ?
-+      client->security_ctx->host_or_ip :
-+      client->security_ctx->host ? client->security_ctx->host : "";
-+}
- struct Item_change_record: public ilink
- {
-@@ -1753,6 +1865,7 @@
-     buffer.set(buff, sizeof(buff), &my_charset_bin);
-   }
-   thd->sent_row_count++;
-+  thd->sent_row_count_2++;
-   if (thd->is_error())
-   {
-     protocol->remove_last_row();
-@@ -1857,6 +1970,7 @@
- select_export::~select_export()
- {
-   thd->sent_row_count=row_count;
-+  thd->sent_row_count_2=row_count;
- }
-@@ -2889,6 +3003,7 @@
-   if (likely(thd != 0))
-   { /* current_thd==0 when close_connection() calls net_send_error() */
-     thd->status_var.bytes_sent+= length;
-+    thd->bytes_sent+= length;
-   }
- }
-@@ -2896,6 +3011,7 @@
- void thd_increment_bytes_received(ulong length)
- {
-   current_thd->status_var.bytes_received+= length;
-+  current_thd->bytes_received+= length;
- }
---- a/sql/sql_class.h
-+++ b/sql/sql_class.h
-@@ -1440,6 +1440,8 @@
-     first byte of the packet in do_command()
-   */
-   enum enum_server_command command;
-+  // Used to save the command, before it is set to COM_SLEEP.
-+  enum enum_server_command old_command;
-   uint32     server_id;
-   uint32     file_id;                 // for LOAD DATA INFILE
-   /* remote (peer) port */
-@@ -1831,6 +1833,8 @@
-   /* variables.transaction_isolation is reset to this after each commit */
-   enum_tx_isolation session_tx_isolation;
-   enum_check_fields count_cuted_fields;
-+  ha_rows    updated_row_count;
-+  ha_rows    sent_row_count_2; /* for userstat */
-   DYNAMIC_ARRAY user_var_events;        /* For user variables replication */
-   MEM_ROOT      *user_var_events_alloc; /* Allocate above array elements here */
-@@ -1919,6 +1923,49 @@
-   */
-   LOG_INFO*  current_linfo;
-   NET*       slave_net;                       // network connection from slave -> m.
-+
-+  /*
-+    Used to update global user stats.  The global user stats are updated
-+    occasionally with the 'diff' variables.  After the update, the 'diff'
-+    variables are reset to 0.
-+   */
-+  // Time when the current thread connected to MySQL.
-+  time_t current_connect_time;
-+  // Last time when THD stats were updated in global_user_stats.
-+  time_t last_global_update_time;
-+  // Busy (non-idle) time for just one command.
-+  double busy_time;
-+  // Busy time not updated in global_user_stats yet.
-+  double diff_total_busy_time;
-+  // Cpu (non-idle) time for just one thread.
-+  double cpu_time;
-+  // Cpu time not updated in global_user_stats yet.
-+  double diff_total_cpu_time;
-+  /* bytes counting */
-+  ulonglong bytes_received;
-+  ulonglong diff_total_bytes_received;
-+  ulonglong bytes_sent;
-+  ulonglong diff_total_bytes_sent;
-+  ulonglong binlog_bytes_written;
-+  ulonglong diff_total_binlog_bytes_written;
-+
-+  // Number of rows not reflected in global_user_stats yet.
-+  ha_rows diff_total_sent_rows, diff_total_updated_rows, diff_total_read_rows;
-+  // Number of commands not reflected in global_user_stats yet.
-+  ulonglong diff_select_commands, diff_update_commands, diff_other_commands;
-+  // Number of transactions not reflected in global_user_stats yet.
-+  ulonglong diff_commit_trans, diff_rollback_trans;
-+  // Number of connection errors not reflected in global_user_stats yet.
-+  ulonglong diff_denied_connections, diff_lost_connections;
-+  // Number of db access denied, not reflected in global_user_stats yet.
-+  ulonglong diff_access_denied_errors;
-+  // Number of queries that return 0 rows
-+  ulonglong diff_empty_queries;
-+
-+  // Per account query delay in miliseconds. When not 0, sleep this number of
-+  // milliseconds before every SQL command.
-+  ulonglong query_delay_millis;
-+
-   /* Used by the sys_var class to store temporary values */
-   union
-   {
-@@ -1984,6 +2031,11 @@
-     alloc_root. 
-   */
-   void init_for_queries();
-+  void reset_stats(void);
-+  void reset_diff_stats(void);
-+  // ran_command is true when this is called immediately after a
-+  // command has been run.
-+  void update_stats(bool ran_command);
-   void change_user(void);
-   void cleanup(void);
-   void cleanup_after_query();
-@@ -2353,9 +2405,15 @@
-     *p_db= strmake(db, db_length);
-     *p_db_length= db_length;
-     return FALSE;
-+
-+  // Returns string as 'IP:port' for the client-side of the connnection represented
-+  // by 'client' as displayed by SHOW PROCESSLIST. Allocates memory from the heap of
-+  // this THD and that is not reclaimed immediately, so use sparingly. May return NULL.
-   }
-   thd_scheduler scheduler;
-+  char *get_client_host_port(THD *client);
-+
- public:
-   inline Internal_error_handler *get_internal_handler()
-   { return m_internal_handler; }
-@@ -2439,6 +2497,9 @@
-   LEX_STRING invoker_host;
- };
-+// Returns string as 'IP' for the client-side of the connection represented by
-+// 'client'. Does not allocate memory. May return "".
-+const char *get_client_host(THD *client);
- /** A short cut for thd->main_da.set_ok_status(). */
---- a/sql/sql_connect.cc
-+++ b/sql/sql_connect.cc
-@@ -30,6 +30,24 @@
- extern void win_install_sigabrt_handler();
- #endif
-+// Increments connection count for user.
-+static int increment_connection_count(THD* thd, bool use_lock);
-+
-+// Uses the THD to update the global stats by user name and client IP
-+void update_global_user_stats(THD* thd, bool create_user, time_t now);
-+
-+HASH global_user_stats;
-+HASH global_client_stats;
-+HASH global_thread_stats;
-+// Protects global_user_stats and global_client_stats
-+extern pthread_mutex_t LOCK_global_user_client_stats;
-+
-+HASH global_table_stats;
-+extern pthread_mutex_t LOCK_global_table_stats;
-+
-+HASH global_index_stats;
-+extern pthread_mutex_t LOCK_global_index_stats;
-+
- /*
-   Get structure for logging connection data for the current user
- */
-@@ -87,6 +105,563 @@
- }
-+extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length,
-+                         my_bool not_used __attribute__((unused)))
-+{
-+  *length = strlen(user_stats->user);
-+  return (uchar*)user_stats->user;
-+}
-+
-+extern "C" uchar *get_key_thread_stats(THREAD_STATS *thread_stats, size_t *length,
-+                         my_bool not_used __attribute__((unused)))
-+{
-+  *length = sizeof(my_thread_id);
-+  return (uchar*)&(thread_stats->id);
-+}
-+
-+void free_user_stats(USER_STATS* user_stats)
-+{
-+  my_free((char*)user_stats, MYF(0));
-+}
-+
-+void free_thread_stats(THREAD_STATS* thread_stats)
-+{
-+  my_free((char*)thread_stats, MYF(0));
-+}
-+
-+void init_user_stats(USER_STATS *user_stats,
-+                     const char *user,
-+                     const char *priv_user,
-+                     uint total_connections,
-+                     uint concurrent_connections,
-+                     time_t connected_time,
-+                     double busy_time,
-+                     double cpu_time,
-+                     ulonglong bytes_received,
-+                     ulonglong bytes_sent,
-+                     ulonglong binlog_bytes_written,
-+                     ha_rows rows_fetched,
-+                     ha_rows rows_updated,
-+                     ha_rows rows_read,
-+                     ulonglong select_commands,
-+                     ulonglong update_commands,
-+                     ulonglong other_commands,
-+                     ulonglong commit_trans,
-+                     ulonglong rollback_trans,
-+                     ulonglong denied_connections,
-+                     ulonglong lost_connections,
-+                     ulonglong access_denied_errors,
-+                     ulonglong empty_queries)
-+{
-+  DBUG_ENTER("init_user_stats");
-+  DBUG_PRINT("info",
-+             ("Add user_stats entry for user %s - priv_user %s",
-+              user, priv_user));
-+  strncpy(user_stats->user, user, sizeof(user_stats->user));
-+  strncpy(user_stats->priv_user, priv_user, sizeof(user_stats->priv_user));
-+
-+  user_stats->total_connections = total_connections;
-+  user_stats->concurrent_connections = concurrent_connections;
-+  user_stats->connected_time = connected_time;
-+  user_stats->busy_time = busy_time;
-+  user_stats->cpu_time = cpu_time;
-+  user_stats->bytes_received = bytes_received;
-+  user_stats->bytes_sent = bytes_sent;
-+  user_stats->binlog_bytes_written = binlog_bytes_written;
-+  user_stats->rows_fetched = rows_fetched;
-+  user_stats->rows_updated = rows_updated;
-+  user_stats->rows_read = rows_read;
-+  user_stats->select_commands = select_commands;
-+  user_stats->update_commands = update_commands;
-+  user_stats->other_commands = other_commands;
-+  user_stats->commit_trans = commit_trans;
-+  user_stats->rollback_trans = rollback_trans;
-+  user_stats->denied_connections = denied_connections;
-+  user_stats->lost_connections = lost_connections;
-+  user_stats->access_denied_errors = access_denied_errors;
-+  user_stats->empty_queries = empty_queries;
-+  DBUG_VOID_RETURN;
-+}
-+
-+void init_thread_stats(THREAD_STATS *thread_stats,
-+                     my_thread_id id,
-+                     uint total_connections,
-+                     uint concurrent_connections,
-+                     time_t connected_time,
-+                     double busy_time,
-+                     double cpu_time,
-+                     ulonglong bytes_received,
-+                     ulonglong bytes_sent,
-+                     ulonglong binlog_bytes_written,
-+                     ha_rows rows_fetched,
-+                     ha_rows rows_updated,
-+                     ha_rows rows_read,
-+                     ulonglong select_commands,
-+                     ulonglong update_commands,
-+                     ulonglong other_commands,
-+                     ulonglong commit_trans,
-+                     ulonglong rollback_trans,
-+                     ulonglong denied_connections,
-+                     ulonglong lost_connections,
-+                     ulonglong access_denied_errors,
-+                     ulonglong empty_queries)
-+{
-+  DBUG_ENTER("init_thread_stats");
-+  DBUG_PRINT("info",
-+             ("Add thread_stats entry for thread %lu",
-+              id));
-+  thread_stats->id = id;
-+
-+  thread_stats->total_connections = total_connections;
-+  thread_stats->concurrent_connections = concurrent_connections;
-+  thread_stats->connected_time = connected_time;
-+  thread_stats->busy_time = busy_time;
-+  thread_stats->cpu_time = cpu_time;
-+  thread_stats->bytes_received = bytes_received;
-+  thread_stats->bytes_sent = bytes_sent;
-+  thread_stats->binlog_bytes_written = binlog_bytes_written;
-+  thread_stats->rows_fetched = rows_fetched;
-+  thread_stats->rows_updated = rows_updated;
-+  thread_stats->rows_read = rows_read;
-+  thread_stats->select_commands = select_commands;
-+  thread_stats->update_commands = update_commands;
-+  thread_stats->other_commands = other_commands;
-+  thread_stats->commit_trans = commit_trans;
-+  thread_stats->rollback_trans = rollback_trans;
-+  thread_stats->denied_connections = denied_connections;
-+  thread_stats->lost_connections = lost_connections;
-+  thread_stats->access_denied_errors = access_denied_errors;
-+  thread_stats->empty_queries = empty_queries;
-+  DBUG_VOID_RETURN;
-+}
-+
-+void add_user_stats(USER_STATS *user_stats,
-+                    uint total_connections,
-+                    uint concurrent_connections,
-+                    time_t connected_time,
-+                    double busy_time,
-+                    double cpu_time,
-+                    ulonglong bytes_received,
-+                    ulonglong bytes_sent,
-+                    ulonglong binlog_bytes_written,
-+                    ha_rows rows_fetched,
-+                    ha_rows rows_updated,
-+                    ha_rows rows_read,
-+                    ulonglong select_commands,
-+                    ulonglong update_commands,
-+                    ulonglong other_commands,
-+                    ulonglong commit_trans,
-+                    ulonglong rollback_trans,
-+                    ulonglong denied_connections,
-+                    ulonglong lost_connections,
-+                    ulonglong access_denied_errors,
-+                    ulonglong empty_queries)
-+{
-+  user_stats->total_connections += total_connections;
-+  user_stats->concurrent_connections += concurrent_connections;
-+  user_stats->connected_time += connected_time;
-+  user_stats->busy_time += busy_time;
-+  user_stats->cpu_time += cpu_time;
-+  user_stats->bytes_received += bytes_received;
-+  user_stats->bytes_sent += bytes_sent;
-+  user_stats->binlog_bytes_written += binlog_bytes_written;
-+  user_stats->rows_fetched += rows_fetched;
-+  user_stats->rows_updated += rows_updated;
-+  user_stats->rows_read += rows_read;
-+  user_stats->select_commands += select_commands;
-+  user_stats->update_commands += update_commands;
-+  user_stats->other_commands += other_commands;
-+  user_stats->commit_trans += commit_trans;
-+  user_stats->rollback_trans += rollback_trans;
-+  user_stats->denied_connections += denied_connections;
-+  user_stats->lost_connections += lost_connections;
-+  user_stats->access_denied_errors += access_denied_errors;
-+  user_stats->empty_queries += empty_queries;
-+}
-+
-+void add_thread_stats(THREAD_STATS *thread_stats,
-+                    uint total_connections,
-+                    uint concurrent_connections,
-+                    time_t connected_time,
-+                    double busy_time,
-+                    double cpu_time,
-+                    ulonglong bytes_received,
-+                    ulonglong bytes_sent,
-+                    ulonglong binlog_bytes_written,
-+                    ha_rows rows_fetched,
-+                    ha_rows rows_updated,
-+                    ha_rows rows_read,
-+                    ulonglong select_commands,
-+                    ulonglong update_commands,
-+                    ulonglong other_commands,
-+                    ulonglong commit_trans,
-+                    ulonglong rollback_trans,
-+                    ulonglong denied_connections,
-+                    ulonglong lost_connections,
-+                    ulonglong access_denied_errors,
-+                    ulonglong empty_queries)
-+{
-+  thread_stats->total_connections += total_connections;
-+  thread_stats->concurrent_connections += concurrent_connections;
-+  thread_stats->connected_time += connected_time;
-+  thread_stats->busy_time += busy_time;
-+  thread_stats->cpu_time += cpu_time;
-+  thread_stats->bytes_received += bytes_received;
-+  thread_stats->bytes_sent += bytes_sent;
-+  thread_stats->binlog_bytes_written += binlog_bytes_written;
-+  thread_stats->rows_fetched += rows_fetched;
-+  thread_stats->rows_updated += rows_updated;
-+  thread_stats->rows_read += rows_read;
-+  thread_stats->select_commands += select_commands;
-+  thread_stats->update_commands += update_commands;
-+  thread_stats->other_commands += other_commands;
-+  thread_stats->commit_trans += commit_trans;
-+  thread_stats->rollback_trans += rollback_trans;
-+  thread_stats->denied_connections += denied_connections;
-+  thread_stats->lost_connections += lost_connections;
-+  thread_stats->access_denied_errors += access_denied_errors;
-+  thread_stats->empty_queries += empty_queries;
-+}
-+
-+void init_global_user_stats(void)
-+{
-+  if (hash_init(&global_user_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_user_stats,
-+                (hash_free_key)free_user_stats, 0)) {
-+    sql_print_error("Initializing global_user_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+void init_global_client_stats(void)
-+{
-+  if (hash_init(&global_client_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_user_stats,
-+                (hash_free_key)free_user_stats, 0)) {
-+    sql_print_error("Initializing global_client_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+void init_global_thread_stats(void)
-+{
-+  if (hash_init(&global_thread_stats, &my_charset_bin, max_connections,
-+                0, 0, (hash_get_key)get_key_thread_stats,
-+                (hash_free_key)free_thread_stats, 0)) {
-+    sql_print_error("Initializing global_client_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+extern "C" uchar *get_key_table_stats(TABLE_STATS *table_stats, size_t *length,
-+                                     my_bool not_used __attribute__((unused)))
-+{
-+  *length = strlen(table_stats->table);
-+  return (uchar*)table_stats->table;
-+}
-+
-+extern "C" void free_table_stats(TABLE_STATS* table_stats)
-+{
-+  my_free((char*)table_stats, MYF(0));
-+}
-+
-+void init_global_table_stats(void)
-+{
-+  if (hash_init(&global_table_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_table_stats,
-+                (hash_free_key)free_table_stats, 0)) {
-+    sql_print_error("Initializing global_table_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+extern "C" uchar *get_key_index_stats(INDEX_STATS *index_stats, size_t *length,
-+                                     my_bool not_used __attribute__((unused)))
-+{
-+  *length = strlen(index_stats->index);
-+  return (uchar*)index_stats->index;
-+}
-+
-+extern "C" void free_index_stats(INDEX_STATS* index_stats)
-+{
-+  my_free((char*)index_stats, MYF(0));
-+}
-+
-+void init_global_index_stats(void)
-+{
-+  if (hash_init(&global_index_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_index_stats,
-+                (hash_free_key)free_index_stats, 0)) {
-+    sql_print_error("Initializing global_index_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+void free_global_user_stats(void)
-+{
-+  hash_free(&global_user_stats);
-+}
-+
-+void free_global_thread_stats(void)
-+{
-+  hash_free(&global_thread_stats);
-+}
-+
-+void free_global_table_stats(void)
-+{
-+  hash_free(&global_table_stats);
-+}
-+
-+void free_global_index_stats(void)
-+{
-+  hash_free(&global_index_stats);
-+}
-+
-+void free_global_client_stats(void)
-+{
-+  hash_free(&global_client_stats);
-+}
-+
-+// 'mysql_system_user' is used for when the user is not defined for a THD.
-+static char mysql_system_user[] = "#mysql_system#";
-+
-+// Returns 'user' if it's not NULL.  Returns 'mysql_system_user' otherwise.
-+static char* get_valid_user_string(char* user) {
-+  return user ? user : mysql_system_user;
-+}
-+
-+// Increments the global stats connection count for an entry from
-+// global_client_stats or global_user_stats. Returns 0 on success
-+// and 1 on error.
-+static int increment_count_by_name(const char *name, const char *role_name,
-+                                   HASH *users_or_clients, THD *thd)
-+{
-+  USER_STATS* user_stats;
-+
-+  if (!(user_stats = (USER_STATS*)hash_search(users_or_clients, (uchar*) name,
-+                                              strlen(name))))
-+  {
-+    // First connection for this user or client
-+    if (!(user_stats = ((USER_STATS*)
-+                        my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL)))))
-+    {
-+      return 1; // Out of memory
-+    }
-+
-+    init_user_stats(user_stats, name, role_name,
-+                    0, 0,      // connections
-+                    0, 0, 0,   // time
-+                    0, 0, 0,   // bytes sent, received and written
-+                    0, 0, 0,   // rows fetched, updated and read
-+                    0, 0, 0,   // select, update and other commands
-+                    0, 0,      // commit and rollback trans
-+                    thd->diff_denied_connections,
-+                    0,         // lost connections
-+                    0,         // access denied errors
-+                    0);        // empty queries
-+
-+    if (my_hash_insert(users_or_clients, (uchar*)user_stats))
-+    {
-+      my_free((char*)user_stats, 0);
-+      return 1; // Out of memory
-+    }
-+  }
-+  user_stats->total_connections++;
-+  return 0;
-+}
-+
-+static int increment_count_by_id(my_thread_id id,
-+                                 HASH *users_or_clients, THD *thd)
-+{
-+  THREAD_STATS* thread_stats;
-+
-+  if (!(thread_stats = (THREAD_STATS*)hash_search(users_or_clients, (uchar*) &id,
-+                                              sizeof(my_thread_id))))
-+  {
-+    // First connection for this user or client
-+    if (!(thread_stats = ((THREAD_STATS*)
-+                        my_malloc(sizeof(THREAD_STATS), MYF(MY_WME | MY_ZEROFILL)))))
-+    {
-+      return 1; // Out of memory
-+    }
-+
-+    init_thread_stats(thread_stats, id,
-+                    0, 0,      // connections
-+                    0, 0, 0,   // time
-+                    0, 0, 0,   // bytes sent, received and written
-+                    0, 0, 0,   // rows fetched, updated and read
-+                    0, 0, 0,   // select, update and other commands
-+                    0, 0,      // commit and rollback trans
-+                    thd->diff_denied_connections,
-+                    0,         // lost connections
-+                    0,         // access denied errors
-+                    0);        // empty queries
-+
-+    if (my_hash_insert(users_or_clients, (uchar*)thread_stats))
-+    {
-+      my_free((char*)thread_stats, 0);
-+      return 1; // Out of memory
-+    }
-+  }
-+  thread_stats->total_connections++;
-+  return 0;
-+}
-+
-+// Increments the global user and client stats connection count.  If 'use_lock'
-+// is true, LOCK_global_user_client_stats will be locked/unlocked.  Returns
-+// 0 on success, 1 on error.
-+static int increment_connection_count(THD* thd, bool use_lock)
-+{
-+  char* user_string = get_valid_user_string(thd->main_security_ctx.user);
-+  const char* client_string = get_client_host(thd);
-+  int return_value = 0;
-+
-+  if (!opt_userstat_running)
-+    return return_value;
-+
-+  if (use_lock) pthread_mutex_lock(&LOCK_global_user_client_stats);
-+
-+  if (increment_count_by_name(user_string, user_string,
-+                              &global_user_stats, thd))
-+  {
-+    return_value = 1;
-+    goto end;
-+  }
-+  if (increment_count_by_name(client_string,
-+                              user_string,
-+                              &global_client_stats, thd))
-+  {
-+    return_value = 1;
-+    goto end;
-+  }
-+  if (opt_thread_statistics) {
-+    if (increment_count_by_id(thd->thread_id, &global_thread_stats, thd))
-+    {
-+      return_value = 1;
-+      goto end;
-+    }
-+  }
-+
-+end:
-+  if (use_lock) pthread_mutex_unlock(&LOCK_global_user_client_stats);
-+  return return_value;
-+}
-+
-+// Used to update the global user and client stats.
-+static void update_global_user_stats_with_user(THD* thd,
-+                                               USER_STATS* user_stats,
-+                                               time_t now)
-+{
-+  user_stats->connected_time += now - thd->last_global_update_time;
-+//  thd->last_global_update_time = now;
-+  user_stats->busy_time += thd->diff_total_busy_time;
-+  user_stats->cpu_time += thd->diff_total_cpu_time;
-+  user_stats->bytes_received += thd->diff_total_bytes_received;
-+  user_stats->bytes_sent += thd->diff_total_bytes_sent;
-+  user_stats->binlog_bytes_written += thd->diff_total_binlog_bytes_written;
-+  user_stats->rows_fetched += thd->diff_total_sent_rows;
-+  user_stats->rows_updated += thd->diff_total_updated_rows;
-+  user_stats->rows_read += thd->diff_total_read_rows;
-+  user_stats->select_commands += thd->diff_select_commands;
-+  user_stats->update_commands += thd->diff_update_commands;
-+  user_stats->other_commands += thd->diff_other_commands;
-+  user_stats->commit_trans += thd->diff_commit_trans;
-+  user_stats->rollback_trans += thd->diff_rollback_trans;
-+  user_stats->denied_connections += thd->diff_denied_connections;
-+  user_stats->lost_connections += thd->diff_lost_connections;
-+  user_stats->access_denied_errors += thd->diff_access_denied_errors;
-+  user_stats->empty_queries += thd->diff_empty_queries;
-+}
-+
-+static void update_global_thread_stats_with_thread(THD* thd,
-+                                               THREAD_STATS* thread_stats,
-+                                               time_t now)
-+{
-+  thread_stats->connected_time += now - thd->last_global_update_time;
-+//  thd->last_global_update_time = now;
-+  thread_stats->busy_time += thd->diff_total_busy_time;
-+  thread_stats->cpu_time += thd->diff_total_cpu_time;
-+  thread_stats->bytes_received += thd->diff_total_bytes_received;
-+  thread_stats->bytes_sent += thd->diff_total_bytes_sent;
-+  thread_stats->binlog_bytes_written += thd->diff_total_binlog_bytes_written;
-+  thread_stats->rows_fetched += thd->diff_total_sent_rows;
-+  thread_stats->rows_updated += thd->diff_total_updated_rows;
-+  thread_stats->rows_read += thd->diff_total_read_rows;
-+  thread_stats->select_commands += thd->diff_select_commands;
-+  thread_stats->update_commands += thd->diff_update_commands;
-+  thread_stats->other_commands += thd->diff_other_commands;
-+  thread_stats->commit_trans += thd->diff_commit_trans;
-+  thread_stats->rollback_trans += thd->diff_rollback_trans;
-+  thread_stats->denied_connections += thd->diff_denied_connections;
-+  thread_stats->lost_connections += thd->diff_lost_connections;
-+  thread_stats->access_denied_errors += thd->diff_access_denied_errors;
-+  thread_stats->empty_queries += thd->diff_empty_queries;
-+}
-+
-+// Updates the global stats of a user or client
-+void update_global_user_stats(THD* thd, bool create_user, time_t now)
-+{
-+  if (opt_userstat_running) {
-+  char* user_string = get_valid_user_string(thd->main_security_ctx.user);
-+  const char* client_string = get_client_host(thd);
-+
-+  USER_STATS* user_stats;
-+  THREAD_STATS* thread_stats;
-+  pthread_mutex_lock(&LOCK_global_user_client_stats);
-+
-+  // Update by user name
-+  if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
-+                                             (uchar*)user_string,
-+                                             strlen(user_string)))) {
-+    // Found user.
-+    update_global_user_stats_with_user(thd, user_stats, now);
-+  } else {
-+    // Create the entry
-+    if (create_user) {
-+      increment_count_by_name(user_string, user_string,
-+                              &global_user_stats, thd);
-+    }
-+  }
-+
-+  // Update by client IP
-+  if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
-+                                             (uchar*)client_string,
-+                                             strlen(client_string)))) {
-+    // Found by client IP
-+    update_global_user_stats_with_user(thd, user_stats, now);
-+  } else {
-+    // Create the entry
-+    if (create_user) {
-+      increment_count_by_name(client_string,
-+                              user_string,
-+                              &global_client_stats, thd);
-+    }
-+  }
-+
-+  if (opt_thread_statistics) {
-+    // Update by thread ID
-+    if ((thread_stats = (THREAD_STATS*)hash_search(&global_thread_stats,
-+                                             (uchar*) &(thd->thread_id),
-+                                             sizeof(my_thread_id)))) {
-+      // Found by thread ID
-+      update_global_thread_stats_with_thread(thd, thread_stats, now);
-+    } else {
-+      // Create the entry
-+      if (create_user) {
-+        increment_count_by_id(thd->thread_id,
-+                              &global_thread_stats, thd);
-+      }
-+    }
-+  }
-+
-+  thd->last_global_update_time = now;
-+  thd->reset_diff_stats();
-+
-+  pthread_mutex_unlock(&LOCK_global_user_client_stats);
-+  } else {
-+  thd->reset_diff_stats();
-+  }
-+}
- /*
-   check if user has already too many connections
-@@ -142,7 +717,10 @@
- end:
-   if (error)
-+  {
-     uc->connections--; // no need for decrease_user_connections() here
-+    statistic_increment(denied_connections, &LOCK_status);
-+  }
-   (void) pthread_mutex_unlock(&LOCK_user_conn);
-   DBUG_RETURN(error);
- }
-@@ -478,6 +1056,7 @@
-     general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
-     DBUG_RETURN(1);
-   }
-+  thd->diff_access_denied_errors++;
-   my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
-            thd->main_security_ctx.user,
-            thd->main_security_ctx.host_or_ip,
-@@ -1264,11 +1843,20 @@
-       my_sleep(1000);                         /* must wait after eof() */
- #endif
-     statistic_increment(aborted_connects,&LOCK_status);
-+    thd->diff_denied_connections++;
-     DBUG_RETURN(1);
-   }
-   /* Connect completed, set read/write timeouts back to default */
-   my_net_set_read_timeout(net, thd->variables.net_read_timeout);
-   my_net_set_write_timeout(net, thd->variables.net_write_timeout);
-+
-+  thd->reset_stats();
-+  // Updates global user connection stats.
-+  if (increment_connection_count(thd, true)) {
-+    net_send_error(thd, ER_OUTOFMEMORY);  // Out of memory
-+    DBUG_RETURN(1);
-+  }
-+
-   DBUG_RETURN(0);
- }
-@@ -1290,6 +1878,7 @@
-   if (thd->killed || (net->error && net->vio != 0))
-   {
-     statistic_increment(aborted_threads,&LOCK_status);
-+    thd->diff_lost_connections++;
-   }
-   if (net->error && net->vio != 0)
-@@ -1416,10 +2005,14 @@
-   for (;;)
-   {
-     NET *net= &thd->net;
-+    bool create_user= TRUE;
-     lex_start(thd);
-     if (login_connection(thd))
-+    {
-+      create_user= FALSE;
-       goto end_thread;
-+    }
-     /* 
-       If rate limiting of slow log writes is enabled, decide whether to log this 
-@@ -1442,6 +2035,8 @@
-    
- end_thread:
-     close_connection(thd, 0, 1);
-+    thd->update_stats(false);
-+    update_global_user_stats(thd, create_user, time(NULL));
-     if (thread_scheduler.end_thread(thd,1))
-       return 0;                                 // Probably no-threads
---- a/sql/sql_delete.cc
-+++ b/sql/sql_delete.cc
-@@ -454,6 +454,7 @@
-     my_ok(thd, (ha_rows) thd->row_count_func);
-     DBUG_PRINT("info",("%ld records deleted",(long) deleted));
-   }
-+  thd->updated_row_count += deleted;
-   DBUG_RETURN(error >= 0 || thd->is_error());
- }
-@@ -1061,6 +1062,7 @@
-     thd->row_count_func= deleted;
-     ::my_ok(thd, (ha_rows) thd->row_count_func);
-   }
-+  thd->updated_row_count += deleted;
-   return 0;
- }
---- a/sql/sql_insert.cc
-+++ b/sql/sql_insert.cc
-@@ -982,6 +982,7 @@
-     thd->row_count_func= info.copied + info.deleted + updated;
-     ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
-   }
-+  thd->updated_row_count += thd->row_count_func;
-   thd->abort_on_warning= 0;
-   DBUG_RETURN(FALSE);
-@@ -3310,6 +3311,7 @@
-      thd->first_successful_insert_id_in_prev_stmt :
-      (info.copied ? autoinc_value_of_last_inserted_row : 0));
-   ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
-+  thd->updated_row_count += thd->row_count_func;
-   DBUG_RETURN(0);
- }
---- a/sql/sql_lex.h
-+++ b/sql/sql_lex.h
-@@ -126,6 +126,9 @@
-     When a command is added here, be sure it's also added in mysqld.cc
-     in "struct show_var_st status_vars[]= {" ...
-   */
-+  // TODO(mcallaghan): update status_vars in mysqld to export these
-+  SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
-+  SQLCOM_SHOW_CLIENT_STATS, SQLCOM_SHOW_THREAD_STATS,
-   /* This should be the last !!! */
-   SQLCOM_END
- };
---- a/sql/sql_parse.cc
-+++ b/sql/sql_parse.cc
-@@ -50,6 +50,9 @@
- static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
- static inline ulonglong get_query_exec_time(THD *thd, ulonglong cur_utime);
-+// Uses the THD to update the global stats by user name and client IP
-+void update_global_user_stats(THD* thd, bool create_user, time_t now);
-+
- const char *any_db="*any*";   // Special symbol for check_access
- const LEX_STRING command_name[]={
-@@ -828,6 +831,12 @@
-   */
-   thd->clear_error();                         // Clear error message
-   thd->main_da.reset_diagnostics_area();
-+  thd->updated_row_count=0;
-+  thd->busy_time=0;
-+  thd->cpu_time=0;
-+  thd->bytes_received=0;
-+  thd->bytes_sent=0;
-+  thd->binlog_bytes_written=0;
-   net_new_transaction(net);
-@@ -997,6 +1006,9 @@
-   DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
-   thd->command=command;
-+  // To increment the corrent command counter for user stats, 'command' must
-+  // be saved because it is set to COM_SLEEP at the end of this function.
-+  thd->old_command = command;
-   /*
-     Commands which always take a long time are logged into
-     the slow log only if opt_log_slow_admin_statements is set.
-@@ -1923,6 +1935,13 @@
-     thd->profiling.discard_current_query();
- #endif
-     break;
-+  case SCH_USER_STATS:
-+  case SCH_CLIENT_STATS:
-+  case SCH_THREAD_STATS:
-+    if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
-+      DBUG_RETURN(1);
-+  case SCH_TABLE_STATS:
-+  case SCH_INDEX_STATS:
-   case SCH_OPEN_TABLES:
-   case SCH_VARIABLES:
-   case SCH_STATUS:
-@@ -2079,6 +2098,7 @@
-                        thd->security_ctx->priv_host)) &&
-         check_global_access(thd, SUPER_ACL))
-     {
-+      thd->diff_access_denied_errors++;
-       my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
-       DBUG_RETURN(TRUE);
-     }
-@@ -5420,6 +5440,7 @@
-       if (!no_errors)
-       {
-         const char *db_name= db ? db : thd->db;
-+        thd->diff_access_denied_errors++;
-         my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-                  sctx->priv_user, sctx->priv_host, db_name);
-       }
-@@ -5452,12 +5473,15 @@
-   {                                           // We can never grant this
-     DBUG_PRINT("error",("No possible access"));
-     if (!no_errors)
-+    {
-+      thd->diff_access_denied_errors++;
-       my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
-                sctx->priv_user,
-                sctx->priv_host,
-                (thd->password ?
-                 ER(ER_YES) :
-                 ER(ER_NO)));                    /* purecov: tested */
-+    }
-     DBUG_RETURN(TRUE);                                /* purecov: tested */
-   }
-@@ -5483,11 +5507,15 @@
-   DBUG_PRINT("error",("Access denied"));
-   if (!no_errors)
-+  {
-+    // increment needs !no_errors condition, otherwise double counting.
-+    thd->diff_access_denied_errors++;
-     my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-              sctx->priv_user, sctx->priv_host,
-              (db ? db : (thd->db ?
-                          thd->db :
-                          "unknown")));          /* purecov: tested */
-+  }
-   DBUG_RETURN(TRUE);                          /* purecov: tested */
- }
-@@ -5516,6 +5544,7 @@
-     if (!thd->col_access && check_grant_db(thd, dst_db_name))
-     {
-+      thd->diff_access_denied_errors++;
-       my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-                thd->security_ctx->priv_user,
-                thd->security_ctx->priv_host,
-@@ -5597,9 +5626,12 @@
-         (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
-     {
-       if (!no_errors)
-+      {
-+        thd->diff_access_denied_errors++;
-         my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-                  sctx->priv_user, sctx->priv_host,
-                  INFORMATION_SCHEMA_NAME.str);
-+      }
-       return TRUE;
-     }
-     /*
-@@ -5762,6 +5794,7 @@
-   if ((thd->security_ctx->master_access & want_access))
-     return 0;
-   get_privilege_desc(command, sizeof(command), want_access);
-+  thd->diff_access_denied_errors++;
-   my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
-   return 1;
- #else
-@@ -6136,6 +6169,32 @@
-   lex_start(thd);
-   mysql_reset_thd_for_next_command(thd);
-+  int start_time_error = 0;
-+  int end_time_error = 0;
-+  struct timeval start_time, end_time;
-+  double start_usecs = 0;
-+  double end_usecs = 0;
-+  /* cpu time */
-+  int cputime_error = 0;
-+#ifdef HAVE_CLOCK_GETTIME
-+  struct timespec tp;
-+#endif
-+  double start_cpu_nsecs = 0;
-+  double end_cpu_nsecs = 0;
-+
-+  if (opt_userstat_running) {
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get start cputime */
-+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+
-+    // Gets the start time, in order to measure how long this command takes.
-+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
-+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
-+    }
-+  }
-+
-   if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
-   {
-     LEX *lex= thd->lex;
-@@ -6216,6 +6275,43 @@
-     *found_semicolon= NULL;
-   }
-+  if (opt_userstat_running) {
-+    // Gets the end time.
-+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
-+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
-+    }
-+
-+    // Calculates the difference between the end and start times.
-+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
-+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->busy_time > 2629743) {
-+        thd->busy_time = 0;
-+      }
-+    } else {
-+      // end time went back in time, or gettimeofday() failed.
-+      thd->busy_time = 0;
-+    }
-+
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get end cputime */
-+    if (!cputime_error &&
-+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+    if (start_cpu_nsecs && !cputime_error) {
-+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->cpu_time > 2629743) {
-+        thd->cpu_time = 0;
-+      }
-+    } else
-+      thd->cpu_time = 0;
-+  }
-+  // Updates THD stats and the global user stats.
-+  thd->update_stats(true);
-+  update_global_user_stats(thd, true, time(NULL));
-+
-   DBUG_VOID_RETURN;
- }
-@@ -7088,6 +7184,13 @@
-     if (flush_error_log())
-       result=1;
-   }
-+  if (((options & (REFRESH_SLOW_QUERY_LOG | REFRESH_LOG)) ==
-+       REFRESH_SLOW_QUERY_LOG))
-+  {
-+    /* We are only flushing slow query log */
-+    logger.flush_slow_log(thd);
-+  }
-+
- #ifdef HAVE_QUERY_CACHE
-   if (options & REFRESH_QUERY_CACHE_FREE)
-   {
-@@ -7188,6 +7291,40 @@
- #endif
-  if (options & REFRESH_USER_RESOURCES)
-    reset_mqh((LEX_USER *) NULL, 0);             /* purecov: inspected */
-+  if (options & REFRESH_TABLE_STATS)
-+  {
-+    pthread_mutex_lock(&LOCK_global_table_stats);
-+    free_global_table_stats();
-+    init_global_table_stats();
-+    pthread_mutex_unlock(&LOCK_global_table_stats);
-+  }
-+  if (options & REFRESH_INDEX_STATS)
-+  {
-+    pthread_mutex_lock(&LOCK_global_index_stats);
-+    free_global_index_stats();
-+    init_global_index_stats();
-+    pthread_mutex_unlock(&LOCK_global_index_stats);
-+  }
-+  if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS | REFRESH_THREAD_STATS))
-+  {
-+    pthread_mutex_lock(&LOCK_global_user_client_stats);
-+    if (options & REFRESH_USER_STATS)
-+    {
-+      free_global_user_stats();
-+      init_global_user_stats();
-+    }
-+    if (options & REFRESH_CLIENT_STATS)
-+    {
-+      free_global_client_stats();
-+      init_global_client_stats();
-+    }
-+    if (options & REFRESH_THREAD_STATS)
-+    {
-+      free_global_thread_stats();
-+      init_global_thread_stats();
-+    }
-+    pthread_mutex_unlock(&LOCK_global_user_client_stats);
-+  }
-  if (*write_to_binlog != -1)
-    *write_to_binlog= tmp_write_to_binlog;
-  /*
---- a/sql/sql_prepare.cc
-+++ b/sql/sql_prepare.cc
-@@ -96,6 +96,9 @@
- #include <mysql_com.h>
- #endif
-+// Uses the THD to update the global stats by user name and client IP
-+void update_global_user_stats(THD* thd, bool create_user, time_t now);
-+
- /**
-   A result class used to send cursor rows using the binary protocol.
- */
-@@ -2103,8 +2106,34 @@
-   /* First of all clear possible warnings from the previous command */
-   mysql_reset_thd_for_next_command(thd);
-+  int start_time_error = 0;
-+  int end_time_error = 0;
-+  struct timeval start_time, end_time;
-+  double start_usecs = 0;
-+  double end_usecs = 0;
-+  /* cpu time */
-+  int cputime_error = 0;
-+#ifdef HAVE_CLOCK_GETTIME
-+  struct timespec tp;
-+#endif
-+  double start_cpu_nsecs = 0;
-+  double end_cpu_nsecs = 0;
-+
-+  if (opt_userstat_running) {
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get start cputime */
-+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+
-+    // Gets the start time, in order to measure how long this command takes.
-+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
-+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
-+    }
-+  }
-+
-   if (! (stmt= new Prepared_statement(thd)))
--    DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
-+    goto end; /* out of memory: error is set in Sql_alloc */
-   if (thd->stmt_map.insert(thd, stmt))
-   {
-@@ -2112,7 +2141,7 @@
-       The error is set in the insert. The statement itself
-       will be also deleted there (this is how the hash works).
-     */
--    DBUG_VOID_RETURN;
-+    goto end;
-   }
-   /* Reset warnings from previous command */
-@@ -2139,6 +2168,44 @@
-   thd->protocol= save_protocol;
-   /* check_prepared_statemnt sends the metadata packet in case of success */
-+end:
-+  if (opt_userstat_running) {
-+    // Gets the end time.
-+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
-+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
-+    }
-+
-+    // Calculates the difference between the end and start times.
-+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
-+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->busy_time > 2629743) {
-+        thd->busy_time = 0;
-+      }
-+    } else {
-+      // end time went back in time, or gettimeofday() failed.
-+      thd->busy_time = 0;
-+    }
-+
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get end cputime */
-+    if (!cputime_error &&
-+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+    if (start_cpu_nsecs && !cputime_error) {
-+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->cpu_time > 2629743) {
-+        thd->cpu_time = 0;
-+      }
-+    } else
-+      thd->cpu_time = 0;
-+  }
-+  // Updates THD stats and the global user stats.
-+  thd->update_stats(true);
-+  update_global_user_stats(thd, true, time(NULL));
-+
-   DBUG_VOID_RETURN;
- }
-@@ -2476,12 +2543,38 @@
-   /* First of all clear possible warnings from the previous command */
-   mysql_reset_thd_for_next_command(thd);
-+  int start_time_error = 0;
-+  int end_time_error = 0;
-+  struct timeval start_time, end_time;
-+  double start_usecs = 0;
-+  double end_usecs = 0;
-+  /* cpu time */
-+  int cputime_error = 0;
-+#ifdef HAVE_CLOCK_GETTIME
-+  struct timespec tp;
-+#endif
-+  double start_cpu_nsecs = 0;
-+  double end_cpu_nsecs = 0;
-+
-+  if (opt_userstat_running) {
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get start cputime */
-+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+
-+    // Gets the start time, in order to measure how long this command takes.
-+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
-+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
-+    }
-+  }
-+
-   if (!(stmt= find_prepared_statement(thd, stmt_id)))
-   {
-     char llbuf[22];
-     my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
-              llstr(stmt_id, llbuf), "mysqld_stmt_execute");
--    DBUG_VOID_RETURN;
-+    goto end;
-   }
- #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-@@ -2502,6 +2595,44 @@
-   /* Close connection socket; for use with client testing (Bug#43560). */
-   DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_close(thd->net.vio););
-+end:
-+  if (opt_userstat_running) {
-+    // Gets the end time.
-+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
-+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
-+    }
-+
-+    // Calculates the difference between the end and start times.
-+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
-+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->busy_time > 2629743) {
-+        thd->busy_time = 0;
-+      }
-+    } else {
-+      // end time went back in time, or gettimeofday() failed.
-+      thd->busy_time = 0;
-+    }
-+
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get end cputime */
-+    if (!cputime_error &&
-+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+    if (start_cpu_nsecs && !cputime_error) {
-+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->cpu_time > 2629743) {
-+        thd->cpu_time = 0;
-+      }
-+    } else
-+      thd->cpu_time = 0;
-+  }
-+  // Updates THD stats and the global user stats.
-+  thd->update_stats(true);
-+  update_global_user_stats(thd, true, time(NULL));
-+
-   DBUG_VOID_RETURN;
- }
-@@ -2575,20 +2706,47 @@
-   /* First of all clear possible warnings from the previous command */
-   mysql_reset_thd_for_next_command(thd);
-+
-+  int start_time_error = 0;
-+  int end_time_error = 0;
-+  struct timeval start_time, end_time;
-+  double start_usecs = 0;
-+  double end_usecs = 0;
-+  /* cpu time */
-+  int cputime_error = 0;
-+#ifdef HAVE_CLOCK_GETTIME
-+  struct timespec tp;
-+#endif
-+  double start_cpu_nsecs = 0;
-+  double end_cpu_nsecs = 0;
-+
-+  if (opt_userstat_running) {
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get start cputime */
-+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+
-+    // Gets the start time, in order to measure how long this command takes.
-+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
-+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
-+    }
-+  }
-+
-   status_var_increment(thd->status_var.com_stmt_fetch);
-   if (!(stmt= find_prepared_statement(thd, stmt_id)))
-   {
-     char llbuf[22];
-     my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
-              llstr(stmt_id, llbuf), "mysqld_stmt_fetch");
--    DBUG_VOID_RETURN;
-+    goto end;
-   }
-   cursor= stmt->cursor;
-   if (!cursor)
-   {
-     my_error(ER_STMT_HAS_NO_OPEN_CURSOR, MYF(0), stmt_id);
--    DBUG_VOID_RETURN;
-+    goto end;
-   }
-   thd->stmt_arena= stmt;
-@@ -2612,6 +2770,44 @@
-   thd->restore_backup_statement(stmt, &stmt_backup);
-   thd->stmt_arena= thd;
-+end:
-+  if (opt_userstat_running) {
-+    // Gets the end time.
-+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
-+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
-+    }
-+
-+    // Calculates the difference between the end and start times.
-+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
-+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->busy_time > 2629743) {
-+        thd->busy_time = 0;
-+      }
-+    } else {
-+      // end time went back in time, or gettimeofday() failed.
-+      thd->busy_time = 0;
-+    }
-+
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get end cputime */
-+    if (!cputime_error &&
-+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+    if (start_cpu_nsecs && !cputime_error) {
-+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->cpu_time > 2629743) {
-+        thd->cpu_time = 0;
-+      }
-+    } else
-+      thd->cpu_time = 0;
-+  }
-+  // Updates THD stats and the global user stats.
-+  thd->update_stats(true);
-+  update_global_user_stats(thd, true, time(NULL));
-+
-   DBUG_VOID_RETURN;
- }
-@@ -2642,13 +2838,39 @@
-   /* First of all clear possible warnings from the previous command */
-   mysql_reset_thd_for_next_command(thd);
-+  int start_time_error = 0;
-+  int end_time_error = 0;
-+  struct timeval start_time, end_time;
-+  double start_usecs = 0;
-+  double end_usecs = 0;
-+  /* cpu time */
-+  int cputime_error = 0;
-+#ifdef HAVE_CLOCK_GETTIME
-+  struct timespec tp;
-+#endif
-+  double start_cpu_nsecs = 0;
-+  double end_cpu_nsecs = 0;
-+
-+  if (opt_userstat_running) {
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get start cputime */
-+    if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+
-+    // Gets the start time, in order to measure how long this command takes.
-+    if (!(start_time_error = gettimeofday(&start_time, NULL))) {
-+      start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
-+    }
-+  }
-+
-   status_var_increment(thd->status_var.com_stmt_reset);
-   if (!(stmt= find_prepared_statement(thd, stmt_id)))
-   {
-     char llbuf[22];
-     my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
-              llstr(stmt_id, llbuf), "mysqld_stmt_reset");
--    DBUG_VOID_RETURN;
-+    goto end;
-   }
-   stmt->close_cursor();
-@@ -2665,6 +2887,44 @@
-   my_ok(thd);
-+end:
-+  if (opt_userstat_running) {
-+    // Gets the end time.
-+    if (!(end_time_error = gettimeofday(&end_time, NULL))) {
-+      end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
-+    }
-+
-+    // Calculates the difference between the end and start times.
-+    if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
-+      thd->busy_time = (end_usecs - start_usecs) / 1000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->busy_time > 2629743) {
-+        thd->busy_time = 0;
-+      }
-+    } else {
-+      // end time went back in time, or gettimeofday() failed.
-+      thd->busy_time = 0;
-+    }
-+
-+#ifdef HAVE_CLOCK_GETTIME
-+    /* get end cputime */
-+    if (!cputime_error &&
-+        !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
-+      end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
-+#endif
-+    if (start_cpu_nsecs && !cputime_error) {
-+      thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
-+      // In case there are bad values, 2629743 is the #seconds in a month.
-+      if (thd->cpu_time > 2629743) {
-+        thd->cpu_time = 0;
-+      }
-+    } else
-+      thd->cpu_time = 0;
-+  }
-+  // Updates THD stats and the global user stats.
-+  thd->update_stats(true);
-+  update_global_user_stats(thd, true, time(NULL));
-+
-   DBUG_VOID_RETURN;
- }
---- a/sql/sql_show.cc
-+++ b/sql/sql_show.cc
-@@ -84,6 +84,40 @@
- static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table);
-+/*
-+ * Solaris 10 does not have strsep(). 
-+ * 
-+ * based on getToken from http://www.winehq.org/pipermail/wine-patches/2001-November/001322.html
-+ *
-+ */
-+
-+#ifndef HAVE_STRSEP
-+static char* strsep(char** str, const char* delims)
-+{
-+  char *token;
-+
-+  if (*str == NULL) {
-+    /* No more tokens */
-+    return NULL;
-+  }
-+
-+  token = *str;
-+  while (**str != '\0') {
-+    if (strchr(delims, **str) != NULL) {
-+      **str = '\0';
-+      (*str)++;
-+      return token;
-+    }
-+    (*str)++;
-+  }
-+
-+  /* There is not another token */
-+  *str = NULL;
-+
-+  return token;
-+}
-+#endif
-+
- /***************************************************************************
- ** List all table types supported
- ***************************************************************************/
-@@ -826,6 +860,7 @@
-               sctx->master_access);
-   if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname))
-   {
-+    thd->diff_access_denied_errors++;
-     my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-              sctx->priv_user, sctx->host_or_ip, dbname);
-     general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
-@@ -2380,6 +2415,279 @@
-   DBUG_RETURN(res);
- }
-+/*
-+   Write result to network for SHOW USER_STATISTICS
-+
-+   SYNOPSIS
-+     send_user_stats
-+       all_user_stats - values to return
-+       table - I_S table
-+
-+   RETURN
-+     0 - OK
-+     1 - error
-+ */
-+int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table)
-+{
-+  DBUG_ENTER("send_user_stats");
-+  for (uint i = 0; i < all_user_stats->records; ++i) {
-+    restore_record(table, s->default_values);
-+    USER_STATS *user_stats = (USER_STATS*)hash_element(all_user_stats, i);
-+      table->field[0]->store(user_stats->user, strlen(user_stats->user), system_charset_info);
-+      table->field[1]->store((longlong)user_stats->total_connections);
-+      table->field[2]->store((longlong)user_stats->concurrent_connections);
-+      table->field[3]->store((longlong)user_stats->connected_time);
-+      table->field[4]->store((longlong)user_stats->busy_time);
-+      table->field[5]->store((longlong)user_stats->cpu_time);
-+      table->field[6]->store((longlong)user_stats->bytes_received);
-+      table->field[7]->store((longlong)user_stats->bytes_sent);
-+      table->field[8]->store((longlong)user_stats->binlog_bytes_written);
-+      table->field[9]->store((longlong)user_stats->rows_fetched);
-+      table->field[10]->store((longlong)user_stats->rows_updated);
-+      table->field[11]->store((longlong)user_stats->rows_read);
-+      table->field[12]->store((longlong)user_stats->select_commands);
-+      table->field[13]->store((longlong)user_stats->update_commands);
-+      table->field[14]->store((longlong)user_stats->other_commands);
-+      table->field[15]->store((longlong)user_stats->commit_trans);
-+      table->field[16]->store((longlong)user_stats->rollback_trans);
-+      table->field[17]->store((longlong)user_stats->denied_connections);
-+      table->field[18]->store((longlong)user_stats->lost_connections);
-+      table->field[19]->store((longlong)user_stats->access_denied_errors);
-+      table->field[20]->store((longlong)user_stats->empty_queries);
-+      if (schema_table_store_record(thd, table))
-+      {
-+            DBUG_PRINT("error", ("store record error"));
-+            DBUG_RETURN(1);
-+      }
-+  }
-+  DBUG_RETURN(0);
-+}
-+
-+int send_thread_stats(THD* thd, HASH *all_thread_stats, TABLE *table)
-+{
-+  DBUG_ENTER("send_thread_stats");
-+  for (uint i = 0; i < all_thread_stats->records; ++i) {
-+    restore_record(table, s->default_values);
-+    THREAD_STATS *user_stats = (THREAD_STATS*)hash_element(all_thread_stats, i);
-+      table->field[0]->store((longlong)user_stats->id);
-+      table->field[1]->store((longlong)user_stats->total_connections);
-+      table->field[2]->store((longlong)user_stats->concurrent_connections);
-+      table->field[3]->store((longlong)user_stats->connected_time);
-+      table->field[4]->store((longlong)user_stats->busy_time);
-+      table->field[5]->store((longlong)user_stats->cpu_time);
-+      table->field[6]->store((longlong)user_stats->bytes_received);
-+      table->field[7]->store((longlong)user_stats->bytes_sent);
-+      table->field[8]->store((longlong)user_stats->binlog_bytes_written);
-+      table->field[9]->store((longlong)user_stats->rows_fetched);
-+      table->field[10]->store((longlong)user_stats->rows_updated);
-+      table->field[11]->store((longlong)user_stats->rows_read);
-+      table->field[12]->store((longlong)user_stats->select_commands);
-+      table->field[13]->store((longlong)user_stats->update_commands);
-+      table->field[14]->store((longlong)user_stats->other_commands);
-+      table->field[15]->store((longlong)user_stats->commit_trans);
-+      table->field[16]->store((longlong)user_stats->rollback_trans);
-+      table->field[17]->store((longlong)user_stats->denied_connections);
-+      table->field[18]->store((longlong)user_stats->lost_connections);
-+      table->field[19]->store((longlong)user_stats->access_denied_errors);
-+      table->field[20]->store((longlong)user_stats->empty_queries);
-+      if (schema_table_store_record(thd, table))
-+      {
-+              DBUG_PRINT("error", ("store record error"));
-+              DBUG_RETURN(1);
-+      }
-+  }
-+  DBUG_RETURN(0);
-+}
-+
-+/*
-+   Process SHOW USER_STATISTICS
-+
-+   SYNOPSIS
-+     mysqld_show_user_stats
-+       thd - current thread
-+       wild - limit results to the entry for this user
-+       with_roles - when true, display role for mapped users
-+
-+   RETURN
-+     0 - OK
-+     1 - error
-+ */
-+
-+
-+int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_user_stats");
-+
-+  if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
-+          DBUG_RETURN(1);
-+
-+  // Iterates through all the global stats and sends them to the client.
-+  // Pattern matching on the client IP is supported.
-+
-+  pthread_mutex_lock(&LOCK_global_user_client_stats);
-+  int result= send_user_stats(thd, &global_user_stats, table);
-+  pthread_mutex_unlock(&LOCK_global_user_client_stats);
-+  if (result)
-+    goto err;
-+
-+  DBUG_PRINT("exit", ("fill_schema_user_stats result is 0"));
-+  DBUG_RETURN(0);
-+
-+ err:
-+  DBUG_PRINT("exit", ("fill_schema_user_stats result is 1"));
-+  DBUG_RETURN(1);
-+}
-+
-+/*
-+   Process SHOW CLIENT_STATISTICS
-+
-+   SYNOPSIS
-+     mysqld_show_client_stats
-+       thd - current thread
-+       wild - limit results to the entry for this client
-+
-+   RETURN
-+     0 - OK
-+     1 - error
-+ */
-+
-+
-+int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_client_stats");
-+
-+  if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
-+          DBUG_RETURN(1);
-+
-+  // Iterates through all the global stats and sends them to the client.
-+  // Pattern matching on the client IP is supported.
-+
-+  pthread_mutex_lock(&LOCK_global_user_client_stats);
-+  int result= send_user_stats(thd, &global_client_stats, table);
-+  pthread_mutex_unlock(&LOCK_global_user_client_stats);
-+  if (result)
-+    goto err;
-+
-+  DBUG_PRINT("exit", ("mysqld_show_client_stats result is 0"));
-+  DBUG_RETURN(0);
-+
-+ err:
-+  DBUG_PRINT("exit", ("mysqld_show_client_stats result is 1"));
-+  DBUG_RETURN(1);
-+}
-+
-+int fill_schema_thread_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_thread_stats");
-+
-+  if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
-+          DBUG_RETURN(1);
-+
-+  // Iterates through all the global stats and sends them to the client.
-+  // Pattern matching on the client IP is supported.
-+
-+  pthread_mutex_lock(&LOCK_global_user_client_stats);
-+  int result= send_thread_stats(thd, &global_thread_stats, table);
-+  pthread_mutex_unlock(&LOCK_global_user_client_stats);
-+  if (result)
-+    goto err;
-+
-+  DBUG_PRINT("exit", ("mysqld_show_thread_stats result is 0"));
-+  DBUG_RETURN(0);
-+
-+ err:
-+  DBUG_PRINT("exit", ("mysqld_show_thread_stats result is 1"));
-+  DBUG_RETURN(1);
-+}
-+
-+// Sends the global table stats back to the client.
-+int fill_schema_table_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_table_stats");
-+  char *table_full_name, *table_schema;
-+
-+  pthread_mutex_lock(&LOCK_global_table_stats);
-+  for (uint i = 0; i < global_table_stats.records; ++i) {
-+    restore_record(table, s->default_values);
-+    TABLE_STATS *table_stats = 
-+      (TABLE_STATS*)hash_element(&global_table_stats, i);
-+
-+    table_full_name= thd->strdup(table_stats->table);
-+    table_schema= strsep(&table_full_name, ".");
-+
-+    TABLE_LIST tmp_table;
-+    bzero((char*) &tmp_table,sizeof(tmp_table));
-+    tmp_table.table_name= table_full_name;
-+    tmp_table.db= table_schema;
-+    tmp_table.grant.privilege= 0;
-+    if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
-+                      &tmp_table.grant.privilege, 0, 0,
-+                      is_schema_db(table_schema)) ||
-+         check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
-+        continue;
-+
-+    table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
-+    table->field[1]->store(table_full_name, strlen(table_full_name), system_charset_info);
-+    table->field[2]->store((longlong)table_stats->rows_read, TRUE);
-+    table->field[3]->store((longlong)table_stats->rows_changed, TRUE);
-+    table->field[4]->store((longlong)table_stats->rows_changed_x_indexes, TRUE);
-+
-+    if (schema_table_store_record(thd, table))
-+    {
-+      VOID(pthread_mutex_unlock(&LOCK_global_table_stats));
-+      DBUG_RETURN(1);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_global_table_stats);
-+  DBUG_RETURN(0);
-+}
-+
-+// Sends the global index stats back to the client.
-+int fill_schema_index_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_index_stats");
-+  char *index_full_name, *table_schema, *table_name;
-+
-+  pthread_mutex_lock(&LOCK_global_index_stats);
-+  for (uint i = 0; i < global_index_stats.records; ++i) {
-+    restore_record(table, s->default_values);
-+    INDEX_STATS *index_stats =
-+      (INDEX_STATS*)hash_element(&global_index_stats, i);
-+
-+    index_full_name= thd->strdup(index_stats->index);
-+    table_schema= strsep(&index_full_name, ".");
-+    table_name= strsep(&index_full_name, ".");
-+
-+    TABLE_LIST tmp_table;
-+    bzero((char*) &tmp_table,sizeof(tmp_table));
-+    tmp_table.table_name= table_name;
-+    tmp_table.db= table_schema;
-+    tmp_table.grant.privilege= 0;
-+    if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
-+                      &tmp_table.grant.privilege, 0, 0,
-+                      is_schema_db(table_schema)) ||
-+         check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
-+        continue;
-+
-+    table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
-+    table->field[1]->store(table_name, strlen(table_name), system_charset_info);
-+    table->field[2]->store(index_full_name, strlen(index_full_name), system_charset_info);
-+    table->field[3]->store((longlong)index_stats->rows_read, TRUE);
-+
-+    if (schema_table_store_record(thd, table))
-+    { 
-+      VOID(pthread_mutex_unlock(&LOCK_global_index_stats));
-+      DBUG_RETURN(1);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_global_index_stats);
-+  DBUG_RETURN(0);
-+}
- /* collect status for all running threads */
-@@ -6751,6 +7059,104 @@
- };
-+ST_FIELD_INFO user_stats_fields_info[]=
-+{
-+  {"USER", USERNAME_LENGTH, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
-+  {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections", SKIP_OPEN_TABLE},
-+  {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections", SKIP_OPEN_TABLE},
-+  {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time", SKIP_OPEN_TABLE},
-+  {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time", SKIP_OPEN_TABLE},
-+  {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time", SKIP_OPEN_TABLE},
-+  {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received", SKIP_OPEN_TABLE},
-+  {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent", SKIP_OPEN_TABLE},
-+  {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written", SKIP_OPEN_TABLE},
-+  {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched", SKIP_OPEN_TABLE},
-+  {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated", SKIP_OPEN_TABLE},
-+  {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read", SKIP_OPEN_TABLE},
-+  {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands", SKIP_OPEN_TABLE},
-+  {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands", SKIP_OPEN_TABLE},
-+  {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands", SKIP_OPEN_TABLE},
-+  {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions", SKIP_OPEN_TABLE},
-+  {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions", SKIP_OPEN_TABLE},
-+  {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections", SKIP_OPEN_TABLE},
-+  {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections", SKIP_OPEN_TABLE},
-+  {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied", SKIP_OPEN_TABLE},
-+  {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
-+};
-+
-+ST_FIELD_INFO client_stats_fields_info[]=
-+{
-+  {"CLIENT", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Client", SKIP_OPEN_TABLE},
-+  {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections", SKIP_OPEN_TABLE},
-+  {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections", SKIP_OPEN_TABLE},
-+  {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time", SKIP_OPEN_TABLE},
-+  {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time", SKIP_OPEN_TABLE},
-+  {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time", SKIP_OPEN_TABLE},
-+  {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received", SKIP_OPEN_TABLE},
-+  {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent", SKIP_OPEN_TABLE},
-+  {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written", SKIP_OPEN_TABLE},
-+  {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched", SKIP_OPEN_TABLE},
-+  {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated", SKIP_OPEN_TABLE},
-+  {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read", SKIP_OPEN_TABLE},
-+  {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands", SKIP_OPEN_TABLE},
-+  {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands", SKIP_OPEN_TABLE},
-+  {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands", SKIP_OPEN_TABLE},
-+  {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions", SKIP_OPEN_TABLE},
-+  {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions", SKIP_OPEN_TABLE},
-+  {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections", SKIP_OPEN_TABLE},
-+  {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections", SKIP_OPEN_TABLE},
-+  {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied", SKIP_OPEN_TABLE},
-+  {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
-+};
-+
-+ST_FIELD_INFO thread_stats_fields_info[]=
-+{
-+  {"THREAD_ID", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Thread_id", SKIP_OPEN_TABLE},
-+  {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections", SKIP_OPEN_TABLE},
-+  {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections", SKIP_OPEN_TABLE},
-+  {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time", SKIP_OPEN_TABLE},
-+  {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time", SKIP_OPEN_TABLE},
-+  {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time", SKIP_OPEN_TABLE},
-+  {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received", SKIP_OPEN_TABLE},
-+  {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent", SKIP_OPEN_TABLE},
-+  {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written", SKIP_OPEN_TABLE},
-+  {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched", SKIP_OPEN_TABLE},
-+  {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated", SKIP_OPEN_TABLE},
-+  {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read", SKIP_OPEN_TABLE},
-+  {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands", SKIP_OPEN_TABLE},
-+  {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands", SKIP_OPEN_TABLE},
-+  {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands", SKIP_OPEN_TABLE},
-+  {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions", SKIP_OPEN_TABLE},
-+  {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions", SKIP_OPEN_TABLE},
-+  {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections", SKIP_OPEN_TABLE},
-+  {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections", SKIP_OPEN_TABLE},
-+  {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied", SKIP_OPEN_TABLE},
-+  {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
-+};
-+
-+ST_FIELD_INFO table_stats_fields_info[]=
-+{
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema", SKIP_OPEN_TABLE},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name", SKIP_OPEN_TABLE},
-+  {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read", SKIP_OPEN_TABLE},
-+  {"ROWS_CHANGED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed", SKIP_OPEN_TABLE},
-+  {"ROWS_CHANGED_X_INDEXES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed_x_#indexes", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
-+};
-+
-+ST_FIELD_INFO index_stats_fields_info[]=
-+{
-+  {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema", SKIP_OPEN_TABLE},
-+  {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name", SKIP_OPEN_TABLE},
-+  {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name", SKIP_OPEN_TABLE},
-+  {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
-+};
-+
-+
- ST_FIELD_INFO processlist_fields_info[]=
- {
-   {"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
-@@ -6886,6 +7292,8 @@
- {
-   {"CHARACTER_SETS", charsets_fields_info, create_schema_table, 
-    fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
-+  {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table, 
-+    fill_schema_client_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"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,
-@@ -6895,6 +7303,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},
-+  {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
-+   fill_schema_index_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"ENGINES", engines_fields_info, create_schema_table,
-    fill_schema_engines, make_old_format, 0, -1, -1, 0, 0},
- #ifdef HAVE_EVENT_SCHEDULER
-@@ -6951,11 +7361,17 @@
-    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},
-+  {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
-+    fill_schema_table_stats, make_old_format, 0, -1, -1, 0, 0},
-+  {"THREAD_STATISTICS", thread_stats_fields_info, create_schema_table,
-+    fill_schema_thread_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"TRIGGERS", triggers_fields_info, create_schema_table,
-    get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
-    OPEN_TABLE_ONLY},
-   {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, 
-    fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
-+  {"USER_STATISTICS", user_stats_fields_info, create_schema_table, 
-+    fill_schema_user_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
-    make_old_format, 0, 0, -1, 1, 0},
-   {"VIEWS", view_fields_info, create_schema_table, 
---- a/sql/sql_update.cc
-+++ b/sql/sql_update.cc
-@@ -890,6 +890,7 @@
-     thd->row_count_func=
-       (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-     my_ok(thd, (ulong) thd->row_count_func, id, buff);
-+    thd->updated_row_count += thd->row_count_func;
-     DBUG_PRINT("info",("%ld records updated", (long) updated));
-   }
-   thd->count_cuted_fields= CHECK_FIELD_IGNORE;                /* calc cuted fields */
-@@ -2176,5 +2177,6 @@
-   thd->row_count_func=
-     (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-   ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
-+  thd->updated_row_count += thd->row_count_func;
-   DBUG_RETURN(FALSE);
- }
---- a/sql/sql_yacc.yy
-+++ b/sql/sql_yacc.yy
-@@ -759,6 +759,7 @@
- %token  CHECK_SYM                     /* SQL-2003-R */
- %token  CIPHER_SYM
- %token  CLIENT_SYM
-+%token  CLIENT_STATS_SYM
- %token  CLOSE_SYM                     /* SQL-2003-R */
- %token  COALESCE                      /* SQL-2003-N */
- %token  CODE_SYM
-@@ -905,6 +906,7 @@
- %token  IMPORT
- %token  INDEXES
- %token  INDEX_SYM
-+%token  INDEX_STATS_SYM
- %token  INFILE
- %token  INITIAL_SIZE_SYM
- %token  INNER_SYM                     /* SQL-2003-R */
-@@ -1146,6 +1148,7 @@
- %token  SIGNED_SYM
- %token  SIMPLE_SYM                    /* SQL-2003-N */
- %token  SLAVE
-+%token  SLOW_SYM
- %token  SMALLINT                      /* SQL-2003-R */
- %token  SNAPSHOT_SYM
- %token  SOCKET_SYM
-@@ -1191,6 +1194,7 @@
- %token  TABLESPACE
- %token  TABLE_REF_PRIORITY
- %token  TABLE_SYM                     /* SQL-2003-R */
-+%token  TABLE_STATS_SYM
- %token  TABLE_CHECKSUM_SYM
- %token  TEMPORARY                     /* SQL-2003-N */
- %token  TEMPTABLE_SYM
-@@ -1199,6 +1203,7 @@
- %token  TEXT_SYM
- %token  THAN_SYM
- %token  THEN_SYM                      /* SQL-2003-R */
-+%token  THREAD_STATS_SYM
- %token  TIMESTAMP                     /* SQL-2003-R */
- %token  TIMESTAMP_ADD
- %token  TIMESTAMP_DIFF
-@@ -1236,6 +1241,7 @@
- %token  UPGRADE_SYM
- %token  USAGE                         /* SQL-2003-N */
- %token  USER                          /* SQL-2003-R */
-+%token  USER_STATS_SYM
- %token  USE_FRM
- %token  USE_SYM
- %token  USING                         /* SQL-2003-R */
-@@ -10366,6 +10372,41 @@
-           {
-             Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
-           }
-+        | CLIENT_STATS_SYM wild_and_where 
-+          {
-+           LEX *lex= Lex;
-+           Lex->sql_command = SQLCOM_SELECT;
-+           if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
-+             MYSQL_YYABORT;
-+          }
-+        | USER_STATS_SYM wild_and_where 
-+          {
-+           LEX *lex= Lex;
-+           lex->sql_command = SQLCOM_SELECT;
-+           if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
-+             MYSQL_YYABORT;
-+          }
-+        | THREAD_STATS_SYM wild_and_where
-+          {
-+           LEX *lex= Lex;
-+           Lex->sql_command = SQLCOM_SELECT;
-+           if (prepare_schema_table(YYTHD, lex, 0, SCH_THREAD_STATS))
-+             MYSQL_YYABORT;
-+          }
-+        | TABLE_STATS_SYM wild_and_where
-+          {
-+           LEX *lex= Lex;
-+           lex->sql_command= SQLCOM_SELECT;
-+           if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
-+             MYSQL_YYABORT;
-+          }
-+        | INDEX_STATS_SYM wild_and_where
-+          {
-+           LEX *lex= Lex;
-+           lex->sql_command= SQLCOM_SELECT;
-+           if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
-+             MYSQL_YYABORT;
-+          }
-         | CREATE PROCEDURE sp_name
-           {
-             LEX *lex= Lex;
-@@ -10574,6 +10615,18 @@
-           { Lex->type|= REFRESH_STATUS; }
-         | SLAVE
-           { Lex->type|= REFRESH_SLAVE; }
-+        | SLOW_SYM QUERY_SYM LOGS_SYM
-+          { Lex->type |= REFRESH_SLOW_QUERY_LOG; }
-+        | CLIENT_STATS_SYM
-+          { Lex->type|= REFRESH_CLIENT_STATS; }
-+        | USER_STATS_SYM
-+          { Lex->type|= REFRESH_USER_STATS; }
-+        | THREAD_STATS_SYM
-+          { Lex->type|= REFRESH_THREAD_STATS; }
-+        | TABLE_STATS_SYM
-+          { Lex->type|= REFRESH_TABLE_STATS; }
-+        | INDEX_STATS_SYM
-+          { Lex->type|= REFRESH_INDEX_STATS; }
-         | MASTER_SYM
-           { Lex->type|= REFRESH_MASTER; }
-         | DES_KEY_FILE
-@@ -11697,6 +11750,7 @@
-         | CHAIN_SYM                {}
-         | CHANGED                  {}
-         | CIPHER_SYM               {}
-+        | CLIENT_STATS_SYM         {}
-         | CLIENT_SYM               {}
-         | COALESCE                 {}
-         | CODE_SYM                 {}
-@@ -11758,6 +11812,7 @@
-         | HOSTS_SYM                {}
-         | HOUR_SYM                 {}
-         | IDENTIFIED_SYM           {}
-+        | INDEX_STATS_SYM          {}
-         | INVOKER_SYM              {}
-         | IMPORT                   {}
-         | INDEXES                  {}
-@@ -11882,6 +11937,7 @@
-         | SIMPLE_SYM               {}
-         | SHARE_SYM                {}
-         | SHUTDOWN                 {}
-+        | SLOW_SYM                 {}
-         | SNAPSHOT_SYM             {}
-         | SOUNDS_SYM               {}
-         | SOURCE_SYM               {}
-@@ -11901,6 +11957,7 @@
-         | SUSPEND_SYM              {}
-         | SWAPS_SYM                {}
-         | SWITCHES_SYM             {}
-+        | TABLE_STATS_SYM          {}
-         | TABLES                   {}
-         | TABLE_CHECKSUM_SYM       {}
-         | TABLESPACE               {}
-@@ -11908,6 +11965,7 @@
-         | TEMPTABLE_SYM            {}
-         | TEXT_SYM                 {}
-         | THAN_SYM                 {}
-+        | THREAD_STATS_SYM         {}
-         | TRANSACTION_SYM          {}
-         | TRIGGERS_SYM             {}
-         | TIMESTAMP                {}
-@@ -11925,6 +11983,7 @@
-         | UNKNOWN_SYM              {}
-         | UNTIL_SYM                {}
-         | USER                     {}
-+        | USER_STATS_SYM           {}
-         | USE_FRM                  {}
-         | VARIABLES                {}
-         | VIEW_SYM                 {}
---- a/sql/structs.h
-+++ b/sql/structs.h
-@@ -240,6 +240,171 @@
-   USER_RESOURCES user_resources;
- } USER_CONN;
-+typedef struct st_user_stats {
-+  char user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
-+  // Account name the user is mapped to when this is a user from mapped_user.
-+  // Otherwise, the same value as user.
-+  char priv_user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
-+  uint total_connections;
-+  uint concurrent_connections;
-+  time_t connected_time;  // in seconds
-+  double busy_time;       // in seconds
-+  double cpu_time;        // in seconds
-+  ulonglong bytes_received;
-+  ulonglong bytes_sent;
-+  ulonglong binlog_bytes_written;
-+  ha_rows rows_fetched, rows_updated, rows_read;
-+  ulonglong select_commands, update_commands, other_commands;
-+  ulonglong commit_trans, rollback_trans;
-+  ulonglong denied_connections, lost_connections;
-+  ulonglong access_denied_errors;
-+  ulonglong empty_queries;
-+} USER_STATS;
-+
-+/* Lookup function for hash tables with USER_STATS entries */
-+extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length,
-+                                my_bool not_used __attribute__((unused)));
-+
-+/* Free all memory for a hash table with USER_STATS entries */
-+extern void free_user_stats(USER_STATS* user_stats);
-+
-+/* Intialize an instance of USER_STATS */
-+extern void
-+init_user_stats(USER_STATS *user_stats,
-+                const char *user,
-+                const char *priv_user,
-+                uint total_connections,
-+                uint concurrent_connections,
-+                time_t connected_time,
-+                double busy_time,
-+                double cpu_time,
-+                ulonglong bytes_received,
-+                ulonglong bytes_sent,
-+                ulonglong binlog_bytes_written,
-+                ha_rows rows_fetched,
-+                ha_rows rows_updated,
-+                ha_rows rows_read,
-+                ulonglong select_commands,
-+                ulonglong update_commands,
-+                ulonglong other_commands,
-+                ulonglong commit_trans,
-+                ulonglong rollback_trans,
-+                ulonglong denied_connections,
-+                ulonglong lost_connections,
-+                ulonglong access_denied_errors,
-+                ulonglong empty_queries);
-+
-+/* Increment values of an instance of USER_STATS */
-+extern void
-+add_user_stats(USER_STATS *user_stats,
-+               uint total_connections,
-+               uint concurrent_connections,
-+               time_t connected_time,
-+               double busy_time,
-+               double cpu_time,
-+               ulonglong bytes_received,
-+               ulonglong bytes_sent,
-+               ulonglong binlog_bytes_written,
-+               ha_rows rows_fetched,
-+               ha_rows rows_updated,
-+               ha_rows rows_read,
-+               ulonglong select_commands,
-+               ulonglong update_commands,
-+               ulonglong other_commands,
-+               ulonglong commit_trans,
-+               ulonglong rollback_trans,
-+               ulonglong denied_connections,
-+               ulonglong lost_connections,
-+               ulonglong access_denied_errors,
-+               ulonglong empty_queries);
-+
-+typedef struct st_thread_stats {
-+  my_thread_id id;
-+  uint total_connections;
-+  uint concurrent_connections;
-+  time_t connected_time;  // in seconds
-+  double busy_time;       // in seconds
-+  double cpu_time;        // in seconds
-+  ulonglong bytes_received;
-+  ulonglong bytes_sent;
-+  ulonglong binlog_bytes_written;
-+  ha_rows rows_fetched, rows_updated, rows_read;
-+  ulonglong select_commands, update_commands, other_commands;
-+  ulonglong commit_trans, rollback_trans;
-+  ulonglong denied_connections, lost_connections;
-+  ulonglong access_denied_errors;
-+  ulonglong empty_queries;
-+} THREAD_STATS;
-+
-+/* Lookup function for hash tables with THREAD_STATS entries */
-+extern "C" uchar *get_key_thread_stats(THREAD_STATS *thread_stats, size_t *length,
-+                                my_bool not_used __attribute__((unused)));
-+
-+/* Free all memory for a hash table with THREAD_STATS entries */
-+extern void free_thread_stats(THREAD_STATS* thread_stats);
-+
-+/* Intialize an instance of THREAD_STATS */
-+extern void
-+init_thread_stats(THREAD_STATS *thread_stats,
-+                my_thread_id id,
-+                uint total_connections,
-+                uint concurrent_connections,
-+                time_t connected_time,
-+                double busy_time,
-+                double cpu_time,
-+                ulonglong bytes_received,
-+                ulonglong bytes_sent,
-+                ulonglong binlog_bytes_written,
-+                ha_rows rows_fetched,
-+                ha_rows rows_updated,
-+                ha_rows rows_read,
-+                ulonglong select_commands,
-+                ulonglong update_commands,
-+                ulonglong other_commands,
-+                ulonglong commit_trans,
-+                ulonglong rollback_trans,
-+                ulonglong denied_connections,
-+                ulonglong lost_connections,
-+                ulonglong access_denied_errors,
-+                ulonglong empty_queries);
-+
-+/* Increment values of an instance of THREAD_STATS */
-+extern void
-+add_thread_stats(THREAD_STATS *thread_stats,
-+               uint total_connections,
-+               uint concurrent_connections,
-+               time_t connected_time,
-+               double busy_time,
-+               double cpu_time,
-+               ulonglong bytes_received,
-+               ulonglong bytes_sent,
-+               ulonglong binlog_bytes_written,
-+               ha_rows rows_fetched,
-+               ha_rows rows_updated,
-+               ha_rows rows_read,
-+               ulonglong select_commands,
-+               ulonglong update_commands,
-+               ulonglong other_commands,
-+               ulonglong commit_trans,
-+               ulonglong rollback_trans,
-+               ulonglong denied_connections,
-+               ulonglong lost_connections,
-+               ulonglong access_denied_errors,
-+               ulonglong empty_queries);
-+
-+typedef struct st_table_stats {
-+  char table[NAME_LEN * 2 + 2];  // [db] + '.' + [table] + '\0'
-+  ulonglong rows_read, rows_changed;
-+  ulonglong rows_changed_x_indexes;
-+  /* Stores enum db_type, but forward declarations cannot be done */
-+  int engine_type;
-+} TABLE_STATS;
-+
-+typedef struct st_index_stats {
-+  char index[NAME_LEN * 3 + 3];  // [db] + '.' + [table] + '.' + [index] + '\0'
-+  ulonglong rows_read;
-+} INDEX_STATS;
-+
-       /* Bits in form->update */
- #define REG_MAKE_DUPP         1       /* Make a copy of record when read */
- #define REG_NEW_RECORD                2       /* Write a new record if not found */
---- a/sql/table.h
-+++ b/sql/table.h
-@@ -944,10 +944,12 @@
- enum enum_schema_tables
- {
-   SCH_CHARSETS= 0,
-+  SCH_CLIENT_STATS,
-   SCH_COLLATIONS,
-   SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
-   SCH_COLUMNS,
-   SCH_COLUMN_PRIVILEGES,
-+  SCH_INDEX_STATS,
-   SCH_ENGINES,
-   SCH_EVENTS,
-   SCH_FILES,
-@@ -971,8 +973,11 @@
-   SCH_TABLE_CONSTRAINTS,
-   SCH_TABLE_NAMES,
-   SCH_TABLE_PRIVILEGES,
-+  SCH_TABLE_STATS,
-+  SCH_THREAD_STATS,
-   SCH_TRIGGERS,
-   SCH_USER_PRIVILEGES,
-+  SCH_USER_STATS,
-   SCH_VARIABLES,
-   SCH_VIEWS
- };
---- a/storage/innobase/handler/ha_innodb.cc
-+++ b/storage/innobase/handler/ha_innodb.cc
-@@ -4055,6 +4055,8 @@
-       error = row_insert_for_mysql((byte*) record, prebuilt);
-+      if (error == DB_SUCCESS) rows_changed++;
-+
-       /* Handle duplicate key errors */
-       if (auto_inc_used) {
-               ulint           err;
-@@ -4392,6 +4394,8 @@
-               }
-       }
-+      if (error == DB_SUCCESS) rows_changed++;
-+
-       innodb_srv_conc_exit_innodb(trx);
-       error = convert_error_code_to_mysql(error, user_thd);
-@@ -4444,6 +4448,8 @@
-       error = row_update_for_mysql((byte*) record, prebuilt);
-+      if (error == DB_SUCCESS) rows_changed++;
-+
-       innodb_srv_conc_exit_innodb(trx);
-       error = convert_error_code_to_mysql(error, user_thd);
-@@ -4923,6 +4929,9 @@
-       if (ret == DB_SUCCESS) {
-               error = 0;
-               table->status = 0;
-+              rows_read++;
-+              if (active_index < MAX_KEY)
-+                      index_rows_read[active_index]++;
-       } else if (ret == DB_RECORD_NOT_FOUND) {
-               error = HA_ERR_END_OF_FILE;
---- a/storage/myisam/ha_myisam.cc
-+++ b/storage/myisam/ha_myisam.cc
-@@ -772,6 +772,7 @@
- int ha_myisam::write_row(uchar *buf)
- {
-+  int error;
-   ha_statistic_increment(&SSV::ha_write_count);
-   /* If we have a timestamp column, update it to the current time */
-@@ -784,11 +785,12 @@
-   */
-   if (table->next_number_field && buf == table->record[0])
-   {
--    int error;
-     if ((error= update_auto_increment()))
-       return error;
-   }
--  return mi_write(file,buf);
-+  error=mi_write(file,buf);
-+  if (!error) rows_changed++;
-+  return error;
- }
- int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
-@@ -1649,16 +1651,22 @@
- int ha_myisam::update_row(const uchar *old_data, uchar *new_data)
- {
-+  int error;
-   ha_statistic_increment(&SSV::ha_update_count);
-   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
-     table->timestamp_field->set_time();
--  return mi_update(file,old_data,new_data);
-+  error=mi_update(file,old_data,new_data);
-+  if (!error) rows_changed++;
-+  return error;
- }
- int ha_myisam::delete_row(const uchar *buf)
- {
-+  int error;
-   ha_statistic_increment(&SSV::ha_delete_count);
--  return mi_delete(file,buf);
-+  error=mi_delete(file,buf);
-+  if (!error) rows_changed++;
-+  return error;
- }
- int ha_myisam::index_read_map(uchar *buf, const uchar *key,
-@@ -1669,6 +1677,13 @@
-   ha_statistic_increment(&SSV::ha_read_key_count);
-   int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1679,6 +1694,13 @@
-   ha_statistic_increment(&SSV::ha_read_key_count);
-   int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1691,6 +1713,13 @@
-   int error=mi_rkey(file, buf, active_index, key, keypart_map,
-                     HA_READ_PREFIX_LAST);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   DBUG_RETURN(error);
- }
-@@ -1700,6 +1729,13 @@
-   ha_statistic_increment(&SSV::ha_read_next_count);
-   int error=mi_rnext(file,buf,active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1709,6 +1745,13 @@
-   ha_statistic_increment(&SSV::ha_read_prev_count);
-   int error=mi_rprev(file,buf, active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1718,6 +1761,13 @@
-   ha_statistic_increment(&SSV::ha_read_first_count);
-   int error=mi_rfirst(file, buf, active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1727,6 +1777,13 @@
-   ha_statistic_increment(&SSV::ha_read_last_count);
-   int error=mi_rlast(file, buf, active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1742,6 +1799,13 @@
-     error= mi_rnext_same(file,buf);
-   } while (error == HA_ERR_RECORD_DELETED);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == MAX_KEY) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1758,6 +1822,7 @@
-   ha_statistic_increment(&SSV::ha_read_rnd_next_count);
-   int error=mi_scan(file, buf);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) rows_read++;
-   return error;
- }
-@@ -1771,6 +1836,7 @@
-   ha_statistic_increment(&SSV::ha_read_rnd_count);
-   int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) rows_read++;
-   return error;
- }
---- /dev/null
-+++ b/mysql-test/r/userstat_bug602047.result
-@@ -0,0 +1,16 @@
-+DROP TABLE IF EXISTS t1;
-+SET @userstat_running_old= @@userstat_running;
-+SET GLOBAL userstat_running=ON;
-+CREATE TABLE t1 ( id int(10), PRIMARY KEY (id)) ENGINE=InnoDB;
-+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
-+SELECT COUNT(*) FROM t1;
-+COUNT(*)
-+10
-+SELECT ROWS_READ FROM information_schema.table_statistics WHERE TABLE_NAME='t1';
-+ROWS_READ
-+10
-+SELECT ROWS_READ FROM information_schema.index_statistics WHERE TABLE_NAME='t1';
-+ROWS_READ
-+10
-+SET GLOBAL userstat_running= @userstat_running_old;
-+DROP TABLE t1;
---- /dev/null
-+++ b/mysql-test/t/userstat_bug602047.test
-@@ -0,0 +1,13 @@
-+--source include/have_innodb.inc
-+--disable_warnings
-+DROP TABLE IF EXISTS t1; 
-+--enable_warnings
-+SET @userstat_running_old= @@userstat_running;
-+SET GLOBAL userstat_running=ON;
-+CREATE TABLE t1 ( id int(10), PRIMARY KEY (id)) ENGINE=InnoDB;
-+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
-+SELECT COUNT(*) FROM t1; 
-+SELECT ROWS_READ FROM information_schema.table_statistics WHERE TABLE_NAME='t1';
-+SELECT ROWS_READ FROM information_schema.index_statistics WHERE TABLE_NAME='t1';
-+SET GLOBAL userstat_running= @userstat_running_old;
-+DROP TABLE t1;
diff --git a/mysql-userstats.patch b/mysql-userstats.patch
deleted file mode 100644 (file)
index 29b5727..0000000
+++ /dev/null
@@ -1,1466 +0,0 @@
-diff -r 3ed7e96969f9 include/mysql_com.h
---- a/include/mysql_com.h      Thu Dec 04 08:54:17 2008 -0800
-+++ b/include/mysql_com.h      Thu Dec 04 08:54:27 2008 -0800
-@@ -115,6 +115,8 @@
-                                          thread */
- #define REFRESH_MASTER          128     /* Remove all bin logs in the index
-                                          and truncate the index */
-+#define REFRESH_TABLE_STATS     256     /* Refresh table stats hash table */
-+#define REFRESH_INDEX_STATS     512     /* Refresh index stats hash table */
- /* The following can't be set with mysql_refresh() */
- #define REFRESH_READ_LOCK     16384   /* Lock tables for read */
-diff -r 3ed7e96969f9 sql/handler.cc
---- a/sql/handler.cc   Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/handler.cc   Thu Dec 04 08:54:27 2008 -0800
-@@ -1205,6 +1205,7 @@
-         error=1;
-       }
-       status_var_increment(thd->status_var.ha_commit_count);
-+      thd->diff_commit_trans++;
-       ha_info_next= ha_info->next();
-       ha_info->reset(); /* keep it conveniently zero-filled */
-     }
-@@ -1272,6 +1273,7 @@
-         error=1;
-       }
-       status_var_increment(thd->status_var.ha_rollback_count);
-+      thd->diff_rollback_trans++;
-       ha_info_next= ha_info->next();
-       ha_info->reset(); /* keep it conveniently zero-filled */
-     }
-@@ -1724,6 +1726,7 @@
-       error=1;
-     }
-     status_var_increment(thd->status_var.ha_rollback_count);
-+    thd->diff_rollback_trans++;
-     ha_info_next= ha_info->next();
-     ha_info->reset(); /* keep it conveniently zero-filled */
-   }
-@@ -2058,6 +2061,8 @@
-       dup_ref=ref+ALIGN_SIZE(ref_length);
-     cached_table_flags= table_flags();
-   }
-+  rows_read = rows_changed = 0;
-+  memset(index_rows_read, 0, sizeof(index_rows_read));
-   DBUG_RETURN(error);
- }
-@@ -3487,6 +3492,97 @@
-   return;
- }
-+// Updates the global table stats with the TABLE this handler represents.
-+void handler::update_global_table_stats() {
-+  if (!rows_read && !rows_changed) return;  // Nothing to update.
-+  // table_cache_key is db_name + '\0' + table_name + '\0'.
-+  if (!table->s || !table->s->table_cache_key.str || !table->s->table_name.str) return;
-+
-+  TABLE_STATS* table_stats;
-+  char key[NAME_LEN * 2 + 2];
-+  // [db] + '.' + [table]
-+  sprintf(key, "%s.%s", table->s->table_cache_key.str, table->s->table_name.str);
-+
-+  pthread_mutex_lock(&LOCK_global_table_stats);
-+  // Gets the global table stats, creating one if necessary.
-+  if (!(table_stats = (TABLE_STATS*)hash_search(&global_table_stats,
-+                                                (uchar*)key,
-+                                                strlen(key)))) {
-+    if (!(table_stats = ((TABLE_STATS*)
-+                         my_malloc(sizeof(TABLE_STATS), MYF(MY_WME))))) {
-+      // Out of memory.
-+      sql_print_error("Allocating table stats failed.");
-+      goto end;
-+    }
-+    strncpy(table_stats->table, key, sizeof(table_stats->table));
-+    table_stats->rows_read = 0;
-+    table_stats->rows_changed = 0;
-+    table_stats->rows_changed_x_indexes = 0;
-+
-+    if (my_hash_insert(&global_table_stats, (uchar*)table_stats)) {
-+      // Out of memory.
-+      sql_print_error("Inserting table stats failed.");
-+      my_free((char*)table_stats, 0);
-+      goto end;
-+    }
-+  }
-+  // Updates the global table stats.
-+  table_stats->rows_read += rows_read;
-+  table_stats->rows_changed += rows_changed;
-+  table_stats->rows_changed_x_indexes +=
-+      rows_changed * (table->s->keys ? table->s->keys : 1);
-+  rows_read = rows_changed = 0;
-+end:
-+  pthread_mutex_unlock(&LOCK_global_table_stats);
-+}
-+
-+// Updates the global index stats with this handler's accumulated index reads.
-+void handler::update_global_index_stats() {
-+  // table_cache_key is db_name + '\0' + table_name + '\0'.
-+  if (!table->s || !table->s->table_cache_key.str || !table->s->table_name.str) return;
-+
-+  for (int x = 0; x < table->s->keys; x++) {
-+    if (index_rows_read[x]) {
-+      // Rows were read using this index.
-+      KEY* key_info = &table->key_info[x];
-+
-+      if (!key_info->name) continue;
-+
-+      INDEX_STATS* index_stats;
-+      char key[NAME_LEN * 3 + 3];
-+      // [db] + '.' + [table] + '.' + [index]
-+      sprintf(key, "%s.%s.%s",  table->s->table_cache_key.str,
-+              table->s->table_name.str, key_info->name);
-+
-+      pthread_mutex_lock(&LOCK_global_index_stats);
-+      // Gets the global index stats, creating one if necessary.
-+      if (!(index_stats = (INDEX_STATS*)hash_search(&global_index_stats,
-+                                                    (uchar*)key,
-+                                                    strlen(key)))) {
-+        if (!(index_stats = ((INDEX_STATS*)
-+                             my_malloc(sizeof(INDEX_STATS), MYF(MY_WME))))) {
-+          // Out of memory.
-+          sql_print_error("Allocating index stats failed.");
-+          goto end;
-+        }
-+        strncpy(index_stats->index, key, sizeof(index_stats->index));
-+        index_stats->rows_read = 0;
-+
-+        if (my_hash_insert(&global_index_stats, (uchar*)index_stats)) {
-+          // Out of memory.
-+          sql_print_error("Inserting index stats failed.");
-+          my_free((char*)index_stats, 0);
-+          goto end;
-+        }
-+      }
-+      // Updates the global index stats.
-+      index_stats->rows_read += index_rows_read[x];
-+      index_rows_read[x] = 0;
-+end:
-+      pthread_mutex_unlock(&LOCK_global_index_stats);
-+    }
-+  }
-+}
- /****************************************************************************
- ** Some general functions that isn't in the handler class
-diff -r 3ed7e96969f9 sql/handler.h
---- a/sql/handler.h    Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/handler.h    Thu Dec 04 08:54:27 2008 -0800
-@@ -29,6 +29,10 @@
- #endif
- #define USING_TRANSACTIONS
-+
-+#if MAX_KEY > 128
-+#error MAX_KEY is too large.  Values up to 128 are supported.
-+#endif
- // the following is for checking tables
-@@ -690,6 +694,7 @@
-    */
-    enum log_status (*get_log_status)(handlerton *hton, char *log);
-+
-    /*
-      Iterators creator.
-      Presence of the pointer should be checked before using
-@@ -1137,6 +1142,10 @@
-   */
-   uint auto_inc_intervals_count;
-+   ulonglong rows_read;
-+   ulonglong rows_changed;
-+   ulonglong index_rows_read[MAX_KEY];
-+
-   handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
-     :table_share(share_arg), table(0),
-     estimation_rows_to_insert(0), ht(ht_arg),
-@@ -1145,8 +1154,10 @@
-     ft_handler(0), inited(NONE),
-     locked(FALSE), implicit_emptied(0),
-     pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
--    auto_inc_intervals_count(0)
--    {}
-+    auto_inc_intervals_count(0), rows_read(0), rows_changed(0)
-+    {
-+        memset(index_rows_read, 0, sizeof(index_rows_read));
-+    }
-   virtual ~handler(void)
-   {
-     DBUG_ASSERT(locked == FALSE);
-@@ -1267,7 +1278,13 @@
-   {
-     table= table_arg;
-     table_share= share;
-+    rows_read = rows_changed = 0;
-+    memset(index_rows_read, 0, sizeof(index_rows_read));
-   }
-+  
-+  void update_global_table_stats();
-+  void update_global_index_stats();
-+
-   virtual double scan_time()
-   { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
-   virtual double read_time(uint index, uint ranges, ha_rows rows)
-diff -r 3ed7e96969f9 sql/lex.h
---- a/sql/lex.h        Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/lex.h        Thu Dec 04 08:54:27 2008 -0800
-@@ -245,6 +245,7 @@
-   { "IN",             SYM(IN_SYM)},
-   { "INDEX",          SYM(INDEX_SYM)},
-   { "INDEXES",                SYM(INDEXES)},
-+  { "INDEX_STATISTICS",       SYM(INDEX_STATS_SYM)},
-   { "INFILE",         SYM(INFILE)},
-   { "INITIAL_SIZE",   SYM(INITIAL_SIZE_SYM)},
-   { "INNER",          SYM(INNER_SYM)},
-@@ -528,6 +529,7 @@
-   { "TABLES",         SYM(TABLES)},
-   { "TABLESPACE",             SYM(TABLESPACE)},
-   { "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)},
-+  { "TABLE_STATISTICS",       SYM(TABLE_STATS_SYM)},
-   { "TEMPORARY",      SYM(TEMPORARY)},
-   { "TEMPTABLE",      SYM(TEMPTABLE_SYM)},
-   { "TERMINATED",     SYM(TERMINATED)},
-@@ -570,6 +572,7 @@
-   { "USE",            SYM(USE_SYM)},
-   { "USER",           SYM(USER)},
-   { "USER_RESOURCES", SYM(RESOURCES)},
-+  { "USER_STATISTICS",        SYM(USER_STATS_SYM)},
-   { "USE_FRM",                SYM(USE_FRM)},
-   { "USING",          SYM(USING)},
-   { "UTC_DATE",         SYM(UTC_DATE_SYM)},
-diff -r 3ed7e96969f9 sql/mysql_priv.h
---- a/sql/mysql_priv.h Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/mysql_priv.h Thu Dec 04 08:54:27 2008 -0800
-@@ -1060,7 +1060,19 @@
- bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
- void init_max_user_conn(void);
- void init_update_queries(void);
-+void init_global_user_stats(void);
-+void init_global_table_stats(void);
-+void init_global_index_stats(void);
- void free_max_user_conn(void);
-+void free_global_user_stats(void);
-+void free_global_table_stats(void);
-+void free_global_index_stats(void);
-+// Uses the THD to update the global stats.
-+void update_global_user_stats(THD* thd);
-+// Set stats for concurrent connections displayed by mysqld_show().
-+void set_concurrent_connections_stats();
-+// Increments connection count for user.
-+int increment_connection_count(THD* thd, bool use_lock);
- pthread_handler_t handle_bootstrap(void *arg);
- int mysql_execute_command(THD *thd);
- bool do_command(THD *thd);
-@@ -2015,6 +2027,12 @@
- extern struct system_variables max_system_variables;
- extern struct system_status_var global_status_var;
- extern struct rand_struct sql_rand;
-+extern HASH global_user_stats;
-+extern pthread_mutex_t LOCK_global_user_stats;
-+extern HASH global_table_stats;
-+extern pthread_mutex_t LOCK_global_table_stats;
-+extern HASH global_index_stats;
-+extern pthread_mutex_t LOCK_global_index_stats;
- extern const char *opt_date_time_formats[];
- extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
-diff -r 3ed7e96969f9 sql/mysqld.cc
---- a/sql/mysqld.cc    Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/mysqld.cc    Thu Dec 04 08:54:27 2008 -0800
-@@ -589,6 +589,11 @@
-               LOCK_global_system_variables,
-               LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
-                 LOCK_connection_count;
-+
-+pthread_mutex_t LOCK_global_user_stats;
-+pthread_mutex_t LOCK_global_table_stats;
-+pthread_mutex_t LOCK_global_index_stats;
-+
- /**
-   The below lock protects access to two global server variables:
-   max_prepared_stmt_count and prepared_stmt_count. These variables
-@@ -1266,6 +1271,9 @@
-   x_free(opt_secure_file_priv);
-   bitmap_free(&temp_pool);
-   free_max_user_conn();
-+  free_global_user_stats();
-+  free_global_table_stats();
-+  free_global_index_stats();
- #ifdef HAVE_REPLICATION
-   end_slave_list();
- #endif
-@@ -1378,6 +1386,9 @@
-   (void) pthread_cond_destroy(&COND_thread_cache);
-   (void) pthread_cond_destroy(&COND_flush_thread_cache);
-   (void) pthread_cond_destroy(&COND_manager);
-+  (void) pthread_mutex_destroy(&LOCK_global_user_stats);
-+  (void) pthread_mutex_destroy(&LOCK_global_table_stats);
-+  (void) pthread_mutex_destroy(&LOCK_global_index_stats);
- }
- #endif /*EMBEDDED_LIBRARY*/
-@@ -3072,6 +3083,7 @@
-   {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
-   {"show_grants",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
-   {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
-+  {"show_index_stats",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_INDEX_STATS]), SHOW_LONG_STATUS},
-   {"show_master_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
-   {"show_new_master",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
-   {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
-@@ -3089,9 +3101,11 @@
-   {"show_slave_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
-   {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
-   {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
-+  {"show_table_stats",     (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS},
-   {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
-   {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
-   {"show_triggers",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
-+  {"show_user_stats",      (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS},
-   {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
-   {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
-   {"slave_start",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
-@@ -3507,6 +3521,9 @@
- #endif
-   (void) pthread_mutex_init(&LOCK_server_started, MY_MUTEX_INIT_FAST);
-   (void) pthread_cond_init(&COND_server_started,NULL);
-+  (void) pthread_mutex_init(&LOCK_global_user_stats, MY_MUTEX_INIT_FAST);
-+  (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
-+  (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
-   sp_cache_init();
- #ifdef HAVE_EVENT_SCHEDULER
-   Events::init_mutexes();
-@@ -3872,6 +3889,9 @@
-   if (!errmesg[0][0])
-     unireg_abort(1);
-+   init_global_table_stats();
-+   init_global_index_stats();
-+
-   /* We have to initialize the storage engines before CSV logging */
-   if (ha_init())
-   {
-@@ -4018,6 +4038,7 @@
-   init_max_user_conn();
-   init_update_queries();
-+  init_global_user_stats();
-   DBUG_RETURN(0);
- }
-diff -r 3ed7e96969f9 sql/sql_base.cc
---- a/sql/sql_base.cc  Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_base.cc  Thu Dec 04 08:54:27 2008 -0800
-@@ -1343,6 +1343,12 @@
-   DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str,
-                         table->s->table_name.str, (long) table));
-+  if(table->file)
-+  {
-+    table->file->update_global_table_stats();
-+    table->file->update_global_index_stats();
-+  }
-+
-   *table_ptr=table->next;
-   /*
-     When closing a MERGE parent or child table, detach the children first.
-@@ -1882,6 +1888,9 @@
-   DBUG_ENTER("close_temporary");
-   DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
-                           table->s->db.str, table->s->table_name.str));
-+ 
-+  table->file->update_global_table_stats();
-+  table->file->update_global_index_stats();
-   free_io_cache(table);
-   closefrm(table, 0);
-diff -r 3ed7e96969f9 sql/sql_class.cc
---- a/sql/sql_class.cc Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_class.cc Thu Dec 04 08:54:27 2008 -0800
-@@ -578,6 +578,8 @@
-   bzero(ha_data, sizeof(ha_data));
-   mysys_var=0;
-   binlog_evt_union.do_union= FALSE;
-+  busy_time = 0;
-+  updated_row_count = 0;
-   enable_slow_log= 0;
- #ifndef DBUG_OFF
-   dbug_sentry=THD_SENTRY_MAGIC;
-@@ -838,6 +838,7 @@
-   reset_current_stmt_binlog_row_based();
-   bzero((char *) &status_var, sizeof(status_var));
-   sql_log_bin_toplevel= options & OPTION_BIN_LOG;
-+  reset_stats();
- #if defined(ENABLED_DEBUG_SYNC)
-   /* Initialize the Debug Sync Facility. See debug_sync.cc. */
-@@ -845,6 +846,52 @@
- #endif /* defined(ENABLED_DEBUG_SYNC) */
- }
-+// Resets stats in a THD.
-+void THD::reset_stats(void) {
-+  current_connect_time = time(NULL);
-+  last_global_update_time = current_connect_time;
-+  reset_diff_stats();
-+}
-+
-+// Resets the 'diff' stats, which are used to update global stats.
-+void THD::reset_diff_stats(void) {
-+  diff_total_busy_time = 0;
-+  diff_total_sent_rows = 0;
-+  diff_total_updated_rows = 0;
-+  diff_select_commands = 0;
-+  diff_update_commands = 0;
-+  diff_other_commands = 0;
-+  diff_commit_trans = 0;
-+  diff_rollback_trans = 0;
-+}
-+
-+// Updates 'diff' stats of a THD.
-+void THD::update_stats() {
-+  diff_total_busy_time += busy_time;
-+  diff_total_sent_rows += sent_row_count;
-+  diff_total_updated_rows += updated_row_count;
-+  // The replication thread has the COM_CONNECT command.
-+  if ((old_command == COM_QUERY || command == COM_CONNECT) &&
-+      (lex->sql_command >= 0 && lex->sql_command < SQLCOM_END)) {
-+    // A SQL query.
-+    if (lex->sql_command == SQLCOM_SELECT) {
-+      if (!(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)) {
-+        diff_select_commands++;
-+      } else {
-+        // 'SHOW ' commands become SQLCOM_SELECT.
-+        diff_other_commands++;
-+        // 'SHOW ' commands shouldn't inflate total sent row count.
-+        diff_total_sent_rows -= sent_row_count;
-+      }
-+    } else if (is_update_query(lex->sql_command)) {
-+      diff_update_commands++;
-+    } else {
-+      diff_other_commands++;
-+    }
-+  }
-+  // diff_commit_trans is updated in handler.cc.
-+  // diff_rollback_trans is updated in handler.cc.
-+}
- /*
-   Init THD for query processing.
-diff -r 3ed7e96969f9 sql/sql_class.h
---- a/sql/sql_class.h  Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_class.h  Thu Dec 04 08:54:27 2008 -0800
-@@ -1327,6 +1327,8 @@
-     first byte of the packet in do_command()
-   */
-   enum enum_server_command command;
-+  // Used to save the command, before it is set to COM_SLEEP.
-+  enum enum_server_command old_command;
-   uint32     server_id;
-   uint32     file_id;                 // for LOAD DATA INFILE
-   /* remote (peer) port */
-@@ -1616,6 +1618,7 @@
-   ulonglong  options;           /* Bitmap of states */
-   longlong   row_count_func;    /* For the ROW_COUNT() function */
-   ha_rows    cuted_fields;
-+  ha_rows    updated_row_count;
-   /*
-     number of rows we actually sent to the client, including "synthetic"
-@@ -1767,6 +1770,27 @@
-   */
-   LOG_INFO*  current_linfo;
-   NET*       slave_net;                       // network connection from slave -> m.
-+
-+  /*
-+    Used to update global user stats.  The global user stats are updated
-+    occasionally with the 'diff' variables.  After the update, the 'diff'
-+    variables are reset to 0.
-+   */
-+  // Time when the current thread connected to MySQL.
-+  time_t current_connect_time;
-+  // Last time when THD stats were updated in global_user_stats.
-+  time_t last_global_update_time;
-+  // Busy (non-idle) time for just one command.
-+  double busy_time;
-+  // Busy time not updated in global_user_stats yet.
-+  double diff_total_busy_time;
-+  // Number of rows not reflected in global_user_stats yet.
-+  ha_rows diff_total_sent_rows, diff_total_updated_rows;
-+  // Number of commands not reflected in global_user_stats yet.
-+  ulonglong diff_select_commands, diff_update_commands, diff_other_commands;
-+  // Number of transactions not reflected in global_user_stats yet.
-+  ulonglong diff_commit_trans, diff_rollback_trans;
-+
-   /* Used by the sys_var class to store temporary values */
-   union
-   {
-@@ -1827,6 +1851,9 @@
-     alloc_root. 
-   */
-   void init_for_queries();
-+  void reset_stats(void);
-+  void reset_diff_stats(void);
-+  void update_stats(void);
-   void change_user(void);
-   void cleanup(void);
-   void cleanup_after_query();
-diff -r 3ed7e96969f9 sql/sql_connect.cc
---- a/sql/sql_connect.cc       Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_connect.cc       Thu Dec 04 08:54:27 2008 -0800
-@@ -520,6 +520,14 @@
-                  0,0,
-                  (hash_get_key) get_key_conn, (hash_free_key) free_user,
-                  0);
-+  if (hash_init(&hash_user_connections,system_charset_info,max_connections,
-+                0,0,
-+                (hash_get_key) get_key_conn, (hash_free_key) free_user,
-+                0)) {
-+    sql_print_error("Initializing hash_user_connections failed.");
-+    exit(1);
-+  }
-+
- #endif
- }
-@@ -1107,6 +1115,13 @@
-     if (login_connection(thd))
-       goto end_thread;
-+    thd->reset_stats();
-+    // Updates global user connection stats.
-+    if (increment_connection_count(thd, true)) {
-+      net_send_error(thd, ER_OUTOFMEMORY);  // Out of memory
-+      goto end_thread;
-+    }
-+
-     prepare_new_connection_state(thd);
-     while (!net->error && net->vio != 0 &&
-@@ -1119,6 +1134,8 @@
-    
- end_thread:
-     close_connection(thd, 0, 1);
-+    thd->update_stats();
-+    update_global_user_stats(thd);
-     if (thread_scheduler.end_thread(thd,1))
-       return 0;                                 // Probably no-threads
-diff -r 3ed7e96969f9 sql/sql_delete.cc
---- a/sql/sql_delete.cc        Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_delete.cc        Thu Dec 04 08:54:27 2008 -0800
-@@ -402,6 +402,7 @@
-     my_ok(thd, (ha_rows) thd->row_count_func);
-     DBUG_PRINT("info",("%ld records deleted",(long) deleted));
-   }
-+  thd->updated_row_count += deleted;
-   DBUG_RETURN(error >= 0 || thd->is_error());
- }
-@@ -938,6 +939,7 @@
-     thd->row_count_func= deleted;
-     ::my_ok(thd, (ha_rows) thd->row_count_func);
-   }
-+  thd->updated_row_count += deleted;
-   return 0;
- }
-diff -r 3ed7e96969f9 sql/sql_insert.cc
---- a/sql/sql_insert.cc        Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_insert.cc        Thu Dec 04 08:54:27 2008 -0800
-@@ -969,6 +969,7 @@
-     thd->row_count_func= info.copied + info.deleted + updated;
-     ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
-   }
-+  thd->updated_row_count += thd->row_count_func;
-   thd->abort_on_warning= 0;
-   DBUG_RETURN(FALSE);
-diff -r 3ed7e96969f9 sql/sql_lex.h
---- a/sql/sql_lex.h    Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_lex.h    Thu Dec 04 08:54:27 2008 -0800
-@@ -118,7 +118,7 @@
-   SQLCOM_SHOW_CREATE_TRIGGER,
-   SQLCOM_ALTER_DB_UPGRADE,
-   SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
--
-+  SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, 
-   /*
-     When a command is added here, be sure it's also added in mysqld.cc
-     in "struct show_var_st status_vars[]= {" ...
-diff -r 3ed7e96969f9 sql/sql_parse.cc
---- a/sql/sql_parse.cc Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_parse.cc Thu Dec 04 08:54:27 2008 -0800
-@@ -45,6 +45,15 @@
- static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
- static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
-+
-+HASH global_user_stats;
-+extern pthread_mutex_t LOCK_global_user_stats;
-+
-+HASH global_table_stats;
-+extern pthread_mutex_t LOCK_global_table_stats;
-+
-+HASH global_index_stats;
-+extern pthread_mutex_t LOCK_global_index_stats;
- const char *any_db="*any*";   // Special symbol for check_access
-@@ -326,7 +335,9 @@
-   sql_command_flags[SQLCOM_SHOW_FUNC_CODE]=  CF_STATUS_COMMAND;
-   sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]=  CF_STATUS_COMMAND;
-   sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND;
--  sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND;
-+  sql_command_flags[SQLCOM_SHOW_USER_STATS]= CF_STATUS_COMMAND;
-+  sql_command_flags[SQLCOM_SHOW_TABLE_STATS]= CF_STATUS_COMMAND;
-+  sql_command_flags[SQLCOM_SHOW_INDEX_STATS]= CF_STATUS_COMMAND;
-    sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
-                                                  CF_SHOW_TABLE_COMMAND |
-@@ -544,6 +555,86 @@
-   DBUG_RETURN(0);
- }
-+extern "C" uchar *get_key_user_stats(USER_STATS *user_stats, size_t *length,
-+                                    my_bool not_used __attribute__((unused)))
-+{
-+  *length = strlen(user_stats->user);
-+  return (uchar*)user_stats->user;
-+}
-+
-+extern "C" void free_user_stats(USER_STATS* user_stats)
-+{
-+  my_free((char*)user_stats, MYF(0));
-+}
-+
-+void init_global_user_stats(void)
-+{
-+  if (hash_init(&global_user_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_user_stats,
-+                (hash_free_key)free_user_stats, 0)) {
-+    sql_print_error("Initializing global_user_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+extern "C" uchar *get_key_table_stats(TABLE_STATS *table_stats, size_t *length,
-+                                     my_bool not_used __attribute__((unused)))
-+{
-+  *length = strlen(table_stats->table);
-+  return (uchar*)table_stats->table;
-+}
-+
-+extern "C" void free_table_stats(TABLE_STATS* table_stats)
-+{
-+  my_free((char*)table_stats, MYF(0));
-+}
-+
-+void init_global_table_stats(void)
-+{
-+  if (hash_init(&global_table_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_table_stats,
-+                (hash_free_key)free_table_stats, 0)) {
-+    sql_print_error("Initializing global_table_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+extern "C" uchar *get_key_index_stats(INDEX_STATS *index_stats, size_t *length,
-+                                     my_bool not_used __attribute__((unused)))
-+{
-+  *length = strlen(index_stats->index);
-+  return (uchar*)index_stats->index;
-+}
-+
-+extern "C" void free_index_stats(INDEX_STATS* index_stats)
-+{
-+  my_free((char*)index_stats, MYF(0));
-+}
-+
-+void init_global_index_stats(void)
-+{
-+  if (hash_init(&global_index_stats, system_charset_info, max_connections,
-+                0, 0, (hash_get_key)get_key_index_stats,
-+                (hash_free_key)free_index_stats, 0)) {
-+    sql_print_error("Initializing global_index_stats failed.");
-+    exit(1);
-+  }
-+}
-+
-+void free_global_user_stats(void)
-+{
-+  hash_free(&global_user_stats);
-+}
-+
-+void free_global_table_stats(void)
-+{
-+  hash_free(&global_table_stats);
-+}
-+
-+void free_global_index_stats(void)
-+{
-+  hash_free(&global_index_stats);
-+}
- /**
-   @brief Check access privs for a MERGE table and fix children lock types.
-@@ -962,6 +1053,9 @@
-   DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
-   thd->command=command;
-+  // To increment the correct command counter for user stats, 'command' must
-+  // be saved because it is set to COM_SLEEP at the end of this function.
-+  thd->old_command = command;
-   /*
-     Commands which always take a long time are logged into
-     the slow log only if opt_log_slow_admin_statements is set.
-@@ -1740,6 +1834,9 @@
-   case SCH_COLUMN_PRIVILEGES:
-   case SCH_TABLE_CONSTRAINTS:
-   case SCH_KEY_COLUMN_USAGE:
-+  case SCH_USER_STATS:
-+  case SCH_TABLE_STATS:
-+  case SCH_INDEX_STATS:
-   default:
-     break;
-   }
-@@ -2129,6 +2226,9 @@
-     my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
-     break;
- #endif
-+  case SQLCOM_SHOW_USER_STATS:
-+  case SQLCOM_SHOW_TABLE_STATS:
-+  case SQLCOM_SHOW_INDEX_STATS:
-   case SQLCOM_SHOW_STATUS_PROC:
-   case SQLCOM_SHOW_STATUS_FUNC:
-     if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
-@@ -2306,6 +2406,7 @@
-   }
- #endif
-+
-   case SQLCOM_BACKUP_TABLE:
-   {
-     DBUG_ASSERT(first_table == all_tables && first_table != 0);
-@@ -5372,6 +5473,130 @@
- #endif /*NO_EMBEDDED_ACCESS_CHECKS*/
-+// 'mysql_system_user' is used for when the user is not defined for a THD.
-+static char mysql_system_user[] = "#mysql_system#";
-+
-+// Returns 'user' if it's not NULL.  Returns 'mysql_system_user' otherwise.
-+static char* get_valid_user_string(char* user) {
-+  return user ? user : mysql_system_user;
-+}
-+
-+// Increments the global user stats connection count.  If 'use_lock' is true,
-+// 'LOCK_global_user_stats' will be locked/unlocked.  Returns 0 on success,
-+// 1 on error.
-+int increment_connection_count(THD* thd, bool use_lock) {
-+  char* user_string = get_valid_user_string(thd->main_security_ctx.user);
-+
-+  USER_STATS* user_stats;
-+  int return_value = 0;
-+
-+  if (use_lock) pthread_mutex_lock(&LOCK_global_user_stats);
-+  if (!(user_stats = (USER_STATS*)hash_search(&global_user_stats,
-+                                              (uchar*)user_string,
-+                                              strlen(user_string)))) {
-+    // First connection for this user.
-+    if (!(user_stats = ((USER_STATS*)
-+                        my_malloc(sizeof(USER_STATS), MYF(MY_WME))))) {
-+      // Out of memory.
-+      return_value = 1;
-+      goto end;
-+    }
-+    strncpy(user_stats->user, user_string, sizeof(user_stats->user));
-+    user_stats->total_connections = 0;
-+    user_stats->concurrent_connections = 0;
-+    user_stats->connected_time = 0;
-+    user_stats->busy_time = 0;
-+    user_stats->rows_fetched = 0;
-+    user_stats->rows_updated = 0;
-+    user_stats->select_commands = 0;
-+    user_stats->update_commands = 0;
-+    user_stats->other_commands = 0;
-+    user_stats->commit_trans = 0;
-+    user_stats->rollback_trans = 0;
-+
-+    if (my_hash_insert(&global_user_stats, (uchar*)user_stats)) {
-+      // Out of memory.
-+      my_free((char*)user_stats, 0);
-+      return_value = 1;
-+      goto end;
-+    }
-+  }
-+  user_stats->total_connections++;
-+end:
-+  if (use_lock) pthread_mutex_unlock(&LOCK_global_user_stats);
-+  return return_value;
-+}
-+
-+// Used to update the global user stats.
-+static void update_global_user_stats_with_user(THD* thd,
-+                                               USER_STATS* user_stats) {
-+  time_t current_time = time(NULL);
-+  user_stats->connected_time += current_time - thd->last_global_update_time;
-+  thd->last_global_update_time = current_time;
-+  user_stats->busy_time += thd->diff_total_busy_time;
-+  user_stats->rows_fetched += thd->diff_total_sent_rows;
-+  user_stats->rows_updated += thd->diff_total_updated_rows;
-+  user_stats->select_commands += thd->diff_select_commands;
-+  user_stats->update_commands += thd->diff_update_commands;
-+  user_stats->other_commands += thd->diff_other_commands;
-+  user_stats->commit_trans += thd->diff_commit_trans;
-+  user_stats->rollback_trans += thd->diff_rollback_trans;
-+}
-+
-+// Updates the global stats of a thread/user.
-+void update_global_user_stats(THD* thd) {
-+  char* user_string = get_valid_user_string(thd->main_security_ctx.user);
-+
-+  USER_STATS* user_stats;
-+  pthread_mutex_lock(&LOCK_global_user_stats);
-+  if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
-+                                             (uchar*)user_string,
-+                                             strlen(user_string)))) {
-+    // Found user.
-+    update_global_user_stats_with_user(thd, user_stats);
-+    thd->reset_diff_stats();
-+  } else {
-+    // The user name should exist.
-+    increment_connection_count(thd, false);
-+  }
-+  pthread_mutex_unlock(&LOCK_global_user_stats);
-+}
-+
-+// Determines the concurrent number of connections of current threads.
-+void set_concurrent_connections_stats() {
-+  USER_STATS* user_stats;
-+
-+  pthread_mutex_lock(&LOCK_global_user_stats);
-+  pthread_mutex_lock(&LOCK_thread_count);
-+
-+  // Resets all concurrent connections to 0.
-+  for (int i = 0; i < global_user_stats.records; ++i) {
-+    user_stats = (USER_STATS*)hash_element(&global_user_stats, i);
-+    user_stats->concurrent_connections = 0;
-+  }
-+
-+  I_List_iterator<THD> it(threads);
-+  THD* thd;
-+  // Iterates through the current threads.
-+  while ((thd = it++)) {
-+    char* user_string = get_valid_user_string(thd->main_security_ctx.user);
-+    if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
-+                                               (uchar*)user_string,
-+                                               strlen(user_string)))) {
-+      // Found user.
-+      user_stats->concurrent_connections++;
-+      update_global_user_stats_with_user(thd, user_stats);
-+      thd->reset_diff_stats();
-+    } else {
-+      // The user name should exist.
-+      increment_connection_count(thd, false);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_thread_count);
-+  pthread_mutex_unlock(&LOCK_global_user_stats);
-+}
-+
-+
- /**
-   check for global access and give descriptive error message if it fails.
-@@ -5539,6 +5764,10 @@
-     reset_dynamic(&thd->user_var_events);
-     thd->user_var_events_alloc= thd->mem_root;
-   }
-+  
-+  thd->updated_row_count=0;
-+  thd->busy_time=0;
-+
-   thd->clear_error();
-   thd->main_da.reset_diagnostics_area();
-   thd->total_warn_count=0;                    // Warnings for this query
-@@ -5722,6 +5951,16 @@
-   DBUG_ENTER("mysql_parse");
-   DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
-+
-+  int start_time_error = 0;
-+  int end_time_error = 0;
-+  struct timeval start_time, end_time;
-+  double start_usecs = 0;
-+  double end_usecs = 0;
-+  // Gets the start time, in order to measure how long this command takes.
-+  if (!(start_time_error = gettimeofday(&start_time, NULL))) {
-+    start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
-+  }
-   /*
-     Warning.
-@@ -5816,6 +6055,27 @@
-     *found_semicolon= NULL;
-   }
-+  // Gets the end time.
-+  if (!(end_time_error = gettimeofday(&end_time, NULL))) {
-+    end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
-+  }
-+
-+  // Calculates the difference between the end and start times.
-+  if (end_usecs >= start_usecs && !start_time_error && !end_time_error) {
-+    thd->busy_time = (end_usecs - start_usecs) / 1000000;
-+    // In case there are bad values, 2629743 is the #seconds in a month.
-+    if (thd->busy_time > 2629743) {
-+      thd->busy_time = 0;
-+    }
-+  } else {
-+    // end time went back in time, or gettimeofday() failed.
-+    thd->busy_time = 0;
-+  }
-+
-+  // Updates THD stats and the global user stats.
-+  thd->update_stats();
-+  update_global_user_stats(thd);
-+
-   DBUG_VOID_RETURN;
- }
-@@ -6398,6 +6658,7 @@
-     tables->lock_type= lock_type;
-     tables->updating=  for_update;
-   }
-+
-   DBUG_VOID_RETURN;
- }
-@@ -6779,6 +7040,21 @@
- #endif
-  if (options & REFRESH_USER_RESOURCES)
-    reset_mqh((LEX_USER *) NULL, 0);             /* purecov: inspected */
-+ if (options & REFRESH_TABLE_STATS)
-+ {
-+   pthread_mutex_lock(&LOCK_global_table_stats);
-+   free_global_table_stats();
-+   init_global_table_stats();
-+   pthread_mutex_unlock(&LOCK_global_table_stats);
-+ }
-+ if (options & REFRESH_INDEX_STATS)
-+ {
-+   pthread_mutex_lock(&LOCK_global_index_stats);
-+   free_global_index_stats();
-+   init_global_index_stats();
-+   pthread_mutex_unlock(&LOCK_global_index_stats);
-+ }
-+   
-  *write_to_binlog= tmp_write_to_binlog;
-  return result;
- }
-diff -r 3ed7e96969f9 sql/sql_show.cc
---- a/sql/sql_show.cc  Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_show.cc  Thu Dec 04 08:54:27 2008 -0800
-@@ -2260,6 +2260,90 @@
-   DBUG_RETURN(FALSE);
- }
-+
-+int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_user_stats");
-+
-+  set_concurrent_connections_stats();
-+
-+  pthread_mutex_lock(&LOCK_global_user_stats);
-+  for (int i = 0; i < global_user_stats.records; ++i) {
-+    restore_record(table, s->default_values);
-+    USER_STATS *user_stats = (USER_STATS*)hash_element(&global_user_stats, i);
-+    table->field[0]->store(user_stats->user, strlen(user_stats->user), system_charset_info);
-+    table->field[1]->store((longlong)user_stats->total_connections, TRUE);
-+    table->field[2]->store((longlong)user_stats->concurrent_connections, TRUE);
-+    table->field[3]->store((longlong)user_stats->connected_time, TRUE);
-+    table->field[4]->store((longlong)user_stats->busy_time, TRUE);
-+    table->field[5]->store((longlong)user_stats->rows_fetched, TRUE);
-+    table->field[6]->store((longlong)user_stats->rows_updated, TRUE);
-+    table->field[7]->store((longlong)user_stats->select_commands, TRUE);
-+    table->field[8]->store((longlong)user_stats->update_commands, TRUE);
-+    table->field[9]->store((longlong)user_stats->other_commands, TRUE);
-+    table->field[10]->store((longlong)user_stats->commit_trans, TRUE);
-+    table->field[11]->store((longlong)user_stats->rollback_trans, TRUE);
-+
-+    if (schema_table_store_record(thd, table))
-+    {
-+      VOID(pthread_mutex_unlock(&LOCK_global_user_stats));
-+      DBUG_RETURN(1);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_global_user_stats);
-+  DBUG_RETURN(0);
-+}
-+
-+
-+int fill_schema_table_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_table_stats");
-+
-+  pthread_mutex_lock(&LOCK_global_table_stats);
-+  for (int i = 0; i < global_table_stats.records; ++i) {
-+    restore_record(table, s->default_values);
-+    TABLE_STATS *table_stats = 
-+      (TABLE_STATS*)hash_element(&global_table_stats, i);
-+    table->field[0]->store(table_stats->table, strlen(table_stats->table), system_charset_info);
-+    table->field[1]->store((longlong)table_stats->rows_read, TRUE);
-+    table->field[2]->store((longlong)table_stats->rows_changed, TRUE);
-+    table->field[3]->store((longlong)table_stats->rows_changed_x_indexes, TRUE);
-+
-+    if (schema_table_store_record(thd, table))
-+    {
-+      VOID(pthread_mutex_unlock(&LOCK_global_table_stats));
-+      DBUG_RETURN(1);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_global_table_stats);
-+  DBUG_RETURN(0);
-+}
-+
-+
-+int fill_schema_index_stats(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+  TABLE *table= tables->table;
-+  DBUG_ENTER("fill_schema_index_stats");
-+
-+  pthread_mutex_lock(&LOCK_global_index_stats);
-+  for (int i = 0; i < global_index_stats.records; ++i) {
-+    restore_record(table, s->default_values);
-+    INDEX_STATS *index_stats = 
-+      (INDEX_STATS*)hash_element(&global_index_stats, i);
-+    table->field[0]->store(index_stats->index, strlen(index_stats->index), system_charset_info);
-+    table->field[1]->store((longlong)index_stats->rows_read, TRUE);
-+
-+    if (schema_table_store_record(thd, table))
-+    {
-+      VOID(pthread_mutex_unlock(&LOCK_global_index_stats));
-+      DBUG_RETURN(1);
-+    }
-+  }
-+  pthread_mutex_unlock(&LOCK_global_index_stats);
-+  DBUG_RETURN(0);
-+}
- /* collect status for all running threads */
-@@ -6606,6 +6690,38 @@
-   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
- };
-+ST_FIELD_INFO user_stats_fields_info[]=
-+{
-+  {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
-+  {"TOTAL_CONNECTIONS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Total_connections", SKIP_OPEN_TABLE},
-+  {"CONCURRENT_CONNECTIONS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Concurrent_connections", SKIP_OPEN_TABLE},
-+  {"CONNECTED_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Connected_time", SKIP_OPEN_TABLE},
-+  {"BUSY_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Busy_time", SKIP_OPEN_TABLE},
-+  {"ROWS_FETCHED", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_fetched", SKIP_OPEN_TABLE},
-+  {"ROWS_UPDATED", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_updated", SKIP_OPEN_TABLE},
-+  {"SELECT_COMMANDS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Select_commands", SKIP_OPEN_TABLE},
-+  {"UPDATE_COMMANDS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Update_commands", SKIP_OPEN_TABLE},
-+  {"OTHER_COMMANDS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Other_commands", SKIP_OPEN_TABLE},
-+  {"COMMIT_TRANSACTIONS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Commit_transactions", SKIP_OPEN_TABLE},
-+  {"ROLLBACK_TRANSACTIONS", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rollback_transactions", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+ST_FIELD_INFO table_stats_fields_info[]=
-+{
-+  {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name", SKIP_OPEN_TABLE},
-+  {"ROWS_READ", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_read", SKIP_OPEN_TABLE},
-+  {"ROWS_CHANGED", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_changed", SKIP_OPEN_TABLE},
-+  {"ROWS_CHANGED_INDEXES", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_changed_x_#indexes", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+ST_FIELD_INFO index_stats_fields_info[]=
-+{
-+  {"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name", SKIP_OPEN_TABLE},
-+  {"ROWS_READ", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Rows_read", SKIP_OPEN_TABLE},
-+  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
- /*
-   Description of ST_FIELD_INFO in table.h
-@@ -6824,6 +6824,8 @@
-    fill_status, make_old_format, 0, 0, -1, 0, 0},
-   {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
-    fill_variables, make_old_format, 0, 0, -1, 0, 0},
-+  {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
-+   fill_schema_index_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
-    get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
-    OPEN_TABLE_ONLY},
-@@ -6683,11 +6801,15 @@
-    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},
-+  {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
-+   fill_schema_table_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"TRIGGERS", triggers_fields_info, create_schema_table,
-    get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
-    OPEN_TABLE_ONLY},
-   {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, 
-    fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
-+  {"USER_STATISTICS", user_stats_fields_info, create_schema_table, 
-+   fill_schema_user_stats, make_old_format, 0, -1, -1, 0, 0},
-   {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
-    make_old_format, 0, -1, -1, 1, 0},
-   {"VIEWS", view_fields_info, create_schema_table, 
-diff -r 3ed7e96969f9 sql/sql_update.cc
---- a/sql/sql_update.cc        Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_update.cc        Thu Dec 04 08:54:27 2008 -0800
-@@ -816,6 +816,7 @@
-     thd->row_count_func=
-       (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-     my_ok(thd, (ulong) thd->row_count_func, id, buff);
-+    thd->updated_row_count += thd->row_count_func;
-     DBUG_PRINT("info",("%ld records updated", (long) updated));
-   }
-   thd->count_cuted_fields= CHECK_FIELD_IGNORE;                /* calc cuted fields */
-@@ -2038,5 +2039,6 @@
-   thd->row_count_func=
-     (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-   ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
-+  thd->updated_row_count += thd->row_count_func;
-   DBUG_RETURN(FALSE);
- }
-diff -r 3ed7e96969f9 sql/sql_yacc.yy
---- a/sql/sql_yacc.yy  Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/sql_yacc.yy  Thu Dec 04 08:54:27 2008 -0800
-@@ -738,6 +738,7 @@
- %token  IMPORT
- %token  INDEXES
- %token  INDEX_SYM
-+%token        INDEX_STATS_SYM
- %token  INFILE
- %token  INITIAL_SIZE_SYM
- %token  INNER_SYM                     /* SQL-2003-R */
-@@ -1026,6 +1027,7 @@
- %token  TABLE_REF_PRIORITY
- %token  TABLE_SYM                     /* SQL-2003-R */
- %token  TABLE_CHECKSUM_SYM
-+%token        TABLE_STATS_SYM
- %token  TEMPORARY                     /* SQL-2003-N */
- %token  TEMPTABLE_SYM
- %token  TERMINATED
-@@ -1071,6 +1073,7 @@
- %token  UPGRADE_SYM
- %token  USAGE                         /* SQL-2003-N */
- %token  USER                          /* SQL-2003-R */
-+%token        USER_STATS_SYM
- %token  USE_FRM
- %token  USE_SYM
- %token  USING                         /* SQL-2003-R */
-@@ -10090,6 +10093,27 @@
-           {
-             Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
-           }
-+        | USER_STATS_SYM wild_and_where
-+          {
-+             LEX *lex= Lex;
-+             lex->sql_command= SQLCOM_SHOW_USER_STATS;
-+             if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
-+               MYSQL_YYABORT;
-+          }
-+        | TABLE_STATS_SYM wild_and_where
-+          {
-+             LEX *lex= Lex;
-+             lex->sql_command= SQLCOM_SHOW_TABLE_STATS;
-+             if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
-+               MYSQL_YYABORT;
-+          }
-+        | INDEX_STATS_SYM wild_and_where
-+          {
-+             LEX *lex= Lex;
-+             lex->sql_command= SQLCOM_SHOW_INDEX_STATS;
-+             if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
-+               MYSQL_YYABORT;
-+          }
-         | CREATE PROCEDURE sp_name
-           {
-             LEX *lex= Lex;
-@@ -10304,6 +10328,10 @@
-           { Lex->type|= REFRESH_DES_KEY_FILE; }
-         | RESOURCES
-           { Lex->type|= REFRESH_USER_RESOURCES; }
-+        | TABLE_STATS_SYM
-+          { Lex->type|= REFRESH_TABLE_STATS; }
-+        | INDEX_STATS_SYM
-+          { Lex->type|= REFRESH_INDEX_STATS; }
-         ;
- opt_table_list:
-diff -r 3ed7e96969f9 sql/structs.h
---- a/sql/structs.h    Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/structs.h    Thu Dec 04 08:54:27 2008 -0800
-@@ -226,6 +226,28 @@
-   /* Maximum amount of resources which account is allowed to consume. */
-   USER_RESOURCES user_resources;
- } USER_CONN;
-+
-+typedef struct st_user_stats {
-+  char user[USERNAME_LENGTH + 1];
-+  uint total_connections;
-+  uint concurrent_connections;
-+  time_t connected_time;  // in seconds
-+  double busy_time;       // in seconds
-+  ha_rows rows_fetched, rows_updated;
-+  ulonglong select_commands, update_commands, other_commands;
-+  ulonglong commit_trans, rollback_trans;
-+} USER_STATS;
-+
-+typedef struct st_table_stats {
-+  char table[NAME_LEN * 2 + 2];  // [db] + '.' + [table] + '\0'
-+  ulonglong rows_read, rows_changed;
-+  ulonglong rows_changed_x_indexes;
-+} TABLE_STATS;
-+
-+typedef struct st_index_stats {
-+  char index[NAME_LEN * 3 + 3];  // [db] + '.' + [table] + '.' + [index] + '\0'
-+  ulonglong rows_read;
-+} INDEX_STATS;
-       /* Bits in form->update */
- #define REG_MAKE_DUPP         1       /* Make a copy of record when read */
-diff -r 3ed7e96969f9 sql/table.h
---- a/sql/table.h      Thu Dec 04 08:54:17 2008 -0800
-+++ b/sql/table.h      Thu Dec 04 08:54:27 2008 -0800
-@@ -879,6 +879,7 @@
-   SCH_FILES,
-   SCH_GLOBAL_STATUS,
-   SCH_GLOBAL_VARIABLES,
-+  SCH_INDEX_STATS,
-   SCH_KEY_COLUMN_USAGE,
-   SCH_OPEN_TABLES,
-   SCH_PARTITIONS,
-@@ -897,8 +898,10 @@
-   SCH_TABLE_CONSTRAINTS,
-   SCH_TABLE_NAMES,
-   SCH_TABLE_PRIVILEGES,
-+  SCH_TABLE_STATS,
-   SCH_TRIGGERS,
-   SCH_USER_PRIVILEGES,
-+  SCH_USER_STATS,
-   SCH_VARIABLES,
-   SCH_VIEWS
- };
-diff -r 3ed7e96969f9 storage/innobase/handler/ha_innodb.cc
---- a/storage/innobase/handler/ha_innodb.cc    Thu Dec 04 08:54:17 2008 -0800
-+++ b/storage/innobase/handler/ha_innodb.cc    Thu Dec 04 08:54:27 2008 -0800
-@@ -3494,6 +3494,8 @@
-       error = row_insert_for_mysql((byte*) record, prebuilt);
-+  if (error == DB_SUCCESS) rows_changed++;
-+
-       /* Handle duplicate key errors */
-       if (auto_inc_used) {
-               ulint           err;
-@@ -3571,6 +3573,8 @@
-                       break;
-               }
-       }
-+
-+      if (error == DB_SUCCESS) rows_changed++;
-       innodb_srv_conc_exit_innodb(prebuilt->trx);
-@@ -4178,6 +4182,8 @@
-               ret = row_search_for_mysql((byte*) buf, mode, prebuilt,
-                                          match_mode, 0);
-+      if (error == DB_SUCCESS) rows_changed++;
-+
-               innodb_srv_conc_exit_innodb(prebuilt->trx);
-       } else {
-@@ -4187,6 +4193,9 @@
-       if (ret == DB_SUCCESS) {
-               error = 0;
-               table->status = 0;
-+              rows_read++;
-+              if (active_index >= 0 && active_index < MAX_KEY)
-+                      index_rows_read[active_index]++;
-       } else if (ret == DB_RECORD_NOT_FOUND) {
-               error = HA_ERR_KEY_NOT_FOUND;
-@@ -4360,6 +4369,9 @@
-       if (ret == DB_SUCCESS) {
-               error = 0;
-               table->status = 0;
-+              rows_read++;
-+              if (active_index >= 0 && active_index < MAX_KEY)
-+                      index_rows_read[active_index]++;
-       } else if (ret == DB_RECORD_NOT_FOUND) {
-               error = HA_ERR_END_OF_FILE;
-diff -r 3ed7e96969f9 storage/myisam/ha_myisam.cc
---- a/storage/myisam/ha_myisam.cc      Thu Dec 04 08:54:17 2008 -0800
-+++ b/storage/myisam/ha_myisam.cc      Thu Dec 04 08:54:27 2008 -0800
-@@ -738,7 +738,9 @@
-     if ((error= update_auto_increment()))
-       return error;
-   }
--  return mi_write(file,buf);
-+  int error=mi_write(file,buf);
-+  if (!error) rows_changed++;
-+  return error;
- }
- int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
-@@ -1589,13 +1591,17 @@
-   ha_statistic_increment(&SSV::ha_update_count);
-   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
-     table->timestamp_field->set_time();
--  return mi_update(file,old_data,new_data);
-+  int error=mi_update(file,old_data,new_data);
-+  if (!error) rows_changed++;
-+  return error;
- }
- int ha_myisam::delete_row(const uchar *buf)
- {
-   ha_statistic_increment(&SSV::ha_delete_count);
--  return mi_delete(file,buf);
-+  int error=mi_delete(file,buf);
-+  if (!error) rows_changed++;
-+  return error;
- }
- int ha_myisam::index_read_map(uchar *buf, const uchar *key,
-@@ -1606,6 +1612,13 @@
-   ha_statistic_increment(&SSV::ha_read_key_count);
-   int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1616,6 +1629,14 @@
-   ha_statistic_increment(&SSV::ha_read_key_count);
-   int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+//    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    int inx = index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1637,6 +1658,13 @@
-   ha_statistic_increment(&SSV::ha_read_next_count);
-   int error=mi_rnext(file,buf,active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1646,6 +1674,13 @@
-   ha_statistic_increment(&SSV::ha_read_prev_count);
-   int error=mi_rprev(file,buf, active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1655,6 +1690,13 @@
-   ha_statistic_increment(&SSV::ha_read_first_count);
-   int error=mi_rfirst(file, buf, active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1664,6 +1706,13 @@
-   ha_statistic_increment(&SSV::ha_read_last_count);
-   int error=mi_rlast(file, buf, active_index);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1679,6 +1728,20 @@
-     error= mi_rnext_same(file,buf);
-   } while (error == HA_ERR_RECORD_DELETED);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-+  if (!error) {
-+    rows_read++;
-+
-+    int inx = (active_index == -1) ? file->lastinx : active_index;
-+    if (inx >= 0 && inx < MAX_KEY)
-+      index_rows_read[inx]++;
-+  }
-   return error;
- }
-@@ -1695,6 +1758,7 @@
-   ha_statistic_increment(&SSV::ha_read_rnd_next_count);
-   int error=mi_scan(file, buf);
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) rows_read++;
-   return error;
- }
-@@ -1708,6 +1772,7 @@
-   ha_statistic_increment(&SSV::ha_read_rnd_count);
-   int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
-   table->status=error ? STATUS_NOT_FOUND: 0;
-+  if (!error) rows_read++;
-   return error;
- }
index 0580524f914f3295e1bfa91c570b84393b626df5..c9e54a351063df9ca181bf05a5335e4e74a8723a 100644 (file)
@@ -8,6 +8,10 @@
 # - segfaults on select from non-mysql user (caused by builder environment):
 #     https://bugs.launchpad.net/pld-linux/+bug/381904
 #     (profiling disabled temporaily to workaround this)
+# - add avoid-version for:
+#        /usr/lib64/mysql/plugin/mypluglib.so
+#        /usr/lib64/mysql/plugin/mypluglib.so.0
+#        /usr/lib64/mysql/plugin/mypluglib.so.0.0.0
 #
 # Conditional build:
 %bcond_with    autodeps        # BR packages needed only for resolving deps
@@ -21,6 +25,8 @@
 %bcond_with    tests           # FIXME: don't run correctly
 %bcond_with    ndb             # NDB is now a separate product, this here is broken, so disable it
 
+%define                rel     1
+%define                percona_rel     14.8
 %include       /usr/lib/rpm/macros.perl
 Summary:       MySQL: a very fast and reliable SQL database engine
 Summary(de.UTF-8):     MySQL: ist eine SQL-Datenbank
@@ -31,13 +37,13 @@ Summary(ru.UTF-8):  MySQL - быстрый SQL-сервер
 Summary(uk.UTF-8):     MySQL - швидкий SQL-сервер
 Summary(zh_CN.UTF-8):  MySQL数据库服务器
 Name:          mysql
-Version:       5.1.63
-Release:       0.1
+Version:       5.1.70
+Release:       %{percona_rel}.%{rel}
 License:       GPL + MySQL FLOSS Exception
 Group:         Applications/Databases
-#Source0Download: http://dev.mysql.com/downloads/mysql/5.1.html#source
-Source0:       http://vesta.informatik.rwth-aachen.de/mysql/Downloads/MySQL-5.1/%{name}-%{version}.tar.gz
-# Source0-md5: 672167c3f03f969febae66c43859d76d
+# Source0Download: http://www.percona.com/downloads/Percona-Server-5.1/LATEST/source/
+Source0:       http://www.percona.com/downloads/Percona-Server-5.1/LATEST/source/Percona-Server-%{version}-rel%{percona_rel}.tar.gz
+# Source0-md5: 164230ac7b449eb69f0918fc5b8b09f2
 Source100:     http://www.sphinxsearch.com/downloads/sphinx-0.9.9.tar.gz
 # Source100-md5:       7b9b618cb9b378f949bb1b91ddcc4f54
 Source1:       %{name}.init
@@ -53,15 +59,12 @@ Source11:   %{name}-ndb-cpc.init
 Source12:      %{name}-ndb-cpc.sysconfig
 Source13:      %{name}-client.conf
 Source14:      my.cnf
-Source15:      percona.sh
 Patch0:                %{name}-libs.patch
 Patch1:                %{name}-libwrap.patch
 Patch2:                %{name}-c++.patch
-Patch3:                %{name}-info.patch
 Patch4:                %{name}-sql-cxx-pic.patch
 Patch5:                %{name}-noproc.patch
 Patch6:                %{name}-system-users.patch
-Patch7:                %{name}-bug-34192.patch
 Patch8:                %{name}-client-config.patch
 Patch9:                %{name}-build.patch
 Patch10:       %{name}-alpha.patch
@@ -72,75 +75,6 @@ Patch14:     %{name}-bug-43594.patch
 Patch15:       plugin-avoid-version.patch
 Patch16:       %{name}-fix-dummy-thread-race-condition.patch
 Patch18:       %{name}-sphinx.patch
-# <percona patches, http://www.percona.com/percona-lab.html>
-Patch100:      %{name}-innodb_swap_builtin_plugin.patch
-Patch101:      %{name}-show_patches.patch
-Patch102:      %{name}-slow_extended.patch
-Patch103:      %{name}-profiling_slow.patch
-Patch104:      %{name}-microsec_process.patch
-Patch105:      %{name}-userstat.patch
-Patch106:      %{name}-optimizer_fix.patch
-Patch107:      %{name}-show_temp_51.patch
-Patch108:      %{name}-suppress_log_warning_1592.patch
-Patch109:      %{name}-innodb_show_enhancements.patch
-Patch110:      %{name}-innodb_show_status.patch
-Patch111:      %{name}-innodb_io_patches.patch
-Patch112:      %{name}-innodb_opt_lru_count.patch
-Patch113:      %{name}-i_s_innodb_buffer_pool_pages.patch
-Patch114:      %{name}-innodb_expand_undo_slots.patch
-Patch115:      %{name}-innodb_extra_rseg.patch
-Patch116:      %{name}-innodb_overwrite_relay_log_info.patch
-Patch117:      %{name}-innodb_thread_concurrency_timer_based.patch
-Patch118:      %{name}-innodb_dict_size_limit.patch
-Patch119:      %{name}-innodb_split_buf_pool_mutex.patch
-Patch120:      %{name}-innodb_expand_import.patch
-Patch121:      %{name}-innodb_recovery_patches.patch
-Patch122:      %{name}-innodb_purge_thread.patch
-Patch123:      %{name}-innodb_admin_command_base.patch
-Patch124:      %{name}-innodb_show_lock_name.patch
-Patch125:      %{name}-innodb_extend_slow.patch
-Patch126:      %{name}-innodb_lru_dump_restore.patch
-Patch127:      %{name}-innodb_separate_doublewrite.patch
-Patch128:      %{name}-innodb_pass_corrupt_table.patch
-Patch129:      %{name}-innodb_stats.patch
-Patch130:      %{name}-innodb_fast_checksum.patch
-Patch131:      %{name}-innodb_files_extend.patch
-Patch132:      %{name}-innodb_show_sys_tables.patch
-Patch133:      %{name}-innodb_fix_misc.patch
-Patch134:      %{name}-innodb_adjust_defaults.patch
-Patch135:      innodb_kill_idle_transaction.patch
-Patch136:      innodb_fake_changes.patch
-Patch137:      %{name}-innodb_deadlock_count.patch
-Patch138:      %{name}-bug580324.patch
-Patch139:      %{name}-bugfix48929.patch
-Patch140:      %{name}-query_cache_enhance.patch
-Patch141:      %{name}-control_online_alter_index.patch
-Patch142:      %{name}-log_connection_error.patch
-Patch143:      %{name}-mysql-syslog.patch
-Patch144:      %{name}-innodb_buffer_pool_shm.patch
-Patch145:      %{name}-error_pad.patch
-Patch146:      response_time_distribution.patch
-Patch147:      %{name}-remove_fcntl_excessive_calls.patch
-Patch148:      %{name}-sql_no_fcache.patch
-Patch149:      %{name}-show_slave_status_nolock.patch
-Patch150:      %{name}-innodb_fast_shutdown.patch
-Patch151:      %{name}-bug677407.patch
-Patch152:      %{name}-fix-bug671764.patch
-Patch153:      %{name}-mysql_remove_eol_carret.patch
-Patch154:      %{name}-innodb_expand_fast_index_creation.patch
-Patch155:      %{name}-innodb_bug60788.patch
-Patch156:      slave_timeout_fix.patch
-Patch157:      utf8_general50_ci.patch
-Patch158:      bug813587.patch
-Patch159:      innodb_bug47167_test_fix.patch
-Patch160:      disable_query_cache_28249_test_sporadic_failure.patch
-Patch161:      bug53761.patch
-Patch162:      xtradb_bug317074.patch
-Patch163:      subunit.patch
-Patch164:      warning_fixes.patch
-Patch165:      bug860910.patch
-Patch166:      bug45702.patch
-# </percona>
 URL:           http://www.mysql.com/products/community/
 BuildRequires: autoconf
 BuildRequires: automake
@@ -556,7 +490,7 @@ This package contains the standard MySQL NDB CPC Daemon.
 Ten pakiet zawiera standardowego demona MySQL NDB CPC.
 
 %prep
-%setup -q %{?with_sphinx:-a100}
+%setup -q -n Percona-Server-%{version}-rel%{percona_rel} %{?with_sphinx:-a100}
 %if %{with sphinx}
 # http://www.sphinxsearch.com/docs/manual-0.9.9.html#sphinxse-mysql51
 mv sphinx-*/mysqlse storage/sphinx
@@ -564,8 +498,7 @@ mv sphinx-*/mysqlse storage/sphinx
 %endif
 %patch0 -p1
 #%{?with_tcpd:%patch1 -p1}  # WHATS PURPOSE OF THIS PATCH?
-#%patch2 -p1 # NEEDS CHECK, which exact program needs -lc++
-%patch3 -p1
+#patch2 -p1 # NEEDS CHECK, which exact program needs -lc++
 %ifarch alpha
 # this is strange: mysqld functions for UDF modules are not explicitly defined,
 # so -rdynamic is used; in such case gcc3+ld on alpha doesn't like C++ vtables
@@ -576,7 +509,6 @@ mv sphinx-*/mysqlse storage/sphinx
 %endif
 %patch5 -p1
 %patch6 -p1
-%patch7 -p1
 %patch8 -p1
 %patch9 -p1
 %patch11 -p1
@@ -587,75 +519,6 @@ mv sphinx-*/mysqlse storage/sphinx
 %patch14 -p0
 %patch15 -p1
 %patch16 -p1
-# <percona %patches>
-%patch100 -p1
-%patch101 -p1
-%patch102 -p1
-%patch103 -p1
-%patch104 -p1
-%patch105 -p1
-%patch106 -p1
-%patch107 -p1
-%patch108 -p1
-%patch109 -p1
-%patch110 -p1
-%patch111 -p1
-%patch112 -p1
-%patch113 -p1
-%patch114 -p1
-%patch115 -p1
-%patch116 -p1
-%patch117 -p1
-%patch118 -p1
-%patch119 -p1
-%patch120 -p1
-%patch121 -p1
-%patch122 -p1
-%patch123 -p1
-%patch124 -p1
-%patch125 -p1
-%patch126 -p1
-%patch127 -p1
-%patch128 -p1
-%patch129 -p1
-%patch130 -p1
-%patch131 -p1
-%patch132 -p1
-%patch133 -p1
-%patch134 -p1
-%patch135 -p1
-%patch136 -p1
-%patch137 -p1
-%patch138 -p1
-%patch139 -p1
-%patch140 -p1
-%patch141 -p1
-%patch142 -p1
-%patch143 -p1
-%patch144 -p1
-%patch145 -p1
-%patch146 -p1
-%patch147 -p1
-%patch148 -p1
-%patch149 -p1
-%patch150 -p1
-%patch151 -p1
-%patch152 -p1
-%patch153 -p1
-%patch154 -p1
-%patch155 -p1
-%patch156 -p1
-%patch157 -p1
-%patch158 -p1
-%patch159 -p1
-%patch160 -p1
-%patch161 -p1
-%patch162 -p1
-%patch163 -p1
-%patch164 -p1
-%patch165 -p1
-%patch166 -p1
-# </percona>
 
 %build
 %if "%{pld_release}" == "ac"
@@ -725,15 +588,13 @@ echo -e "all:\ninstall:\nclean:\nlink_sources:\n" > libmysqld/examples/Makefile
 %{__make} \
        benchdir=$RPM_BUILD_ROOT%{_datadir}/sql-bench
 
-%{__make} -C Docs mysql.info
-
 %{?with_tests:%{__make} test}
 
 %install
 rm -rf $RPM_BUILD_ROOT
 install -d $RPM_BUILD_ROOT/etc/{logrotate.d,rc.d/init.d,sysconfig,mysql,skel} \
           $RPM_BUILD_ROOT/var/{log/{archive,}/mysql,lib/mysql} \
-          $RPM_BUILD_ROOT{%{_infodir},%{_mysqlhome}}
+          $RPM_BUILD_ROOT%{_mysqlhome}
 
 # Make install
 %{__make} install \
@@ -742,8 +603,6 @@ install -d $RPM_BUILD_ROOT/etc/{logrotate.d,rc.d/init.d,sysconfig,mysql,skel} \
        libsdir=/tmp
 # libsdir is to avoid installing innodb static libs in $RPM_BUILD_ROOT../libs
 
-install Docs/mysql.info $RPM_BUILD_ROOT%{_infodir}
-
 install %{SOURCE1} $RPM_BUILD_ROOT/etc/rc.d/init.d/mysql
 install %{SOURCE2} $RPM_BUILD_ROOT/etc/sysconfig/mysql
 install %{SOURCE3} $RPM_BUILD_ROOT/etc/logrotate.d/mysql
@@ -827,7 +686,9 @@ rm $RPM_BUILD_ROOT%{_mandir}/man1/mysqlman.1*
 rm $RPM_BUILD_ROOT%{_bindir}/resolveip
 rm $RPM_BUILD_ROOT%{_mandir}/man1/resolveip.1*
 rm $RPM_BUILD_ROOT%{_mandir}/man1/comp_err.1*
-rm $RPM_BUILD_ROOT%{_datadir}/mysql/ChangeLog
+# not an .info file
+%{__rm} $RPM_BUILD_ROOT/usr/share/info/mysql.info
+
 
 # we don't package those (we have no -test or -testsuite pkg) and some of them just segfault
 rm $RPM_BUILD_ROOT%{_bindir}/mysql_client_test
@@ -846,6 +707,8 @@ rm $RPM_BUILD_ROOT%{_datadir}/%{name}/*.{ini,cnf}
 rm -f $RPM_BUILD_ROOT%{_libdir}/mysql/plugin/ha_*.{a,la}
 rm -f $RPM_BUILD_ROOT%{_libdir}/mysql/plugin/ha_example.*
 rm -f $RPM_BUILD_ROOT%{_libdir}/mysql/plugin/sphinx.{a,la}
+%{__rm} $RPM_BUILD_ROOT%{_libdir}/%{name}/plugin/mypluglib.{a,la}
+%{__rm} $RPM_BUILD_ROOT%{_libdir}/%{name}/plugin/libdaemon_example.*
 
 %clean
 rm -rf $RPM_BUILD_ROOT
@@ -855,7 +718,6 @@ rm -rf $RPM_BUILD_ROOT
 %useradd -u 89 -d %{_mysqlhome} -s /bin/sh -g mysql -c "MySQL Server" mysql
 
 %post
-[ ! -x /usr/sbin/fix-info-dir ] || /usr/sbin/fix-info-dir -c %{_infodir} >/dev/null 2>&1
 /sbin/chkconfig --add mysql
 %service mysql restart
 
@@ -866,8 +728,6 @@ if [ "$1" = "0" ]; then
 fi
 
 %postun
-[ ! -x /usr/sbin/fix-info-dir ] || /usr/sbin/fix-info-dir -c %{_infodir} >/dev/null 2>&1
-
 if [ "$1" = "0" ]; then
        %userremove mysql
        %groupremove mysql
@@ -999,7 +859,7 @@ done
 
 %files
 %defattr(644,root,root,755)
-%doc support-files/*.cnf support-files/*.ini ChangeLog
+%doc support-files/*.cnf support-files/*.ini
 %attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/logrotate.d/mysql
 %attr(754,root,root) /etc/rc.d/init.d/mysql
 %attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/sysconfig/mysql
@@ -1017,6 +877,7 @@ done
 %dir %{_libdir}/mysql
 %dir %{_libdir}/mysql/plugin
 %attr(755,root,root) %{_libdir}/mysql/plugin/ha_innodb.so
+%attr(755,root,root) %{_libdir}/mysql/plugin/mypluglib.*
 %if %{with sphinx}
 %attr(755,root,root) %{_libdir}/mysql/plugin/sphinx.so
 %endif
@@ -1044,7 +905,6 @@ done
 %attr(750,mysql,mysql) %dir /var/log/archive/mysql
 %attr(640,mysql,mysql) %ghost /var/log/mysql/*
 
-%{_infodir}/mysql.info*
 # This is template for configuration file which is created after 'service mysql init'
 %{_datadir}/mysql/mysqld.conf
 %{_datadir}/mysql/mysql_system_tables.sql
diff --git a/response_time_distribution.patch b/response_time_distribution.patch
deleted file mode 100644 (file)
index 170151e..0000000
+++ /dev/null
@@ -1,4842 +0,0 @@
-# name       : response-time-distribution.patch
-# introduced : 12
-# maintainer : Oleg
-#
-#!!! notice !!!
-# Any small change to this file in the main branch
-# should be done or reviewed by the maintainer!
---- a/include/mysql_com.h
-+++ b/include/mysql_com.h
-@@ -132,6 +132,7 @@
- #define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */
- #define REFRESH_DES_KEY_FILE  0x40000L
- #define REFRESH_USER_RESOURCES        0x80000L
-+#define REFRESH_QUERY_RESPONSE_TIME 0x100000L /* response time distibution */
- #define CLIENT_LONG_PASSWORD  1       /* new more secure passwords */
- #define CLIENT_FOUND_ROWS     2       /* Found instead of affected rows */
---- /dev/null
-+++ b/mysql-test/include/have_response_time_distribution.inc
-@@ -0,0 +1,4 @@
-+-- require r/have_response_time_distribution.require
-+disable_query_log;
-+show variables like 'have_response_time_distribution';
-+enable_query_log;
---- /dev/null
-+++ b/mysql-test/r/have_response_time_distribution.require
-@@ -0,0 +1,2 @@
-+Variable_name Value
-+have_response_time_distribution       YES
---- /dev/null
-+++ b/mysql-test/include/query_response_time.inc
-@@ -0,0 +1,43 @@
-+SET SESSION query_exec_time=0.1;
-+
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+EVAL SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=$base;
-+# Following two queries check works of FLUSH and 
-+# respecting of "QUERY_RESPONSE_TIME_STATS" variable (see launchpad bug #855312)
-+FLUSH QUERY_RESPONSE_TIME;
-+SHOW QUERY_RESPONSE_TIME;
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+
-+SET SESSION query_exec_time=0.31; SELECT 1;
-+SET SESSION query_exec_time=0.32; SELECT 1;
-+SET SESSION query_exec_time=0.33; SELECT 1;
-+SET SESSION query_exec_time=0.34; SELECT 1;
-+SET SESSION query_exec_time=0.35; SELECT 1;
-+SET SESSION query_exec_time=0.36; SELECT 1;
-+SET SESSION query_exec_time=0.37; SELECT 1;
-+SET SESSION query_exec_time=0.38; SELECT 1;
-+SET SESSION query_exec_time=0.39; SELECT 1;
-+SET SESSION query_exec_time=0.4; SELECT 1;
-+SET SESSION query_exec_time=1.1; SELECT 1;
-+SET SESSION query_exec_time=1.2; SELECT 1;
-+SET SESSION query_exec_time=1.3; SELECT 1;
-+SET SESSION query_exec_time=1.5; SELECT 1;
-+SET SESSION query_exec_time=1.4; SELECT 1;
-+SET SESSION query_exec_time=0.5; SELECT 1;
-+SET SESSION query_exec_time=2.1; SELECT 1;
-+SET SESSION query_exec_time=2.3; SELECT 1;
-+SET SESSION query_exec_time=2.5; SELECT 1;
-+SET SESSION query_exec_time=3.1; SELECT 1;
-+SET SESSION query_exec_time=4.1; SELECT 1;
-+SET SESSION query_exec_time=5.1; SELECT 1;
-+
-+SET SESSION query_exec_time=0.1;
-+
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+SHOW QUERY_RESPONSE_TIME;
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+
-+SET SESSION query_exec_time=default;
---- /dev/null
-+++ b/mysql-test/include/query_response_time-replication.inc
-@@ -0,0 +1,58 @@
-+connection master;
-+
-+CREATE TABLE t(id INT);
-+sync_slave_with_master;
-+
-+connection slave;
-+SET GLOBAL query_exec_time=0.1;
-+--source include/restart_slave_sql.inc
-+
-+connection slave;
-+
-+SET SESSION query_exec_time=0.1;
-+
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+--eval SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=$base
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+
-+connection master;
-+
-+SET SESSION query_exec_time = 0.31; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.32; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.33; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.34; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.35; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.36; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.37; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.38; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.39; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.4; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.1; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.2; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.3; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.5; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.4; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.5; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.1; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.3; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.5; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 3.1; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 4.1; INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 5.1; INSERT INTO t VALUES(1);
-+
-+sync_slave_with_master;
-+
-+connection slave;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+SHOW QUERY_RESPONSE_TIME;
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+
-+connection master;
-+DROP TABLE t;
-+
-+sync_slave_with_master;
---- /dev/null
-+++ b/mysql-test/include/query_response_time-stored.inc
-@@ -0,0 +1,37 @@
-+SET SESSION query_exec_time=0.1;
-+
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+EVAL SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=$base;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+
-+CALL test_f(0.31);
-+CALL test_f(0.32);
-+CALL test_f(0.33);
-+CALL test_f(0.34);
-+CALL test_f(0.35);
-+CALL test_f(0.36);
-+CALL test_f(0.37);
-+CALL test_f(0.38);
-+CALL test_f(0.39);
-+CALL test_f(0.4);
-+CALL test_f(1.1);
-+CALL test_f(1.2);
-+CALL test_f(1.3);
-+CALL test_f(1.5);
-+CALL test_f(1.4);
-+CALL test_f(0.5);
-+CALL test_f(2.1);
-+CALL test_f(2.3);
-+CALL test_f(2.5);
-+CALL test_f(3.1);
-+CALL test_f(4.1);
-+CALL test_f(5.1);
-+
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+SHOW QUERY_RESPONSE_TIME;
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+
-+SET SESSION query_exec_time=default;
---- /dev/null
-+++ b/mysql-test/r/percona_query_response_time-replication.result
-@@ -0,0 +1,727 @@
-+SET GLOBAL query_exec_time=0.1;
-+include/master-slave.inc
-+[connection master]
-+CREATE TABLE t(id INT);
-+SET GLOBAL query_exec_time=0.1;
-+include/restart_slave.inc
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_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;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time = 0.31;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.32;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.33;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.34;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.35;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.36;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.37;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.38;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.39;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.2;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 3.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 4.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 5.1;
-+INSERT INTO t VALUES(1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        2
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        1             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        1             0.100000
-+      0.250000        0             0.000000
-+      0.500000        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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        1             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        1             0.100000
-+      0.250000        0             0.000000
-+      0.500000        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+DROP TABLE t;
-+CREATE TABLE t(id INT);
-+SET GLOBAL query_exec_time=0.1;
-+include/restart_slave.inc
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=2;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time = 0.31;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.32;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.33;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.34;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.35;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.36;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.37;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.38;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.39;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.2;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 3.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 4.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 5.1;
-+INSERT INTO t VALUES(1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        2
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        1             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        1             0.100000
-+      0.250000        0             0.000000
-+      0.500000        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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        1             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        1             0.100000
-+      0.250000        0             0.000000
-+      0.500000        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+DROP TABLE t;
-+CREATE TABLE t(id INT);
-+SET GLOBAL query_exec_time=0.1;
-+include/restart_slave.inc
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=10;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time = 0.31;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.32;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.33;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.34;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.35;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.36;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.37;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.38;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.39;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.2;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 3.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 4.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 5.1;
-+INSERT INTO t VALUES(1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        10
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      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        12            4.150000
-+     10.000000        11           25.700000
-+    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        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        12            4.150000
-+     10.000000        11           25.700000
-+    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_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+DROP TABLE t;
-+CREATE TABLE t(id INT);
-+SET GLOBAL query_exec_time=0.1;
-+include/restart_slave.inc
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=7;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time = 0.31;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.32;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.33;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.34;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.35;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.36;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.37;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.38;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.39;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.2;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 3.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 4.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 5.1;
-+INSERT INTO t VALUES(1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        7
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      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        1             0.100000
-+      1.000000        11            4.050000
-+      7.000000        11           25.700000
-+     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        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        1             0.100000
-+      1.000000        11            4.050000
-+      7.000000        11           25.700000
-+     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_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+DROP TABLE t;
-+CREATE TABLE t(id INT);
-+SET GLOBAL query_exec_time=0.1;
-+include/restart_slave.inc
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=156;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time = 0.31;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.32;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.33;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.34;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.35;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.36;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.37;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.38;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.39;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.2;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 3.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 4.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 5.1;
-+INSERT INTO t VALUES(1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        156
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000041        1             0.000000
-+      0.006410        0             0.000000
-+      1.000000        12            4.150000
-+    156.000000        11           25.700000
-+  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        1             0.000000
-+      0.006410        0             0.000000
-+      1.000000        12            4.150000
-+    156.000000        11           25.700000
-+  24336.000000        0             0.000000
-+ 3796416.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+DROP TABLE t;
-+CREATE TABLE t(id INT);
-+SET GLOBAL query_exec_time=0.1;
-+include/restart_slave.inc
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1000;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time = 0.31;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.32;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.33;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.34;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.35;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.36;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.37;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.38;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.39;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.2;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 3.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 4.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 5.1;
-+INSERT INTO t VALUES(1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        1000
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        1             0.000000
-+      0.001000        0             0.000000
-+      1.000000        12            4.150000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+time  count   total
-+      0.000001        1             0.000000
-+      0.001000        0             0.000000
-+      1.000000        12            4.150000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+DROP TABLE t;
-+CREATE TABLE t(id INT);
-+SET GLOBAL query_exec_time=0.1;
-+include/restart_slave.inc
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1001;
-+Warnings:
-+Warning       1292    Truncated incorrect query_response_time_range_base value: '1001'
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time = 0.31;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.32;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.33;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.34;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.35;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.36;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.37;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.38;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.39;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.2;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 1.4;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 0.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.3;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 2.5;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 3.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 4.1;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time = 5.1;
-+INSERT INTO t VALUES(1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        1000
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        1             0.000000
-+      0.001000        0             0.000000
-+      1.000000        12            4.150000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+time  count   total
-+      0.000001        1             0.000000
-+      0.001000        0             0.000000
-+      1.000000        12            4.150000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+DROP TABLE t;
-+include/rpl_end.inc
-+SET GLOBAL query_exec_time=default;
-+SET GLOBAL query_exec_time=default;
---- /dev/null
-+++ b/mysql-test/r/percona_query_response_time.result
-@@ -0,0 +1,1307 @@
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_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 ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time=0.31;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.32;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.33;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.34;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.35;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.36;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.37;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.38;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.39;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.2;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=4.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        2
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        24            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        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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        24            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        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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 SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_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 ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time=0.31;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.32;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.33;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.34;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.35;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.36;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.37;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.38;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.39;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.2;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=4.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        2
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        24            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        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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        24            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        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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 SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_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 ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time=0.31;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.32;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.33;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.34;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.35;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.36;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.37;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.38;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.39;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.2;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=4.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        10
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      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        11            4.050000
-+     10.000000        11           25.700000
-+    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        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        11            4.050000
-+     10.000000        11           25.700000
-+    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 SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_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 ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time=0.31;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.32;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.33;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.34;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.35;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.36;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.37;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.38;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.39;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.2;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=4.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        7
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      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        0             0.000000
-+      1.000000        11            4.050000
-+      7.000000        11           25.700000
-+     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        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        0             0.000000
-+      1.000000        11            4.050000
-+      7.000000        11           25.700000
-+     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 SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_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 ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time=0.31;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.32;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.33;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.34;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.35;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.36;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.37;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.38;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.39;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.2;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=4.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        156
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000041        24            0.000000
-+      0.006410        0             0.000000
-+      1.000000        11            4.050000
-+    156.000000        11           25.700000
-+  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        24            0.000000
-+      0.006410        0             0.000000
-+      1.000000        11            4.050000
-+    156.000000        11           25.700000
-+  24336.000000        0             0.000000
-+ 3796416.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SET SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_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 ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time=0.31;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.32;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.33;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.34;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.35;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.36;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.37;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.38;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.39;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.2;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=4.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        1000
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        24            0.000000
-+      0.001000        0             0.000000
-+      1.000000        11            4.050000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+time  count   total
-+      0.000001        24            0.000000
-+      0.001000        0             0.000000
-+      1.000000        11            4.050000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SET SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1001;
-+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 ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+SET SESSION query_exec_time=0.31;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.32;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.33;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.34;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.35;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.36;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.37;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.38;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.39;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.2;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=1.4;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.3;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=2.5;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=3.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=4.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=5.1;
-+SELECT 1;
-+1
-+1
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        1000
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        24            0.000000
-+      0.001000        0             0.000000
-+      1.000000        11            4.050000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+time  count   total
-+      0.000001        24            0.000000
-+      0.001000        0             0.000000
-+      1.000000        11            4.050000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SET SESSION query_exec_time=default;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
---- /dev/null
-+++ b/mysql-test/r/percona_query_response_time-stored.result
-@@ -0,0 +1,544 @@
-+CREATE TABLE t(a INT);
-+CREATE PROCEDURE test_f(t DECIMAL(3,2))
-+BEGIN
-+SET SESSION query_exec_time=t;
-+INSERT INTO t VALUES(1);
-+SET SESSION query_exec_time=0.1;
-+DELETE FROM t;
-+END^
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_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;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+CALL test_f(0.31);
-+CALL test_f(0.32);
-+CALL test_f(0.33);
-+CALL test_f(0.34);
-+CALL test_f(0.35);
-+CALL test_f(0.36);
-+CALL test_f(0.37);
-+CALL test_f(0.38);
-+CALL test_f(0.39);
-+CALL test_f(0.4);
-+CALL test_f(1.1);
-+CALL test_f(1.2);
-+CALL test_f(1.3);
-+CALL test_f(1.5);
-+CALL test_f(1.4);
-+CALL test_f(0.5);
-+CALL test_f(2.1);
-+CALL test_f(2.3);
-+CALL test_f(2.5);
-+CALL test_f(3.1);
-+CALL test_f(4.1);
-+CALL test_f(5.1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        2
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        45            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        44            4.400000
-+      0.250000        0             0.000000
-+      0.500000        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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        45            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        44            4.400000
-+      0.250000        0             0.000000
-+      0.500000        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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 SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=2;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+CALL test_f(0.31);
-+CALL test_f(0.32);
-+CALL test_f(0.33);
-+CALL test_f(0.34);
-+CALL test_f(0.35);
-+CALL test_f(0.36);
-+CALL test_f(0.37);
-+CALL test_f(0.38);
-+CALL test_f(0.39);
-+CALL test_f(0.4);
-+CALL test_f(1.1);
-+CALL test_f(1.2);
-+CALL test_f(1.3);
-+CALL test_f(1.5);
-+CALL test_f(1.4);
-+CALL test_f(0.5);
-+CALL test_f(2.1);
-+CALL test_f(2.3);
-+CALL test_f(2.5);
-+CALL test_f(3.1);
-+CALL test_f(4.1);
-+CALL test_f(5.1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        2
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        45            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        44            4.400000
-+      0.250000        0             0.000000
-+      0.500000        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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        45            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        44            4.400000
-+      0.250000        0             0.000000
-+      0.500000        10            3.550000
-+      1.000000        1             0.500000
-+      2.000000        5             6.500000
-+      4.000000        4            10.000000
-+      8.000000        2             9.200000
-+     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 SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=10;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+CALL test_f(0.31);
-+CALL test_f(0.32);
-+CALL test_f(0.33);
-+CALL test_f(0.34);
-+CALL test_f(0.35);
-+CALL test_f(0.36);
-+CALL test_f(0.37);
-+CALL test_f(0.38);
-+CALL test_f(0.39);
-+CALL test_f(0.4);
-+CALL test_f(1.1);
-+CALL test_f(1.2);
-+CALL test_f(1.3);
-+CALL test_f(1.5);
-+CALL test_f(1.4);
-+CALL test_f(0.5);
-+CALL test_f(2.1);
-+CALL test_f(2.3);
-+CALL test_f(2.5);
-+CALL test_f(3.1);
-+CALL test_f(4.1);
-+CALL test_f(5.1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        10
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      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        55            8.450000
-+     10.000000        11           25.700000
-+    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        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        55            8.450000
-+     10.000000        11           25.700000
-+    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 SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=7;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+CALL test_f(0.31);
-+CALL test_f(0.32);
-+CALL test_f(0.33);
-+CALL test_f(0.34);
-+CALL test_f(0.35);
-+CALL test_f(0.36);
-+CALL test_f(0.37);
-+CALL test_f(0.38);
-+CALL test_f(0.39);
-+CALL test_f(0.4);
-+CALL test_f(1.1);
-+CALL test_f(1.2);
-+CALL test_f(1.3);
-+CALL test_f(1.5);
-+CALL test_f(1.4);
-+CALL test_f(0.5);
-+CALL test_f(2.1);
-+CALL test_f(2.3);
-+CALL test_f(2.5);
-+CALL test_f(3.1);
-+CALL test_f(4.1);
-+CALL test_f(5.1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        7
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      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        44            4.400000
-+      1.000000        11            4.050000
-+      7.000000        11           25.700000
-+     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        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        44            4.400000
-+      1.000000        11            4.050000
-+      7.000000        11           25.700000
-+     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 SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=156;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+CALL test_f(0.31);
-+CALL test_f(0.32);
-+CALL test_f(0.33);
-+CALL test_f(0.34);
-+CALL test_f(0.35);
-+CALL test_f(0.36);
-+CALL test_f(0.37);
-+CALL test_f(0.38);
-+CALL test_f(0.39);
-+CALL test_f(0.4);
-+CALL test_f(1.1);
-+CALL test_f(1.2);
-+CALL test_f(1.3);
-+CALL test_f(1.5);
-+CALL test_f(1.4);
-+CALL test_f(0.5);
-+CALL test_f(2.1);
-+CALL test_f(2.3);
-+CALL test_f(2.5);
-+CALL test_f(3.1);
-+CALL test_f(4.1);
-+CALL test_f(5.1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        156
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000041        45            0.000000
-+      0.006410        0             0.000000
-+      1.000000        55            8.450000
-+    156.000000        11           25.700000
-+  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        45            0.000000
-+      0.006410        0             0.000000
-+      1.000000        55            8.450000
-+    156.000000        11           25.700000
-+  24336.000000        0             0.000000
-+ 3796416.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SET SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1000;
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+CALL test_f(0.31);
-+CALL test_f(0.32);
-+CALL test_f(0.33);
-+CALL test_f(0.34);
-+CALL test_f(0.35);
-+CALL test_f(0.36);
-+CALL test_f(0.37);
-+CALL test_f(0.38);
-+CALL test_f(0.39);
-+CALL test_f(0.4);
-+CALL test_f(1.1);
-+CALL test_f(1.2);
-+CALL test_f(1.3);
-+CALL test_f(1.5);
-+CALL test_f(1.4);
-+CALL test_f(0.5);
-+CALL test_f(2.1);
-+CALL test_f(2.3);
-+CALL test_f(2.5);
-+CALL test_f(3.1);
-+CALL test_f(4.1);
-+CALL test_f(5.1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        1000
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        45            0.000000
-+      0.001000        0             0.000000
-+      1.000000        55            8.450000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+time  count   total
-+      0.000001        45            0.000000
-+      0.001000        0             0.000000
-+      1.000000        55            8.450000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SET SESSION query_exec_time=default;
-+SET SESSION query_exec_time=0.1;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1001;
-+Warnings:
-+Warning       1292    Truncated incorrect query_response_time_range_base value: '1001'
-+FLUSH QUERY_RESPONSE_TIME;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
-+CALL test_f(0.31);
-+CALL test_f(0.32);
-+CALL test_f(0.33);
-+CALL test_f(0.34);
-+CALL test_f(0.35);
-+CALL test_f(0.36);
-+CALL test_f(0.37);
-+CALL test_f(0.38);
-+CALL test_f(0.39);
-+CALL test_f(0.4);
-+CALL test_f(1.1);
-+CALL test_f(1.2);
-+CALL test_f(1.3);
-+CALL test_f(1.5);
-+CALL test_f(1.4);
-+CALL test_f(0.5);
-+CALL test_f(2.1);
-+CALL test_f(2.3);
-+CALL test_f(2.5);
-+CALL test_f(3.1);
-+CALL test_f(4.1);
-+CALL test_f(5.1);
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
-+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
-+Variable_name Value
-+query_response_time_range_base        1000
-+SHOW QUERY_RESPONSE_TIME;
-+              
-+      0.000001        45            0.000000
-+      0.001000        0             0.000000
-+      1.000000        55            8.450000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
-+time  count   total
-+      0.000001        45            0.000000
-+      0.001000        0             0.000000
-+      1.000000        55            8.450000
-+   1000.000000        11           25.700000
-+ 1000000.00000        0             0.000000
-+TOO LONG      0       TOO LONG
-+SET SESSION query_exec_time=default;
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+DROP PROCEDURE test_f;
-+DROP TABLE t;
---- /dev/null
-+++ b/mysql-test/t/percona_query_response_time-replication.test
-@@ -0,0 +1,28 @@
-+SET GLOBAL query_exec_time=0.1;
-+
-+--source include/have_response_time_distribution.inc
-+--source include/have_debug.inc
-+--source include/have_binlog_format_statement.inc
-+--source include/master-slave.inc
-+
-+--let base=1
-+--source include/query_response_time-replication.inc
-+--let base=2
-+--source include/query_response_time-replication.inc
-+--let base=10
-+--source include/query_response_time-replication.inc
-+--let base=7
-+--source include/query_response_time-replication.inc
-+--let base=156
-+--source include/query_response_time-replication.inc
-+--let base=1000
-+--source include/query_response_time-replication.inc
-+--let base=1001
-+--source include/query_response_time-replication.inc
-+
-+--source include/rpl_end.inc
-+
-+SET GLOBAL query_exec_time=default;
-+
-+connection slave;
-+SET GLOBAL query_exec_time=default;
---- /dev/null
-+++ b/mysql-test/t/percona_query_response_time-stored.test
-@@ -0,0 +1,36 @@
-+--source include/have_response_time_distribution.inc
-+--source include/have_debug.inc
-+
-+CREATE TABLE t(a INT);
-+
-+delimiter ^;
-+CREATE PROCEDURE test_f(t DECIMAL(3,2))
-+BEGIN
-+  SET SESSION query_exec_time=t;
-+  INSERT INTO t VALUES(1);
-+  SET SESSION query_exec_time=0.1;
-+  DELETE FROM t;
-+END^
-+delimiter ;^
-+
-+--let base=1
-+--source include/query_response_time-stored.inc
-+--let base=2
-+--source include/query_response_time-stored.inc
-+--let base=10
-+--source include/query_response_time-stored.inc
-+--let base=7
-+--source include/query_response_time-stored.inc
-+--let base=156
-+--source include/query_response_time-stored.inc
-+--let base=1000
-+--source include/query_response_time-stored.inc
-+--let base=1001
-+--source include/query_response_time-stored.inc
-+
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
-+
-+DROP PROCEDURE test_f;
-+
-+DROP TABLE t;
---- /dev/null
-+++ b/mysql-test/t/percona_query_response_time.test
-@@ -0,0 +1,20 @@
-+--source include/have_response_time_distribution.inc
-+--source include/have_debug.inc
-+
-+--let base=1
-+--source include/query_response_time.inc
-+--let base=2
-+--source include/query_response_time.inc
-+--let base=10
-+--source include/query_response_time.inc
-+--let base=7
-+--source include/query_response_time.inc
-+--let base=156
-+--source include/query_response_time.inc
-+--let base=1000
-+--source include/query_response_time.inc
-+--let base=1001
-+--source include/query_response_time.inc
-+
-+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default;
-+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=default;
---- /dev/null
-+++ b/patch_info/response-time-distribution.info
-@@ -0,0 +1,9 @@
-+File=response-time-distribution.patch
-+Name=Response time distribution
-+Version=1.0
-+Author=Percona <info@percona.com>
-+License=GPL
-+Comment=
-+Changelog
-+2010-07-02 first version avaliable
-+2010-09-15 add column 'total'
---- a/sql/lex.h
-+++ b/sql/lex.h
-@@ -418,6 +418,7 @@
-   { "PURGE",          SYM(PURGE)},
-   { "QUARTER",          SYM(QUARTER_SYM)},
-   { "QUERY",          SYM(QUERY_SYM)},
-+  { "QUERY_RESPONSE_TIME", SYM(QUERY_RESPONSE_TIME_SYM)},
-   { "QUICK",          SYM(QUICK)},
-   { "RANGE",            SYM(RANGE_SYM)},
-   { "READ",           SYM(READ_SYM)},
---- a/sql/Makefile.am
-+++ b/sql/Makefile.am
-@@ -66,7 +66,7 @@
-                       sql_repl.h slave.h rpl_filter.h rpl_injector.h \
-                       log_event.h rpl_record.h \
-                       log_event_old.h rpl_record_old.h \
--                      sql_sort.h sql_cache.h set_var.h \
-+                      sql_sort.h sql_cache.h set_var.h query_response_time.h \
-                       spatial.h gstream.h client_settings.h tzfile.h \
-                       tztime.h my_decimal.h\
-                       sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
-@@ -89,7 +89,7 @@
-                       sql_string.cc sql_manager.cc sql_map.cc \
-                       mysqld.cc password.c hash_filo.cc hostname.cc \
-                       sql_connect.cc scheduler.cc sql_parse.cc \
--                      set_var.cc sql_yacc.yy \
-+                      set_var.cc query_response_time.cc sql_yacc.yy \
-                       sql_base.cc table.cc sql_select.cc sql_insert.cc \
-                       sql_profile.cc \
-                       sql_prepare.cc sql_error.cc sql_locale.cc \
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -33,6 +33,7 @@
- #include "rpl_injector.h"
-+#include "query_response_time.h"
- #ifdef HAVE_SYS_PRCTL_H
- #include <sys/prctl.h>
- #endif
-@@ -538,6 +539,10 @@
- my_bool opt_query_cache_strip_comments = 0;
- my_bool opt_use_global_long_query_time= 0;
- my_bool opt_slow_query_log_microseconds_timestamp= 0;
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+ulong   opt_query_response_time_range_base  = QRT_DEFAULT_BASE;
-+my_bool opt_enable_query_response_time_stats= 0;
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
- my_bool lower_case_file_system= 0;
- my_bool opt_large_pages= 0;
- my_bool opt_myisam_use_mmap= 0;
-@@ -688,6 +693,7 @@
- MY_LOCALE *my_default_lc_time_names;
- SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
-+SHOW_COMP_OPTION have_response_time_distribution;
- SHOW_COMP_OPTION have_geometry, have_rtree_keys;
- SHOW_COMP_OPTION have_crypt, have_compress;
- SHOW_COMP_OPTION have_community_features;
-@@ -1398,6 +1404,9 @@
-   free_global_thread_stats();
-   free_global_table_stats();
-   free_global_index_stats();
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  query_response_time_free();
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
- #ifdef HAVE_REPLICATION
-   end_slave_list();
- #endif
-@@ -4118,6 +4127,9 @@
-   init_global_table_stats();
-   init_global_index_stats();
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  query_response_time_init();
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   /* We have to initialize the storage engines before CSV logging */
-   if (ha_init())
-@@ -5932,6 +5944,10 @@
-   OPT_USE_GLOBAL_LONG_QUERY_TIME,
-   OPT_USE_GLOBAL_LOG_SLOW_CONTROL,
-   OPT_SLOW_QUERY_LOG_MICROSECONDS_TIMESTAMP,
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  OPT_QRT_RANGE_BASE,
-+  OPT_ENABLE_QRT_STATS,
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   OPT_IGNORE_BUILTIN_INNODB,
-   OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
-   OPT_DEFAULT_CHARACTER_SET_OLD,
-@@ -7003,6 +7019,23 @@
-    "Use microsecond time's precision in slow query log",
-    (uchar**) &opt_slow_query_log_microseconds_timestamp, (uchar**) &opt_slow_query_log_microseconds_timestamp,
-    0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  {"query_response_time_range_base", OPT_QRT_RANGE_BASE,
-+     "Select base of log for query_response_time ranges. WARNING: variable change affect only after flush",
-+   (uchar**) &opt_query_response_time_range_base, (uchar**) &opt_query_response_time_range_base,
-+   0, GET_ULONG, REQUIRED_ARG, 
-+   /* def_value */  QRT_DEFAULT_BASE,
-+   /* min_value */  2,
-+   /* max_value */  QRT_MAXIMUM_BASE, 
-+   /* sub_size */   0,
-+   /* block_size */ 1,
-+   /* app_type */ 0
-+  },
-+  {"enable_query_response_time_stats", OPT_ENABLE_QRT_STATS,
-+   "Enable or disable query response time statisics collecting",
-+   (uchar**) &opt_enable_query_response_time_stats, (uchar**) &opt_enable_query_response_time_stats,
-+   0, GET_BOOL, REQUIRED_ARG, 0, 0, 1, 0, 1, 0},
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
-    "If set to 1, table names are stored in lowercase on disk and table names "
-    "will be case-insensitive.  Should be set to 2 if you are using a case-"
-@@ -8226,6 +8259,11 @@
- #else
-   have_query_cache=SHOW_OPTION_NO;
- #endif
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  have_response_time_distribution= SHOW_OPTION_YES;
-+#else /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+  have_response_time_distribution= SHOW_OPTION_NO;
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
- #ifdef HAVE_SPATIAL
-   have_geometry=SHOW_OPTION_YES;
- #else
---- a/sql/mysql_priv.h
-+++ b/sql/mysql_priv.h
-@@ -2120,6 +2120,11 @@
- extern my_bool opt_query_cache_strip_comments;
- extern my_bool opt_use_global_long_query_time;
- extern my_bool opt_slow_query_log_microseconds_timestamp;
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+extern ulong   opt_query_response_time_range_base;
-+extern my_bool opt_enable_query_response_time_stats;
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+extern SHOW_COMP_OPTION have_response_time_distribution;
- extern my_bool sp_automatic_privileges, opt_noacl;
- extern my_bool opt_old_style_user_limits, trust_function_creators;
- extern uint opt_crash_binlog_innodb;
---- /dev/null
-+++ b/sql/query_response_time.cc
-@@ -0,0 +1,313 @@
-+#include "my_global.h"
-+#include "my_atomic.h"
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+#include "mysql_priv.h"
-+#include "mysql_com.h"
-+#include "rpl_tblmap.h"
-+#include "query_response_time.h"
-+
-+#define TIME_STRING_POSITIVE_POWER_LENGTH QRT_TIME_STRING_POSITIVE_POWER_LENGTH
-+#define TIME_STRING_NEGATIVE_POWER_LENGTH 6
-+#define TOTAL_STRING_POSITIVE_POWER_LENGTH QRT_TOTAL_STRING_POSITIVE_POWER_LENGTH
-+#define TOTAL_STRING_NEGATIVE_POWER_LENGTH 6
-+#define MINIMUM_BASE 2
-+#define MAXIMUM_BASE QRT_MAXIMUM_BASE
-+#define POSITIVE_POWER_FILLER QRT_POSITIVE_POWER_FILLER
-+#define NEGATIVE_POWER_FILLER QRT_NEGATIVE_POWER_FILLER
-+#define STRING_OVERFLOW QRT_STRING_OVERFLOW
-+#define TIME_OVERFLOW   QRT_TIME_OVERFLOW
-+#define DEFAULT_BASE    QRT_DEFAULT_BASE
-+
-+#define do_xstr(s) do_str(s)
-+#define do_str(s) #s
-+#define do_format(filler,width) "%" filler width "lld"
-+/*
-+  Format strings for snprintf. Generate from:
-+  POSITIVE_POWER_FILLER and TIME_STRING_POSITIVE_POWER_LENGTH
-+  NEFATIVE_POWER_FILLER and TIME_STRING_NEGATIVE_POWER_LENGTH
-+*/
-+#define TIME_STRING_POSITIVE_POWER_FORMAT do_format(POSITIVE_POWER_FILLER,do_xstr(TIME_STRING_POSITIVE_POWER_LENGTH))
-+#define TIME_STRING_NEGATIVE_POWER_FORMAT do_format(NEGATIVE_POWER_FILLER,do_xstr(TIME_STRING_NEGATIVE_POWER_LENGTH))
-+#define TIME_STRING_FORMAT                  TIME_STRING_POSITIVE_POWER_FORMAT "." TIME_STRING_NEGATIVE_POWER_FORMAT
-+
-+#define TOTAL_STRING_POSITIVE_POWER_FORMAT do_format(POSITIVE_POWER_FILLER,do_xstr(TOTAL_STRING_POSITIVE_POWER_LENGTH))
-+#define TOTAL_STRING_NEGATIVE_POWER_FORMAT do_format(NEGATIVE_POWER_FILLER,do_xstr(TOTAL_STRING_NEGATIVE_POWER_LENGTH))
-+#define TOTAL_STRING_FORMAT                 TOTAL_STRING_POSITIVE_POWER_FORMAT "." TOTAL_STRING_NEGATIVE_POWER_FORMAT
-+
-+#define TIME_STRING_LENGTH    QRT_TIME_STRING_LENGTH
-+#define TIME_STRING_BUFFER_LENGTH     (TIME_STRING_LENGTH + 1 /* '\0' */)
-+
-+#define TOTAL_STRING_LENGTH   QRT_TOTAL_STRING_LENGTH
-+#define TOTAL_STRING_BUFFER_LENGTH    (TOTAL_STRING_LENGTH + 1 /* '\0' */)
-+
-+/*
-+  Calculate length of "log linear"
-+  1)
-+  (MINIMUM_BASE ^ result) <= (10 ^ STRING_POWER_LENGTH) < (MINIMUM_BASE ^ (result + 1))
-+
-+  2)
-+  (MINIMUM_BASE ^ result) <= (10 ^ STRING_POWER_LENGTH)
-+  and
-+  (MINIMUM_BASE ^ (result + 1)) > (10 ^ STRING_POWER_LENGTH)
-+
-+  3)
-+  result     <= LOG(MINIMUM_BASE, 10 ^ STRING_POWER_LENGTH)= STRING_POWER_LENGTH * LOG(MINIMUM_BASE,10)
-+  result + 1 >  LOG(MINIMUM_BASE, 10 ^ STRING_POWER_LENGTH)= STRING_POWER_LENGTH * LOG(MINIMUM_BASE,10)
-+
-+  4) STRING_POWER_LENGTH * LOG(MINIMUM_BASE,10) - 1 < result <= STRING_POWER_LENGTH * LOG(MINIMUM_BASE,10)
-+
-+  MINIMUM_BASE= 2 always, LOG(MINIMUM_BASE,10)= 3.3219280948873626, result= (int)3.3219280948873626 * STRING_POWER_LENGTH
-+
-+  Last counter always use for time overflow
-+*/
-+#define POSITIVE_POWER_COUNT ((int)(3.32192809 * TIME_STRING_POSITIVE_POWER_LENGTH))
-+#define NEGATIVE_POWER_COUNT ((int)(3.32192809 * TIME_STRING_NEGATIVE_POWER_LENGTH))
-+#define OVERALL_POWER_COUNT (NEGATIVE_POWER_COUNT + 1 + POSITIVE_POWER_COUNT)
-+
-+#define MILLION ((unsigned long)1000 * 1000)
-+
-+namespace query_response_time
-+{
-+
-+class utility
-+{
-+public:
-+  utility() : m_base(0)
-+  {
-+    m_max_dec_value= MILLION;
-+    for(int i= 0; TIME_STRING_POSITIVE_POWER_LENGTH > i; ++i)
-+      m_max_dec_value *= 10;
-+    setup(DEFAULT_BASE);
-+  }
-+public:
-+  uint      base()            const { return m_base; }
-+  uint      negative_count()  const { return m_negative_count; }
-+  uint      positive_count()  const { return m_positive_count; }
-+  uint      bound_count()     const { return m_bound_count; }
-+  ulonglong max_dec_value()   const { return m_max_dec_value; }
-+  ulonglong bound(uint index) const { return m_bound[ index ]; }
-+public:
-+  void setup(uint base)
-+  {
-+    if(base != m_base)
-+    {
-+      m_base= base;
-+
-+      const ulonglong million= 1000 * 1000;
-+      ulonglong value= million;
-+      m_negative_count= 0;
-+      while(value > 0)
-+      {
-+      m_negative_count += 1;
-+      value /= m_base;
-+      }
-+      m_negative_count -= 1;
-+
-+      value= million;
-+      m_positive_count= 0;
-+      while(value < m_max_dec_value)
-+      {
-+      m_positive_count += 1;
-+      value *= m_base;
-+      }
-+      m_bound_count= m_negative_count + m_positive_count;
-+
-+      value= million;
-+      for(uint i= 0; i < m_negative_count; ++i)
-+      {
-+      value /= m_base;
-+      m_bound[m_negative_count - i - 1]= value;
-+      }
-+      value= million;
-+      for(uint i= 0; i < m_positive_count;  ++i)
-+      {
-+      m_bound[m_negative_count + i]= value;
-+      value *= m_base;
-+      }
-+    }
-+  }
-+private:
-+  uint      m_base;
-+  uint      m_negative_count;
-+  uint      m_positive_count;
-+  uint      m_bound_count;
-+  ulonglong m_max_dec_value; /* for TIME_STRING_POSITIVE_POWER_LENGTH=7 is 10000000 */
-+  ulonglong m_bound[OVERALL_POWER_COUNT];
-+};
-+
-+void print_time(char* buffer, std::size_t buffer_size, std::size_t string_positive_power_length, const char* format, uint64 value)
-+{
-+  memset(buffer,'X',buffer_size);
-+  buffer[string_positive_power_length]= '.';
-+  ulonglong second=      (value / MILLION);
-+  ulonglong microsecond= (value % MILLION);
-+  int result_length= snprintf(buffer, buffer_size, format, second, microsecond);
-+  if(result_length < 0)
-+  {
-+    assert(sizeof(STRING_OVERFLOW) <= buffer_size);
-+    memcpy(buffer, STRING_OVERFLOW, sizeof(STRING_OVERFLOW));
-+    return;
-+  }
-+  buffer[result_length]= 0;
-+}
-+
-+class time_collector
-+{
-+public:
-+  time_collector(utility& u) : m_utility(&u)
-+  {
-+    my_atomic_rwlock_init(&time_collector_lock);
-+  }
-+  ~time_collector()
-+  {
-+    my_atomic_rwlock_destroy(&time_collector_lock);
-+  }
-+  uint32 count(uint index) const
-+  {
-+    my_atomic_rwlock_rdlock(&time_collector_lock);
-+    uint32 result = my_atomic_load32((int32*)&m_count[index]);
-+    my_atomic_rwlock_rdunlock(&time_collector_lock);
-+    return result;
-+  }
-+  uint64 total(uint index) const
-+  {
-+    my_atomic_rwlock_rdlock(&time_collector_lock);
-+    uint64 result= my_atomic_load64((int64*)&m_total[index]);
-+    my_atomic_rwlock_rdunlock(&time_collector_lock);
-+    return result;
-+  }
-+public:
-+  void flush()
-+  {
-+    my_atomic_rwlock_wrlock(&time_collector_lock);
-+    memset((void*)&m_count,0,sizeof(m_count));
-+    memset((void*)&m_total,0,sizeof(m_total));
-+    my_atomic_rwlock_wrunlock(&time_collector_lock);
-+  }
-+  void collect(uint64 time)
-+  {
-+    bool no_collect= false;
-+    DBUG_EXECUTE_IF("response_time_distribution_log_only_more_300_milliseconds", {   \
-+        no_collect= time < 300 * 1000;                                  \
-+      });
-+    if(no_collect) return;
-+    int i= 0;
-+    for(int count= m_utility->bound_count(); count > i; ++i)
-+    {
-+      if(m_utility->bound(i) > time)
-+      {
-+        my_atomic_rwlock_wrlock(&time_collector_lock);
-+        my_atomic_add32((int32*)(&m_count[i]), 1);
-+        my_atomic_add64((int64*)(&m_total[i]), time);
-+        my_atomic_rwlock_wrunlock(&time_collector_lock);
-+        break;
-+      }
-+    }
-+  }
-+private:
-+  utility* m_utility;
-+  /* The lock for atomic operations on m_count and m_total.  Only actually
-+     used on architectures that do not have atomic implementation of atomic
-+     operations. */
-+  my_atomic_rwlock_t time_collector_lock;
-+  uint32   m_count[OVERALL_POWER_COUNT + 1];
-+  uint64   m_total[OVERALL_POWER_COUNT + 1];
-+};
-+
-+class collector
-+{
-+public:
-+  collector() : m_time(m_utility)
-+  {
-+    m_utility.setup(DEFAULT_BASE);
-+    m_time.flush();
-+  }
-+public:
-+  void flush()
-+  {
-+    m_utility.setup(opt_query_response_time_range_base);
-+    m_time.flush();
-+  }
-+  int fill(THD* thd, TABLE_LIST *tables, COND *cond)
-+  {
-+    DBUG_ENTER("fill_schema_query_response_time");
-+    TABLE        *table= static_cast<TABLE*>(tables->table);
-+    Field        **fields= table->field;
-+    for(uint i= 0, count= bound_count() + 1 /* with overflow */; count > i; ++i)
-+    {
-+      char time[TIME_STRING_BUFFER_LENGTH];
-+      char total[TOTAL_STRING_BUFFER_LENGTH];
-+      if(i == bound_count())
-+      {        
-+        assert(sizeof(TIME_OVERFLOW) <= TIME_STRING_BUFFER_LENGTH);
-+        assert(sizeof(TIME_OVERFLOW) <= TOTAL_STRING_BUFFER_LENGTH);
-+        memcpy(time,TIME_OVERFLOW,sizeof(TIME_OVERFLOW));
-+        memcpy(total,TIME_OVERFLOW,sizeof(TIME_OVERFLOW));
-+      }
-+      else
-+      {
-+        print_time(time,sizeof(time),TIME_STRING_POSITIVE_POWER_LENGTH,TIME_STRING_FORMAT,this->bound(i));
-+        print_time(total,sizeof(total),TOTAL_STRING_POSITIVE_POWER_LENGTH,TOTAL_STRING_FORMAT,this->total(i));
-+      }
-+      fields[0]->store(time,strlen(time),system_charset_info);
-+      fields[1]->store(this->count(i));
-+      fields[2]->store(total,strlen(total),system_charset_info);
-+      if (schema_table_store_record(thd, table))
-+      {
-+      DBUG_RETURN(1);
-+      }
-+    }
-+    DBUG_RETURN(0);
-+  }
-+  void collect(ulonglong time)
-+  {
-+    m_time.collect(time);
-+  }
-+  uint bound_count() const
-+  {
-+    return m_utility.bound_count();
-+  }
-+  ulonglong bound(uint index)
-+  {
-+    return m_utility.bound(index);
-+  }
-+  ulonglong count(uint index)
-+  {
-+    return m_time.count(index);
-+  }
-+  ulonglong total(uint index)
-+  {
-+    return m_time.total(index);
-+  }
-+private:
-+  utility          m_utility;
-+  time_collector   m_time;
-+};
-+
-+static collector g_collector;
-+
-+} // namespace query_response_time
-+
-+void query_response_time_init()
-+{
-+}
-+
-+void query_response_time_free()
-+{
-+  query_response_time::g_collector.flush();
-+}
-+
-+void query_response_time_flush()
-+{
-+  query_response_time::g_collector.flush();
-+}
-+void query_response_time_collect(ulonglong query_time)
-+{
-+  query_response_time::g_collector.collect(query_time);
-+}
-+
-+int query_response_time_fill(THD* thd, TABLE_LIST *tables, COND *cond)
-+{
-+  return query_response_time::g_collector.fill(thd,tables,cond);
-+}
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
---- /dev/null
-+++ b/sql/query_response_time.h
-@@ -0,0 +1,71 @@
-+#ifndef QUERY_RESPONSE_TIME_H
-+#define QUERY_RESPONSE_TIME_H
-+
-+/*
-+  Settings for query response time
-+*/
-+
-+/*
-+  Maximum string length for (10 ^ (-1 * QRT_STRING_NEGATIVE_POWER_LENGTH)) in text representation.
-+  Example: for 6 is 0.000001
-+  Always 2
-+
-+  Maximum string length for (10 ^ (QRT_STRING_POSITIVE_POWER_LENGTH + 1) - 1) in text representation.
-+  Example: for 7 is 9999999.0
-+*/
-+#define QRT_TIME_STRING_POSITIVE_POWER_LENGTH 7
-+#define QRT_TOTAL_STRING_POSITIVE_POWER_LENGTH 7
-+
-+/*
-+  Minimum base for log - ALWAYS 2
-+  Maximum base for log:
-+*/
-+#define QRT_MAXIMUM_BASE 1000
-+
-+/*
-+  Filler for whole number (positive power)
-+  Example: for
-+  QRT_POSITIVE_POWER_FILLER ' '
-+  QRT_POSITIVE_POWER_LENGTH 7
-+  and number 7234 result is:
-+  '   7234'
-+*/
-+#define QRT_POSITIVE_POWER_FILLER " "
-+/*
-+  Filler for fractional number. Similiary to whole number
-+*/
-+#define QRT_NEGATIVE_POWER_FILLER "0"
-+
-+/*
-+  Message if string overflow (string overflow - internal error, this string say about bug in QRT)
-+*/
-+#define QRT_STRING_OVERFLOW "TOO BIG STRING"
-+
-+/*
-+  Message if time too big for statistic collecting (very long query)
-+*/
-+#define QRT_TIME_OVERFLOW "TOO LONG"
-+
-+#define QRT_DEFAULT_BASE 10
-+
-+#define QRT_TIME_STRING_LENGTH                                \
-+  max( (QRT_TIME_STRING_POSITIVE_POWER_LENGTH + 1 /* '.' */ + 6 /*QRT_TIME_STRING_NEGATIVE_POWER_LENGTH*/), \
-+       max( (sizeof(QRT_TIME_OVERFLOW) - 1),          \
-+          (sizeof(QRT_STRING_OVERFLOW) - 1) ) )
-+
-+#define QRT_TOTAL_STRING_LENGTH                               \
-+  max( (QRT_TOTAL_STRING_POSITIVE_POWER_LENGTH + 1 /* '.' */ + 6 /*QRT_TOTAL_STRING_NEGATIVE_POWER_LENGTH*/), \
-+       max( (sizeof(QRT_TIME_OVERFLOW) - 1),          \
-+          (sizeof(QRT_STRING_OVERFLOW) - 1) ) )
-+
-+extern ST_SCHEMA_TABLE query_response_time_table;
-+
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+extern void query_response_time_init   ();
-+extern void query_response_time_free   ();
-+extern void query_response_time_flush  ();
-+extern void query_response_time_collect(ulonglong query_time);
-+extern int  query_response_time_fill   (THD* thd, TABLE_LIST *tables, COND *cond);
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+
-+#endif // QUERY_RESPONSE_TIME_H
---- a/sql/set_var.cc
-+++ b/sql/set_var.cc
-@@ -1026,6 +1026,18 @@
-                                                     &SV::query_exec_time,
-                                                     sys_var::SESSION_VARIABLE_IN_BINLOG);
- #endif
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+static sys_var_bool_ptr
-+sys_enable_query_response_time_stats(&vars,
-+                                     "enable_query_response_time_stats",
-+                                     &opt_enable_query_response_time_stats);
-+static sys_var_long_ptr
-+sys_query_response_time_range_base(&vars,
-+                                   "query_response_time_range_base",
-+                                   &opt_query_response_time_range_base);
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+static sys_var_have_variable sys_have_response_time_distribution(&vars, "have_response_time_distribution",
-++                                                        &have_response_time_distribution);
- /* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
- static sys_var_log_state sys_var_log_slow(&vars, "log_slow_queries",
-                                           &opt_slow_log, QUERY_LOG_SLOW);
---- a/sql/sql_parse.cc
-+++ b/sql/sql_parse.cc
-@@ -30,6 +30,7 @@
- #include "events.h"
- #include "sql_trigger.h"
- #include "debug_sync.h"
-+#include "query_response_time.h"
- /**
-   @defgroup Runtime_Environment Runtime Environment
-@@ -1779,6 +1780,12 @@
-   ulonglong end_utime_of_query= thd->current_utime();
-   ulonglong query_exec_time= get_query_exec_time(thd, end_utime_of_query);
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  if (opt_enable_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
-@@ -1949,6 +1956,7 @@
-   case SCH_CHARSETS:
-   case SCH_ENGINES:
-   case SCH_COLLATIONS:
-+  case SCH_QUERY_RESPONSE_TIME:
-   case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
-   case SCH_USER_PRIVILEGES:
-   case SCH_SCHEMA_PRIVILEGES:
-@@ -7308,6 +7316,12 @@
-     init_global_index_stats();
-     pthread_mutex_unlock(&LOCK_global_index_stats);
-   }
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  if (options & REFRESH_QUERY_RESPONSE_TIME)
-+  {
-+    query_response_time_flush();
-+  }
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS | REFRESH_THREAD_STATS))
-   {
-     pthread_mutex_lock(&LOCK_global_user_client_stats);
---- a/sql/sql_show.cc
-+++ b/sql/sql_show.cc
-@@ -31,6 +31,7 @@
- #include "event_data_objects.h"
- #endif
- #include <my_dir.h>
-+#include "query_response_time.h"
- #include "debug_sync.h"
- #define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
-@@ -7533,6 +7534,13 @@
- */
-+ST_FIELD_INFO query_response_time_fields_info[] =
-+  {
-+    {"time",  QRT_TIME_STRING_LENGTH,      MYSQL_TYPE_STRING,  0, 0,            "", SKIP_OPEN_TABLE },
-+    {"count", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, MY_I_S_UNSIGNED, "", SKIP_OPEN_TABLE },
-+    {"total",  QRT_TIME_STRING_LENGTH,     MYSQL_TYPE_STRING,  0, 0,            "", SKIP_OPEN_TABLE },
-+    {0,       0,                           MYSQL_TYPE_STRING,  0, 0,             0, SKIP_OPEN_TABLE }
-+  };
- ST_SCHEMA_TABLE schema_tables[]=
- {
-   {"CHARACTER_SETS", charsets_fields_info, create_schema_table, 
-@@ -7587,6 +7595,13 @@
-    1, 9, 0, OPEN_TABLE_ONLY},
-   {"ROUTINES", proc_fields_info, create_schema_table, 
-    fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+  {"QUERY_RESPONSE_TIME", query_response_time_fields_info, create_schema_table, 
-+   query_response_time_fill, make_old_format, 0, -1, -1, 0, 0},
-+#else /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+  {"QUERY_RESPONSE_TIME", query_response_time_fields_info, create_schema_table, 
-+   0, make_old_format, 0, -1, -1, 0, 0},
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-   {"SCHEMATA", schema_fields_info, create_schema_table,
-    fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
-   {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
---- a/sql/sql_yacc.yy
-+++ b/sql/sql_yacc.yy
-@@ -1081,6 +1081,7 @@
- %token  PURGE
- %token  QUARTER_SYM
- %token  QUERY_SYM
-+%token  QUERY_RESPONSE_TIME_SYM
- %token  QUICK
- %token  RANGE_SYM                     /* SQL-2003-R */
- %token  READS_SYM                     /* SQL-2003-R */
-@@ -10416,6 +10417,15 @@
-            if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
-              MYSQL_YYABORT;
-           }
-+        | QUERY_RESPONSE_TIME_SYM wild_and_where
-+        {
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+           LEX *lex= Lex;
-+           lex->sql_command= SQLCOM_SELECT;
-+           if (prepare_schema_table(YYTHD, lex, 0, SCH_QUERY_RESPONSE_TIME))
-+             MYSQL_YYABORT;     
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+        }
-         | CREATE PROCEDURE sp_name
-           {
-             LEX *lex= Lex;
-@@ -10636,6 +10646,12 @@
-           { Lex->type|= REFRESH_TABLE_STATS; }
-         | INDEX_STATS_SYM
-           { Lex->type|= REFRESH_INDEX_STATS; }
-+        | QUERY_RESPONSE_TIME_SYM
-+          { 
-+#ifdef HAVE_RESPONSE_TIME_DISTRIBUTION
-+            Lex->type|= REFRESH_QUERY_RESPONSE_TIME; 
-+#endif /* HAVE_RESPONSE_TIME_DISTRIBUTION */
-+          }
-         | MASTER_SYM
-           { Lex->type|= REFRESH_MASTER; }
-         | DES_KEY_FILE
-@@ -11915,6 +11931,7 @@
-         | PROFILES_SYM             {}
-         | QUARTER_SYM              {}
-         | QUERY_SYM                {}
-+        | QUERY_RESPONSE_TIME_SYM  {}
-         | QUICK                    {}
-         | READ_ONLY_SYM            {}
-         | REBUILD_SYM              {}
---- a/sql/table.h
-+++ b/sql/table.h
-@@ -964,6 +964,7 @@
-   SCH_PROFILES,
-   SCH_REFERENTIAL_CONSTRAINTS,
-   SCH_PROCEDURES,
-+  SCH_QUERY_RESPONSE_TIME,
-   SCH_SCHEMATA,
-   SCH_SCHEMA_PRIVILEGES,
-   SCH_SESSION_STATUS,
---- a/configure.in
-+++ b/configure.in
-@@ -1738,6 +1738,7 @@
-   int main()
-   {
-     int foo= -10; int bar= 10;
-+    long long int foo64= -10; long long int bar64= 10;
-     if (!__sync_fetch_and_add(&foo, bar) || foo)
-       return -1;
-     bar= __sync_lock_test_and_set(&foo, bar);
-@@ -1746,6 +1747,14 @@
-     bar= __sync_val_compare_and_swap(&bar, foo, 15);
-     if (bar)
-       return -1;
-+    if (!__sync_fetch_and_add(&foo64, bar64) || foo64)
-+      return -1;
-+    bar64= __sync_lock_test_and_set(&foo64, bar64);
-+    if (bar64 || foo64 != 10)
-+      return -1;
-+    bar64= __sync_val_compare_and_swap(&bar64, foo, 15);
-+    if (bar64)
-+      return -1;
-     return 0;
-   }
- ], [mysql_cv_gcc_atomic_builtins=yes],
-@@ -1757,6 +1766,46 @@
-             [Define to 1 if compiler provides atomic builtins.])
- fi
-+AC_CACHE_CHECK([whether the OS provides atomic_* functions like Solaris],
-+               [mysql_cv_solaris_atomic],
-+  [AC_RUN_IFELSE(
-+     [AC_LANG_PROGRAM(
-+        [[
-+        #include <atomic.h>
-+        ]],
-+     [[
-+        int foo = -10; int bar = 10;
-+        int64_t foo64 = -10; int64_t bar64 = 10;
-+        if (atomic_add_int_nv((uint_t *)&foo, bar) || foo)
-+          return -1;
-+        bar = atomic_swap_uint((uint_t *)&foo, (uint_t)bar);
-+        if (bar || foo != 10)
-+          return -1;
-+        bar = atomic_cas_uint((uint_t *)&bar, (uint_t)foo, 15);
-+        if (bar)
-+          return -1;
-+        if (atomic_add_64_nv((volatile uint64_t *)&foo64, bar64) || foo64)
-+          return -1;
-+        bar64 = atomic_swap_64((volatile uint64_t *)&foo64, (uint64_t)bar64);
-+        if (bar64 || foo64 != 10)
-+          return -1;
-+        bar64 = atomic_cas_64((volatile uint64_t *)&bar64, (uint_t)foo64, 15);
-+        if (bar64)
-+          return -1;
-+        atomic_or_64((volatile uint64_t *)&bar64, 0);
-+        return 0;
-+     ]]
-+     )],
-+   [mysql_cv_solaris_atomic=yes],
-+   [mysql_cv_solaris_atomic=no],
-+   [mysql_cv_solaris_atomic=no]
-+)])
-+
-+if test "x$mysql_cv_solaris_atomic" = xyes; then
-+  AC_DEFINE(HAVE_SOLARIS_ATOMIC, 1,
-+            [Define to 1 if OS provides atomic_* functions like Solaris.])
-+fi
-+
- # Force static compilation to avoid linking problems/get more speed
- AC_ARG_WITH(mysqld-ldflags,
-     [  --with-mysqld-ldflags   Extra linking arguments for mysqld],
-@@ -2683,7 +2732,16 @@
- AC_SUBST(readline_link)
- AC_SUBST(readline_h_ln_cmd)
-+AC_ARG_WITH(response_time_distribution,
-+    AC_HELP_STRING([--without-response_time_distribution],[Disable response_time_distribution feature.]),
-+    [with_response_time_distribution=$withval],
-+    [with_response_time_distribution=yes]
-+)
-+if test "$with_response_time_distribution" = "yes"
-+then
-+  AC_DEFINE([HAVE_RESPONSE_TIME_DISTRIBUTION], [1], [If we want to have response_time_distribution])
-+fi
- # Include man pages, if desired, adapted to the configured parts.
- if test X"$with_man" = Xyes
---- /dev/null
-+++ b/include/my_atomic.h
-@@ -0,0 +1,287 @@
-+#ifndef MY_ATOMIC_INCLUDED
-+#define MY_ATOMIC_INCLUDED
-+
-+/* Copyright (C) 2006 MySQL AB
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+/*
-+  This header defines five atomic operations:
-+
-+  my_atomic_add#(&var, what)
-+    'Fetch and Add'
-+    add 'what' to *var, and return the old value of *var
-+
-+  my_atomic_fas#(&var, what)
-+    'Fetch And Store'
-+    store 'what' in *var, and return the old value of *var
-+
-+  my_atomic_cas#(&var, &old, new)
-+    An odd variation of 'Compare And Set/Swap'
-+    if *var is equal to *old, then store 'new' in *var, and return TRUE
-+    otherwise store *var in *old, and return FALSE
-+    Usually, &old should not be accessed if the operation is successful.
-+
-+  my_atomic_load#(&var)
-+    return *var
-+
-+  my_atomic_store#(&var, what)
-+    store 'what' in *var
-+
-+  '#' is substituted by a size suffix - 8, 16, 32, 64, or ptr
-+  (e.g. my_atomic_add8, my_atomic_fas32, my_atomic_casptr).
-+
-+  NOTE This operations are not always atomic, so they always must be
-+  enclosed in my_atomic_rwlock_rdlock(lock)/my_atomic_rwlock_rdunlock(lock)
-+  or my_atomic_rwlock_wrlock(lock)/my_atomic_rwlock_wrunlock(lock).
-+  Hint: if a code block makes intensive use of atomic ops, it make sense
-+  to take/release rwlock once for the whole block, not for every statement.
-+
-+  On architectures where these operations are really atomic, rwlocks will
-+  be optimized away.
-+  8- and 16-bit atomics aren't implemented for windows (see generic-msvc.h),
-+  but can be added, if necessary. 
-+*/
-+
-+#ifndef my_atomic_rwlock_init
-+
-+#define intptr         void *
-+/**
-+  Currently we don't support 8-bit and 16-bit operations.
-+  It can be added later if needed.
-+*/
-+#undef MY_ATOMIC_HAS_8_16
-+
-+#ifndef MY_ATOMIC_MODE_RWLOCKS
-+/*
-+ * Attempt to do atomic ops without locks
-+ */
-+#include "atomic/nolock.h"
-+#endif
-+
-+#ifndef make_atomic_cas_body
-+/* nolock.h was not able to generate even a CAS function, fall back */
-+#include "atomic/rwlock.h"
-+#endif
-+
-+/* define missing functions by using the already generated ones */
-+#ifndef make_atomic_add_body
-+#define make_atomic_add_body(S)                                 \
-+  int ## S tmp=*a;                                              \
-+  while (!my_atomic_cas ## S(a, &tmp, tmp+v)) ;                 \
-+  v=tmp;
-+#endif
-+#ifndef make_atomic_fas_body
-+#define make_atomic_fas_body(S)                                 \
-+  int ## S tmp=*a;                                              \
-+  while (!my_atomic_cas ## S(a, &tmp, v)) ;                     \
-+  v=tmp;
-+#endif
-+#ifndef make_atomic_load_body
-+#define make_atomic_load_body(S)                                \
-+  ret= 0; /* avoid compiler warning */                          \
-+  (void)(my_atomic_cas ## S(a, &ret, ret));
-+#endif
-+#ifndef make_atomic_store_body
-+#define make_atomic_store_body(S)                               \
-+  (void)(my_atomic_fas ## S (a, v));
-+#endif
-+
-+/*
-+  transparent_union doesn't work in g++
-+  Bug ?
-+
-+  Darwin's gcc doesn't want to put pointers in a transparent_union
-+  when built with -arch ppc64. Complains:
-+  warning: 'transparent_union' attribute ignored
-+*/
-+#if defined(__GNUC__) && !defined(__cplusplus) && \
-+      ! (defined(__APPLE__) && (defined(_ARCH_PPC64) ||defined (_ARCH_PPC)))
-+/*
-+  we want to be able to use my_atomic_xxx functions with
-+  both signed and unsigned integers. But gcc will issue a warning
-+  "passing arg N of `my_atomic_XXX' as [un]signed due to prototype"
-+  if the signedness of the argument doesn't match the prototype, or
-+  "pointer targets in passing argument N of my_atomic_XXX differ in signedness"
-+  if int* is used where uint* is expected (or vice versa).
-+  Let's shut these warnings up
-+*/
-+#define make_transparent_unions(S)                              \
-+        typedef union {                                         \
-+          int  ## S  i;                                         \
-+          uint ## S  u;                                         \
-+        } U_ ## S   __attribute__ ((transparent_union));        \
-+        typedef union {                                         \
-+          int  ## S volatile *i;                                \
-+          uint ## S volatile *u;                                \
-+        } Uv_ ## S   __attribute__ ((transparent_union));
-+#define uintptr intptr
-+make_transparent_unions(8)
-+make_transparent_unions(16)
-+make_transparent_unions(32)
-+make_transparent_unions(64)
-+make_transparent_unions(ptr)
-+#undef uintptr
-+#undef make_transparent_unions
-+#define a       U_a.i
-+#define cmp     U_cmp.i
-+#define v       U_v.i
-+#define set     U_set.i
-+#else
-+#define U_8    int8
-+#define U_16   int16
-+#define U_32   int32
-+#define U_64   int64
-+#define U_ptr  intptr
-+#define Uv_8   int8
-+#define Uv_16  int16
-+#define Uv_32  int32
-+#define Uv_64  int64
-+#define Uv_ptr intptr
-+#define U_a    volatile *a
-+#define U_cmp  *cmp
-+#define U_v    v
-+#define U_set  set
-+#endif /* __GCC__ transparent_union magic */
-+
-+#define make_atomic_cas(S)                                      \
-+static inline int my_atomic_cas ## S(Uv_ ## S U_a,              \
-+                            Uv_ ## S U_cmp, U_ ## S U_set)      \
-+{                                                               \
-+  int8 ret;                                                     \
-+  make_atomic_cas_body(S);                                      \
-+  return ret;                                                   \
-+}
-+
-+#define make_atomic_add(S)                                      \
-+static inline int ## S my_atomic_add ## S(                      \
-+                        Uv_ ## S U_a, U_ ## S U_v)              \
-+{                                                               \
-+  make_atomic_add_body(S);                                      \
-+  return v;                                                     \
-+}
-+
-+#define make_atomic_fas(S)                                      \
-+static inline int ## S my_atomic_fas ## S(                      \
-+                         Uv_ ## S U_a, U_ ## S U_v)             \
-+{                                                               \
-+  make_atomic_fas_body(S);                                      \
-+  return v;                                                     \
-+}
-+
-+#define make_atomic_load(S)                                     \
-+static inline int ## S my_atomic_load ## S(Uv_ ## S U_a)        \
-+{                                                               \
-+  int ## S ret;                                                 \
-+  make_atomic_load_body(S);                                     \
-+  return ret;                                                   \
-+}
-+
-+#define make_atomic_store(S)                                    \
-+static inline void my_atomic_store ## S(                        \
-+                     Uv_ ## S U_a, U_ ## S U_v)                 \
-+{                                                               \
-+  make_atomic_store_body(S);                                    \
-+}
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_cas(8)
-+make_atomic_cas(16)
-+#endif
-+make_atomic_cas(32)
-+make_atomic_cas(64)
-+make_atomic_cas(ptr)
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_add(8)
-+make_atomic_add(16)
-+#endif
-+make_atomic_add(32)
-+make_atomic_add(64)
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_load(8)
-+make_atomic_load(16)
-+#endif
-+make_atomic_load(32)
-+make_atomic_load(64)
-+make_atomic_load(ptr)
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_fas(8)
-+make_atomic_fas(16)
-+#endif
-+make_atomic_fas(32)
-+make_atomic_fas(64)
-+make_atomic_fas(ptr)
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_store(8)
-+make_atomic_store(16)
-+#endif
-+make_atomic_store(32)
-+make_atomic_store(64)
-+make_atomic_store(ptr)
-+
-+#ifdef _atomic_h_cleanup_
-+#include _atomic_h_cleanup_
-+#undef _atomic_h_cleanup_
-+#endif
-+
-+#undef U_8
-+#undef U_16
-+#undef U_32
-+#undef U_64
-+#undef U_ptr
-+#undef Uv_8
-+#undef Uv_16
-+#undef Uv_32
-+#undef Uv_64
-+#undef Uv_ptr
-+#undef a
-+#undef cmp
-+#undef v
-+#undef set
-+#undef U_a
-+#undef U_cmp
-+#undef U_v
-+#undef U_set
-+#undef make_atomic_add
-+#undef make_atomic_cas
-+#undef make_atomic_load
-+#undef make_atomic_store
-+#undef make_atomic_fas
-+#undef make_atomic_add_body
-+#undef make_atomic_cas_body
-+#undef make_atomic_load_body
-+#undef make_atomic_store_body
-+#undef make_atomic_fas_body
-+#undef intptr
-+
-+/*
-+  the macro below defines (as an expression) the code that
-+  will be run in spin-loops. Intel manuals recummend to have PAUSE there.
-+  It is expected to be defined in include/atomic/ *.h files
-+*/
-+#ifndef LF_BACKOFF
-+#define LF_BACKOFF (1)
-+#endif
-+
-+#define MY_ATOMIC_OK       0
-+#define MY_ATOMIC_NOT_1CPU 1
-+extern int my_atomic_initialize();
-+
-+#endif
-+
-+#endif /* MY_ATOMIC_INCLUDED */
---- a/mysys/Makefile.am
-+++ b/mysys/Makefile.am
-@@ -51,7 +51,8 @@
-                       rijndael.c my_aes.c sha1.c \
-                       my_compare.c my_netware.c my_largepage.c \
-                       my_memmem.c stacktrace.c \
--                      my_windac.c my_access.c base64.c my_libwrap.c
-+                      my_windac.c my_access.c base64.c my_libwrap.c \
-+                      my_atomic.c
- if NEED_THREAD
- # mf_keycache is used only in the server, so it is safe to leave the file
---- a/mysys/CMakeLists.txt
-+++ b/mysys/CMakeLists.txt
-@@ -41,7 +41,8 @@
-                               my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
-                               my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c
-                               rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
--                              thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c)
-+                              thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c
-+                                my_atomic.c)
- IF(NOT SOURCE_SUBLIBS)
-   ADD_LIBRARY(mysys ${MYSYS_SOURCES})
---- a/include/Makefile.am
-+++ b/include/Makefile.am
-@@ -38,7 +38,10 @@
-                       my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \
-                       thr_lock.h t_ctype.h violite.h my_md5.h base64.h \
-                       my_compare.h my_time.h my_vle.h my_user.h \
--                      my_libwrap.h my_stacktrace.h welcome_copyright_notice.h
-+                      my_libwrap.h my_stacktrace.h  welcome_copyright_notice.h \
-+                       my_atomic.h atomic/gcc_builtins.h atomic/generic-msvc.h \
-+                      atomic/nolock.h atomic/rwlock.h atomic/solaris.h \
-+                      atomic/x86-gcc.h
- EXTRA_DIST =        mysql.h.pp mysql/plugin.h.pp
---- /dev/null
-+++ b/include/atomic/gcc_builtins.h
-@@ -0,0 +1,42 @@
-+#ifndef ATOMIC_GCC_BUILTINS_INCLUDED
-+#define ATOMIC_GCC_BUILTINS_INCLUDED
-+
-+/* Copyright (C) 2008 MySQL AB
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+#define make_atomic_add_body(S)                     \
-+  v= __sync_fetch_and_add(a, v);
-+#define make_atomic_fas_body(S)                     \
-+  v= __sync_lock_test_and_set(a, v);
-+#define make_atomic_cas_body(S)                     \
-+  int ## S sav;                                     \
-+  int ## S cmp_val= *cmp;                           \
-+  sav= __sync_val_compare_and_swap(a, cmp_val, set);\
-+  if (!(ret= (sav == cmp_val))) *cmp= sav
-+
-+#ifdef MY_ATOMIC_MODE_DUMMY
-+#define make_atomic_load_body(S)   ret= *a
-+#define make_atomic_store_body(S)  *a= v
-+#define MY_ATOMIC_MODE "gcc-builtins-up"
-+
-+#else
-+#define MY_ATOMIC_MODE "gcc-builtins-smp"
-+#define make_atomic_load_body(S)                    \
-+  ret= __sync_fetch_and_or(a, 0);
-+#define make_atomic_store_body(S)                   \
-+  (void) __sync_lock_test_and_set(a, v);
-+#endif
-+
-+#endif /* ATOMIC_GCC_BUILTINS_INCLUDED */
---- /dev/null
-+++ b/include/atomic/generic-msvc.h
-@@ -0,0 +1,134 @@
-+/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+#ifndef _atomic_h_cleanup_
-+#define _atomic_h_cleanup_ "atomic/generic-msvc.h"
-+
-+/*
-+  We don't implement anything specific for MY_ATOMIC_MODE_DUMMY, always use
-+  intrinsics.
-+  8 and 16-bit atomics are not implemented, but it can be done if necessary.
-+*/
-+#undef MY_ATOMIC_HAS_8_16
-+
-+#include <windows.h>
-+/*
-+  x86 compilers (both VS2003 or VS2005) never use instrinsics, but generate 
-+  function calls to kernel32 instead, even in the optimized build. 
-+  We force intrinsics as described in MSDN documentation for 
-+  _InterlockedCompareExchange.
-+*/
-+#ifdef _M_IX86
-+
-+#if (_MSC_VER >= 1500)
-+#include <intrin.h>
-+#else
-+C_MODE_START
-+/*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/
-+LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp);
-+LONGLONG _InterlockedCompareExchange64 (LONGLONG volatile *Target,
-+                                        LONGLONG Value, LONGLONG Comp);
-+C_MODE_END
-+
-+#pragma intrinsic(_InterlockedCompareExchange)
-+#pragma intrinsic(_InterlockedCompareExchange64)
-+#endif
-+
-+#define InterlockedCompareExchange _InterlockedCompareExchange
-+#define InterlockedCompareExchange64 _InterlockedCompareExchange64
-+/*
-+ No need to do something special for InterlockedCompareExchangePointer
-+ as it is a #define to InterlockedCompareExchange. The same applies to
-+ InterlockedExchangePointer. 
-+*/
-+#endif /*_M_IX86*/
-+
-+#define MY_ATOMIC_MODE "msvc-intrinsics"
-+/* Implement using CAS on WIN32 */
-+#define IL_COMP_EXCHG32(X,Y,Z)  \
-+  InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z))
-+#define IL_COMP_EXCHG64(X,Y,Z)  \
-+  InterlockedCompareExchange64((volatile LONGLONG *)(X), \
-+                               (LONGLONG)(Y),(LONGLONG)(Z))
-+#define IL_COMP_EXCHGptr        InterlockedCompareExchangePointer
-+
-+#define make_atomic_cas_body(S)                                 \
-+  int ## S initial_cmp= *cmp;                                   \
-+  int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \
-+  if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a;
-+
-+#ifndef _M_IX86
-+/* Use full set of optimised functions on WIN64 */
-+#define IL_EXCHG_ADD32(X,Y)     \
-+  InterlockedExchangeAdd((volatile LONG *)(X),(Y))
-+#define IL_EXCHG_ADD64(X,Y)     \
-+  InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y))
-+#define IL_EXCHG32(X,Y)         \
-+  InterlockedExchange((volatile LONG *)(X),(Y))
-+#define IL_EXCHG64(X,Y)         \
-+  InterlockedExchange64((volatile LONGLONG *)(X),(LONGLONG)(Y))
-+#define IL_EXCHGptr             InterlockedExchangePointer
-+
-+#define make_atomic_add_body(S) \
-+  v= IL_EXCHG_ADD ## S (a, v)
-+#define make_atomic_swap_body(S) \
-+  v= IL_EXCHG ## S (a, v)
-+#define make_atomic_load_body(S)       \
-+  ret= 0; /* avoid compiler warning */ \
-+  ret= IL_COMP_EXCHG ## S (a, ret, ret);
-+#endif
-+/*
-+  my_yield_processor (equivalent of x86 PAUSE instruction) should be used
-+  to improve performance on hyperthreaded CPUs. Intel recommends to use it in
-+  spin loops also on non-HT machines to reduce power consumption (see e.g 
-+  http://softwarecommunity.intel.com/articles/eng/2004.htm)
-+
-+  Running benchmarks for spinlocks implemented with InterlockedCompareExchange
-+  and YieldProcessor shows that much better performance is achieved by calling
-+  YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting
-+  loop count in the range 200-300 brought best results.
-+ */
-+#ifndef YIELD_LOOPS
-+#define YIELD_LOOPS 200
-+#endif
-+
-+static __inline int my_yield_processor()
-+{
-+  int i;
-+  for(i=0; i<YIELD_LOOPS; i++)
-+  {
-+#if (_MSC_VER <= 1310)
-+    /* On older compilers YieldProcessor is not available, use inline assembly*/
-+    __asm { rep nop }
-+#else
-+    YieldProcessor();
-+#endif
-+  }
-+  return 1;
-+}
-+
-+#define LF_BACKOFF my_yield_processor()
-+#else /* cleanup */
-+
-+#undef IL_EXCHG_ADD32
-+#undef IL_EXCHG_ADD64
-+#undef IL_COMP_EXCHG32
-+#undef IL_COMP_EXCHG64
-+#undef IL_COMP_EXCHGptr
-+#undef IL_EXCHG32
-+#undef IL_EXCHG64
-+#undef IL_EXCHGptr
-+
-+#endif
---- /dev/null
-+++ b/include/atomic/nolock.h
-@@ -0,0 +1,69 @@
-+#ifndef ATOMIC_NOLOCK_INCLUDED
-+#define ATOMIC_NOLOCK_INCLUDED
-+
-+/* Copyright (C) 2006 MySQL AB
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+#if defined(__i386__) || defined(_MSC_VER) || defined(__x86_64__)   \
-+    || defined(HAVE_GCC_ATOMIC_BUILTINS) \
-+    || defined(HAVE_SOLARIS_ATOMIC)
-+
-+#  ifdef MY_ATOMIC_MODE_DUMMY
-+#    define LOCK_prefix ""
-+#  else
-+#    define LOCK_prefix "lock"
-+#  endif
-+/*
-+  We choose implementation as follows:
-+  ------------------------------------
-+  On Windows using Visual C++ the native implementation should be
-+  preferrable. When using gcc we prefer the Solaris implementation
-+  before the gcc because of stability preference, we choose gcc
-+  builtins if available, otherwise we choose the somewhat broken
-+  native x86 implementation. If neither Visual C++ or gcc we still
-+  choose the Solaris implementation on Solaris (mainly for SunStudio
-+  compilers).
-+*/
-+#  if defined(_MSV_VER)
-+#    include "generic-msvc.h"
-+#  elif __GNUC__
-+#    if defined(HAVE_SOLARIS_ATOMIC)
-+#      include "solaris.h"
-+#    elif defined(HAVE_GCC_ATOMIC_BUILTINS)
-+#      include "gcc_builtins.h"
-+#    elif defined(__i386__) || defined(__x86_64__)
-+#      include "x86-gcc.h"
-+#    endif
-+#  elif defined(HAVE_SOLARIS_ATOMIC)
-+#    include "solaris.h"
-+#  endif
-+#endif
-+
-+#if defined(make_atomic_cas_body)
-+/*
-+  Type not used so minimal size (emptry struct has different size between C
-+  and C++, zero-length array is gcc-specific).
-+*/
-+typedef char my_atomic_rwlock_t __attribute__ ((unused));
-+#define my_atomic_rwlock_destroy(name)
-+#define my_atomic_rwlock_init(name)
-+#define my_atomic_rwlock_rdlock(name)
-+#define my_atomic_rwlock_wrlock(name)
-+#define my_atomic_rwlock_rdunlock(name)
-+#define my_atomic_rwlock_wrunlock(name)
-+
-+#endif
-+
-+#endif /* ATOMIC_NOLOCK_INCLUDED */
---- /dev/null
-+++ b/include/atomic/rwlock.h
-@@ -0,0 +1,100 @@
-+#ifndef ATOMIC_RWLOCK_INCLUDED
-+#define ATOMIC_RWLOCK_INCLUDED
-+
-+/* Copyright (C) 2006 MySQL AB, 2009 Sun Microsystems, Inc.
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+#define MY_ATOMIC_MODE_RWLOCKS 1
-+
-+#ifdef MY_ATOMIC_MODE_DUMMY
-+/*
-+  the following can never be enabled by ./configure, one need to put #define in
-+  a source to trigger the following warning. The resulting code will be broken,
-+  it only makes sense to do it to see now test_atomic detects broken
-+  implementations (another way is to run a UP build on an SMP box).
-+*/
-+#warning MY_ATOMIC_MODE_DUMMY and MY_ATOMIC_MODE_RWLOCKS are incompatible
-+
-+typedef char my_atomic_rwlock_t;
-+
-+#define my_atomic_rwlock_destroy(name)
-+#define my_atomic_rwlock_init(name)
-+#define my_atomic_rwlock_rdlock(name)
-+#define my_atomic_rwlock_wrlock(name)
-+#define my_atomic_rwlock_rdunlock(name)
-+#define my_atomic_rwlock_wrunlock(name)
-+#define MY_ATOMIC_MODE "dummy (non-atomic)"
-+#else /* not MY_ATOMIC_MODE_DUMMY */
-+
-+typedef struct {pthread_mutex_t rw;} my_atomic_rwlock_t;
-+
-+#ifndef SAFE_MUTEX
-+
-+/*
-+  we're using read-write lock macros but map them to mutex locks, and they're
-+  faster. Still, having semantically rich API we can change the
-+  underlying implementation, if necessary.
-+*/
-+#define my_atomic_rwlock_destroy(name)     pthread_mutex_destroy(& (name)->rw)
-+#define my_atomic_rwlock_init(name)        pthread_mutex_init(& (name)->rw, 0)
-+#define my_atomic_rwlock_rdlock(name)      pthread_mutex_lock(& (name)->rw)
-+#define my_atomic_rwlock_wrlock(name)      pthread_mutex_lock(& (name)->rw)
-+#define my_atomic_rwlock_rdunlock(name)    pthread_mutex_unlock(& (name)->rw)
-+#define my_atomic_rwlock_wrunlock(name)    pthread_mutex_unlock(& (name)->rw)
-+
-+#else /* SAFE_MUTEX */
-+
-+/*
-+  SAFE_MUTEX pollutes the compiling name space with macros
-+  that alter pthread_mutex_t, pthread_mutex_init, etc.
-+  Atomic operations should never use the safe mutex wrappers.
-+  Unfortunately, there is no way to have both:
-+  - safe mutex macros expanding pthread_mutex_lock to safe_mutex_lock
-+  - my_atomic macros expanding to unmodified pthread_mutex_lock
-+  inlined in the same compilation unit.
-+  So, in case of SAFE_MUTEX, a function call is required.
-+  Given that SAFE_MUTEX is a debugging facility,
-+  this extra function call is not a performance concern for
-+  production builds.
-+*/
-+C_MODE_START
-+extern void plain_pthread_mutex_init(safe_mutex_t *);
-+extern void plain_pthread_mutex_destroy(safe_mutex_t *);
-+extern void plain_pthread_mutex_lock(safe_mutex_t *);
-+extern void plain_pthread_mutex_unlock(safe_mutex_t *);
-+C_MODE_END
-+
-+#define my_atomic_rwlock_destroy(name)     plain_pthread_mutex_destroy(&(name)->rw)
-+#define my_atomic_rwlock_init(name)        plain_pthread_mutex_init(&(name)->rw)
-+#define my_atomic_rwlock_rdlock(name)      plain_pthread_mutex_lock(&(name)->rw)
-+#define my_atomic_rwlock_wrlock(name)      plain_pthread_mutex_lock(&(name)->rw)
-+#define my_atomic_rwlock_rdunlock(name)    plain_pthread_mutex_unlock(&(name)->rw)
-+#define my_atomic_rwlock_wrunlock(name)    plain_pthread_mutex_unlock(&(name)->rw)
-+
-+#endif /* SAFE_MUTEX */
-+
-+#define MY_ATOMIC_MODE "mutex"
-+#ifndef MY_ATOMIC_MODE_RWLOCKS
-+#define MY_ATOMIC_MODE_RWLOCKS 1
-+#endif
-+#endif
-+
-+#define make_atomic_add_body(S)     int ## S sav; sav= *a; *a+= v; v=sav;
-+#define make_atomic_fas_body(S)     int ## S sav; sav= *a; *a= v; v=sav;
-+#define make_atomic_cas_body(S)     if ((ret= (*a == *cmp))) *a= set; else *cmp=*a;
-+#define make_atomic_load_body(S)    ret= *a;
-+#define make_atomic_store_body(S)   *a= v;
-+
-+#endif /* ATOMIC_RWLOCK_INCLUDED */
---- /dev/null
-+++ b/include/atomic/solaris.h
-@@ -0,0 +1,72 @@
-+/* Copyright (C) 2008 MySQL AB, 2009 Sun Microsystems, Inc
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+#ifndef _atomic_h_cleanup_
-+#define _atomic_h_cleanup_ "atomic/solaris.h"
-+
-+#include <atomic.h>
-+
-+#define       MY_ATOMIC_MODE  "solaris-atomic"
-+
-+#if defined(__GNUC__)
-+#define atomic_typeof(T,V)      __typeof__(V)
-+#else
-+#define atomic_typeof(T,V)      T
-+#endif
-+
-+#define uintptr_t void *
-+#define atomic_or_ptr_nv(X,Y) (void *)atomic_or_ulong_nv((volatile ulong_t *)X, Y)
-+
-+#define make_atomic_cas_body(S)                         \
-+  atomic_typeof(uint ## S ## _t, *cmp) sav;             \
-+  sav = atomic_cas_ ## S(                               \
-+           (volatile uint ## S ## _t *)a,               \
-+           (uint ## S ## _t)*cmp,                       \
-+           (uint ## S ## _t)set);                       \
-+  if (! (ret= (sav == *cmp)))                           \
-+    *cmp= sav;
-+
-+#define make_atomic_add_body(S)                         \
-+  int ## S nv;  /* new value */                         \
-+  nv= atomic_add_ ## S ## _nv((volatile uint ## S ## _t *)a, v); \
-+  v= nv - v
-+
-+/* ------------------------------------------------------------------------ */
-+
-+#ifdef MY_ATOMIC_MODE_DUMMY
-+
-+#define make_atomic_load_body(S)  ret= *a
-+#define make_atomic_store_body(S)   *a= v
-+
-+#else /* MY_ATOMIC_MODE_DUMMY */
-+
-+#define make_atomic_load_body(S)                        \
-+  ret= atomic_or_ ## S ## _nv((volatile uint ## S ## _t *)a, 0)
-+
-+#define make_atomic_store_body(S)                       \
-+  (void) atomic_swap_ ## S((volatile uint ## S ## _t *)a, (uint ## S ## _t)v)
-+
-+#endif
-+
-+#define make_atomic_fas_body(S)                        \
-+  v= atomic_swap_ ## S((volatile uint ## S ## _t *)a, (uint ## S ## _t)v)
-+
-+#else /* cleanup */
-+
-+#undef uintptr_t
-+#undef atomic_or_ptr_nv
-+
-+#endif
-+
---- /dev/null
-+++ b/include/atomic/x86-gcc.h
-@@ -0,0 +1,140 @@
-+#ifndef ATOMIC_X86_GCC_INCLUDED
-+#define ATOMIC_X86_GCC_INCLUDED
-+
-+/* Copyright (C) 2006 MySQL AB
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+/*
-+  XXX 64-bit atomic operations can be implemented using
-+  cmpxchg8b, if necessary. Though I've heard that not all 64-bit
-+  architectures support double-word (128-bit) cas.
-+*/
-+
-+/*
-+  No special support of 8 and 16 bit operations are implemented here
-+  currently.
-+*/
-+#undef MY_ATOMIC_HAS_8_AND_16
-+
-+#ifdef __x86_64__
-+#  ifdef MY_ATOMIC_NO_XADD
-+#    define MY_ATOMIC_MODE "gcc-amd64" LOCK_prefix "-no-xadd"
-+#  else
-+#    define MY_ATOMIC_MODE "gcc-amd64" LOCK_prefix
-+#  endif
-+#else
-+#  ifdef MY_ATOMIC_NO_XADD
-+#    define MY_ATOMIC_MODE "gcc-x86" LOCK_prefix "-no-xadd"
-+#  else
-+#    define MY_ATOMIC_MODE "gcc-x86" LOCK_prefix
-+#  endif
-+#endif
-+
-+/* fix -ansi errors while maintaining readability */
-+#ifndef asm
-+#define asm __asm__
-+#endif
-+
-+#ifndef MY_ATOMIC_NO_XADD
-+#define make_atomic_add_body(S)         make_atomic_add_body ## S
-+#define make_atomic_cas_body(S)         make_atomic_cas_body ## S
-+#endif
-+
-+#define make_atomic_add_body32                                  \
-+  asm volatile (LOCK_prefix "; xadd %0, %1;"                    \
-+                : "+r" (v), "=m" (*a)                           \
-+                : "m" (*a)                                      \
-+                : "memory")
-+
-+#define make_atomic_cas_body32                                  \
-+  __typeof__(*cmp) sav;                                         \
-+  asm volatile (LOCK_prefix "; cmpxchg %3, %0; setz %2;"      \
-+                : "=m" (*a), "=a" (sav), "=q" (ret)             \
-+                : "r" (set), "m" (*a), "a" (*cmp)               \
-+                : "memory");                                    \
-+  if (!ret)                                                     \
-+    *cmp= sav
-+
-+#ifdef __x86_64__
-+#define make_atomic_add_body64 make_atomic_add_body32
-+#define make_atomic_cas_body64 make_atomic_cas_body32
-+
-+#define make_atomic_fas_body(S)                                 \
-+  asm volatile ("xchg %0, %1;"                                  \
-+                : "+r" (v), "=m" (*a)                           \
-+                : "m" (*a)                                      \
-+                : "memory")
-+
-+/*
-+  Actually 32/64-bit reads/writes are always atomic on x86_64,
-+  nonetheless issue memory barriers as appropriate.
-+*/
-+#define make_atomic_load_body(S)                                \
-+  /* Serialize prior load and store operations. */              \
-+  asm volatile ("mfence" ::: "memory");                         \
-+  ret= *a;                                                      \
-+  /* Prevent compiler from reordering instructions. */          \
-+  asm volatile ("" ::: "memory")
-+#define make_atomic_store_body(S)                               \
-+  asm volatile ("; xchg %0, %1;"                                \
-+                : "=m" (*a), "+r" (v)                           \
-+                : "m" (*a)                                      \
-+                : "memory")
-+
-+#else
-+/*
-+  Use default implementations of 64-bit operations since we solved
-+  the 64-bit problem on 32-bit platforms for CAS, no need to solve it
-+  once more for ADD, LOAD, STORE and FAS as well.
-+  Since we already added add32 support, we need to define add64
-+  here, but we haven't defined fas, load and store at all, so
-+  we can fallback on default implementations.
-+*/
-+#define make_atomic_add_body64                                  \
-+  int64 tmp=*a;                                                 \
-+  while (!my_atomic_cas64(a, &tmp, tmp+v)) ;                    \
-+  v=tmp;
-+
-+/*
-+  cmpxchg8b works on both 32-bit platforms and 64-bit platforms but
-+  the code here is only used on 32-bit platforms, on 64-bit
-+  platforms the much simpler make_atomic_cas_body32 will work
-+  fine.
-+*/
-+#define make_atomic_cas_body64                                              \
-+  asm volatile ("movl %%edi, -4(%%esp);"                                    \
-+                "leal %0, %%edi;"                                           \
-+                "xchgl %%ebx, %%esi;"                                       \
-+                LOCK_prefix "; cmpxchg8b (%%edi);"                          \
-+                "movl %%esi, %%ebx;"                                        \
-+                "movl -4(%%esp), %%edi;"                                    \
-+                "setz %1;"                                                  \
-+                : "+m" (*a), "=q" (ret), "+A" (*cmp)                        \
-+                : "S" ((int32)(set & 0xFFFFFFFF)), "c" ((int32)(set >> 32)) \
-+                : "memory", "flags")
-+#endif
-+
-+/*
-+  The implementation of make_atomic_cas_body32 is adaptable to
-+  the OS word size, so on 64-bit platforms it will automatically
-+  adapt to 64-bits and so it will work also on 64-bit platforms
-+*/
-+#define make_atomic_cas_bodyptr make_atomic_cas_body32
-+
-+#ifdef MY_ATOMIC_MODE_DUMMY
-+#define make_atomic_load_body(S)   ret=*a
-+#define make_atomic_store_body(S)  *a=v
-+#endif
-+#endif /* ATOMIC_X86_GCC_INCLUDED */
---- /dev/null
-+++ b/mysys/my_atomic.c
-@@ -0,0 +1,289 @@
-+#ifndef MY_ATOMIC_INCLUDED
-+#define MY_ATOMIC_INCLUDED
-+
-+/* Copyright (C) 2006 MySQL AB
-+
-+   This program is free software; you can redistribute it and/or modify
-+   it under the terms of the GNU General Public License as published by
-+   the Free Software Foundation; version 2 of the License.
-+
-+   This program is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+   GNU General Public License for more details.
-+
-+   You should have received a copy of the GNU General Public License
-+   along with this program; if not, write to the Free Software
-+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-+
-+/*
-+  This header defines five atomic operations:
-+
-+  my_atomic_add#(&var, what)
-+    'Fetch and Add'
-+    add 'what' to *var, and return the old value of *var
-+
-+  my_atomic_fas#(&var, what)
-+    'Fetch And Store'
-+    store 'what' in *var, and return the old value of *var
-+
-+  my_atomic_cas#(&var, &old, new)
-+    An odd variation of 'Compare And Set/Swap'
-+    if *var is equal to *old, then store 'new' in *var, and return TRUE
-+    otherwise store *var in *old, and return FALSE
-+    Usually, &old should not be accessed if the operation is successful.
-+
-+  my_atomic_load#(&var)
-+    return *var
-+
-+  my_atomic_store#(&var, what)
-+    store 'what' in *var
-+
-+  '#' is substituted by a size suffix - 8, 16, 32, 64, or ptr
-+  (e.g. my_atomic_add8, my_atomic_fas32, my_atomic_casptr).
-+
-+  NOTE This operations are not always atomic, so they always must be
-+  enclosed in my_atomic_rwlock_rdlock(lock)/my_atomic_rwlock_rdunlock(lock)
-+  or my_atomic_rwlock_wrlock(lock)/my_atomic_rwlock_wrunlock(lock).
-+  Hint: if a code block makes intensive use of atomic ops, it make sense
-+  to take/release rwlock once for the whole block, not for every statement.
-+
-+  On architectures where these operations are really atomic, rwlocks will
-+  be optimized away.
-+  8- and 16-bit atomics aren't implemented for windows (see generic-msvc.h),
-+  but can be added, if necessary. 
-+*/
-+
-+#include "my_global.h"
-+
-+#ifndef my_atomic_rwlock_init
-+
-+#define intptr         void *
-+/**
-+  Currently we don't support 8-bit and 16-bit operations.
-+  It can be added later if needed.
-+*/
-+#undef MY_ATOMIC_HAS_8_16
-+
-+#ifndef MY_ATOMIC_MODE_RWLOCKS
-+/*
-+ * Attempt to do atomic ops without locks
-+ */
-+#include "atomic/nolock.h"
-+#endif
-+
-+#ifndef make_atomic_cas_body
-+/* nolock.h was not able to generate even a CAS function, fall back */
-+#include "atomic/rwlock.h"
-+#endif
-+
-+/* define missing functions by using the already generated ones */
-+#ifndef make_atomic_add_body
-+#define make_atomic_add_body(S)                                 \
-+  int ## S tmp=*a;                                              \
-+  while (!my_atomic_cas ## S(a, &tmp, tmp+v)) ;                 \
-+  v=tmp;
-+#endif
-+#ifndef make_atomic_fas_body
-+#define make_atomic_fas_body(S)                                 \
-+  int ## S tmp=*a;                                              \
-+  while (!my_atomic_cas ## S(a, &tmp, v)) ;                     \
-+  v=tmp;
-+#endif
-+#ifndef make_atomic_load_body
-+#define make_atomic_load_body(S)                                \
-+  ret= 0; /* avoid compiler warning */                          \
-+  (void)(my_atomic_cas ## S(a, &ret, ret));
-+#endif
-+#ifndef make_atomic_store_body
-+#define make_atomic_store_body(S)                               \
-+  (void)(my_atomic_fas ## S (a, v));
-+#endif
-+
-+/*
-+  transparent_union doesn't work in g++
-+  Bug ?
-+
-+  Darwin's gcc doesn't want to put pointers in a transparent_union
-+  when built with -arch ppc64. Complains:
-+  warning: 'transparent_union' attribute ignored
-+*/
-+#if defined(__GNUC__) && !defined(__cplusplus) && \
-+      ! (defined(__APPLE__) && (defined(_ARCH_PPC64) ||defined (_ARCH_PPC)))
-+/*
-+  we want to be able to use my_atomic_xxx functions with
-+  both signed and unsigned integers. But gcc will issue a warning
-+  "passing arg N of `my_atomic_XXX' as [un]signed due to prototype"
-+  if the signedness of the argument doesn't match the prototype, or
-+  "pointer targets in passing argument N of my_atomic_XXX differ in signedness"
-+  if int* is used where uint* is expected (or vice versa).
-+  Let's shut these warnings up
-+*/
-+#define make_transparent_unions(S)                              \
-+        typedef union {                                         \
-+          int  ## S  i;                                         \
-+          uint ## S  u;                                         \
-+        } U_ ## S   __attribute__ ((transparent_union));        \
-+        typedef union {                                         \
-+          int  ## S volatile *i;                                \
-+          uint ## S volatile *u;                                \
-+        } Uv_ ## S   __attribute__ ((transparent_union));
-+#define uintptr intptr
-+make_transparent_unions(8)
-+make_transparent_unions(16)
-+make_transparent_unions(32)
-+make_transparent_unions(64)
-+make_transparent_unions(ptr)
-+#undef uintptr
-+#undef make_transparent_unions
-+#define a       U_a.i
-+#define cmp     U_cmp.i
-+#define v       U_v.i
-+#define set     U_set.i
-+#else
-+#define U_8    int8
-+#define U_16   int16
-+#define U_32   int32
-+#define U_64   int64
-+#define U_ptr  intptr
-+#define Uv_8   int8
-+#define Uv_16  int16
-+#define Uv_32  int32
-+#define Uv_64  int64
-+#define Uv_ptr intptr
-+#define U_a    volatile *a
-+#define U_cmp  *cmp
-+#define U_v    v
-+#define U_set  set
-+#endif /* __GCC__ transparent_union magic */
-+
-+#define make_atomic_cas(S)                                      \
-+static inline int my_atomic_cas ## S(Uv_ ## S U_a,              \
-+                            Uv_ ## S U_cmp, U_ ## S U_set)      \
-+{                                                               \
-+  int8 ret;                                                     \
-+  make_atomic_cas_body(S);                                      \
-+  return ret;                                                   \
-+}
-+
-+#define make_atomic_add(S)                                      \
-+static inline int ## S my_atomic_add ## S(                      \
-+                        Uv_ ## S U_a, U_ ## S U_v)              \
-+{                                                               \
-+  make_atomic_add_body(S);                                      \
-+  return v;                                                     \
-+}
-+
-+#define make_atomic_fas(S)                                      \
-+static inline int ## S my_atomic_fas ## S(                      \
-+                         Uv_ ## S U_a, U_ ## S U_v)             \
-+{                                                               \
-+  make_atomic_fas_body(S);                                      \
-+  return v;                                                     \
-+}
-+
-+#define make_atomic_load(S)                                     \
-+static inline int ## S my_atomic_load ## S(Uv_ ## S U_a)        \
-+{                                                               \
-+  int ## S ret;                                                 \
-+  make_atomic_load_body(S);                                     \
-+  return ret;                                                   \
-+}
-+
-+#define make_atomic_store(S)                                    \
-+static inline void my_atomic_store ## S(                        \
-+                     Uv_ ## S U_a, U_ ## S U_v)                 \
-+{                                                               \
-+  make_atomic_store_body(S);                                    \
-+}
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_cas(8)
-+make_atomic_cas(16)
-+#endif
-+make_atomic_cas(32)
-+make_atomic_cas(64)
-+make_atomic_cas(ptr)
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_add(8)
-+make_atomic_add(16)
-+#endif
-+make_atomic_add(32)
-+make_atomic_add(64)
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_load(8)
-+make_atomic_load(16)
-+#endif
-+make_atomic_load(32)
-+make_atomic_load(64)
-+make_atomic_load(ptr)
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_fas(8)
-+make_atomic_fas(16)
-+#endif
-+make_atomic_fas(32)
-+make_atomic_fas(64)
-+make_atomic_fas(ptr)
-+
-+#ifdef MY_ATOMIC_HAS_8_16
-+make_atomic_store(8)
-+make_atomic_store(16)
-+#endif
-+make_atomic_store(32)
-+make_atomic_store(64)
-+make_atomic_store(ptr)
-+
-+#ifdef _atomic_h_cleanup_
-+#include _atomic_h_cleanup_
-+#undef _atomic_h_cleanup_
-+#endif
-+
-+#undef U_8
-+#undef U_16
-+#undef U_32
-+#undef U_64
-+#undef U_ptr
-+#undef Uv_8
-+#undef Uv_16
-+#undef Uv_32
-+#undef Uv_64
-+#undef Uv_ptr
-+#undef a
-+#undef cmp
-+#undef v
-+#undef set
-+#undef U_a
-+#undef U_cmp
-+#undef U_v
-+#undef U_set
-+#undef make_atomic_add
-+#undef make_atomic_cas
-+#undef make_atomic_load
-+#undef make_atomic_store
-+#undef make_atomic_fas
-+#undef make_atomic_add_body
-+#undef make_atomic_cas_body
-+#undef make_atomic_load_body
-+#undef make_atomic_store_body
-+#undef make_atomic_fas_body
-+#undef intptr
-+
-+/*
-+  the macro below defines (as an expression) the code that
-+  will be run in spin-loops. Intel manuals recummend to have PAUSE there.
-+  It is expected to be defined in include/atomic/ *.h files
-+*/
-+#ifndef LF_BACKOFF
-+#define LF_BACKOFF (1)
-+#endif
-+
-+#define MY_ATOMIC_OK       0
-+#define MY_ATOMIC_NOT_1CPU 1
-+extern int my_atomic_initialize();
-+
-+#endif
-+
-+#endif /* MY_ATOMIC_INCLUDED */
diff --git a/slave_timeout_fix.patch b/slave_timeout_fix.patch
deleted file mode 100644 (file)
index 925b2f0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/mysql-test/include/wait_for_slave_param.inc
-+++ b/mysql-test/include/wait_for_slave_param.inc
-@@ -79,7 +79,7 @@
- # mysqltest doesn't provide any better way to multiply by 10
- --let $_wait_for_slave_param_zero= 0
----let $_slave_timeout_counter= $_slave_timeout$zero
-+--let $_slave_timeout_counter= $_slave_timeout$_wait_for_slave_param_zero
- --let $_slave_continue= 1
- while ($_slave_continue)
- {
diff --git a/subunit.patch b/subunit.patch
deleted file mode 100644 (file)
index fb59574..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-=== 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 <jelmer@samba.org>
-+#
-+#  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 ];
-@@ -223,6 +225,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_unique;
- use IO::Socket::INET;
- use IO::Select;
-+use Subunit;
- require "lib/mtr_process.pl";
- require "lib/mtr_io.pl";
-@@ -529,6 +530,7 @@
-         # Report test status
-         mtr_report_test($result);
-+        mtr_report_test_subunit($result);
-         if ( $result->is_failed() ) {
diff --git a/utf8_general50_ci.patch b/utf8_general50_ci.patch
deleted file mode 100644 (file)
index 260adef..0000000
+++ /dev/null
@@ -1,440 +0,0 @@
-# MySQL bug#43593 dump/backup/restore/upgrade tools fails
-# 
-# The patch is intended to help to those users:
-# - Having indexes on columns with collations
-#   utf8_general_ci or ucs2_general_ci
-# - Having German letter SHARP S (SZLIG) in these columns
-# - Upgrading from MySQL from versions 5.0.x or
-#   5.1.23 (and earlier) to version 5.1.24 (and higher).
-# 
-# This patch introduces new collations utf8_general50_ci
-# and ucs2_general50_ci which reproduce the "old"
-# sorting order provided by pre-5.1.24 versions of xxx_general_ci.
-# 
-# In order to start using new MySQL-5.1.24+ please do the following:
-# 
-# - Start new version of mysqld
-# - Convert all affected tables using this query (in case of utf8):
-# 
-# ALTER TABLE t1 CONVERT TO CHARACTER SET utf8 COLLATE utf8_general50_ci;
-# 
-# Or if you need to apply changes per-column level, use this example:
-# 
-# ALTER TABLE t1 MODIFY c1 CHAR(N) CHARACTER SET utf8 COLLATE utf8_general50_ci;
-# 
-# (Make sure you're using the old data type and size,
-# NULL/NOT NULL constraints, etc).
-# 
-=== modified file 'mysys/charset-def.c'
---- a/mysys/charset-def.c
-+++ b/mysys/charset-def.c
-@@ -21,6 +21,9 @@
-   init_compiled_charsets() that only adds those that he wants
- */
-+extern CHARSET_INFO my_charset_ucs2_general50_ci;
-+extern CHARSET_INFO my_charset_utf8_general50_ci;
-+
- #ifdef HAVE_UCA_COLLATIONS
- #ifdef HAVE_CHARSET_ucs2
-@@ -132,6 +135,7 @@
- #ifdef HAVE_CHARSET_ucs2
-   add_compiled_collation(&my_charset_ucs2_general_ci);
-   add_compiled_collation(&my_charset_ucs2_bin);
-+  add_compiled_collation(&my_charset_ucs2_general50_ci);
- #ifdef HAVE_UCA_COLLATIONS
-   add_compiled_collation(&my_charset_ucs2_unicode_ci);
-   add_compiled_collation(&my_charset_ucs2_icelandic_uca_ci);
-@@ -163,6 +167,7 @@
- #ifdef HAVE_CHARSET_utf8
-   add_compiled_collation(&my_charset_utf8_general_ci);
-   add_compiled_collation(&my_charset_utf8_bin);
-+  add_compiled_collation(&my_charset_utf8_general50_ci);
- #ifdef HAVE_UTF8_GENERAL_CS
-   add_compiled_collation(&my_charset_utf8_general_cs);
- #endif
---- a/strings/ctype-ucs2.c
-+++ b/strings/ctype-ucs2.c
-@@ -1732,6 +1732,42 @@
-     &my_collation_ucs2_general_ci_handler
- };
-+
-+extern MY_UNICASE_INFO *my_unicase_general50[256];
-+
-+CHARSET_INFO my_charset_ucs2_general50_ci=
-+{
-+    159,0,0,                  /* number       */
-+    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
-+    "ucs2",                   /* cs name    */
-+    "ucs2_general50_ci",      /* name         */
-+    "",                               /* comment      */
-+    NULL,                     /* tailoring    */
-+    ctype_ucs2,                       /* ctype        */
-+    to_lower_ucs2,            /* to_lower     */
-+    to_upper_ucs2,            /* to_upper     */
-+    to_upper_ucs2,            /* sort_order   */
-+    NULL,                     /* contractions */
-+    NULL,                     /* sort_order_big*/
-+    NULL,                     /* tab_to_uni   */
-+    NULL,                     /* tab_from_uni */
-+    my_unicase_general50,     /* caseinfo     */
-+    NULL,                     /* state_map    */
-+    NULL,                     /* ident_map    */
-+    1,                                /* strxfrm_multiply */
-+    1,                        /* caseup_multiply  */
-+    1,                        /* casedn_multiply  */
-+    2,                                /* mbminlen     */
-+    2,                                /* mbmaxlen     */
-+    0,                                /* min_sort_char */
-+    0xFFFF,                   /* max_sort_char */
-+    ' ',                      /* pad char      */
-+    0,                        /* escape_with_backslash_is_dangerous */
-+    &my_charset_ucs2_handler,
-+    &my_collation_ucs2_general_ci_handler
-+};
-+
-+
- CHARSET_INFO my_charset_ucs2_bin=
- {
-     90,0,0,           /* number       */
---- a/strings/ctype-utf8.c
-+++ b/strings/ctype-utf8.c
-@@ -177,6 +177,138 @@
- };
-+static MY_UNICASE_INFO plane00_general50[]={
-+  {0x0000,0x0000,0x0000},  {0x0001,0x0001,0x0001},
-+  {0x0002,0x0002,0x0002},  {0x0003,0x0003,0x0003},
-+  {0x0004,0x0004,0x0004},  {0x0005,0x0005,0x0005},
-+  {0x0006,0x0006,0x0006},  {0x0007,0x0007,0x0007},
-+  {0x0008,0x0008,0x0008},  {0x0009,0x0009,0x0009},
-+  {0x000A,0x000A,0x000A},  {0x000B,0x000B,0x000B},
-+  {0x000C,0x000C,0x000C},  {0x000D,0x000D,0x000D},
-+  {0x000E,0x000E,0x000E},  {0x000F,0x000F,0x000F},
-+  {0x0010,0x0010,0x0010},  {0x0011,0x0011,0x0011},
-+  {0x0012,0x0012,0x0012},  {0x0013,0x0013,0x0013},
-+  {0x0014,0x0014,0x0014},  {0x0015,0x0015,0x0015},
-+  {0x0016,0x0016,0x0016},  {0x0017,0x0017,0x0017},
-+  {0x0018,0x0018,0x0018},  {0x0019,0x0019,0x0019},
-+  {0x001A,0x001A,0x001A},  {0x001B,0x001B,0x001B},
-+  {0x001C,0x001C,0x001C},  {0x001D,0x001D,0x001D},
-+  {0x001E,0x001E,0x001E},  {0x001F,0x001F,0x001F},
-+  {0x0020,0x0020,0x0020},  {0x0021,0x0021,0x0021},
-+  {0x0022,0x0022,0x0022},  {0x0023,0x0023,0x0023},
-+  {0x0024,0x0024,0x0024},  {0x0025,0x0025,0x0025},
-+  {0x0026,0x0026,0x0026},  {0x0027,0x0027,0x0027},
-+  {0x0028,0x0028,0x0028},  {0x0029,0x0029,0x0029},
-+  {0x002A,0x002A,0x002A},  {0x002B,0x002B,0x002B},
-+  {0x002C,0x002C,0x002C},  {0x002D,0x002D,0x002D},
-+  {0x002E,0x002E,0x002E},  {0x002F,0x002F,0x002F},
-+  {0x0030,0x0030,0x0030},  {0x0031,0x0031,0x0031},
-+  {0x0032,0x0032,0x0032},  {0x0033,0x0033,0x0033},
-+  {0x0034,0x0034,0x0034},  {0x0035,0x0035,0x0035},
-+  {0x0036,0x0036,0x0036},  {0x0037,0x0037,0x0037},
-+  {0x0038,0x0038,0x0038},  {0x0039,0x0039,0x0039},
-+  {0x003A,0x003A,0x003A},  {0x003B,0x003B,0x003B},
-+  {0x003C,0x003C,0x003C},  {0x003D,0x003D,0x003D},
-+  {0x003E,0x003E,0x003E},  {0x003F,0x003F,0x003F},
-+  {0x0040,0x0040,0x0040},  {0x0041,0x0061,0x0041},
-+  {0x0042,0x0062,0x0042},  {0x0043,0x0063,0x0043},
-+  {0x0044,0x0064,0x0044},  {0x0045,0x0065,0x0045},
-+  {0x0046,0x0066,0x0046},  {0x0047,0x0067,0x0047},
-+  {0x0048,0x0068,0x0048},  {0x0049,0x0069,0x0049},
-+  {0x004A,0x006A,0x004A},  {0x004B,0x006B,0x004B},
-+  {0x004C,0x006C,0x004C},  {0x004D,0x006D,0x004D},
-+  {0x004E,0x006E,0x004E},  {0x004F,0x006F,0x004F},
-+  {0x0050,0x0070,0x0050},  {0x0051,0x0071,0x0051},
-+  {0x0052,0x0072,0x0052},  {0x0053,0x0073,0x0053},
-+  {0x0054,0x0074,0x0054},  {0x0055,0x0075,0x0055},
-+  {0x0056,0x0076,0x0056},  {0x0057,0x0077,0x0057},
-+  {0x0058,0x0078,0x0058},  {0x0059,0x0079,0x0059},
-+  {0x005A,0x007A,0x005A},  {0x005B,0x005B,0x005B},
-+  {0x005C,0x005C,0x005C},  {0x005D,0x005D,0x005D},
-+  {0x005E,0x005E,0x005E},  {0x005F,0x005F,0x005F},
-+  {0x0060,0x0060,0x0060},  {0x0041,0x0061,0x0041},
-+  {0x0042,0x0062,0x0042},  {0x0043,0x0063,0x0043},
-+  {0x0044,0x0064,0x0044},  {0x0045,0x0065,0x0045},
-+  {0x0046,0x0066,0x0046},  {0x0047,0x0067,0x0047},
-+  {0x0048,0x0068,0x0048},  {0x0049,0x0069,0x0049},
-+  {0x004A,0x006A,0x004A},  {0x004B,0x006B,0x004B},
-+  {0x004C,0x006C,0x004C},  {0x004D,0x006D,0x004D},
-+  {0x004E,0x006E,0x004E},  {0x004F,0x006F,0x004F},
-+  {0x0050,0x0070,0x0050},  {0x0051,0x0071,0x0051},
-+  {0x0052,0x0072,0x0052},  {0x0053,0x0073,0x0053},
-+  {0x0054,0x0074,0x0054},  {0x0055,0x0075,0x0055},
-+  {0x0056,0x0076,0x0056},  {0x0057,0x0077,0x0057},
-+  {0x0058,0x0078,0x0058},  {0x0059,0x0079,0x0059},
-+  {0x005A,0x007A,0x005A},  {0x007B,0x007B,0x007B},
-+  {0x007C,0x007C,0x007C},  {0x007D,0x007D,0x007D},
-+  {0x007E,0x007E,0x007E},  {0x007F,0x007F,0x007F},
-+  {0x0080,0x0080,0x0080},  {0x0081,0x0081,0x0081},
-+  {0x0082,0x0082,0x0082},  {0x0083,0x0083,0x0083},
-+  {0x0084,0x0084,0x0084},  {0x0085,0x0085,0x0085},
-+  {0x0086,0x0086,0x0086},  {0x0087,0x0087,0x0087},
-+  {0x0088,0x0088,0x0088},  {0x0089,0x0089,0x0089},
-+  {0x008A,0x008A,0x008A},  {0x008B,0x008B,0x008B},
-+  {0x008C,0x008C,0x008C},  {0x008D,0x008D,0x008D},
-+  {0x008E,0x008E,0x008E},  {0x008F,0x008F,0x008F},
-+  {0x0090,0x0090,0x0090},  {0x0091,0x0091,0x0091},
-+  {0x0092,0x0092,0x0092},  {0x0093,0x0093,0x0093},
-+  {0x0094,0x0094,0x0094},  {0x0095,0x0095,0x0095},
-+  {0x0096,0x0096,0x0096},  {0x0097,0x0097,0x0097},
-+  {0x0098,0x0098,0x0098},  {0x0099,0x0099,0x0099},
-+  {0x009A,0x009A,0x009A},  {0x009B,0x009B,0x009B},
-+  {0x009C,0x009C,0x009C},  {0x009D,0x009D,0x009D},
-+  {0x009E,0x009E,0x009E},  {0x009F,0x009F,0x009F},
-+  {0x00A0,0x00A0,0x00A0},  {0x00A1,0x00A1,0x00A1},
-+  {0x00A2,0x00A2,0x00A2},  {0x00A3,0x00A3,0x00A3},
-+  {0x00A4,0x00A4,0x00A4},  {0x00A5,0x00A5,0x00A5},
-+  {0x00A6,0x00A6,0x00A6},  {0x00A7,0x00A7,0x00A7},
-+  {0x00A8,0x00A8,0x00A8},  {0x00A9,0x00A9,0x00A9},
-+  {0x00AA,0x00AA,0x00AA},  {0x00AB,0x00AB,0x00AB},
-+  {0x00AC,0x00AC,0x00AC},  {0x00AD,0x00AD,0x00AD},
-+  {0x00AE,0x00AE,0x00AE},  {0x00AF,0x00AF,0x00AF},
-+  {0x00B0,0x00B0,0x00B0},  {0x00B1,0x00B1,0x00B1},
-+  {0x00B2,0x00B2,0x00B2},  {0x00B3,0x00B3,0x00B3},
-+  {0x00B4,0x00B4,0x00B4},  {0x039C,0x00B5,0x039C},
-+  {0x00B6,0x00B6,0x00B6},  {0x00B7,0x00B7,0x00B7},
-+  {0x00B8,0x00B8,0x00B8},  {0x00B9,0x00B9,0x00B9},
-+  {0x00BA,0x00BA,0x00BA},  {0x00BB,0x00BB,0x00BB},
-+  {0x00BC,0x00BC,0x00BC},  {0x00BD,0x00BD,0x00BD},
-+  {0x00BE,0x00BE,0x00BE},  {0x00BF,0x00BF,0x00BF},
-+  {0x00C0,0x00E0,0x0041},  {0x00C1,0x00E1,0x0041},
-+  {0x00C2,0x00E2,0x0041},  {0x00C3,0x00E3,0x0041},
-+  {0x00C4,0x00E4,0x0041},  {0x00C5,0x00E5,0x0041},
-+  {0x00C6,0x00E6,0x00C6},  {0x00C7,0x00E7,0x0043},
-+  {0x00C8,0x00E8,0x0045},  {0x00C9,0x00E9,0x0045},
-+  {0x00CA,0x00EA,0x0045},  {0x00CB,0x00EB,0x0045},
-+  {0x00CC,0x00EC,0x0049},  {0x00CD,0x00ED,0x0049},
-+  {0x00CE,0x00EE,0x0049},  {0x00CF,0x00EF,0x0049},
-+  {0x00D0,0x00F0,0x00D0},  {0x00D1,0x00F1,0x004E},
-+  {0x00D2,0x00F2,0x004F},  {0x00D3,0x00F3,0x004F},
-+  {0x00D4,0x00F4,0x004F},  {0x00D5,0x00F5,0x004F},
-+  {0x00D6,0x00F6,0x004F},  {0x00D7,0x00D7,0x00D7},
-+  {0x00D8,0x00F8,0x00D8},  {0x00D9,0x00F9,0x0055},
-+  {0x00DA,0x00FA,0x0055},  {0x00DB,0x00FB,0x0055},
-+  {0x00DC,0x00FC,0x0055},  {0x00DD,0x00FD,0x0059},
-+  {0x00DE,0x00FE,0x00DE},  {0x00DF,0x00DF,0x00DF},
-+  {0x00C0,0x00E0,0x0041},  {0x00C1,0x00E1,0x0041},
-+  {0x00C2,0x00E2,0x0041},  {0x00C3,0x00E3,0x0041},
-+  {0x00C4,0x00E4,0x0041},  {0x00C5,0x00E5,0x0041},
-+  {0x00C6,0x00E6,0x00C6},  {0x00C7,0x00E7,0x0043},
-+  {0x00C8,0x00E8,0x0045},  {0x00C9,0x00E9,0x0045},
-+  {0x00CA,0x00EA,0x0045},  {0x00CB,0x00EB,0x0045},
-+  {0x00CC,0x00EC,0x0049},  {0x00CD,0x00ED,0x0049},
-+  {0x00CE,0x00EE,0x0049},  {0x00CF,0x00EF,0x0049},
-+  {0x00D0,0x00F0,0x00D0},  {0x00D1,0x00F1,0x004E},
-+  {0x00D2,0x00F2,0x004F},  {0x00D3,0x00F3,0x004F},
-+  {0x00D4,0x00F4,0x004F},  {0x00D5,0x00F5,0x004F},
-+  {0x00D6,0x00F6,0x004F},  {0x00F7,0x00F7,0x00F7},
-+  {0x00D8,0x00F8,0x00D8},  {0x00D9,0x00F9,0x0055},
-+  {0x00DA,0x00FA,0x0055},  {0x00DB,0x00FB,0x0055},
-+  {0x00DC,0x00FC,0x0055},  {0x00DD,0x00FD,0x0059},
-+  {0x00DE,0x00FE,0x00DE},  {0x0178,0x00FF,0x0059}
-+};
-+
-+
- static MY_UNICASE_INFO plane01[]={
-   {0x0100,0x0101,0x0041},  {0x0100,0x0101,0x0041},
-@@ -1526,6 +1658,48 @@
- /*
-+  general50: to reproduce old utf8_general_ci behaviour
-+  before we fixed Bug#27877.
-+*/
-+MY_UNICASE_INFO *my_unicase_general50[256]={
-+ plane00_general50,
-+          plane01, plane02, plane03, plane04, plane05,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL, plane1E, plane1F,
-+    NULL, plane21,    NULL,    NULL, plane24,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
-+    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL, planeFF
-+
-+};
-+
-+
-+/*
-   Turkish lower/upper mapping:
-   1. LOWER(0x0049 LATIN CAPITAL LETTER I) -> 
-            0x0131 LATIN SMALL   LETTER DOTLESS I
-@@ -2720,6 +2894,39 @@
- };
-+CHARSET_INFO my_charset_utf8_general50_ci=
-+{
-+    253,0,0,              /* number       */
-+    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,  /* state  */
-+    "utf8",               /* cs name      */
-+    "utf8_general50_ci",  /* name         */
-+    "",                   /* comment      */
-+    NULL,                 /* tailoring    */
-+    ctype_utf8,           /* ctype        */
-+    to_lower_utf8,        /* to_lower     */
-+    to_upper_utf8,        /* to_upper     */
-+    to_upper_utf8,        /* sort_order   */
-+    NULL,                 /* contractions */
-+    NULL,                 /* sort_order_big*/
-+    NULL,                 /* tab_to_uni   */
-+    NULL,                 /* tab_from_uni */
-+    my_unicase_general50, /* caseinfo     */
-+    NULL,                 /* state_map    */
-+    NULL,                 /* ident_map    */
-+    1,                    /* strxfrm_multiply */
-+    1,                    /* caseup_multiply  */
-+    1,                    /* casedn_multiply  */
-+    1,                    /* mbminlen     */
-+    3,                    /* mbmaxlen     */
-+    0,                    /* min_sort_char */
-+    0xFFFF,               /* max_sort_char */
-+    ' ',                  /* pad char      */
-+    0,                    /* escape_with_backslash_is_dangerous */
-+    &my_charset_utf8_handler,
-+    &my_collation_ci_handler
-+};
-+
-+
- CHARSET_INFO my_charset_utf8_bin=
- {
-     83,0,0,             /* number       */
---- /dev/null
-+++ b/mysql-test/r/percona_ucs2_general50_ci.result
-@@ -0,0 +1,38 @@
-+SET NAMES latin1;
-+SET collation_connection='ucs2_general50_ci';
-+drop table if exists t1;
-+create table t1 as select repeat(' ', 64) as s1;
-+select collation(s1) from t1;
-+collation(s1)
-+ucs2_general50_ci
-+delete from t1;
-+insert into t1 values ('a'),('ae'),(_latin1 0xE4);
-+insert into t1 values ('o'),('oe'),(_latin1 0xF6);
-+insert into t1 values ('s'),('ss'),(_latin1 0xDF);
-+insert into t1 values ('u'),('ue'),(_latin1 0xFC);
-+select s1, hex(s1) from t1 order by s1, binary s1;
-+s1    hex(s1)
-+a     0061
-+ä     00E4
-+ae    00610065
-+o     006F
-+ö     00F6
-+oe    006F0065
-+s     0073
-+ss    00730073
-+u     0075
-+ü     00FC
-+ue    00750065
-+ß     00DF
-+select group_concat(s1 order by binary s1) from t1 group by s1;
-+group_concat(s1 order by binary s1)
-+a,ä
-+ae
-+o,ö
-+oe
-+s
-+ss
-+u,ü
-+ue
-+ß
-+drop table t1;
---- /dev/null
-+++ b/mysql-test/t/percona_ucs2_general50_ci.test
-@@ -0,0 +1,12 @@
-+#
-+# Test that ucs2_general50_ci provides pre-5.1.24 utf8_general_ci behavior,
-+# i.e. SHARP S is only equal to itself.
-+#
-+
-+--source include/have_ucs2.inc
-+
-+SET NAMES latin1;
-+
-+SET collation_connection='ucs2_general50_ci';
-+
-+--source include/ctype_german.inc
---- /dev/null
-+++ b/mysql-test/t/percona_utf8_general50_ci.test
-@@ -0,0 +1,9 @@
-+#
-+# Test that utf8_general50_ci provides pre-5.1.24 utf8_general_ci behavior,
-+# i.e. SHARP S is only equal to itself.
-+#
-+
-+SET NAMES utf8;
-+
-+SET collation_connection='utf8_general50_ci';
-+--source include/ctype_german.inc
---- /dev/null
-+++ b/mysql-test/r/percona_utf8_general50_ci.result
-@@ -0,0 +1,38 @@
-+SET NAMES utf8;
-+SET collation_connection='utf8_general50_ci';
-+drop table if exists t1;
-+create table t1 as select repeat(' ', 64) as s1;
-+select collation(s1) from t1;
-+collation(s1)
-+utf8_general50_ci
-+delete from t1;
-+insert into t1 values ('a'),('ae'),(_latin1 0xE4);
-+insert into t1 values ('o'),('oe'),(_latin1 0xF6);
-+insert into t1 values ('s'),('ss'),(_latin1 0xDF);
-+insert into t1 values ('u'),('ue'),(_latin1 0xFC);
-+select s1, hex(s1) from t1 order by s1, binary s1;
-+s1    hex(s1)
-+a     61
-+ä    C3A4
-+ae    6165
-+o     6F
-+ö    C3B6
-+oe    6F65
-+s     73
-+ss    7373
-+u     75
-+ü    C3BC
-+ue    7565
-+ß    C39F
-+select group_concat(s1 order by binary s1) from t1 group by s1;
-+group_concat(s1 order by binary s1)
-+a,ä
-+ae
-+o,ö
-+oe
-+s
-+ss
-+u,ü
-+ue
-+ß
-+drop table t1;
diff --git a/warning_fixes.patch b/warning_fixes.patch
deleted file mode 100644 (file)
index c0322f0..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
---- a/sql/log.cc
-+++ b/sql/log.cc
-@@ -1905,7 +1905,7 @@
- static int find_uniq_filename(char *name)
- {
--  long                  number;
-+  long                  UNINIT_VAR(number);
-   uint                  i;
-   char                  buff[FN_REFLEN];
-   struct st_my_dir     *dir_info;
---- a/sql/sql_table.cc
-+++ b/sql/sql_table.cc
-@@ -7140,7 +7140,9 @@
-     need_copy_table= ALTER_TABLE_DATA_CHANGED;
-   else
-   {
--    enum_alter_table_change_level need_copy_table_res;
-+    enum_alter_table_change_level need_copy_table_res=
-+        ALTER_TABLE_METADATA_ONLY;
-+
-     /* Check how much the tables differ. */
-     if (compare_tables(table, alter_info,
-                        create_info, order_num,
diff --git a/xtradb_bug317074.patch b/xtradb_bug317074.patch
deleted file mode 100644 (file)
index 93872e4..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
---- /dev/null
-+++ b/mysql-test/r/percona_xtradb_bug317074.result
-@@ -0,0 +1,4 @@
-+SET @old_innodb_file_format=@@innodb_file_format;
-+SET @old_innodb_file_per_table=@@innodb_file_per_table;
-+SET GLOBAL innodb_file_format='Barracuda';
-+SET GLOBAL innodb_file_per_table=ON;
---- /dev/null
-+++ b/mysql-test/t/percona_xtradb_bug317074.test
-@@ -0,0 +1,47 @@
-+-- source include/have_innodb.inc
-+
-+SET @old_innodb_file_format=@@innodb_file_format;
-+SET @old_innodb_file_per_table=@@innodb_file_per_table;
-+let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
-+SET GLOBAL innodb_file_format='Barracuda';
-+SET GLOBAL innodb_file_per_table=ON;
-+
-+-- disable_query_log
-+-- disable_result_log
-+
-+DROP TABLE IF EXISTS `test1`;
-+CREATE TABLE IF NOT EXISTS `test1` (
-+ `a` int primary key auto_increment,
-+ `b` int default 0,
-+ `c` char(100) default 'testtest'
-+) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
-+
-+delimiter |;
-+CREATE PROCEDURE insert_many(p1 int)
-+BEGIN
-+SET @x = 0;
-+SET @y = 0;
-+start transaction;
-+REPEAT
-+  insert into test1 set b=1;
-+  SET @x = @x + 1;
-+  SET @y = @y + 1;
-+  IF @y >= 1000 THEN
-+    commit;
-+    start transaction;
-+    SET @y = 0;
-+  END IF;
-+UNTIL @x >= p1 END REPEAT;
-+commit;
-+END|
-+delimiter ;|
-+call insert_many(100000);
-+DROP PROCEDURE insert_many;
-+
-+# The bug is hangup at the following statement
-+ALTER TABLE test1 ENGINE=MyISAM;
-+
-+DROP TABLE test1;
-+SET GLOBAL innodb_file_format=@old_innodb_file_format;
-+SET GLOBAL innodb_file_per_table=@old_innodb_file_per_table;
-+eval set global innodb_file_format_check=$innodb_file_format_check_orig;
This page took 2.278758 seconds and 4 git commands to generate.