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

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.
This commit is contained in:
Michael Widenius 2010-02-10 21:06:24 +02:00
parent d474428c9a
commit d77e3cde5f
27 changed files with 121 additions and 50 deletions

View File

@ -111,7 +111,7 @@ enum ha_storage_media {
enum ha_extra_function { enum ha_extra_function {
HA_EXTRA_NORMAL=0, /* Optimize for space (def) */ HA_EXTRA_NORMAL=0, /* Optimize for space (def) */
HA_EXTRA_QUICK=1, /* Optimize for speed */ 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_CACHE=3, /* Cache record in HA_rrnd() */
HA_EXTRA_NO_CACHE=4, /* End caching of records (def) */ HA_EXTRA_NO_CACHE=4, /* End caching of records (def) */
HA_EXTRA_NO_READCHECK=5, /* No readcheck on update */ HA_EXTRA_NO_READCHECK=5, /* No readcheck on update */

View File

@ -5542,6 +5542,8 @@ sub usage ($) {
if ( $message ) if ( $message )
{ {
print STDERR "$message\n"; print STDERR "$message\n";
print STDERR "For full list of options, use $0 --help\n";
exit;
} }
print <<HERE; print <<HERE;

View File

@ -1,4 +1,5 @@
call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 20, found 19. The table is probably corrupted"); 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; use test;
drop procedure if exists bug14233; drop procedure if exists bug14233;
drop function if exists bug14233; drop function if exists bug14233;

View File

@ -1261,12 +1261,12 @@ ERROR HY000: Variable 'lower_case_table_names' is a read only variable
# #
SHOW VARIABLES like 'myisam_recover_options'; SHOW VARIABLES like 'myisam_recover_options';
Variable_name Value Variable_name Value
myisam_recover_options OFF myisam_recover_options DEFAULT
SELECT @@session.myisam_recover_options; SELECT @@session.myisam_recover_options;
ERROR HY000: Variable 'myisam_recover_options' is a GLOBAL variable ERROR HY000: Variable 'myisam_recover_options' is a GLOBAL variable
SELECT @@global.myisam_recover_options; SELECT @@global.myisam_recover_options;
@@global.myisam_recover_options @@global.myisam_recover_options
OFF DEFAULT
SET @@session.myisam_recover_options= 'x'; SET @@session.myisam_recover_options= 'x';
ERROR HY000: Variable 'myisam_recover_options' is a read only variable ERROR HY000: Variable 'myisam_recover_options' is a read only variable
SET @@global.myisam_recover_options= 'x'; SET @@global.myisam_recover_options= 'x';

View File

@ -155,13 +155,13 @@ v5 VIEW
v6 VIEW v6 VIEW
show table status; 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 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 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 NULL VIEW 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 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 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 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 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 NULL VIEW v6 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # # NULL NULL NULL VIEW
drop view v1,v2,v3,v4,v5,v6; drop view v1,v2,v3,v4,v5,v6;
create view v1 (c,d,e,f) as select a,b, 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; a in (select a+2 from t1), a = all (select a from t1) from t1;

View File

@ -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=

View File

@ -17,6 +17,7 @@ call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 20, foun
# Backup proc table # Backup proc table
let $MYSQLD_DATADIR= `select @@datadir`; 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.frm $MYSQLTEST_VARDIR/tmp/proc.frm
--copy_file $MYSQLD_DATADIR/mysql/proc.MYD $MYSQLTEST_VARDIR/tmp/proc.MYD --copy_file $MYSQLD_DATADIR/mysql/proc.MYD $MYSQLTEST_VARDIR/tmp/proc.MYD
--copy_file $MYSQLD_DATADIR/mysql/proc.MYI $MYSQLTEST_VARDIR/tmp/proc.MYI --copy_file $MYSQLD_DATADIR/mysql/proc.MYI $MYSQLTEST_VARDIR/tmp/proc.MYI

View File

@ -87,7 +87,7 @@ explain extended select c from v6;
# show table/table status test # show table/table status test
show tables; show tables;
show full tables; show full tables;
--replace_column 8 # 12 # 13 # --replace_column 8 # 12 # 13 # 14 #
show table status; show table status;
drop view v1,v2,v3,v4,v5,v6; drop view v1,v2,v3,v4,v5,v6;

View File

@ -1049,10 +1049,14 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
DBUG_RETURN(-1); DBUG_RETURN(-1);
table_list->table=table; table_list->table=table;
table->s->deleting= table_list->deleting;
/* Return 1 if table is in use */ /* Return 1 if table is in use */
DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name, 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)));
} }

View File

@ -1636,7 +1636,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
#define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002 #define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002
#define RTFC_CHECK_KILLED_FLAG 0x0004 #define RTFC_CHECK_KILLED_FLAG 0x0004
bool remove_table_from_cache(THD *thd, const char *db, const char *table, 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 NORMAL_PART_NAME 0
#define TEMP_PART_NAME 1 #define TEMP_PART_NAME 1

View File

@ -7962,7 +7962,13 @@ static int mysql_init_variables(void)
refresh_version= 1L; /* Increments on each reload */ refresh_version= 1L; /* Increments on each reload */
global_query_id= thread_id= 1L; global_query_id= thread_id= 1L;
strmov(server_version, MYSQL_SERVER_VERSION); 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"; myisam_stats_method_str= "nulls_unequal";
my_bind_addr = htonl(INADDR_ANY); my_bind_addr = htonl(INADDR_ANY);
threads.empty(); threads.empty();
@ -8616,26 +8622,31 @@ mysqld_get_one_option(int optid,
#endif #endif
case OPT_MYISAM_RECOVER: case OPT_MYISAM_RECOVER:
{ {
if (!argument) if (argument && (!argument[0] ||
{ my_strcasecmp(system_charset_info, argument, "OFF") == 0))
myisam_recover_options= HA_RECOVER_DEFAULT;
myisam_recover_options_str= myisam_recover_typelib.type_names[0];
}
else if (!argument[0])
{ {
myisam_recover_options= HA_RECOVER_NONE; myisam_recover_options= HA_RECOVER_NONE;
myisam_recover_options_str= "OFF"; myisam_recover_options_str= "OFF";
ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
} }
else else
{ {
myisam_recover_options_str=argument; if (!argument)
myisam_recover_options= {
find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name, myisam_recover_options= HA_RECOVER_DEFAULT;
&error); myisam_recover_options_str= myisam_recover_typelib.type_names[0];
if (error) }
return 1; 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; break;
} }
case OPT_CONCURRENT_INSERT: case OPT_CONCURRENT_INSERT:

View File

@ -930,7 +930,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
for (TABLE_LIST *table= tables; table; table= table->next_local) for (TABLE_LIST *table= tables; table; table= table->next_local)
{ {
if (remove_table_from_cache(thd, table->db, table->table_name, 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; found=1;
} }
if (!found) if (!found)
@ -8404,6 +8404,11 @@ void remove_db_from_cache(const char *db)
if (!strcmp(table->s->db.str, db)) if (!strcmp(table->s->db.str, db))
{ {
table->s->version= 0L; /* Free when thread is ready */ 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) if (!table->in_use)
relink_unused(table); relink_unused(table);
} }
@ -8446,7 +8451,7 @@ void flush_tables()
*/ */
bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, 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]; char key[MAX_DBKEY_LENGTH];
uint key_length; uint key_length;
@ -8540,7 +8545,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
} }
} }
while (unused_tables && !unused_tables->s->version) while (unused_tables && !unused_tables->s->version)
{
unused_tables->s->deleting= deleting;
VOID(hash_delete(&open_cache,(uchar*) unused_tables)); VOID(hash_delete(&open_cache,(uchar*) unused_tables));
}
DBUG_PRINT("info", ("Removing table from table_def_cache")); DBUG_PRINT("info", ("Removing table from table_def_cache"));
/* Remove table from table definition cache if it's not in use */ /* Remove table from table definition cache if it's not in use */
@ -8734,7 +8742,8 @@ int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt)
/* If MERGE child, forward lock handling to parent. */ /* If MERGE child, forward lock handling to parent. */
mysql_lock_abort(lpt->thd, lpt->table->parent ? lpt->table->parent : mysql_lock_abort(lpt->thd, lpt->table->parent ? lpt->table->parent :
lpt->table, TRUE); 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)); VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -8759,7 +8768,7 @@ void close_open_tables_and_downgrade(ALTER_PARTITION_PARAM_TYPE *lpt)
{ {
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, 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)); VOID(pthread_mutex_unlock(&LOCK_open));
/* If MERGE child, forward lock handling to parent. */ /* If MERGE child, forward lock handling to parent. */
mysql_lock_downgrade_write(lpt->thd, lpt->table->parent ? lpt->table->parent : mysql_lock_downgrade_write(lpt->thd, lpt->table->parent ? lpt->table->parent :

View File

@ -1088,6 +1088,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
HA_CREATE_INFO create_info; HA_CREATE_INFO create_info;
char path[FN_REFLEN + 1]; char path[FN_REFLEN + 1];
TABLE *table; TABLE *table;
TABLE_LIST *tbl;
bool error; bool error;
uint path_length; uint path_length;
bool is_temporary_table= false; bool is_temporary_table= false;
@ -1108,6 +1109,9 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE)) if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
goto trunc_by_del; 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); table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
create_info.options|= HA_LEX_CREATE_TMP_TABLE; create_info.options|= HA_LEX_CREATE_TMP_TABLE;

View File

@ -1880,6 +1880,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
{ {
TABLE_SHARE *share; TABLE_SHARE *share;
table->db_type= NULL; table->db_type= NULL;
if ((share= get_cached_table_share(table->db, table->table_name))) if ((share= get_cached_table_share(table->db, table->table_name)))
table->db_type= share->db_type(); table->db_type= share->db_type();
@ -1974,9 +1975,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
{ {
TABLE *locked_table; TABLE *locked_table;
abort_locked_tables(thd, db, table->table_name); abort_locked_tables(thd, db, table->table_name);
table->deleting= TRUE;
remove_table_from_cache(thd, db, table->table_name, remove_table_from_cache(thd, db, table->table_name,
RTFC_WAIT_OTHER_THREAD_FLAG | 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 If the table was used in lock tables, remember it so that
unlock_table_names can free it unlock_table_names can free it
@ -4213,9 +4215,10 @@ void wait_while_table_is_used(THD *thd,TABLE *table,
/* Wait until all there are no other threads that has this table open */ /* Wait until all there are no other threads that has this table open */
remove_table_from_cache(thd, table->s->db.str, remove_table_from_cache(thd, table->s->db.str,
table->s->table_name.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 */ /* 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; DBUG_VOID_RETURN;
} }
@ -4717,7 +4720,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
remove_table_from_cache(thd, table->table->s->db.str, remove_table_from_cache(thd, table->table->s->db.str,
table->table->s->table_name.str, table->table->s->table_name.str,
RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_WAIT_OTHER_THREAD_FLAG |
RTFC_CHECK_KILLED_FLAG); RTFC_CHECK_KILLED_FLAG, FALSE);
thd->exit_cond(old_message); thd->exit_cond(old_message);
DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd);); DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
if (thd->killed) if (thd->killed)
@ -4975,7 +4978,8 @@ send_result_message:
{ {
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
remove_table_from_cache(thd, table->table->s->db.str, 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); pthread_mutex_unlock(&LOCK_open);
} }
/* May be something modified consequently we have to invalidate cache */ /* May be something modified consequently we have to invalidate cache */
@ -6738,7 +6742,9 @@ view_err:
from concurrent DDL statements. from concurrent DDL statements.
*/ */
VOID(pthread_mutex_lock(&LOCK_open)); 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)); VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000);); DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
@ -6746,7 +6752,9 @@ view_err:
break; break;
case DISABLE: case DISABLE:
VOID(pthread_mutex_lock(&LOCK_open)); 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)); VOID(pthread_mutex_unlock(&LOCK_open));
error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */ /* COND_refresh will be signaled in close_thread_tables() */
@ -7192,7 +7200,9 @@ view_err:
else else
{ {
VOID(pthread_mutex_lock(&LOCK_open)); 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)); VOID(pthread_mutex_unlock(&LOCK_open));
thd_proc_info(thd, "manage keys"); thd_proc_info(thd, "manage keys");
alter_table_manage_keys(table, table->file->indexes_are_disabled(), alter_table_manage_keys(table, table->file->indexes_are_disabled(),

View File

@ -1977,7 +1977,11 @@ int closefrm(register TABLE *table, bool free_share)
DBUG_PRINT("enter", ("table: 0x%lx", (long) table)); DBUG_PRINT("enter", ("table: 0x%lx", (long) table));
if (table->db_stat) if (table->db_stat)
{
if (table->s->deleting)
table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
error=table->file->close(); error=table->file->close();
}
my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
table->alias= 0; table->alias= 0;
if (table->field) if (table->field)

View File

@ -431,6 +431,7 @@ typedef struct st_table_share
bool is_view; bool is_view;
bool name_lock, replace_with_name_lock; bool name_lock, replace_with_name_lock;
bool waiting_on_cond; /* Protection against free */ bool waiting_on_cond; /* Protection against free */
bool deleting; /* going to delete this table */
ulong table_map_id; /* for row-based replication */ ulong table_map_id; /* for row-based replication */
ulonglong table_map_version; ulonglong table_map_version;
@ -1379,7 +1380,7 @@ struct TABLE_LIST
*/ */
bool create; bool create;
bool internal_tmp_table; bool internal_tmp_table;
bool deleting; /* going to delete this table */
/* View creation context. */ /* View creation context. */

View File

@ -2255,9 +2255,12 @@ int ha_maria::extra(enum ha_extra_function operation)
extern_lock(F_UNLOCK) (which resets file->trn) followed by maria_close() extern_lock(F_UNLOCK) (which resets file->trn) followed by maria_close()
without calling commit/rollback in between. If file->trn is not set 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. 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_DROP ||
operation == HA_EXTRA_PREPARE_FOR_RENAME)) operation == HA_EXTRA_PREPARE_FOR_RENAME))
{ {

View File

@ -430,8 +430,9 @@ my_bool _ma_once_end_block_record(MARIA_SHARE *share)
if (share->bitmap.file.file >= 0) if (share->bitmap.file.file >= 0)
{ {
if (flush_pagecache_blocks(share->pagecache, &share->bitmap.file, if (flush_pagecache_blocks(share->pagecache, &share->bitmap.file,
share->temporary ? FLUSH_IGNORE_CHANGED : ((share->temporary || share->deleting) ?
FLUSH_RELEASE)) FLUSH_IGNORE_CHANGED :
FLUSH_RELEASE)))
res= 1; res= 1;
/* /*
File must be synced as it is going out of the maria_open_list and so File must be synced as it is going out of the maria_open_list and so

View File

@ -79,7 +79,7 @@ int maria_close(register MARIA_HA *info)
if ((*share->once_end)(share)) if ((*share->once_end)(share))
error= my_errno; error= my_errno;
if (flush_pagecache_blocks(share->pagecache, &share->kfile, if (flush_pagecache_blocks(share->pagecache, &share->kfile,
(share->temporary ? ((share->temporary || share->deleting) ?
FLUSH_IGNORE_CHANGED : FLUSH_IGNORE_CHANGED :
FLUSH_RELEASE))) FLUSH_RELEASE)))
error= my_errno; error= my_errno;

View File

@ -305,6 +305,12 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
pthread_mutex_unlock(&THR_LOCK_maria); pthread_mutex_unlock(&THR_LOCK_maria);
break; break;
case HA_EXTRA_PREPARE_FOR_DROP: 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: case HA_EXTRA_PREPARE_FOR_RENAME:
{ {
my_bool do_flush= test(function != HA_EXTRA_PREPARE_FOR_DROP); my_bool do_flush= test(function != HA_EXTRA_PREPARE_FOR_DROP);

View File

@ -387,6 +387,9 @@ int _ma_test_if_changed(register MARIA_HA *info)
open_count is not maintained on disk for temporary tables. 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) int _ma_mark_file_changed(MARIA_HA *info)
{ {
uchar buff[3]; uchar buff[3];
@ -394,8 +397,6 @@ int _ma_mark_file_changed(MARIA_HA *info)
int error= 1; int error= 1;
DBUG_ENTER("_ma_mark_file_changed"); 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) if (_MA_ALREADY_MARKED_FILE_CHANGED)
DBUG_RETURN(0); DBUG_RETURN(0);
pthread_mutex_lock(&share->intern_lock); /* recheck under mutex */ pthread_mutex_lock(&share->intern_lock); /* recheck under mutex */

View File

@ -312,11 +312,14 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
now= my_getsystime(); now= my_getsystime();
in_redo_phase= TRUE; in_redo_phase= TRUE;
trnman_init(max_trid_in_control_file);
if (run_redo_phase(from_lsn, apply)) if (run_redo_phase(from_lsn, apply))
{ {
ma_message_no_user(0, "Redo phase failed"); ma_message_no_user(0, "Redo phase failed");
trnman_destroy();
goto err; goto err;
} }
trnman_destroy();
if ((uncommitted_trans= if ((uncommitted_trans=
end_of_redo_phase(should_run_undo_phase)) == (uint)-1) end_of_redo_phase(should_run_undo_phase)) == (uint)-1)

View File

@ -390,6 +390,7 @@ typedef struct st_maria_share
my_bool now_transactional; my_bool now_transactional;
my_bool have_versioning; my_bool have_versioning;
my_bool key_del_used; /* != 0 if key_del is locked */ my_bool key_del_used; /* != 0 if key_del is locked */
my_bool deleting; /* we are going to delete this table */
#ifdef THREAD #ifdef THREAD
THR_LOCK lock; THR_LOCK lock;
void (*lock_restore_status)(void *); void (*lock_restore_status)(void *);

View File

@ -64,8 +64,9 @@ int mi_close(register MI_INFO *info)
if (share->kfile >= 0) abort();); if (share->kfile >= 0) abort(););
if (share->kfile >= 0 && if (share->kfile >= 0 &&
flush_key_blocks(share->key_cache, share->kfile, flush_key_blocks(share->key_cache, share->kfile,
share->temporary ? FLUSH_IGNORE_CHANGED : ((share->temporary || share->deleting) ?
FLUSH_RELEASE)) FLUSH_IGNORE_CHANGED :
FLUSH_RELEASE)))
error=my_errno; error=my_errno;
if (share->kfile >= 0) if (share->kfile >= 0)
{ {

View File

@ -256,8 +256,13 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
share->last_version= 0L; /* Impossible version */ share->last_version= 0L; /* Impossible version */
pthread_mutex_unlock(&THR_LOCK_myisam); pthread_mutex_unlock(&THR_LOCK_myisam);
break; break;
case HA_EXTRA_PREPARE_FOR_RENAME:
case HA_EXTRA_PREPARE_FOR_DROP: 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); pthread_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */ share->last_version= 0L; /* Impossible version */
pthread_mutex_lock(&share->intern_lock); pthread_mutex_lock(&share->intern_lock);

View File

@ -58,6 +58,8 @@ MI_INFO *test_if_reopen(char *filename)
{ {
MI_INFO *info=(MI_INFO*) pos->data; MI_INFO *info=(MI_INFO*) pos->data;
MYISAM_SHARE *share=info->s; 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) if (!strcmp(share->unique_file_name,filename) && share->last_version)
return info; return info;
} }

View File

@ -221,6 +221,7 @@ typedef struct st_mi_isam_share
my_bool changed, /* If changed since lock */ my_bool changed, /* If changed since lock */
global_changed, /* If changed since open */ global_changed, /* If changed since open */
not_flushed, temporary, delay_key_write, concurrent_insert; not_flushed, temporary, delay_key_write, concurrent_insert;
my_bool deleting; /* we are going to delete this table */
#ifdef THREAD #ifdef THREAD
THR_LOCK lock; THR_LOCK lock;
pthread_mutex_t intern_lock; /* Locking for use with _locking */ pthread_mutex_t intern_lock; /* Locking for use with _locking */