MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:June 9 2010 1:35pm
Subject:bzr commit into mysql-trunk-runtime branch (kostja:3050) WL#5419
View as plain text  
#At file:///opt/local/work/trunk-runtime/ based on revid:magne.mahre@stripped

 3050 Konstantin Osipov	2010-06-09
      A pre-requisite patch for WL#5419 "LOCK_open scalability: 
      make tdc_refresh_version an atomic counter".
      
      To avoid orphaned TABLE_SHARE objects left in the
      cache, make sure that wherever we set table->s->version
      we take care of removing all unused table share objects
      from the table cache. 
      
      Always set table->s->version under LOCK_open, to make sure
      that no other connection sees an old value of the
      version and adds the table to unused_tables list.
      
      Add an assert to table_def_unuse_table() that we never
      'unuse' a talbe of a share that has an old version.
      
      With this patch, only three places are left in the code
      that manipulate with table->s->version:
      - tdc_remove_table(). In most cases we have an X mdl lock
      in tdc_remove_table(), the two remaining cases when we
      don't are 'FLUSH TABLE' and mysql_admin_table().
      - sql_view.cc - a crude hack that needs a separate fix
      - initial assignment from refresh_version in table.cc.
     @ mysql-test/r/handler_innodb.result
        We no longer call wait_while_table_is_used() for
        OPTIMIZE, and thus OPTIMIZE no longer closes HANDLER cursor.
        Cursor position, pointing beyond the last record in the test,
        is preserved.
     @ mysql-test/r/handler_myisam.result
        We no longer call wait_while_table_is_used() for
        OPTIMIZE, and thus OPTIMIZE no longer closes HANDLER cursor.
        Cursor position, pointing beyond the last record in the test,
        is preserved.
     @ sql/sql_base.cc
        Add an assert.
        Don't manipulate with table->s->version in auto-repair, auto-discover.
        Use tdc_remove_table() in auto_repair_table() and drop_open_table().
     @ sql/sql_table.cc
        Remove dead code from mysql_admin_table().
        Manipulate with table->s->version through the TDC API.

    modified:
      mysql-test/r/handler_innodb.result
      mysql-test/r/handler_myisam.result
      sql/sql_base.cc
      sql/sql_table.cc
=== modified file 'mysql-test/r/handler_innodb.result'
--- a/mysql-test/r/handler_innodb.result	2010-02-25 17:08:12 +0000
+++ b/mysql-test/r/handler_innodb.result	2010-06-09 13:35:45 +0000
@@ -480,7 +480,6 @@ optimize table t1;
 proceed with the normal connection
 handler t1 read next;
 c1
-1
 handler t1 close;
 read the result from the other connection
 Table	Op	Msg_type	Msg_text

=== modified file 'mysql-test/r/handler_myisam.result'
--- a/mysql-test/r/handler_myisam.result	2010-04-02 15:17:43 +0000
+++ b/mysql-test/r/handler_myisam.result	2010-06-09 13:35:45 +0000
@@ -480,7 +480,6 @@ optimize table t1;
 proceed with the normal connection
 handler t1 read next;
 c1
-1
 handler t1 close;
 read the result from the other connection
 Table	Op	Msg_type	Msg_text

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-06-09 08:39:09 +0000
+++ b/sql/sql_base.cc	2010-06-09 13:35:45 +0000
@@ -439,6 +439,9 @@ static void table_def_unuse_table(TABLE 
 {
   DBUG_ASSERT(table->in_use);
 
+  /* We shouldn't put the table to 'unused' list if the share is old. */
+  DBUG_ASSERT(table->s->version == refresh_version);
+
   table->in_use= 0;
   /* Remove table from the list of tables used in this share. */
   table->s->used_tables.remove(table);
@@ -2233,11 +2236,14 @@ void drop_open_table(THD *thd, TABLE *ta
     DBUG_ASSERT(table == thd->open_tables);
 
     handlerton *table_type= table->s->db_type();
-    /* Ensure the table is removed from the cache. */
-    table->s->version= 0;
 
     table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
     close_thread_table(thd, &thd->open_tables);
+    /* Remove the table share from the table cache. */
+    mysql_mutex_lock(&LOCK_open);
+    tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db_name, table_name);
+    mysql_mutex_unlock(&LOCK_open);
+    /* Remove the table from the storage engine and rm the .frm. */
     quick_rm_table(table_type, db_name, table_name, 0);
   }
   DBUG_VOID_RETURN;
@@ -3028,17 +3034,11 @@ bool open_table(THD *thd, TABLE_LIST *ta
       my_free(table, MYF(0));
 
       if (error == 7)
-      {
-        share->version= 0;
         (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER,
                                               table_list);
-      }
       else if (share->crashed)
-      {
-        share->version= 0;
         (void) ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR,
                                               table_list);
-      }
 
       goto err_unlock;
     }
@@ -3824,7 +3824,7 @@ static bool auto_repair_table(THD *thd, 
   TABLE_SHARE *share;
   TABLE *entry;
   int not_used;
-  bool result= FALSE;
+  bool result= TRUE;
   my_hash_value_type hash_value;
 
   cache_key_length= create_table_def_key(thd, cache_key, table_list, 0);
@@ -3839,20 +3839,19 @@ static bool auto_repair_table(THD *thd, 
                                            cache_key_length,
                                            OPEN_VIEW, &not_used,
                                            hash_value)))
-  {
-    mysql_mutex_unlock(&LOCK_open);
-    return TRUE;
-  }
+    goto end_unlock;
 
   if (share->is_view)
-    goto end_with_lock_open;
+  {
+    release_table_share(share);
+    goto end_unlock;
+  }
 
   if (!(entry= (TABLE*)my_malloc(sizeof(TABLE), MYF(MY_WME))))
   {
-    result= TRUE;
-    goto end_with_lock_open;
+    release_table_share(share);
+    goto end_unlock;
   }
-  share->version= 0;
   mysql_mutex_unlock(&LOCK_open);
 
   if (open_table_from_share(thd, share, table_list->alias,
@@ -3871,19 +3870,21 @@ static bool auto_repair_table(THD *thd, 
                     share->table_name.str);
     if (entry->file)
       closefrm(entry, 0);
-    result= TRUE;
   }
   else
   {
     thd->clear_error();			// Clear error message
     closefrm(entry, 0);
+    result= FALSE;
   }
   my_free(entry, MYF(0));
 
   mysql_mutex_lock(&LOCK_open);
-
-end_with_lock_open:
   release_table_share(share);
+  /* Remove the repaired share from the table cache. */
+  tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
+                   table_list->db, table_list->table_name);
+end_unlock:
   mysql_mutex_unlock(&LOCK_open);
   return result;
 }

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2010-06-08 08:08:46 +0000
+++ b/sql/sql_table.cc	2010-06-09 13:35:45 +0000
@@ -85,19 +85,6 @@ mysql_prepare_alter_table(THD *thd, TABL
                           HA_CREATE_INFO *create_info,
                           Alter_info *alter_info);
 
-#ifndef DBUG_OFF
-
-/* Wait until we get a 'mysql_kill' signal */
-
-static void wait_for_kill_signal(THD *thd)
-{
-  while (thd->killed == 0)
-    sleep(1);
-  // Reset signal and continue as if nothing happend
-  thd->killed= THD::NOT_KILLED;
-}
-#endif
-
 
 /**
   @brief Helper function for explain_filename
@@ -4877,21 +4864,6 @@ static bool mysql_admin_table(THD* thd, 
       /* purecov: end */
     }
 
-    /* Close all instances of the table to allow repair to rename files */
-    if (lock_type == TL_WRITE && table->table->s->version)
-    {
-      if (wait_while_table_is_used(thd, table->table,
-                                   HA_EXTRA_PREPARE_FOR_RENAME))
-        goto err;
-      DBUG_EXECUTE_IF("wait_in_mysql_admin_table",
-                      wait_for_kill_signal(thd);
-                      if (thd->killed)
-                        goto err;);
-      /* Flush entries in the query cache involving this table. */
-      query_cache_invalidate3(thd, table->table, 0);
-      open_for_modify= 0;
-    }
-
     if (table->table->s->crashed && operator_func == &handler::ha_check)
     {
       /* purecov: begin inspected */
@@ -5148,20 +5120,21 @@ send_result_message:
     }
     if (table->table)
     {
-      if (fatal_error)
-        table->table->s->version=0;               // Force close of table
-      else if (open_for_modify)
+      if (table->table->s->tmp_table)
       {
-        if (table->table->s->tmp_table)
+        if (open_for_modify)
           table->table->file->info(HA_STATUS_CONST);
-        else
-        {
-          TABLE_LIST *save_next_global= table->next_global;
-          table->next_global= 0;
-          close_cached_tables(thd, table, FALSE, FALSE);
-          table->next_global= save_next_global;
-        }
-        /* May be something modified consequently we have to invalidate cache */
+      }
+      else if (open_for_modify || fatal_error)
+      {
+        mysql_mutex_lock(&LOCK_open);
+        tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
+                         table->db, table->table_name);
+        mysql_mutex_unlock(&LOCK_open);
+        /*
+          May be something modified. Consequently, we have to
+          invalidate the query cache.
+        */
         query_cache_invalidate3(thd, table->table, 0);
       }
     }


Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20100609133545-x5pq9xn7qxyngeh2.bundle
Thread
bzr commit into mysql-trunk-runtime branch (kostja:3050) WL#5419Konstantin Osipov9 Jun