diff options
author | unknown <monty@tik.mysql.com> | 2000-10-11 00:06:37 +0300 |
---|---|---|
committer | unknown <monty@tik.mysql.com> | 2000-10-11 00:06:37 +0300 |
commit | da5366886f2c852cb05f8b9b31848d13a4816cad (patch) | |
tree | cf18eb0d045153270d68aec8884a4732e953e883 /sql | |
parent | dbde9337c201b7a53357d3904c7f0ac5b046ed85 (diff) | |
download | mariadb-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.cc | 40 | ||||
-rw-r--r-- | sql/ha_myisam.h | 7 | ||||
-rw-r--r-- | sql/handler.h | 8 | ||||
-rw-r--r-- | sql/lock.cc | 3 | ||||
-rw-r--r-- | sql/log_event.cc | 4 | ||||
-rw-r--r-- | sql/sql_base.cc | 71 | ||||
-rw-r--r-- | sql/sql_select.h | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 90 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 5 | ||||
-rw-r--r-- | sql/table.cc | 28 | ||||
-rw-r--r-- | sql/table.h | 1 |
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(¶m, 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(¶m); 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; |