[Commits] Rev 3367: Fixed bug mdev-504. in file:///home/igor/maria/maria-5.5-mwl248-bugs/

Igor Babaev igor at askmonty.org
Sat Sep 8 22:04:31 EEST 2012


At file:///home/igor/maria/maria-5.5-mwl248-bugs/

------------------------------------------------------------
revno: 3367
revision-id: igor at askmonty.org-20120908190431-mje3j7ostvsm7g18
parent: igor at askmonty.org-20120902065147-1b2kr5wc1eks7aaf
committer: Igor Babaev <igor at askmonty.org>
branch nick: maria-5.5-mwl248-bugs
timestamp: Sat 2012-09-08 12:04:31 -0700
message:
  Fixed bug mdev-504.
  Opening system statistical tables and reading statistical data from 
  them for a regular table should be done after opening and locking 
  this regular table.
  No test case is provided with this patch.
-------------- next part --------------
=== modified file 'mysql-test/t/stat_tables_par.test'
--- a/mysql-test/t/stat_tables_par.test	2012-07-28 00:33:23 +0000
+++ b/mysql-test/t/stat_tables_par.test	2012-09-08 19:04:31 +0000
@@ -40,7 +40,7 @@
 #    assumes that start the code of memory allocation for stats data has this line:
 #
 #       DEBUG_SYNC(thd, "statistics_mem_alloc_start1");
-#       DEBUG_SYNC(thd, "statistics_mem_alloc-start2");
+#       DEBUG_SYNC(thd, "statistics_mem_alloc_start2");
 #
 
 let $Q6=

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2012-09-02 06:51:47 +0000
+++ b/sql/sql_base.cc	2012-09-08 19:04:31 +0000
@@ -4665,13 +4665,7 @@
           (*table_field_ptr)->read_stats= (*field_ptr)->read_stats;
   
 	table_share->stats_can_be_read= TRUE;
-      }
-	
-      if (table_share->stats_can_be_read && !table_share->stats_is_read)
-      {    
-         (void) read_statistics_for_table(thd, tables->table);
-         table_share->stats_is_read= TRUE;
-      }  
+      }	
     }
   }
 
@@ -5615,6 +5609,8 @@
   if (lock_tables(thd, tables, counter, flags))
     goto err;
 
+  (void) read_statistics_for_tables_if_needed(thd, tables);
+  
   if (derived)
   {
     if (mysql_handle_derived(thd->lex, DT_INIT))

=== modified file 'sql/sql_base.h'
--- a/sql/sql_base.h	2012-07-27 00:50:08 +0000
+++ b/sql/sql_base.h	2012-09-08 19:04:31 +0000
@@ -312,7 +312,7 @@
 /* open_and_lock_tables with optional derived handling */
 int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived);
 
-int read_statistics_for_table(THD *thd, TABLE *table);
+int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables);
 int collect_statistics_for_table(THD *thd, TABLE *table);
 int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *share,
                                      bool is_safe);

=== modified file 'sql/sql_statistics.cc'
--- a/sql/sql_statistics.cc	2012-08-27 21:19:25 +0000
+++ b/sql/sql_statistics.cc	2012-09-08 19:04:31 +0000
@@ -1726,7 +1726,7 @@
   Field **field_ptr;
   uint cnt= 0;
 
-  DBUG_ENTER("alloc_statistics_for_table");
+  DBUG_ENTER("alloc_statistics_for_table_share");
 
   DEBUG_SYNC(thd, "statistics_mem_alloc_start1");
   DEBUG_SYNC(thd, "statistics_mem_alloc_start2");
@@ -2245,6 +2245,8 @@
   thd         The thread handle
   @param
   table       The table to read statistics on
+  @param
+  stat_tables The array of TABLE_LIST objects for statistical tables
 
   @details
   For each statistical table the function looks for the rows from this
@@ -2252,54 +2254,42 @@
   the data from statistical columns of it is read into the appropriate
   fields of internal structures for 'table'. Later at the query processing
   this data are supposed to be used by the optimizer. 
-  The function is called in function open_tables.
+  The parameter stat_tables should point to an array of TABLE_LIST
+  objects for all statistical tables linked into a list. All statistical
+  tables are supposed to be opened.  
+  The function is called by read_statistics_for_table_if_needed().
 
   @retval
-  0         If data has been successfully read from all statistical tables  
+  0         If data has been successfully read for the table  
   @retval
   1         Otherwise
 
   @note
-  The function first calls the function open_system_tables_for_read to
-  be able to read info from the statistical tables. On success the data is
-  read from one table after another after which the statistical tables are
-  closed. Objects of the helper classes Table_stat, Column_stat and Index_stat
+  Objects of the helper classes Table_stat, Column_stat and Index_stat
   are employed to read statistical data from the statistical tables. 
-  TODO. Consider a variant when statistical tables are opened and closed
-  only once for all tables, not for every table of the query as it's done
   now.        
 */
 
-int read_statistics_for_table(THD *thd, TABLE *table)
+static
+int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
 {
   uint i;
   TABLE *stat_table;
   Field *table_field;
   Field **field_ptr;
   KEY *key_info, *key_info_end;
-  TABLE_LIST tables[STATISTICS_TABLES];
-  Open_tables_backup open_tables_backup;
   TABLE_SHARE *table_share= table->s;
 
   DBUG_ENTER("read_statistics_for_table");
 
-  init_table_list_for_stat_tables(tables, FALSE);  
-  init_mdl_requests(tables);
-  
-  if (open_system_tables_for_read(thd, tables, &open_tables_backup))
-  {
-    thd->clear_error();
-    DBUG_RETURN(0);
-  }
-
   /* Read statistics from the statistical table table_stat */
-  stat_table= tables[TABLE_STAT].table;
+  stat_table= stat_tables[TABLE_STAT].table;
   Table_stat table_stat(stat_table, table);
   table_stat.set_key_fields();
   table_stat.get_stat_values();
    
   /* Read statistics from the statistical table column_stat */
-  stat_table= tables[COLUMN_STAT].table;
+  stat_table= stat_tables[COLUMN_STAT].table;
   Column_stat column_stat(stat_table, table);
   for (field_ptr= table_share->field; *field_ptr; field_ptr++)
   {
@@ -2309,7 +2299,7 @@
   }
 
   /* Read statistics from the statistical table index_stat */
-  stat_table= tables[INDEX_STAT].table;
+  stat_table= stat_tables[INDEX_STAT].table;
   Index_stat index_stat(stat_table, table);
   for (key_info= table_share->key_info,
        key_info_end= key_info + table_share->keys;
@@ -2369,6 +2359,124 @@
     }
   }
       
+  DBUG_RETURN(0);
+}
+
+
+/**
+  @brief
+  Check whether any statistics is to be read for tables from a table list
+
+  @param
+  thd         The thread handle
+  @param
+  tables      The tables list for whose tables the check is to be done
+
+  @details
+  The function checks whether for any of the tables opened and locked for
+  a statement statistics from statistical tables is needed to be read.
+
+  @retval
+  TRUE        statistics for any of the tables is needed to be read 
+  @retval
+  FALSE       Otherwise
+*/
+
+static
+bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables)
+{
+  if (thd->bootstrap || thd->variables.use_stat_tables == 0)
+    return FALSE;
+
+  if (!tables)
+    return FALSE;
+  
+  switch(thd->lex->sql_command) {
+  case SQLCOM_SELECT:
+  case SQLCOM_INSERT:
+  case SQLCOM_INSERT_SELECT:
+  case SQLCOM_UPDATE:
+  case SQLCOM_UPDATE_MULTI:
+  case SQLCOM_DELETE:
+  case SQLCOM_DELETE_MULTI:
+  case SQLCOM_REPLACE:
+  case SQLCOM_REPLACE_SELECT:
+    break;
+  default: 
+    return FALSE;
+  }
+
+  for (TABLE_LIST *tl= tables; tl; tl= tl->next_global)
+  {
+    if (!tl->is_view_or_derived() && tl->table)
+    {
+      TABLE_SHARE *table_share= tl->table->s;
+      if (table_share && 
+          table_share->stats_can_be_read &&
+          !table_share->stats_is_read)
+        return TRUE;
+    } 
+  }
+
+  return FALSE;
+}
+
+
+/**
+  @brief
+  Read statistics for tables from a table list if it is needed
+
+  @param
+  thd         The thread handle
+  @param
+  tables      The tables list for whose tables to read statistics
+
+  @details
+  The function first checks whether for any of the tables opened and locked
+  for a statement statistics from statistical tables is needed to be read.
+  Then, if so, it opens system statistical tables for read and reads
+  the statistical data from them for those tables from the list for which it
+  makes sense. Then the function closes system statistical tables.
+
+  @retval
+  0       Statistics for tables was successfully read  
+  @retval
+  1       Otherwise
+*/
+
+int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables)
+{
+  TABLE_LIST stat_tables[STATISTICS_TABLES];
+  Open_tables_backup open_tables_backup;
+
+  DBUG_ENTER("read_statistics_for_table_if_needed");
+
+  if (!statistics_for_tables_is_needed(thd, tables))
+    DBUG_RETURN(0);
+
+  init_table_list_for_stat_tables(stat_tables, FALSE);  
+  init_mdl_requests(stat_tables);
+  if (open_system_tables_for_read(thd, stat_tables, &open_tables_backup))
+  {
+    thd->clear_error();
+    DBUG_RETURN(1);
+  }
+
+  for (TABLE_LIST *tl= tables; tl; tl= tl->next_global)
+  {
+    if (!tl->is_view_or_derived() && tl->table)
+    { 
+      TABLE_SHARE *table_share= tl->table->s;
+      if (table_share && 
+          table_share->stats_can_be_read &&
+	  !table_share->stats_is_read)
+      {
+        (void) read_statistics_for_table(thd, tl->table, stat_tables);
+        table_share->stats_is_read= TRUE;
+      }
+    }
+  }  
+
   close_system_tables(thd, &open_tables_backup);
 
   DBUG_RETURN(0);



More information about the commits mailing list