Enable archive tables to work with mysql_upgrade / repair

Made long file names from previous patch shorter

mysql-test/r/archive.result:
  Added testing of repair (for upgrade) of 5.0 tables.
mysql-test/std_data/archive_5_0.ARM:
  Archive table created in MySQL 5.0
mysql-test/std_data/archive_5_0.ARZ:
  Archive table created in MySQL 5.0
mysql-test/std_data/archive_5_0.frm:
  Archive table created in MySQL 5.0
mysql-test/std_data/long_table_name.MYD:
  Made long file names shorter
mysql-test/std_data/long_table_name.MYI:
  Made long file names shorter
mysql-test/std_data/long_table_name.frm:
  Made long file names shorter
mysql-test/t/archive.test:
  Added testing of repair (for upgrade) of 5.0 tables.
sql/sql_table.cc:
  Allow recreate to open crashed tables.
sql/table.cc:
  Fix error message if storage engine doesn't exists.
storage/archive/azio.c:
  Reset status values in case archive is of old versions
storage/archive/ha_archive.cc:
  Fix to allow one to open old versions of table during repair
  Reset status variables for old version tables
  If the the table is of old version, force upgrade with ALTER TABLE when doing repair
storage/archive/ha_archive.h:
  Added variables to detect old versions
This commit is contained in:
Michael Widenius 2010-09-03 20:55:56 +03:00
parent a4fff491eb
commit 9f85560212
13 changed files with 72 additions and 15 deletions

View file

@ -12725,8 +12725,7 @@ INSERT INTO t1 (col1, col2) VALUES (1, "value");
ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair Error Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
test.t1 repair error Corrupt
test.t1 repair status OK
DROP TABLE t1;
#
# BUG#48757 - missing .ARZ file causes server crash
@ -12756,3 +12755,12 @@ a
1
2
DROP TABLE t1;
select * from t1;
ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
repair table t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
select sum(length(a)),sum(b) from t1;
sum(length(a)) sum(b)
8670 187
drop table t1;

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1680,3 +1680,16 @@ SELECT * FROM t1;
REPAIR TABLE t1 EXTENDED;
SELECT * FROM t1;
DROP TABLE t1;
#
# Bug #47012 archive tables are not upgradeable, and server crashes on
# any access
#
copy_file std_data/archive_5_0.frm $MYSQLD_DATADIR/test/t1.frm;
copy_file std_data/archive_5_0.ARZ $MYSQLD_DATADIR/test/t1.ARZ;
copy_file std_data/archive_5_0.ARM $MYSQLD_DATADIR/test/t1.ARM;
--error ER_TABLE_NEEDS_UPGRADE
select * from t1;
repair table t1;
select sum(length(a)),sum(b) from t1;
drop table t1;

View file

@ -4804,7 +4804,10 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (check_old_types == HA_ADMIN_NEEDS_ALTER ||
check_for_upgrade == HA_ADMIN_NEEDS_ALTER)
{
/* We use extra_open_options to be able to open crashed tables */
thd->open_options|= extra_open_options;
result_code= admin_recreate_table(thd, table);
thd->open_options= ~extra_open_options;
goto send_result;
}
if (check_old_types || check_for_upgrade)

View file

@ -866,7 +866,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
/* Read extra data segment */
uchar *buff, *next_chunk, *buff_end;
DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
if (!(next_chunk= buff= (uchar*) my_malloc(n_length+1, MYF(MY_WME))))
goto err;
if (my_pread(file, buff, n_length, record_offset + share->reclength,
MYF(MY_NABP)))
@ -945,6 +945,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
{
/* purecov: begin inspected */
error= 8;
name.str[name.length]= 0;
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
my_free(buff, MYF(0));
goto err;

View file

@ -150,6 +150,17 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd)
}
else
{
/* Reset values in case of old version of archive file */
s->rows= 0;
s->forced_flushes= 0;
s->shortest_row= 0;
s->longest_row= 0;
s->auto_increment= 0;
s->check_point= 0;
s->comment_start_pos= 0;
s->comment_length= 0;
s->frm_start_pos= 0;
s->frm_length= 0;
check_header(s); /* skip the .az header */
}

View file

@ -293,7 +293,7 @@ int ha_archive::read_data_header(azio_stream *file_to_read)
DBUG_PRINT("ha_archive", ("Version %u", data_buffer[1]));
if ((data_buffer[0] != (uchar)ARCHIVE_CHECK_HEADER) &&
(data_buffer[1] != (uchar)ARCHIVE_VERSION))
(data_buffer[1] == 1 || data_buffer[1] == 2))
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
DBUG_RETURN(0);
@ -360,9 +360,19 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc)
my_free(share, MYF(0));
DBUG_RETURN(NULL);
}
stats.auto_increment_value= archive_tmp.auto_increment + 1;
share->rows_recorded= (ha_rows)archive_tmp.rows;
share->crashed= archive_tmp.dirty;
share->version= archive_tmp.version;
if (archive_tmp.version == ARCHIVE_VERSION)
{
stats.auto_increment_value= archive_tmp.auto_increment + 1;
share->rows_recorded= (ha_rows)archive_tmp.rows;
share->crashed= archive_tmp.dirty;
}
else
{
/* Used by repair */
share->rows_recorded= ~(ha_rows) 0;
stats.auto_increment_value= 0;
}
/*
If archive version is less than 3, It should be upgraded before
use.
@ -512,10 +522,19 @@ int ha_archive::open(const char *name, int mode, uint open_options)
case 0:
break;
case HA_ERR_CRASHED_ON_USAGE:
DBUG_PRINT("ha_archive", ("archive table was crashed"));
if (open_options & HA_OPEN_FOR_REPAIR)
{
rc= 0;
break;
}
/* fall through */
case HA_ERR_TABLE_NEEDS_UPGRADE:
if (open_options & HA_OPEN_FOR_REPAIR)
{
rc= 0;
break;
}
free_share();
/* fall through */
default:
@ -535,13 +554,6 @@ int ha_archive::open(const char *name, int mode, uint open_options)
thr_lock_data_init(&share->lock, &lock, NULL);
DBUG_PRINT("ha_archive", ("archive table was crashed %s",
rc == HA_ERR_CRASHED_ON_USAGE ? "yes" : "no"));
if (rc == HA_ERR_CRASHED_ON_USAGE && open_options & HA_OPEN_FOR_REPAIR)
{
DBUG_RETURN(0);
}
DBUG_RETURN(rc);
}
@ -1267,6 +1279,14 @@ int ha_archive::rnd_pos(uchar * buf, uchar *pos)
DBUG_RETURN(get_row(&archive, buf));
}
int ha_archive::check_for_upgrade(HA_CHECK_OPT *check_opt)
{
if (share->version < ARCHIVE_VERSION)
return HA_ADMIN_NEEDS_ALTER;
return 0;
}
/*
This method repairs the meta file. It does this by walking the datafile and
rewriting the meta file. If EXTENDED repair is requested, we attempt to

View file

@ -35,7 +35,7 @@ typedef struct st_archive_record_buffer {
typedef struct st_archive_share {
char *table_name;
char data_file_name[FN_REFLEN];
uint table_name_length,use_count;
uint table_name_length,use_count, version;
pthread_mutex_t mutex;
THR_LOCK lock;
azio_stream archive_write; /* Archive file we are working with */
@ -133,6 +133,7 @@ public:
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int repair(THD* thd, HA_CHECK_OPT* check_opt);
int check_for_upgrade(HA_CHECK_OPT *check_opt);
void start_bulk_insert(ha_rows rows);
int end_bulk_insert();
enum row_type get_row_type() const