diff options
-rw-r--r-- | mysql-test/r/archive.result | 11 | ||||
-rw-r--r-- | mysql-test/std_data/bug47012.ARM | bin | 0 -> 19 bytes | |||
-rw-r--r-- | mysql-test/std_data/bug47012.ARZ | bin | 0 -> 22 bytes | |||
-rw-r--r-- | mysql-test/std_data/bug47012.frm | bin | 0 -> 8590 bytes | |||
-rw-r--r-- | mysql-test/t/archive.test | 21 | ||||
-rw-r--r-- | storage/archive/azio.c | 17 | ||||
-rw-r--r-- | storage/archive/ha_archive.cc | 16 |
7 files changed, 60 insertions, 5 deletions
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index e865d775c6a..c620eb97cab 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12717,3 +12717,14 @@ COUNT(t1.a) 729 DROP TABLE t1; SET @@join_buffer_size= @save_join_buffer_size; +SHOW CREATE TABLE t1; +ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +SELECT * FROM t1; +ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +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 +DROP TABLE t1; diff --git a/mysql-test/std_data/bug47012.ARM b/mysql-test/std_data/bug47012.ARM Binary files differnew file mode 100644 index 00000000000..86bbaf829d2 --- /dev/null +++ b/mysql-test/std_data/bug47012.ARM diff --git a/mysql-test/std_data/bug47012.ARZ b/mysql-test/std_data/bug47012.ARZ Binary files differnew file mode 100644 index 00000000000..f2aa19ffea6 --- /dev/null +++ b/mysql-test/std_data/bug47012.ARZ diff --git a/mysql-test/std_data/bug47012.frm b/mysql-test/std_data/bug47012.frm Binary files differnew file mode 100644 index 00000000000..6c0a535cce7 --- /dev/null +++ b/mysql-test/std_data/bug47012.frm diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index aad3d19455d..90f5b1b0b53 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1623,3 +1623,24 @@ INSERT INTO t1 VALUES('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'), SELECT COUNT(t1.a) FROM t1, t1 a, t1 b, t1 c, t1 d, t1 e; DROP TABLE t1; SET @@join_buffer_size= @save_join_buffer_size; + +# +# BUG#47012 archive tables are not upgradeable, and server crashes on any access +# +let $MYSQLD_DATADIR= `SELECT @@datadir`; +copy_file std_data/bug47012.frm $MYSQLD_DATADIR/test/t1.frm; +copy_file std_data/bug47012.ARZ $MYSQLD_DATADIR/test/t1.ARZ; +copy_file std_data/bug47012.ARM $MYSQLD_DATADIR/test/t1.ARM; + +--error ER_TABLE_NEEDS_UPGRADE +SHOW CREATE TABLE t1; + +--error ER_TABLE_NEEDS_UPGRADE +SELECT * FROM t1; + +--error ER_TABLE_NEEDS_UPGRADE +INSERT INTO t1 (col1, col2) VALUES (1, "value"); + +REPAIR TABLE t1; +DROP TABLE t1; +remove_file $MYSQLD_DATADIR/test/t1.ARM; diff --git a/storage/archive/azio.c b/storage/archive/azio.c index 916dd8ba59d..603e328c715 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -69,7 +69,7 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd) s->transparent = 0; s->mode = 'r'; s->version = (unsigned char)az_magic[1]; /* this needs to be a define to version */ - s->version = (unsigned char)az_magic[2]; /* minor version */ + s->minor_version= (unsigned char) az_magic[2]; /* minor version */ /* We do our own version of append by nature. @@ -352,10 +352,19 @@ void read_header(azio_stream *s, unsigned char *buffer) s->comment_length= (unsigned int)uint4korr(buffer + AZ_COMMENT_LENGTH_POS); s->dirty= (unsigned int)buffer[AZ_DIRTY_POS]; } - else + else if (buffer[0] == gz_magic[0] && buffer[1] == gz_magic[1]) { - DBUG_ASSERT(buffer[0] == az_magic[0] && buffer[1] == az_magic[1]); - return; + /* + Set version number to previous version (2). + */ + s->version= (unsigned char) 2; + } else { + /* + Unknown version. + Most probably due to a corrupt archive. + */ + s->dirty= AZ_STATE_DIRTY; + s->z_err= Z_VERSION_ERROR; } } diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 6fa8333c1b7..4648ca798da 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -360,6 +360,12 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc) stats.auto_increment_value= archive_tmp.auto_increment + 1; share->rows_recorded= (ha_rows)archive_tmp.rows; share->crashed= archive_tmp.dirty; + /* + If archive version is less than 3, It should be upgraded before + use. + */ + if (archive_tmp.version < ARCHIVE_VERSION) + *rc= HA_ERR_TABLE_NEEDS_UPGRADE; azclose(&archive_tmp); VOID(my_hash_insert(&archive_open_tables, (uchar*) share)); @@ -491,7 +497,15 @@ int ha_archive::open(const char *name, int mode, uint open_options) (open_options & HA_OPEN_FOR_REPAIR) ? "yes" : "no")); share= get_share(name, &rc); - if (rc == HA_ERR_CRASHED_ON_USAGE && !(open_options & HA_OPEN_FOR_REPAIR)) + /* + Allow open on crashed table in repair mode only. + Block open on 5.0 ARCHIVE table. Though we have almost all + routines to access these tables, they were not well tested. + For now we have to refuse to open such table to avoid + potential data loss. + */ + if ((rc == HA_ERR_CRASHED_ON_USAGE && !(open_options & HA_OPEN_FOR_REPAIR)) + || rc == HA_ERR_TABLE_NEEDS_UPGRADE) { /* purecov: begin inspected */ free_share(); |