Commit 9f855602 authored by Michael Widenius's avatar Michael Widenius

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
parent a4fff491
......@@ -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;
This diff was suppressed by a .gitattributes entry.
......@@ -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;
......@@ -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)
......
......@@ -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;
......
......@@ -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 */
}
......
......@@ -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
......
......@@ -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 @@ class ha_archive: public handler
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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment