Automatic repair of MyISAM tables + small bug fixes

Docs/manual.texi:
  Updates for 3.23.26
include/Makefile.am:
  Install my_config.h
include/my_pthread.h:
  Fix for Ia64
myisam/mi_check.c:
  Wrong new record pos on dupplicate key error
myisam/mi_open.c:
  Fix for automatic repair
myisam/myisamchk.c:
  Fix for automatic repair
myisam/myisamdef.h:
  Fix for automatic repair
mysys/mf_tempfile.c:
  Fix usage of mkstemp
sql-bench/bench-init.pl.sh:
  Better help text
sql-bench/test-insert.sh:
  Fix for slow databases
sql/field.cc:
  Fix of default values for CREATE TABLE ... SELECT
sql/ha_berkeley.cc:
  Fix bug in BDB records_in_range
sql/ha_myisam.cc:
  Fix for automatic repair
sql/ha_myisam.h:
  Fix for automatic repair
sql/handler.cc:
  Fixes for innobase
sql/item_strfunc.cc:
  Fix for SUBSTR_INDEX and REPLACE
sql/log_event.h:
  Portability fix
sql/mysqld.cc:
  Added INNOBASE and fixes for automatic recover of MyISAM tables
sql/sql_base.cc:
  Fix for automatic repair
sql/sql_table.cc:
  Fix for IF EXISTS when used with CREATE TEMPORARY
This commit is contained in:
unknown 2000-10-17 00:47:15 +03:00
commit 0c511215f2
20 changed files with 221 additions and 106 deletions

View file

@ -4574,6 +4574,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
interval= ((Field_enum*) old_field)->typelib;
else
interval=0;
def=0;
if (!old_field->is_real_null() && ! (flags & BLOB_FLAG) &&
old_field->type() != FIELD_TYPE_TIMESTAMP && old_field->ptr &&
orig_field)
@ -4584,15 +4585,14 @@ create_field::create_field(Field *old_field,Field *orig_field)
/* Get the value from record[2] (the default value row) */
my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2);
orig_field->move_field(diff); // Points now at record[2]
bool is_null=orig_field->is_real_null();
res=orig_field->val_str(&tmp,&tmp);
orig_field->move_field(-diff); // Back to record[0]
if (res) // If not NULL value
if (!is_null)
{
pos= (char*) sql_memdup(tmp.ptr(),tmp.length()+1);
pos[tmp.length()]=0;
def=new Item_string(pos,tmp.length());
}
}
else
def=0;
}

View file

@ -1472,11 +1472,11 @@ ha_rows ha_berkeley::records_in_range(int keynr,
DB_KEY_RANGE start_range, end_range;
double start_pos,end_pos,rows;
DBUG_ENTER("records_in_range");
if ((start_key && file->key_range(file,transaction,
if ((start_key && file->key_range(key_file[keynr],transaction,
pack_key(&key, keynr, key_buff, start_key,
start_key_len),
&start_range,0)) ||
(end_key && file->key_range(file,transaction,
(end_key && file->key_range(key_file[keynr],transaction,
pack_key(&key, keynr, key_buff, end_key,
end_key_len),
&end_range,0)))

View file

@ -35,7 +35,7 @@ ulong myisam_recover_options= HA_RECOVER_NONE;
/* bits in myisam_recover_options */
const char *myisam_recover_names[] =
{ "DEFAULT", "BACKUP", "FORCE"};
{ "DEFAULT", "BACKUP", "FORCE", "QUICK"};
TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"",
myisam_recover_names};
@ -423,11 +423,15 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
if (param.retry_without_quick && param.opt_rep_quick)
{
param.opt_rep_quick=0;
sql_print_error("Warning: Retrying recover of: %s without quick",
table->path);
continue;
}
if ((param.testflag & T_REP_BY_SORT))
{
param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
sql_print_error("Warning: Retrying recover of: %s with safe repair",
table->path);
continue;
}
break;
@ -532,6 +536,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
{
if (param.out_flag & (O_NEW_DATA | O_NEW_INDEX))
{
bool in_auto_repair;
/*
We have to close all instances of this file to ensure that we can
do the rename safely on all operating system and to ensure that
@ -539,9 +544,18 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
*/
thd->proc_info="renaming file";
VOID(pthread_mutex_lock(&LOCK_open));
if (close_cached_table(thd,table))
error=1;
if (!(in_auto_repair = (table->table_cache_key == 0)))
{
if (close_cached_table(thd,table))
error=1;
}
else
{
if (param.out_flag & O_NEW_DATA)
my_close(file->dfile,MYF(0));
if (param.out_flag & O_NEW_INDEX)
my_close(file->s->kfile,MYF(0));
}
if (param.out_flag & O_NEW_DATA)
error|=change_to_newfile(fixed_name,MI_NAME_DEXT,
DATA_TMP_EXT, 0, MYF(0));
@ -549,6 +563,13 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
if (param.out_flag & O_NEW_INDEX)
error|=change_to_newfile(fixed_name,MI_NAME_IEXT,
INDEX_TMP_EXT, 0, MYF(0));
if (in_auto_repair)
{
if ((param.out_flag & O_NEW_DATA) && mi_open_datafile(file,file->s))
error=1;
if ((param.out_flag & O_NEW_DATA) && mi_open_keyfile(file->s))
error=1;
}
VOID(pthread_mutex_unlock(&LOCK_open));
}
}
@ -600,16 +621,20 @@ bool ha_myisam::check_and_repair(THD *thd)
DBUG_ENTER("ha_myisam::auto_check_and_repair");
check_opt.init();
check_opt.flags= T_MEDIUM;
check_opt.quick= !file->state->del; // Don't use quick if deleted rows
check_opt.flags= T_MEDIUM | T_AUTO_REPAIR;
// Don't use quick if deleted rows
if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
check_opt.quick=1;
sql_print_error("Warning: Checking table: %s",table->path);
if (mi_is_crashed(file) || check(thd, &check_opt))
{
sql_print_error("Warning: Recovering table: %s",table->path);
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) ?
T_SAFE_REPAIR : 0));
T_SAFE_REPAIR : 0)) | T_AUTO_REPAIR;
if (repair(thd, &check_opt))
error=1;
}

View file

@ -28,6 +28,7 @@
#define HA_RECOVER_DEFAULT 1 // Automatic recover active
#define HA_RECOVER_BACKUP 2 // Make a backupfile on recover
#define HA_RECOVER_FORCE 4 // Recover even if we loose rows
#define HA_RECOVER_QUICK 8 // Don't check rows in data file
extern ulong myisam_sort_buffer_size;
extern TYPELIB myisam_recover_typelib;

View file

@ -32,6 +32,9 @@
#ifdef HAVE_BERKELEY_DB
#include "ha_berkeley.h"
#endif
#ifdef HAVE_INNOBASE_DB
#include "ha_innobase.h"
#endif
#include <myisampack.h>
#include <errno.h>
@ -46,7 +49,7 @@ ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
const char *ha_table_type[] = {
"", "DIAB_ISAM","HASH","MISAM","PISAM","RMS_ISAM","HEAP", "ISAM",
"MRG_ISAM","MYISAM", "MRG_MYISAM", "BERKELEY_DB?", "?", "?",NullS
"MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNOBASE", "?", "?",NullS
};
const char *ha_row_type[] = {
@ -66,6 +69,10 @@ enum db_type ha_checktype(enum db_type database_type)
case DB_TYPE_BERKELEY_DB:
return(berkeley_skip ? DB_TYPE_MYISAM : database_type);
#endif
#ifdef HAVE_INNOBASE_DB
case DB_TYPE_INNOBASE:
return(innobase_skip ? DB_TYPE_MYISAM : database_type);
#endif
#ifndef NO_HASH
case DB_TYPE_HASH:
#endif
@ -103,6 +110,10 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
#ifdef HAVE_BERKELEY_DB
case DB_TYPE_BERKELEY_DB:
return new ha_berkeley(table);
#endif
#ifdef HAVE_INNOBASE_DB
case DB_TYPE_INNOBASE_DB:
return new ha_innobase(table);
#endif
case DB_TYPE_HEAP:
return new ha_heap(table);
@ -123,6 +134,14 @@ int ha_init()
if ((error=berkeley_init()))
return error;
}
#endif
#ifdef HAVE_INNOBASE_DB
if (!innobase_skip)
{
int error;
if ((error=innobase_init()))
return error;
}
#endif
return 0;
}
@ -146,6 +165,10 @@ int ha_panic(enum ha_panic_function flag)
#ifdef HAVE_BERKELEY_DB
if (!berkeley_skip)
error|=berkeley_end();
#endif
#ifdef HAVE_INNOBASE_DB
if (!innobase_skip)
error|=innobase_end();
#endif
return error;
} /* ha_panic */
@ -154,7 +177,7 @@ int ha_panic(enum ha_panic_function flag)
int ha_autocommit_or_rollback(THD *thd, int error)
{
DBUG_ENTER("ha_autocommit_or_rollback");
#ifdef HAVE_BERKELEY_DB
#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB)
if ((thd->options & OPTION_AUTO_COMMIT) && !thd->locked_tables)
{
if (!error)
@ -183,6 +206,17 @@ int ha_commit(THD *thd)
error=1;
}
}
#endif
#ifdef HAVE_INNOBASE_DB
if (thd->transaction.innobase_tid)
{
int error=innobase_commit(thd);
if (error)
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
}
}
#endif
DBUG_RETURN(error);
}
@ -201,6 +235,17 @@ int ha_rollback(THD *thd)
error=1;
}
}
#endif
#ifdef HAVE_INNOBASE_DB
if (thd->transaction.innobase_tid)
{
int error=innobase_rollback(thd);
if (error)
{
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
error=1;
}
}
#endif
DBUG_RETURN(error);
}
@ -212,6 +257,10 @@ bool ha_flush_logs()
#ifdef HAVE_BERKELEY_DB
if (!berkeley_skip && berkeley_flush_logs())
result=1;
#endif
#ifdef HAVE_INNOBASE_DB
if (!innobase_skip && innobase_flush_logs())
result=1;
#endif
return result;
}

View file

@ -448,7 +448,7 @@ skipp:
res->replace((uint) offset,from_length,*res3);
offset+=(int) to_length;
}
while ((offset=res->strstr(*res2,(uint) offset)) >0);
while ((offset=res->strstr(*res2,(uint) offset)) >= 0);
return res;
null:
@ -768,7 +768,7 @@ String *Item_func_substr_index::val_str(String *str)
}
else
{ // Start counting at end
for (offset=res->length() ; ; offset-=delimeter_length)
for (offset=res->length() ; ; offset-=delimeter_length-1)
{
if ((int) (offset=res->strrstr(*delimeter,offset)) < 0)
return res; // Didn't find, return org string

View file

@ -308,7 +308,7 @@ public:
Start_log_event() :Log_event(time(NULL)),binlog_version(BINLOG_VERSION)
{
created = when;
created = (uint32) when;
memcpy(server_version, ::server_version, sizeof(server_version));
}
Start_log_event(FILE* file, time_t when_arg, uint32 server_id) :

View file

@ -21,6 +21,9 @@
#ifdef HAVE_BERKELEY_DB
#include "ha_berkeley.h"
#endif
#ifdef HAVE_INNOBASE_DB
#include "ha_innobase.h"
#endif
#include "ha_myisam.h"
#include <nisam.h>
#include <thr_alarm.h>
@ -147,8 +150,7 @@ static ulong opt_specialflag=SPECIAL_ENGLISH;
static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
static ulong back_log,connect_timeout,concurrency;
static my_string opt_logname=0,opt_update_logname=0,
opt_binlog_index_name = 0,opt_slow_logname=0;
my_string opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
opt_binlog_index_name = 0,opt_slow_logname=0;
static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
static pthread_t select_thread;
static pthread_t flush_thread; // Used when debugging
@ -231,9 +233,11 @@ char mysql_real_data_home[FN_REFLEN],
default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot,
*opt_init_file;
char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
char server_version[50]=MYSQL_SERVER_VERSION;
const char *first_keyword="first";
const char **errmesg; /* Error messages */
const char *myisam_recover_options_str="OFF";
byte last_ref[MAX_REFLENGTH]; /* Index ref of keys */
my_string mysql_unix_port=NULL,mysql_tmpdir=NULL;
ulong my_bind_addr; /* the address we bind to */
@ -2219,7 +2223,8 @@ enum options {
OPT_LOG_SLAVE_UPDATES, OPT_BINLOG_DO_DB,
OPT_BINLOG_IGNORE_DB, OPT_WANT_CORE,
OPT_SKIP_CONCURRENT_INSERT, OPT_MEMLOCK, OPT_MYISAM_RECOVER,
OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, OPT_SKIP_SLAVE_START
OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, OPT_SKIP_SLAVE_START,
OPT_SKIP_INNOBASE
};
static struct option long_options[] = {
@ -2292,6 +2297,9 @@ static struct option long_options[] = {
{"set-variable", required_argument, 0, 'O'},
#ifdef HAVE_BERKELEY_DB
{"skip-bdb", no_argument, 0, (int) OPT_BDB_SKIP},
#endif
#ifdef HAVE_INNOBASE_DB
{"skip-innobase", no_argument, 0, (int) OPT_INNOBASE_SKIP},
#endif
{"skip-concurrent-insert", no_argument, 0, (int) OPT_SKIP_CONCURRENT_INSERT},
{"skip-delay-key-write", no_argument, 0, (int) OPT_SKIP_DELAY_KEY_WRITE},
@ -2443,6 +2451,7 @@ struct show_var_st init_vars[]= {
{"max_sort_length", (char*) &max_item_sort_length, SHOW_LONG},
{"max_tmp_tables", (char*) &max_tmp_tables, SHOW_LONG},
{"max_write_lock_count", (char*) &max_write_lock_count, SHOW_LONG},
{"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
{"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG},
{"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG},
{"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
@ -2647,6 +2656,11 @@ static void usage(void)
--bdb-tmpdir=directory Berkeley DB tempfile name\n\
--skip-bdb Don't use berkeley db (will save memory)\n\
");
#endif
#ifdef HAVE_INNOBASE_DB
puts("\
--skip-innobase Don't use innobase (will save memory)\n\
");
#endif
print_defaults("my",load_default_groups);
puts("");
@ -2917,11 +2931,13 @@ static void get_options(int argc,char **argv)
myisam_delay_key_write=0;
myisam_concurrent_insert=0;
myisam_recover_options= HA_RECOVER_NONE;
ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
break;
case (int) OPT_SAFE:
opt_specialflag|= SPECIAL_SAFE_MODE;
myisam_delay_key_write=0;
myisam_recover_options= HA_RECOVER_NONE; // To be changed
ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
break;
case (int) OPT_SKIP_CONCURRENT_INSERT:
myisam_concurrent_insert=0;
@ -3085,17 +3101,30 @@ static void get_options(int argc,char **argv)
case OPT_BDB_SKIP:
berkeley_skip=1;
break;
#endif
#ifdef HAVE_INNOBASE_DB
case OPT_INNOBASE_SKIP:
innobase_skip=1;
break;
#endif
case OPT_MYISAM_RECOVER:
{
if (!optarg || !optarg[0])
myisam_recover_options=HA_RECOVER_DEFAULT;
else if ((myisam_recover_options=
find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg);
exit(1);
myisam_recover_options= HA_RECOVER_DEFAULT;
myisam_recover_options_str= myisam_recover_typelib.type_names[0];
}
else
{
myisam_recover_options_str=optarg;
if ((myisam_recover_options=
find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg);
exit(1);
}
}
ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
break;
}
case OPT_MASTER_HOST:

View file

@ -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(thd, table,db,table_name,alias,0) ||
if (open_unireg_entry(thd, table,db,table_name,alias,1) ||
!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
key_length)))
{
@ -1157,7 +1157,6 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
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),
@ -1167,11 +1166,17 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
(entry->file->is_crashed() && entry->file->check_and_repair(thd)))
{
sql_print_error("Error: Couldn't repair table: %s.%s",db,name);
closefrm(entry);
error=1;
}
else
{
thd->net.last_error[0]=0; // Clear error message
thd->net.last_errno=0;
}
unlock_table_name(thd,&table_list);
if (locked)
pthread_mutex_lock(&LOCK_open); // Get back old lock
pthread_mutex_lock(&LOCK_open); // Get back original lock
if (error)
goto err;
}

View file

@ -501,6 +501,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
&& find_temporary_table(thd,db,table_name))
{
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
DBUG_RETURN(0);
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
DBUG_RETURN(-1);
}