List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:June 8 2010 12:20pm
Subject:bzr push into mysql-trunk-runtime branch (kostja:3046)
View as plain text  
 3046 Konstantin Osipov	2010-06-08 [merge]
      Merge with trunk-runtime.

    modified:
      mysql-test/r/drop.result
      mysql-test/t/drop.test
      sql/sql_yacc.yy
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-06-07 14:53:50 +0000
+++ b/sql/sql_base.cc	2010-06-08 08:08:46 +0000
@@ -1294,23 +1294,16 @@ static void close_open_tables(THD *thd)
 
   mysql_mutex_assert_not_owner(&LOCK_open);
 
-  mysql_mutex_lock(&LOCK_open);
-
   DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables));
 
   while (thd->open_tables)
     found_old_table|= close_thread_table(thd, &thd->open_tables);
 
-  /* Free tables to hold down open files */
-  while (table_cache_count > table_cache_size && unused_tables)
-    free_cache_entry(unused_tables);
   if (found_old_table)
   {
     /* Tell threads waiting for refresh that something has happened */
     broadcast_refresh();
   }
-
-  mysql_mutex_unlock(&LOCK_open);
 }
 
 
@@ -1342,13 +1335,6 @@ close_all_tables_for_name(THD *thd, TABL
   memcpy(key, share->table_cache_key.str, key_length);
 
   mysql_mutex_assert_not_owner(&LOCK_open);
-  /*
-    We need to hold LOCK_open while changing the open_tables
-    list, since another thread may work on it.
-    @sa mysql_notify_thread_having_shared_lock()
-  */
-  mysql_mutex_lock(&LOCK_open);
-
   for (TABLE **prev= &thd->open_tables; *prev; )
   {
     TABLE *table= *prev;
@@ -1356,10 +1342,9 @@ close_all_tables_for_name(THD *thd, TABL
     if (table->s->table_cache_key.length == key_length &&
         !memcmp(table->s->table_cache_key.str, key, key_length))
     {
-      /* Inform handler that table will be dropped after close */
-      if (table->db_stat)
-        table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
-
+      thd->locked_tables_list.unlink_from_list(thd,
+                                               table->pos_in_locked_tables,
+                                               remove_from_locked_tables);
       /*
         Does nothing if the table is not locked.
         This allows one to use this function after a table
@@ -1367,12 +1352,11 @@ close_all_tables_for_name(THD *thd, TABL
       */
       mysql_lock_remove(thd, thd->lock, table);
 
-      thd->locked_tables_list.unlink_from_list(thd,
-                                               table->pos_in_locked_tables,
-                                               remove_from_locked_tables);
-
       /* Make sure the table is removed from the cache */
       table->s->version= 0;
+      /* Inform handler that table will be dropped after close */
+      if (table->db_stat) /* Not true for partitioned tables. */
+        table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
       close_thread_table(thd, prev);
     }
     else
@@ -1383,7 +1367,6 @@ close_all_tables_for_name(THD *thd, TABL
   }
   /* We have been removing tables from the table cache. */
   broadcast_refresh();
-  mysql_mutex_unlock(&LOCK_open);
 }
 
 
@@ -1582,17 +1565,22 @@ bool close_thread_table(THD *thd, TABLE 
   DBUG_ENTER("close_thread_table");
   DBUG_ASSERT(table->key_read == 0);
   DBUG_ASSERT(!table->file || table->file->inited == handler::NONE);
-  mysql_mutex_assert_owner(&LOCK_open);
+  mysql_mutex_assert_not_owner(&LOCK_open);
+
+  table->mdl_ticket= NULL;
 
+  mysql_mutex_lock(&thd->LOCK_thd_data);
   *table_ptr=table->next;
+  mysql_mutex_unlock(&thd->LOCK_thd_data);
+
+  mysql_mutex_lock(&LOCK_open);
 
-  table->mdl_ticket= NULL;
   if (table->s->needs_reopen() ||
       thd->version != refresh_version || table->needs_reopen() ||
       table_def_shutdown_in_progress)
   {
     free_cache_entry(table);
-    found_old_table=1;
+    found_old_table= 1;
   }
   else
   {
@@ -1602,10 +1590,17 @@ bool close_thread_table(THD *thd, TABLE 
 
     /* Free memory and reset for next loop */
     free_field_buffers_larger_than(table,MAX_TDC_BLOB_SIZE);
-    
+
     table->file->ha_reset();
     table_def_unuse_table(table);
+    /*
+      We free the least used table, not the subject table,
+      to keep the LRU order.
+    */
+    if (table_cache_count > table_cache_size)
+      free_cache_entry(unused_tables);
   }
+  mysql_mutex_unlock(&LOCK_open);
   DBUG_RETURN(found_old_table);
 }
 
@@ -2229,11 +2224,9 @@ void drop_open_table(THD *thd, TABLE *ta
     /* Ensure the table is removed from the cache. */
     table->s->version= 0;
 
-    mysql_mutex_lock(&LOCK_open);
     table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
     close_thread_table(thd, &thd->open_tables);
     quick_rm_table(table_type, db_name, table_name, 0);
-    mysql_mutex_unlock(&LOCK_open);
   }
   DBUG_VOID_RETURN;
 }
@@ -3062,8 +3055,8 @@ bool open_table(THD *thd, TABLE_LIST *ta
 
   table->mdl_ticket= mdl_ticket;
 
-  table->next=thd->open_tables;		/* Link into simple list */
-  thd->open_tables=table;
+  table->next= thd->open_tables;		/* Link into simple list */
+  thd->set_open_tables(table);
 
   table->reginfo.lock_type=TL_READ;		/* Assume read */
 
@@ -3403,7 +3396,6 @@ unlink_all_closed_tables(THD *thd, MYSQL
   */
   if (reopen_count)
   {
-    mysql_mutex_lock(&LOCK_open);
     while (reopen_count--)
     {
       /*
@@ -3420,7 +3412,6 @@ unlink_all_closed_tables(THD *thd, MYSQL
       close_thread_table(thd, &thd->open_tables);
     }
     broadcast_refresh();
-    mysql_mutex_unlock(&LOCK_open);
   }
   /* Exclude all closed tables from the LOCK TABLES list. */
   for (TABLE_LIST *table_list= m_locked_tables; table_list; table_list=
@@ -8655,10 +8646,10 @@ bool mysql_notify_thread_having_shared_l
     mysql_mutex_unlock(&in_use->mysys_var->mutex);
     signalled= TRUE;
   }
-  mysql_mutex_lock(&LOCK_open);
 
   if (needs_thr_lock_abort)
   {
+    mysql_mutex_lock(&in_use->LOCK_thd_data);
     for (TABLE *thd_table= in_use->open_tables;
          thd_table ;
          thd_table= thd_table->next)
@@ -8669,10 +8660,11 @@ bool mysql_notify_thread_having_shared_l
         and do not remove such instances from the THD::open_tables
         for some time, during which other thread can see those instances
         (e.g. see partitioning code).
-        */
+      */
       if (!thd_table->needs_reopen())
         signalled|= mysql_lock_abort_for_thread(thd, thd_table);
     }
+    mysql_mutex_unlock(&in_use->LOCK_thd_data);
   }
   /*
     Wake up threads waiting in tdc_wait_for_old_versions().
@@ -8685,7 +8677,6 @@ bool mysql_notify_thread_having_shared_l
     a multi-statement transaction.
   */
   broadcast_refresh();
-  mysql_mutex_unlock(&LOCK_open);
   return signalled;
 }
 

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-06-06 11:19:29 +0000
+++ b/sql/sql_class.h	2010-06-08 08:08:46 +0000
@@ -2682,6 +2682,12 @@ public:
   void set_query_and_id(char *query_arg, uint32 query_length_arg,
                         query_id_t new_query_id);
   void set_query_id(query_id_t new_query_id);
+  void set_open_tables(TABLE *open_tables_arg)
+  {
+    mysql_mutex_lock(&LOCK_thd_data);
+    open_tables= open_tables_arg;
+    mysql_mutex_unlock(&LOCK_thd_data);
+  }
   void enter_locked_tables_mode(enum_locked_tables_mode mode_arg)
   {
     DBUG_ASSERT(locked_tables_mode == LTM_NONE);

=== modified file 'sql/sql_cursor.cc'
--- a/sql/sql_cursor.cc	2010-03-31 14:05:33 +0000
+++ b/sql/sql_cursor.cc	2010-06-08 08:08:46 +0000
@@ -357,7 +357,7 @@ void
 Sensitive_cursor::reset_thd(THD *thd)
 {
   thd->derived_tables= 0;
-  thd->open_tables= 0;
+  thd->set_open_tables(NULL);
   thd->lock= 0;
   thd->free_list= 0;
   thd->change_list.empty();
@@ -436,7 +436,7 @@ Sensitive_cursor::fetch(ulong num_rows)
               thd->lock == 0);
 
   thd->derived_tables= derived_tables;
-  thd->open_tables= open_tables;
+  thd->set_open_tables(open_tables);
   thd->lock= lock;
   thd->set_query_id(query_id);
   change_list.move_elements_to(&thd->change_list);
@@ -519,14 +519,14 @@ Sensitive_cursor::close()
     TABLE *tmp_derived_tables= thd->derived_tables;
     MYSQL_LOCK *tmp_lock= thd->lock;
 
-    thd->open_tables= open_tables;
+    thd->set_open_tables(open_tables);
     thd->derived_tables= derived_tables;
     thd->lock= lock;
 
     /* Is expected to at least close tables and empty thd->change_list */
     stmt_arena->cleanup_stmt();
 
-    thd->open_tables= tmp_derived_tables;
+    thd->set_open_tables(tmp_derived_tables);
     thd->derived_tables= tmp_derived_tables;
     thd->lock= tmp_lock;
   }

=== modified file 'sql/sql_handler.cc'
--- a/sql/sql_handler.cc	2010-03-31 14:05:33 +0000
+++ b/sql/sql_handler.cc	2010-06-08 08:08:46 +0000
@@ -131,13 +131,11 @@ static void mysql_ha_close_table(THD *th
     /* Non temporary table. */
     tables->table->file->ha_index_or_rnd_end();
     tables->table->open_by_handler= 0;
-    mysql_mutex_lock(&LOCK_open);
     if (close_thread_table(thd, &tables->table))
     {
       /* Tell threads waiting for refresh that something has happened */
       broadcast_refresh();
     }
-    mysql_mutex_unlock(&LOCK_open);
     thd->mdl_context.release_lock(tables->mdl_request.ticket);
   }
   else if (tables->table)
@@ -278,7 +276,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST 
     See open_table() back-off comments for more details.
   */
   backup_open_tables= thd->open_tables;
-  thd->open_tables= NULL;
+  thd->set_open_tables(NULL);
   mdl_savepoint= thd->mdl_context.mdl_savepoint();
 
   /*
@@ -312,7 +310,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST 
   if (error)
   {
     close_thread_tables(thd);
-    thd->open_tables= backup_open_tables;
+    thd->set_open_tables(backup_open_tables);
     thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
     if (!reopen)
       my_hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
@@ -325,7 +323,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST 
     DBUG_PRINT("exit",("ERROR"));
     DBUG_RETURN(TRUE);
   }
-  thd->open_tables= backup_open_tables;
+  thd->set_open_tables(backup_open_tables);
   if (hash_tables->mdl_request.ticket)
   {
     thd->mdl_context.
@@ -559,7 +557,7 @@ retry:
     mysql_lock_tables() needs thd->open_tables to be set correctly to
     be able to handle aborts properly.
   */
-  thd->open_tables= hash_tables->table;
+  thd->set_open_tables(hash_tables->table);
 
 
   sql_handler_lock_error.init();
@@ -575,7 +573,7 @@ retry:
   */
   DBUG_ASSERT(hash_tables->table == thd->open_tables);
   /* Restore previous context. */
-  thd->open_tables= backup_open_tables;
+  thd->set_open_tables(backup_open_tables);
 
   if (sql_handler_lock_error.need_reopen())
   {

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2010-06-06 11:19:29 +0000
+++ b/sql/sql_table.cc	2010-06-08 08:08:46 +0000
@@ -5429,14 +5429,12 @@ bool mysql_create_like_table(THD* thd, T
             goto err;
 
           DBUG_ASSERT(thd->open_tables == table->table);
-          mysql_mutex_lock(&LOCK_open);
           /*
             When opening the table, we ignored the locked tables
             (MYSQL_OPEN_GET_NEW_TABLE). Now we can close the table without
             risking to close some locked table.
           */
           close_thread_table(thd, &thd->open_tables);
-          mysql_mutex_unlock(&LOCK_open);
         }
       }
       else                                      // Case 1
@@ -7490,9 +7488,7 @@ bool mysql_alter_table(THD *thd,char *ne
                                                create_info);
 
     DBUG_ASSERT(thd->open_tables == t_table);
-    mysql_mutex_lock(&LOCK_open);
     close_thread_table(thd, &thd->open_tables);
-    mysql_mutex_unlock(&LOCK_open);
     table_list->table= 0;
 
     if (error)


Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20100608122015-l6xpo080ov8bq3u3.bundle
Thread
bzr push into mysql-trunk-runtime branch (kostja:3046)Konstantin Osipov8 Jun