summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/archive.result12
-rw-r--r--mysql-test/std_data/archive_5_0.ARMbin0 -> 19 bytes
-rw-r--r--mysql-test/std_data/archive_5_0.ARZbin0 -> 138 bytes
-rw-r--r--mysql-test/std_data/archive_5_0.frmbin0 -> 8578 bytes
-rw-r--r--mysql-test/std_data/long_table_name.MYD (renamed from mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYD)bin56 -> 56 bytes
-rw-r--r--mysql-test/std_data/long_table_name.MYI (renamed from mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYI)bin6144 -> 6144 bytes
-rw-r--r--mysql-test/std_data/long_table_name.frm (renamed from mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.frm)bin8650 -> 8650 bytes
-rw-r--r--mysql-test/t/archive.test13
-rw-r--r--sql/sql_table.cc3
-rw-r--r--sql/table.cc3
-rw-r--r--storage/archive/azio.c11
-rw-r--r--storage/archive/ha_archive.cc42
-rw-r--r--storage/archive/ha_archive.h3
13 files changed, 72 insertions, 15 deletions
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index f90bcb521e1..5a731e6476c 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -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;
diff --git a/mysql-test/std_data/archive_5_0.ARM b/mysql-test/std_data/archive_5_0.ARM
new file mode 100644
index 00000000000..8f1111437d8
--- /dev/null
+++ b/mysql-test/std_data/archive_5_0.ARM
Binary files differ
diff --git a/mysql-test/std_data/archive_5_0.ARZ b/mysql-test/std_data/archive_5_0.ARZ
new file mode 100644
index 00000000000..d24e76884cc
--- /dev/null
+++ b/mysql-test/std_data/archive_5_0.ARZ
Binary files differ
diff --git a/mysql-test/std_data/archive_5_0.frm b/mysql-test/std_data/archive_5_0.frm
new file mode 100644
index 00000000000..827213d329d
--- /dev/null
+++ b/mysql-test/std_data/archive_5_0.frm
Binary files differ
diff --git a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYD b/mysql-test/std_data/long_table_name.MYD
index 2ff33451b5f..2ff33451b5f 100644
--- a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYD
+++ b/mysql-test/std_data/long_table_name.MYD
Binary files differ
diff --git a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYI b/mysql-test/std_data/long_table_name.MYI
index cffa158beae..cffa158beae 100644
--- a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYI
+++ b/mysql-test/std_data/long_table_name.MYI
Binary files differ
diff --git a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.frm b/mysql-test/std_data/long_table_name.frm
index 6a812a8b137..6a812a8b137 100644
--- a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.frm
+++ b/mysql-test/std_data/long_table_name.frm
Binary files differ
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index 6704257f9af..7478c7dcdce 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -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;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index a0621dbbdcf..96be7c4437c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -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)
diff --git a/sql/table.cc b/sql/table.cc
index a7ed2dd40ff..a3c6f07cddf 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -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;
diff --git a/storage/archive/azio.c b/storage/archive/azio.c
index a24350dd454..fc54d98ab15 100644
--- a/storage/archive/azio.c
+++ b/storage/archive/azio.c
@@ -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 */
}
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 988337ec50e..d0cb34455b9 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -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
diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h
index ab630ed22fd..653a13b242d 100644
--- a/storage/archive/ha_archive.h
+++ b/storage/archive/ha_archive.h
@@ -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