summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@tik.mysql.com>2000-10-11 00:06:37 +0300
committerunknown <monty@tik.mysql.com>2000-10-11 00:06:37 +0300
commitda5366886f2c852cb05f8b9b31848d13a4816cad (patch)
treecf18eb0d045153270d68aec8884a4732e953e883 /sql
parentdbde9337c201b7a53357d3904c7f0ac5b046ed85 (diff)
downloadmariadb-git-da5366886f2c852cb05f8b9b31848d13a4816cad.tar.gz
Automatic repair of MyISAM tables + portability fixes
Docs/manual.texi: Changes for 3.23 and change Ansi mode -> ANSI mode include/my_base.h: Automatic repair of MyISAM tables include/myisam.h: Automatic repair of MyISAM tables myisam/ft_update.c: Portability fix myisam/mi_check.c: Automatic repair of MyISAM tables myisam/mi_open.c: Automatic repair of MyISAM tables myisam/myisamchk.c: Allow one to combine check with --old-repair myisam/sort.c: Fix for usage of IO_CACHE mysys/charset.c: Portability fixes mysys/default.c: Added --defaults-extra-dir mysys/mf_tempfile.c: Portability fixes mysys/my_init.c: Remove compiler warning mysys/my_pread.c: Remove compiler warning sql-bench/server-cfg.sh: New benchmark tests sql-bench/test-insert.sh: New benchmark tests sql/ha_myisam.cc: Automatic repair of MyISAM tables sql/ha_myisam.h: Automatic repair of MyISAM tables sql/handler.h: Automatic repair of MyISAM tables sql/lock.cc: Add missing free sql/log_event.cc: Portability fixes sql/sql_base.cc: Automatic repair of MyISAM tables sql/sql_select.h: Remove compiler warning sql/sql_table.cc: Clean up intendent sql/sql_yacc.yy: New syntax for CHECK sql/table.cc: Automatic repair of MyISAM tables sql/table.h: Automatic repair of MyISAM tables BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_myisam.cc40
-rw-r--r--sql/ha_myisam.h7
-rw-r--r--sql/handler.h8
-rw-r--r--sql/lock.cc3
-rw-r--r--sql/log_event.cc4
-rw-r--r--sql/sql_base.cc71
-rw-r--r--sql/sql_select.h2
-rw-r--r--sql/sql_table.cc90
-rw-r--r--sql/sql_yacc.yy5
-rw-r--r--sql/table.cc28
-rw-r--r--sql/table.h1
11 files changed, 174 insertions, 85 deletions
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 698a4f64d14..5cb4432dea2 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -254,7 +254,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
STATE_CRASHED_ON_REPAIR)) &&
share->state.open_count == 0) ||
((param.testflag & T_FAST) && (share->state.open_count ==
- (share->global_changed ? 1 : 0)))))
+ (uint) (share->global_changed ? 1 : 0)))))
return HA_ADMIN_ALREADY_DONE;
error = chk_size(&param, file);
@@ -298,6 +298,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
mi_mark_crashed(file);
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
}
+ check_opt->retry_without_quick=param.retry_without_quick;
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
@@ -317,7 +318,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
myisamchk_init(&param);
param.thd = thd;
- param.op_name = (char*)" analyze";
+ param.op_name = (char*) "analyze";
param.table_name = table->table_name;
param.testflag=(T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
T_DONT_CHECK_CHECKSUM);
@@ -338,6 +339,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
+
int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
{
HA_CHECK_OPT tmp_check_opt;
@@ -404,6 +406,7 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
{
+ int error;
if (!file) return HA_ADMIN_INTERNAL_ERROR;
MI_CHECK param;
@@ -415,7 +418,21 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
if (check_opt->quick)
param.opt_rep_quick++;
param.sort_buffer_length= check_opt->sort_buffer_size;
- return repair(thd,param,0);
+ while ((error=repair(thd,param,0)))
+ {
+ if (param.retry_without_quick && param.opt_rep_quick)
+ {
+ param.opt_rep_quick=0;
+ continue;
+ }
+ if ((param.testflag & T_REP_BY_SORT))
+ {
+ param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
+ continue;
+ }
+ break;
+ }
+ return error;
}
int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt)
@@ -576,19 +593,19 @@ bool ha_myisam::activate_all_index(THD *thd)
}
-bool ha_myisam::check_and_repair(THD *thd, const char *name)
+bool ha_myisam::check_and_repair(THD *thd)
{
int error=0;
HA_CHECK_OPT check_opt;
DBUG_ENTER("ha_myisam::auto_check_and_repair");
- if (open(name, O_RDWR, HA_OPEN_WAIT_IF_LOCKED))
- DBUG_RETURN(1);
-
check_opt.init();
- check_opt.flags=T_MEDIUM;
+ check_opt.flags= T_MEDIUM;
+ check_opt.quick= !file->state->del; // Don't use quick if deleted rows
if (mi_is_crashed(file) || check(thd, &check_opt))
{
+ if (check_opt.retry_without_quick)
+ check_opt.quick=0;
check_opt.flags=(((myisam_recover_options & HA_RECOVER_BACKUP) ?
T_BACKUP_DATA : 0) |
(!(myisam_recover_options & HA_RECOVER_FORCE) ?
@@ -596,11 +613,14 @@ bool ha_myisam::check_and_repair(THD *thd, const char *name)
if (repair(thd, &check_opt))
error=1;
}
- if (close())
- error=1;
DBUG_RETURN(error);
}
+bool ha_myisam::is_crashed() const
+{
+ return (file->s->state.changed & STATE_CRASHED ||
+ (my_disable_locking && file->s->state.open_count));
+}
int ha_myisam::update_row(const byte * old_data, byte * new_data)
{
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h
index d33fc52c937..ff959ead883 100644
--- a/sql/ha_myisam.h
+++ b/sql/ha_myisam.h
@@ -45,8 +45,7 @@ class ha_myisam: public handler
HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
HA_HAVE_KEY_READ_ONLY | HA_READ_NOT_EXACT_KEY |
HA_LONGLONG_KEYS | HA_NULL_KEY |
- HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY |
- HA_CHECK_AND_REPAIR)
+ HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY)
{}
~ha_myisam() {}
const char *table_type() const { return "MyISAM"; }
@@ -103,7 +102,9 @@ class ha_myisam: public handler
int check(THD* thd, HA_CHECK_OPT* check_opt);
int analyze(THD* thd,HA_CHECK_OPT* check_opt);
int repair(THD* thd, HA_CHECK_OPT* check_opt);
- bool check_and_repair(THD *thd, const char *name);
+ bool check_and_repair(THD *thd);
+ bool is_crashed() const;
+ bool auto_repair() const { return myisam_recover_options != 0; }
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int restore(THD* thd, HA_CHECK_OPT* check_opt);
int backup(THD* thd, HA_CHECK_OPT* check_opt);
diff --git a/sql/handler.h b/sql/handler.h
index d256ee944e7..1457c033ed9 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -66,7 +66,6 @@
#define HA_NO_WRITE_DELAYED (HA_NOT_EXACT_COUNT*2)
#define HA_PRIMARY_KEY_IN_READ_INDEX (HA_NO_WRITE_DELAYED*2)
#define HA_DROP_BEFORE_CREATE (HA_PRIMARY_KEY_IN_READ_INDEX*2)
-#define HA_CHECK_AND_REPAIR (HA_DROP_BEFORE_CREATE*2)
/* Parameters for open() (in register form->filestat) */
/* HA_GET_INFO does a implicit HA_ABORT_IF_LOCKED */
@@ -146,9 +145,10 @@ typedef struct st_ha_check_opt
bool quick;
bool changed_files;
bool optimize;
+ bool retry_without_quick;
inline void init()
{
- flags= 0; quick= optimize=0;
+ flags= 0; quick= optimize= retry_without_quick=0;
sort_buffer_size = myisam_sort_buffer_size;
}
} HA_CHECK_OPT;
@@ -249,7 +249,7 @@ public:
virtual void update_create_info(HA_CREATE_INFO *create_info) {}
virtual int check(THD* thd, HA_CHECK_OPT* check_opt );
virtual int repair(THD* thd, HA_CHECK_OPT* check_opt);
- virtual bool check_and_repair(THD *thd, const char *name) {return 1;}
+ virtual bool check_and_repair(THD *thd) {return 1;}
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
@@ -274,6 +274,8 @@ public:
virtual uint max_key_length()const =0;
virtual uint min_record_length(uint options) const { return 1; }
virtual bool low_byte_first() const { return 1; }
+ virtual bool is_crashed() const { return 0; }
+ virtual bool auto_repair() const { return 0; }
virtual int rename_table(const char *from, const char *to);
virtual int delete_table(const char *name);
diff --git a/sql/lock.cc b/sql/lock.cc
index 7eb42f6b084..4c7ae8e950b 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -434,7 +434,10 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
table_list->table=table;
if (hash_insert(&open_cache, (byte*) table))
+ {
+ my_free((gptr) table,MYF(0));
DBUG_RETURN(-1);
+ }
if (remove_table_from_cache(thd, table_list->db, table_list->name))
DBUG_RETURN(1); // Table is in use
DBUG_RETURN(0);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index c73dda57504..5d1aad66954 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -261,7 +261,7 @@ void Log_event::print_header(FILE* file)
{
fputc('#', file);
print_timestamp(file);
- fprintf(file, " server id %d ", server_id);
+ fprintf(file, " server id %ld ", server_id);
}
void Log_event::print_timestamp(FILE* file, time_t* ts = 0)
@@ -709,7 +709,7 @@ void Load_log_event::print(FILE* file, bool short_form)
}
if((int)skip_lines > 0)
- fprintf(file, " IGNORE %d LINES ", skip_lines);
+ fprintf(file, " IGNORE %ld LINES ", skip_lines);
if(num_fields)
{
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ed018eb3337..03b799aee7d 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -34,7 +34,7 @@ HASH open_cache; /* Used by mysql_test */
static int open_unireg_entry(TABLE *entry,const char *db,const char *name,
- const char *alias);
+ const char *alias, bool locked);
static bool insert_fields(THD *thd,TABLE_LIST *tables, const char *table_name,
List_iterator<Item> *it);
static void free_cache_entry(TABLE *entry);
@@ -572,7 +572,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
pthread_mutex_lock(&LOCK_open);
- if (open_unireg_entry(table, db, table_name, table_name) ||
+ if (open_unireg_entry(table, db, table_name, table_name,0) ||
!(table->table_cache_key =memdup_root(&table->mem_root,(char*) key,
key_length)))
{
@@ -706,7 +706,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
/* make a new table */
if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
DBUG_RETURN(NULL);
- if (open_unireg_entry(table,db,table_name,alias) ||
+ if (open_unireg_entry(table,db,table_name,alias,0) ||
!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
key_length)))
{
@@ -816,7 +816,7 @@ bool reopen_table(TABLE *table,bool locked)
if (!locked)
VOID(pthread_mutex_lock(&LOCK_open));
- if (open_unireg_entry(&tmp,db,table_name,table->table_name))
+ if (open_unireg_entry(&tmp,db,table_name,table->table_name,locked))
goto end;
free_io_cache(table);
@@ -1113,23 +1113,72 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name)
*/
static int open_unireg_entry(TABLE *entry,const char *db,const char *name,
- const char *alias)
+ const char *alias, bool locked)
{
char path[FN_REFLEN];
+ int error;
DBUG_ENTER("open_unireg_entry");
(void) sprintf(path,"%s/%s/%s",mysql_data_home,db,name);
if (openfrm(path,alias,
- (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
- HA_TRY_READ_ONLY),
- READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
- ha_open_options,
- entry))
+ (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
+ HA_TRY_READ_ONLY),
+ READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
+ ha_open_options,
+ entry))
{
- DBUG_RETURN(1);
+ THD *thd=current_thd;
+ if (!entry->crashed)
+ goto err; // Can't repair the table
+
+ TABLE_LIST table_list;
+ table_list.db=(char*) db;
+ table_list.name=(char*) name;
+ table_list.next=0;
+ if (!locked)
+ pthread_mutex_lock(&LOCK_open);
+ if ((error=lock_table_name(thd,&table_list)))
+ {
+ if (error < 0)
+ {
+ if (!locked)
+ pthread_mutex_lock(&LOCK_open);
+ goto err;
+ }
+ if (wait_for_locked_table_names(thd,&table_list))
+ {
+ unlock_table_name(thd,&table_list);
+ if (!locked)
+ pthread_mutex_lock(&LOCK_open);
+ goto err;
+ }
+ }
+ pthread_mutex_unlock(&LOCK_open);
+ thd->net.last_error[0]=0; // Clear error message
+ thd->net.last_errno=0;
+ error=0;
+ sql_print_error("Warning: Repairing table: %s.%s",db,name);
+ if (openfrm(path,alias,
+ (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
+ HA_TRY_READ_ONLY),
+ READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
+ ha_open_options | HA_OPEN_FOR_REPAIR,
+ entry) ||
+ (entry->file->is_crashed() && entry->file->check_and_repair(thd)))
+ {
+ sql_print_error("Error: Couldn't repair table: %s.%s",db,name);
+ error=1;
+ }
+ unlock_table_name(thd,&table_list);
+ if (locked)
+ pthread_mutex_lock(&LOCK_open); // Get back old lock
+ if (error)
+ goto err;
}
(void) entry->file->extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
DBUG_RETURN(0);
+err:
+ DBUG_RETURN(1);
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 796802c0a50..4bee0bf2c3d 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -127,7 +127,7 @@ class TMP_TABLE_PARAM {
uint group_parts,group_length;
uint quick_group;
- TMP_TABLE_PARAM() :group_parts(0),group_length(0),copy_field(0) {}
+ TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0) {}
~TMP_TABLE_PARAM()
{
cleanup();
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 3cb40d7d9ed..390bfb28fd4 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -745,61 +745,61 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
{
String *packet = &thd->packet;
- if(table->table) // do not overwrite existing tables on restore
- {
- return send_check_errmsg(thd, table, "restore",
- "table exists, will not overwrite on restore"
- );
- }
+ if (table->table) // do not overwrite existing tables on restore
+ {
+ return send_check_errmsg(thd, table, "restore",
+ "table exists, will not overwrite on restore"
+ );
+ }
else
- {
- char* backup_dir = thd->lex.backup_dir;
- char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- char* table_name = table->name;
- char* db = thd->db ? thd->db : table->db;
+ {
+ char* backup_dir = thd->lex.backup_dir;
+ char src_path[FN_REFLEN], dst_path[FN_REFLEN];
+ char* table_name = table->name;
+ char* db = thd->db ? thd->db : table->db;
- if(!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64))
- return -1; // protect buffer overflow
+ if (!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64))
+ return -1; // protect buffer overflow
- sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name);
+ sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name);
- int lock_retcode;
- pthread_mutex_lock(&LOCK_open);
- if((lock_retcode = lock_table_name(thd, table)) < 0)
- {
- pthread_mutex_unlock(&LOCK_open);
- return -1;
- }
-
- if(lock_retcode && wait_for_locked_table_names(thd, table))
- {
- pthread_mutex_unlock(&LOCK_open);
- return -1;
- }
+ int lock_retcode;
+ pthread_mutex_lock(&LOCK_open);
+ if ((lock_retcode = lock_table_name(thd, table)) < 0)
+ {
pthread_mutex_unlock(&LOCK_open);
+ return -1;
+ }
- if(my_copy(src_path,
- fn_format(dst_path, dst_path,"",
- reg_ext, 4),
- MYF(MY_WME)))
- {
- return send_check_errmsg(thd, table, "restore",
- "Failed copying .frm file");
- }
- bool save_no_send_ok = thd->net.no_send_ok;
- thd->net.no_send_ok = 1;
- // generate table will try to send OK which messes up the output
- // for the client
+ if (lock_retcode && wait_for_locked_table_names(thd, table))
+ {
+ pthread_mutex_unlock(&LOCK_open);
+ return -1;
+ }
+ pthread_mutex_unlock(&LOCK_open);
- if(generate_table(thd, table, 0))
- {
- thd->net.no_send_ok = save_no_send_ok;
- return send_check_errmsg(thd, table, "restore",
- "Failed generating table from .frm file");
- }
+ if (my_copy(src_path,
+ fn_format(dst_path, dst_path,"",
+ reg_ext, 4),
+ MYF(MY_WME)))
+ {
+ return send_check_errmsg(thd, table, "restore",
+ "Failed copying .frm file");
+ }
+ bool save_no_send_ok = thd->net.no_send_ok;
+ thd->net.no_send_ok = 1;
+ // generate table will try to send OK which messes up the output
+ // for the client
+ if (generate_table(thd, table, 0))
+ {
thd->net.no_send_ok = save_no_send_ok;
+ return send_check_errmsg(thd, table, "restore",
+ "Failed generating table from .frm file");
}
+
+ thd->net.no_send_ok = save_no_send_ok;
+ }
return 0;
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 1fde60accea..ae1296153e5 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1134,8 +1134,13 @@ repair:
opt_mi_check_type:
/* empty */ { Lex->check_opt.flags = T_MEDIUM; }
| TYPE_SYM EQ mi_check_types {}
+ | mi_check_types {}
mi_check_types:
+ mi_check_type {}
+ | mi_check_type mi_check_types {}
+
+mi_check_type:
QUICK { Lex->check_opt.quick = 1; }
| FAST_SYM { Lex->check_opt.flags|= T_FAST; }
| EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
diff --git a/sql/table.cc b/sql/table.cc
index c7fe81c182c..c0c4fd1eba2 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -212,17 +212,24 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
error=2;
if (db_stat)
{
- if ((outparam->file->
- ha_open(index_file,
- (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
- (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
- (db_stat & HA_WAIT_IF_LOCKED ||
- specialflag & SPECIAL_WAIT_IF_LOCKED) ?
- HA_OPEN_WAIT_IF_LOCKED :
- (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
- HA_OPEN_ABORT_IF_LOCKED :
- HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))
+ int err;
+ if ((err=(outparam->file->
+ ha_open(index_file,
+ (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
+ (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
+ ((db_stat & HA_WAIT_IF_LOCKED) ||
+ (specialflag & SPECIAL_WAIT_IF_LOCKED)) ?
+ HA_OPEN_WAIT_IF_LOCKED :
+ (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
+ HA_OPEN_ABORT_IF_LOCKED :
+ HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
+ {
+ /* Set a flag if the table is crashed and it can be auto. repaired */
+ outparam->crashed=(err == HA_ERR_CRASHED &&
+ outparam->file->auto_repair() &&
+ !(ha_open_flags & HA_OPEN_FOR_REPAIR));
goto err_not_open; /* purecov: inspected */
+ }
}
outparam->db_low_byte_first=outparam->file->low_byte_first();
@@ -549,6 +556,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
delete crypted;
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
frm_error(error,outparam,name,ME_ERROR+ME_WAITTANG);
+ delete outparam->file;
outparam->file=0; // For easyer errorchecking
free_root(&outparam->mem_root,MYF(0));
my_free(outparam->table_name,MYF(MY_ALLOW_ZERO_PTR));
diff --git a/sql/table.h b/sql/table.h
index f7d81e690eb..4f17bbf9c49 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -92,6 +92,7 @@ struct st_table {
my_bool db_low_byte_first; /* Portable row format */
my_bool locked_by_flush;
my_bool locked_by_name;
+ my_bool crashed;
Field *next_number_field, /* Set if next_number is activated */
*found_next_number_field, /* Set on open */
*rowid_field;