← Back to team overview

maria-developers team mailing list archive

bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (monty:2814)

 

#At lp:maria based on revid:monty@xxxxxxxxxxxx-20100209171704-h7stfhbh94k54tbf

 2814 Michael Widenius	2010-02-10
      When one does a drop table, the indexes are not flushed to disk before drop anymore (with MyISAM/Maria)
      myisam-recover options changed from OFF to 'DEFAULT' to get less change of data loss when using MyISAM.
      (The disadvantage is that changed MyISAM tables will be checked at access time; Use --myisam-recover=OFF for old behavior)
      Don't call extra(HA_EXTRA_FORCE_REOPEN) in ALTER TABLE if table is locked as this will mark table as crashed!
      Added assert to detect if we accidently would use MyISAM versioning in MySQL
      modified:
        include/my_base.h
        mysql-test/mysql-test-run.pl
        mysql-test/r/sp-destruct.result
        mysql-test/r/variables.result
        mysql-test/r/view.result
        mysql-test/suite/maria/t/maria-recovery2-master.opt
        mysql-test/t/sp-destruct.test
        mysql-test/t/view.test
        sql/lock.cc
        sql/mysql_priv.h
        sql/mysqld.cc
        sql/sql_base.cc
        sql/sql_delete.cc
        sql/sql_table.cc
        sql/table.cc
        sql/table.h
        storage/maria/ha_maria.cc
        storage/maria/ma_blockrec.c
        storage/maria/ma_close.c
        storage/maria/ma_extra.c
        storage/maria/ma_locking.c
        storage/maria/ma_recovery.c
        storage/maria/maria_def.h
        storage/myisam/mi_close.c
        storage/myisam/mi_extra.c
        storage/myisam/mi_open.c
        storage/myisam/myisamdef.h

per-file messages:
  include/my_base.h
    Mark NOT_USED as USED, as we now use this as a flag to not call extra()
  mysql-test/mysql-test-run.pl
    Don't write all options when there is something wrong with the arguments
  mysql-test/r/sp-destruct.result
    Add missing flush of mysql.proc (as the test copied live tables)
  mysql-test/r/variables.result
    myisam-recover options changed to 'default'
  mysql-test/r/view.result
    Don't show create time in result
  mysql-test/suite/maria/t/maria-recovery2-master.opt
    Don't run test with myisam-recover (as this produces extra warnings during simulated death)
  mysql-test/t/sp-destruct.test
    Add missing flush of mysql.proc (as the test copied live tables)
  mysql-test/t/view.test
    Don't show create time in result
  sql/lock.cc
    Added marker if table was deleted to argument list
  sql/mysql_priv.h
    Added marker if table was deleted to argument list
  sql/mysqld.cc
    myisam-recover options changed from OFF to 'DEFAULT' to get less change of data loss when using MyISAM
    Allow one to specify OFF as argument to myisam-recover (was default before but one couldn't specify it)
  sql/sql_base.cc
    Mark if table is going to be deleted
  sql/sql_delete.cc
    Mark if table is going to be deleted
  sql/sql_table.cc
    Mark if table is going to be deleted
    Don't call extra(HA_EXTRA_FORCE_REOPEN) in ALTER TABLE if table is locked as this will mark table as crashed!
  sql/table.cc
    Signal to handler if table is getting deleted as part of getting droped from table cache.
  sql/table.h
    Added marker if table is going to be deleted.
  storage/maria/ha_maria.cc
    Don't search for transaction handler if file is not transactional or outside of transaction
    (Fixed possible core dump)
  storage/maria/ma_blockrec.c
    Don't write changed information if table is going to be deleted.
  storage/maria/ma_close.c
    Don't write changed information if table is going to be deleted.
  storage/maria/ma_extra.c
    Mark tables that are deleted as crased, to ensure good behavior on restart if we suddenly crash.
  storage/maria/ma_locking.c
    Cleanup
  storage/maria/ma_recovery.c
    We need trnman to be inited during redo phase (to be able to open tables checked with maria_chk)
  storage/maria/maria_def.h
    Added marker if table is going to be deleted.
  storage/myisam/mi_close.c
    Don't write changed information if table is going to be deleted.
  storage/myisam/mi_extra.c
    Mark tables that are deleted as crased, to ensure good behavior on restart if we suddenly crash.
  storage/myisam/mi_open.c
    Added assert to detect if we accidently would use MyISAM versioning in MySQL
  storage/myisam/myisamdef.h
    Added marker if table is going to be deleted.
=== modified file 'include/my_base.h'
--- a/include/my_base.h	2009-09-07 20:50:10 +0000
+++ b/include/my_base.h	2010-02-10 19:06:24 +0000
@@ -111,7 +111,7 @@ enum ha_storage_media {
 enum ha_extra_function {
   HA_EXTRA_NORMAL=0,			/* Optimize for space (def) */
   HA_EXTRA_QUICK=1,			/* Optimize for speed */
-  HA_EXTRA_NOT_USED=2,
+  HA_EXTRA_NOT_USED=2,			/* Should be ignored by handler */
   HA_EXTRA_CACHE=3,			/* Cache record in HA_rrnd() */
   HA_EXTRA_NO_CACHE=4,			/* End caching of records (def) */
   HA_EXTRA_NO_READCHECK=5,		/* No readcheck on update */

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2010-01-29 10:42:31 +0000
+++ b/mysql-test/mysql-test-run.pl	2010-02-10 19:06:24 +0000
@@ -5542,6 +5542,8 @@ sub usage ($) {
   if ( $message )
   {
     print STDERR "$message\n";
+    print STDERR "For full list of options, use $0 --help\n";
+    exit;      
   }
 
   print <<HERE;

=== modified file 'mysql-test/r/sp-destruct.result'
--- a/mysql-test/r/sp-destruct.result	2009-11-21 11:18:21 +0000
+++ b/mysql-test/r/sp-destruct.result	2010-02-10 19:06:24 +0000
@@ -1,4 +1,5 @@
 call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted");
+flush table mysql.proc;
 use test;
 drop procedure if exists bug14233;
 drop function if exists bug14233;

=== modified file 'mysql-test/r/variables.result'
--- a/mysql-test/r/variables.result	2010-01-11 13:15:28 +0000
+++ b/mysql-test/r/variables.result	2010-02-10 19:06:24 +0000
@@ -1261,12 +1261,12 @@ ERROR HY000: Variable 'lower_case_table_
 #
 SHOW VARIABLES like 'myisam_recover_options';
 Variable_name	Value
-myisam_recover_options	OFF
+myisam_recover_options	DEFAULT
 SELECT @@session.myisam_recover_options;
 ERROR HY000: Variable 'myisam_recover_options' is a GLOBAL variable
 SELECT @@global.myisam_recover_options;
 @@global.myisam_recover_options
-OFF
+DEFAULT
 SET @@session.myisam_recover_options= 'x';
 ERROR HY000: Variable 'myisam_recover_options' is a read only variable
 SET @@global.myisam_recover_options= 'x';

=== modified file 'mysql-test/r/view.result'
--- a/mysql-test/r/view.result	2009-10-15 21:38:29 +0000
+++ b/mysql-test/r/view.result	2010-02-10 19:06:24 +0000
@@ -155,13 +155,13 @@ v5	VIEW
 v6	VIEW
 show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
-t1	MyISAM	10	Fixed	5	9	45	#	1024	0	NULL	#	#	NULL	latin1_swedish_ci	NULL		
-v1	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	NULL	NULL	NULL	NULL	VIEW
-v2	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	NULL	NULL	NULL	NULL	VIEW
-v3	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	NULL	NULL	NULL	NULL	VIEW
-v4	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	NULL	NULL	NULL	NULL	VIEW
-v5	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	NULL	NULL	NULL	NULL	VIEW
-v6	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	NULL	NULL	NULL	NULL	VIEW
+t1	MyISAM	10	Fixed	5	9	45	#	1024	0	NULL	#	#	#	latin1_swedish_ci	NULL		
+v1	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	#	NULL	NULL	NULL	VIEW
+v2	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	#	NULL	NULL	NULL	VIEW
+v3	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	#	NULL	NULL	NULL	VIEW
+v4	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	#	NULL	NULL	NULL	VIEW
+v5	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	#	NULL	NULL	NULL	VIEW
+v6	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	#	NULL	NULL	NULL	VIEW
 drop view v1,v2,v3,v4,v5,v6;
 create view v1 (c,d,e,f) as select a,b,
 a in (select a+2 from t1), a = all (select a from t1) from t1;

=== modified file 'mysql-test/suite/maria/t/maria-recovery2-master.opt'
--- a/mysql-test/suite/maria/t/maria-recovery2-master.opt	2009-01-15 14:29:14 +0000
+++ b/mysql-test/suite/maria/t/maria-recovery2-master.opt	2010-02-10 19:06:24 +0000
@@ -1 +1 @@
---skip-stack-trace --skip-core-file --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp
+--skip-stack-trace --skip-core-file --loose-maria-log-dir-path=$MYSQLTEST_VARDIR/tmp --myisam-recover=

=== modified file 'mysql-test/t/sp-destruct.test'
--- a/mysql-test/t/sp-destruct.test	2009-11-21 11:18:21 +0000
+++ b/mysql-test/t/sp-destruct.test	2010-02-10 19:06:24 +0000
@@ -17,6 +17,7 @@ call mtr.add_suppression("Column count o
 
 # Backup proc table
 let $MYSQLD_DATADIR= `select @@datadir`;
+flush table mysql.proc;
 --copy_file $MYSQLD_DATADIR/mysql/proc.frm $MYSQLTEST_VARDIR/tmp/proc.frm
 --copy_file $MYSQLD_DATADIR/mysql/proc.MYD $MYSQLTEST_VARDIR/tmp/proc.MYD
 --copy_file $MYSQLD_DATADIR/mysql/proc.MYI $MYSQLTEST_VARDIR/tmp/proc.MYI

=== modified file 'mysql-test/t/view.test'
--- a/mysql-test/t/view.test	2009-10-15 21:38:29 +0000
+++ b/mysql-test/t/view.test	2010-02-10 19:06:24 +0000
@@ -87,7 +87,7 @@ explain extended select c from v6;
 # show table/table status test
 show tables;
 show full tables;
---replace_column 8 # 12 # 13 #
+--replace_column 8 # 12 # 13 # 14 #
 show table status;
 
 drop view v1,v2,v3,v4,v5,v6;

=== modified file 'sql/lock.cc'
--- a/sql/lock.cc	2009-10-15 21:38:29 +0000
+++ b/sql/lock.cc	2010-02-10 19:06:24 +0000
@@ -1049,10 +1049,14 @@ int lock_table_name(THD *thd, TABLE_LIST
     DBUG_RETURN(-1);
 
   table_list->table=table;
+  table->s->deleting= table_list->deleting;
 
   /* Return 1 if table is in use */
   DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
-             check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
+                                           (check_in_use ?
+                                            RTFC_NO_FLAG :
+                                            RTFC_WAIT_OTHER_THREAD_FLAG),
+                                           table_list->deleting)));
 }
 
 

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2009-12-03 11:19:05 +0000
+++ b/sql/mysql_priv.h	2010-02-10 19:06:24 +0000
@@ -1636,7 +1636,7 @@ uint prep_alter_part_table(THD *thd, TAB
 #define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002
 #define RTFC_CHECK_KILLED_FLAG      0x0004
 bool remove_table_from_cache(THD *thd, const char *db, const char *table,
-                             uint flags);
+                             uint flags, my_bool deleting);
 
 #define NORMAL_PART_NAME 0
 #define TEMP_PART_NAME 1

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-01-29 18:42:22 +0000
+++ b/sql/mysqld.cc	2010-02-10 19:06:24 +0000
@@ -7962,7 +7962,13 @@ static int mysql_init_variables(void)
   refresh_version= 1L;	/* Increments on each reload */
   global_query_id= thread_id= 1L;
   strmov(server_version, MYSQL_SERVER_VERSION);
-  myisam_recover_options_str= sql_mode_str= "OFF";
+  sql_mode_str= "";
+
+  /* By default, auto-repair MyISAM tables after crash */
+  myisam_recover_options_str= "DEFAULT";
+  myisam_recover_options=     HA_RECOVER_DEFAULT;
+  ha_open_options|= HA_OPEN_ABORT_IF_CRASHED;
+
   myisam_stats_method_str= "nulls_unequal";
   my_bind_addr = htonl(INADDR_ANY);
   threads.empty();
@@ -8616,26 +8622,31 @@ mysqld_get_one_option(int optid,
 #endif
   case OPT_MYISAM_RECOVER:
   {
-    if (!argument)
-    {
-      myisam_recover_options=    HA_RECOVER_DEFAULT;
-      myisam_recover_options_str= myisam_recover_typelib.type_names[0];
-    }
-    else if (!argument[0])
+    if (argument && (!argument[0] ||
+                     my_strcasecmp(system_charset_info, argument, "OFF") == 0))
     {
       myisam_recover_options= HA_RECOVER_NONE;
       myisam_recover_options_str= "OFF";
+      ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
     }
     else
     {
-      myisam_recover_options_str=argument;
-      myisam_recover_options=
-        find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
-                              &error);
-      if (error)
-        return 1;
+      if (!argument)
+      {
+        myisam_recover_options=     HA_RECOVER_DEFAULT;
+        myisam_recover_options_str= myisam_recover_typelib.type_names[0];
+      }
+      else
+      {
+        myisam_recover_options_str=argument;
+        myisam_recover_options=
+          find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
+                                &error);
+        if (error)
+          return 1;
+      }
+      ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
     }
-    ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
     break;
   }
   case OPT_CONCURRENT_INSERT:

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-01-15 15:27:55 +0000
+++ b/sql/sql_base.cc	2010-02-10 19:06:24 +0000
@@ -930,7 +930,7 @@ bool close_cached_tables(THD *thd, TABLE
     for (TABLE_LIST *table= tables; table; table= table->next_local)
     {
       if (remove_table_from_cache(thd, table->db, table->table_name,
-                                  RTFC_OWNED_BY_THD_FLAG))
+                                  RTFC_OWNED_BY_THD_FLAG, table->deleting))
 	found=1;
     }
     if (!found)
@@ -8404,6 +8404,11 @@ void remove_db_from_cache(const char *db
     if (!strcmp(table->s->db.str, db))
     {
       table->s->version= 0L;			/* Free when thread is ready */
+      /*
+        This functions only called from DROP DATABASE code, so we are going
+        to drop all tables so we mark them as deleting
+      */
+      table->s->deleting= TRUE;
       if (!table->in_use)
 	relink_unused(table);
     }
@@ -8446,7 +8451,7 @@ void flush_tables()
 */
 
 bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
-                             uint flags)
+                             uint flags, my_bool deleting)
 {
   char key[MAX_DBKEY_LENGTH];
   uint key_length;
@@ -8540,7 +8545,10 @@ bool remove_table_from_cache(THD *thd, c
       }
     }
     while (unused_tables && !unused_tables->s->version)
+    {
+      unused_tables->s->deleting= deleting;
       VOID(hash_delete(&open_cache,(uchar*) unused_tables));
+    }
 
     DBUG_PRINT("info", ("Removing table from table_def_cache"));
     /* Remove table from table definition cache if it's not in use */
@@ -8734,7 +8742,8 @@ int abort_and_upgrade_lock(ALTER_PARTITI
   /* If MERGE child, forward lock handling to parent. */
   mysql_lock_abort(lpt->thd, lpt->table->parent ? lpt->table->parent :
                    lpt->table, TRUE);
-  VOID(remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, flags));
+  VOID(remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, flags,
+                               FALSE));
   VOID(pthread_mutex_unlock(&LOCK_open));
   DBUG_RETURN(0);
 }
@@ -8759,7 +8768,7 @@ void close_open_tables_and_downgrade(ALT
 {
   VOID(pthread_mutex_lock(&LOCK_open));
   remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name,
-                          RTFC_WAIT_OTHER_THREAD_FLAG);
+                          RTFC_WAIT_OTHER_THREAD_FLAG, FALSE);
   VOID(pthread_mutex_unlock(&LOCK_open));
   /* If MERGE child, forward lock handling to parent. */
   mysql_lock_downgrade_write(lpt->thd, lpt->table->parent ? lpt->table->parent :

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2010-01-15 15:27:55 +0000
+++ b/sql/sql_delete.cc	2010-02-10 19:06:24 +0000
@@ -1088,6 +1088,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST
   HA_CREATE_INFO create_info;
   char path[FN_REFLEN + 1];
   TABLE *table;
+  TABLE_LIST *tbl;
   bool error;
   uint path_length;
   bool is_temporary_table= false;
@@ -1108,6 +1109,9 @@ bool mysql_truncate(THD *thd, TABLE_LIST
     if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
       goto trunc_by_del;
 
+    for (tbl= table_list; tbl; tbl= tbl->next_local)
+      tbl->deleting= TRUE; /* to trigger HA_PREPARE_FOR_DROP */
+
     table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
 
     create_info.options|= HA_LEX_CREATE_TMP_TABLE;

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2010-01-15 15:27:55 +0000
+++ b/sql/sql_table.cc	2010-02-10 19:06:24 +0000
@@ -1880,6 +1880,7 @@ int mysql_rm_table_part2(THD *thd, TABLE
   {
     TABLE_SHARE *share;
     table->db_type= NULL;
+
     if ((share= get_cached_table_share(table->db, table->table_name)))
       table->db_type= share->db_type();
 
@@ -1974,9 +1975,10 @@ int mysql_rm_table_part2(THD *thd, TABLE
     {
       TABLE *locked_table;
       abort_locked_tables(thd, db, table->table_name);
+      table->deleting= TRUE;
       remove_table_from_cache(thd, db, table->table_name,
 	                      RTFC_WAIT_OTHER_THREAD_FLAG |
-			      RTFC_CHECK_KILLED_FLAG);
+			      RTFC_CHECK_KILLED_FLAG, FALSE);
       /*
         If the table was used in lock tables, remember it so that
         unlock_table_names can free it
@@ -4213,9 +4215,10 @@ void wait_while_table_is_used(THD *thd,T
   /* Wait until all there are no other threads that has this table open */
   remove_table_from_cache(thd, table->s->db.str,
                           table->s->table_name.str,
-                          RTFC_WAIT_OTHER_THREAD_FLAG);
+                          RTFC_WAIT_OTHER_THREAD_FLAG, FALSE);
   /* extra() call must come only after all instances above are closed */
-  VOID(table->file->extra(function));
+  if (function != HA_EXTRA_NOT_USED)
+    VOID(table->file->extra(function));
   DBUG_VOID_RETURN;
 }
 
@@ -4717,7 +4720,7 @@ static bool mysql_admin_table(THD* thd,
       remove_table_from_cache(thd, table->table->s->db.str,
                               table->table->s->table_name.str,
                               RTFC_WAIT_OTHER_THREAD_FLAG |
-                              RTFC_CHECK_KILLED_FLAG);
+                              RTFC_CHECK_KILLED_FLAG, FALSE);
       thd->exit_cond(old_message);
       DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
       if (thd->killed)
@@ -4975,7 +4978,8 @@ send_result_message:
         {
           pthread_mutex_lock(&LOCK_open);
           remove_table_from_cache(thd, table->table->s->db.str,
-                                  table->table->s->table_name.str, RTFC_NO_FLAG);
+                                  table->table->s->table_name.str,
+                                  RTFC_NO_FLAG, FALSE);
           pthread_mutex_unlock(&LOCK_open);
         }
         /* May be something modified consequently we have to invalidate cache */
@@ -6738,7 +6742,9 @@ view_err:
         from concurrent DDL statements.
       */
       VOID(pthread_mutex_lock(&LOCK_open));
-      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+      wait_while_table_is_used(thd, table,
+                               thd->locked_tables ? HA_EXTRA_NOT_USED :
+                               HA_EXTRA_FORCE_REOPEN);
       VOID(pthread_mutex_unlock(&LOCK_open));
       DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
       error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
@@ -6746,7 +6752,9 @@ view_err:
       break;
     case DISABLE:
       VOID(pthread_mutex_lock(&LOCK_open));
-      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+      wait_while_table_is_used(thd, table,
+                               thd->locked_tables ? HA_EXTRA_NOT_USED :
+                               HA_EXTRA_FORCE_REOPEN);
       VOID(pthread_mutex_unlock(&LOCK_open));
       error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
       /* COND_refresh will be signaled in close_thread_tables() */
@@ -7192,7 +7200,9 @@ view_err:
   else
   {
     VOID(pthread_mutex_lock(&LOCK_open));
-    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+    wait_while_table_is_used(thd, table, 
+                             thd->locked_tables ? HA_EXTRA_NOT_USED :
+                             HA_EXTRA_FORCE_REOPEN);
     VOID(pthread_mutex_unlock(&LOCK_open));
     thd_proc_info(thd, "manage keys");
     alter_table_manage_keys(table, table->file->indexes_are_disabled(),

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2010-01-15 15:27:55 +0000
+++ b/sql/table.cc	2010-02-10 19:06:24 +0000
@@ -1977,7 +1977,11 @@ int closefrm(register TABLE *table, bool
   DBUG_PRINT("enter", ("table: 0x%lx", (long) table));
 
   if (table->db_stat)
+  {
+    if (table->s->deleting)
+      table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
     error=table->file->close();
+  }
   my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
   table->alias= 0;
   if (table->field)

=== modified file 'sql/table.h'
--- a/sql/table.h	2010-01-15 15:27:55 +0000
+++ b/sql/table.h	2010-02-10 19:06:24 +0000
@@ -431,6 +431,7 @@ typedef struct st_table_share
   bool is_view;
   bool name_lock, replace_with_name_lock;
   bool waiting_on_cond;                 /* Protection against free */
+  bool deleting;                        /* going to delete this table */
   ulong table_map_id;                   /* for row-based replication */
   ulonglong table_map_version;
 
@@ -1379,7 +1380,7 @@ struct TABLE_LIST
   */
   bool          create;
   bool          internal_tmp_table;
-
+  bool          deleting;               /* going to delete this table */
 
   /* View creation context. */
 

=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc	2009-12-03 11:34:11 +0000
+++ b/storage/maria/ha_maria.cc	2010-02-10 19:06:24 +0000
@@ -2255,9 +2255,12 @@ int ha_maria::extra(enum ha_extra_functi
     extern_lock(F_UNLOCK) (which resets file->trn) followed by maria_close()
     without calling commit/rollback in between.  If file->trn is not set
     we can't remove file->share from the transaction list in the extra() call.
+
+    table->in_use is not set in the case this is a done as part of closefrm()
+    as part of drop table.
   */
 
-  if (!file->trn &&
+  if (file->s->now_transactional && !file->trn && table->in_use && 
       (operation == HA_EXTRA_PREPARE_FOR_DROP ||
        operation == HA_EXTRA_PREPARE_FOR_RENAME))
   {

=== modified file 'storage/maria/ma_blockrec.c'
--- a/storage/maria/ma_blockrec.c	2010-01-28 11:35:10 +0000
+++ b/storage/maria/ma_blockrec.c	2010-02-10 19:06:24 +0000
@@ -430,8 +430,9 @@ my_bool _ma_once_end_block_record(MARIA_
   if (share->bitmap.file.file >= 0)
   {
     if (flush_pagecache_blocks(share->pagecache, &share->bitmap.file,
-                               share->temporary ? FLUSH_IGNORE_CHANGED :
-                               FLUSH_RELEASE))
+                               ((share->temporary || share->deleting) ?
+                                FLUSH_IGNORE_CHANGED :
+                                FLUSH_RELEASE)))
       res= 1;
     /*
       File must be synced as it is going out of the maria_open_list and so

=== modified file 'storage/maria/ma_close.c'
--- a/storage/maria/ma_close.c	2010-01-29 18:42:22 +0000
+++ b/storage/maria/ma_close.c	2010-02-10 19:06:24 +0000
@@ -79,7 +79,7 @@ int maria_close(register MARIA_HA *info)
       if ((*share->once_end)(share))
         error= my_errno;
       if (flush_pagecache_blocks(share->pagecache, &share->kfile,
-                                 (share->temporary ?
+                                 ((share->temporary || share->deleting) ?
                                   FLUSH_IGNORE_CHANGED :
                                   FLUSH_RELEASE)))
         error= my_errno;

=== modified file 'storage/maria/ma_extra.c'
--- a/storage/maria/ma_extra.c	2009-10-06 06:13:56 +0000
+++ b/storage/maria/ma_extra.c	2010-02-10 19:06:24 +0000
@@ -305,6 +305,12 @@ int maria_extra(MARIA_HA *info, enum ha_
     pthread_mutex_unlock(&THR_LOCK_maria);
     break;
   case HA_EXTRA_PREPARE_FOR_DROP:
+    /* Signals about intent to delete this table */
+    share->deleting= TRUE;
+    share->global_changed= FALSE;     /* force writing changed flag */
+    /* To force repair if reopened */
+    _ma_mark_file_changed(info);
+    /* Fall trough */
   case HA_EXTRA_PREPARE_FOR_RENAME:
   {
     my_bool do_flush= test(function != HA_EXTRA_PREPARE_FOR_DROP);

=== modified file 'storage/maria/ma_locking.c'
--- a/storage/maria/ma_locking.c	2009-10-06 06:13:56 +0000
+++ b/storage/maria/ma_locking.c	2010-02-10 19:06:24 +0000
@@ -387,6 +387,9 @@ int _ma_test_if_changed(register MARIA_H
   open_count is not maintained on disk for temporary tables.
 */
 
+#define _MA_ALREADY_MARKED_FILE_CHANGED                                 \
+  ((share->state.changed & STATE_CHANGED) && share->global_changed)
+
 int _ma_mark_file_changed(MARIA_HA *info)
 {
   uchar buff[3];
@@ -394,8 +397,6 @@ int _ma_mark_file_changed(MARIA_HA *info
   int error= 1;
   DBUG_ENTER("_ma_mark_file_changed");
 
-#define _MA_ALREADY_MARKED_FILE_CHANGED                                 \
-  ((share->state.changed & STATE_CHANGED) && share->global_changed)
   if (_MA_ALREADY_MARKED_FILE_CHANGED)
     DBUG_RETURN(0);
   pthread_mutex_lock(&share->intern_lock); /* recheck under mutex */

=== modified file 'storage/maria/ma_recovery.c'
--- a/storage/maria/ma_recovery.c	2009-10-26 11:35:42 +0000
+++ b/storage/maria/ma_recovery.c	2010-02-10 19:06:24 +0000
@@ -312,11 +312,14 @@ int maria_apply_log(LSN from_lsn, enum m
 
   now= my_getsystime();
   in_redo_phase= TRUE;
+  trnman_init(max_trid_in_control_file);
   if (run_redo_phase(from_lsn, apply))
   {
     ma_message_no_user(0, "Redo phase failed");
+    trnman_destroy();
     goto err;
   }
+  trnman_destroy();
 
   if ((uncommitted_trans=
        end_of_redo_phase(should_run_undo_phase)) == (uint)-1)

=== modified file 'storage/maria/maria_def.h'
--- a/storage/maria/maria_def.h	2009-11-29 23:08:56 +0000
+++ b/storage/maria/maria_def.h	2010-02-10 19:06:24 +0000
@@ -390,6 +390,7 @@ typedef struct st_maria_share
   my_bool now_transactional;
   my_bool have_versioning;
   my_bool key_del_used;                         /* != 0 if key_del is locked */
+  my_bool deleting;                     /* we are going to delete this table */
 #ifdef THREAD
   THR_LOCK lock;
   void (*lock_restore_status)(void *);

=== modified file 'storage/myisam/mi_close.c'
--- a/storage/myisam/mi_close.c	2009-09-07 20:50:10 +0000
+++ b/storage/myisam/mi_close.c	2010-02-10 19:06:24 +0000
@@ -64,8 +64,9 @@ int mi_close(register MI_INFO *info)
                     if (share->kfile >= 0) abort(););
     if (share->kfile >= 0 &&
 	flush_key_blocks(share->key_cache, share->kfile,
-			 share->temporary ? FLUSH_IGNORE_CHANGED :
-			 FLUSH_RELEASE))
+                         ((share->temporary || share->deleting) ?
+                          FLUSH_IGNORE_CHANGED :
+                          FLUSH_RELEASE)))
       error=my_errno;
     if (share->kfile >= 0)
     {

=== modified file 'storage/myisam/mi_extra.c'
--- a/storage/myisam/mi_extra.c	2009-10-06 06:13:56 +0000
+++ b/storage/myisam/mi_extra.c	2010-02-10 19:06:24 +0000
@@ -256,8 +256,13 @@ int mi_extra(MI_INFO *info, enum ha_extr
     share->last_version= 0L;			/* Impossible version */
     pthread_mutex_unlock(&THR_LOCK_myisam);
     break;
-  case HA_EXTRA_PREPARE_FOR_RENAME:
   case HA_EXTRA_PREPARE_FOR_DROP:
+    /* Signals about intent to delete this table */
+    share->deleting= TRUE;
+    share->global_changed= FALSE;     /* force writing changed flag */
+    _mi_mark_file_changed(info);
+    /* Fall trough */
+  case HA_EXTRA_PREPARE_FOR_RENAME:
     pthread_mutex_lock(&THR_LOCK_myisam);
     share->last_version= 0L;			/* Impossible version */
     pthread_mutex_lock(&share->intern_lock);

=== modified file 'storage/myisam/mi_open.c'
--- a/storage/myisam/mi_open.c	2009-12-03 11:19:05 +0000
+++ b/storage/myisam/mi_open.c	2010-02-10 19:06:24 +0000
@@ -58,6 +58,8 @@ MI_INFO *test_if_reopen(char *filename)
   {
     MI_INFO *info=(MI_INFO*) pos->data;
     MYISAM_SHARE *share=info->s;
+    DBUG_ASSERT(strcmp(share->unique_file_name,filename) ||
+                share->last_version);
     if (!strcmp(share->unique_file_name,filename) && share->last_version)
       return info;
   }

=== modified file 'storage/myisam/myisamdef.h'
--- a/storage/myisam/myisamdef.h	2009-12-03 11:34:11 +0000
+++ b/storage/myisam/myisamdef.h	2010-02-10 19:06:24 +0000
@@ -221,6 +221,7 @@ typedef struct st_mi_isam_share
   my_bool changed,                      /* If changed since lock */
     global_changed,                     /* If changed since open */
     not_flushed, temporary, delay_key_write, concurrent_insert;
+  my_bool deleting;                     /* we are going to delete this table */
 #ifdef THREAD
   THR_LOCK lock;
   pthread_mutex_t intern_lock;          /* Locking for use with _locking */