diff options
-rw-r--r-- | mysql-test/r/archive.result | 26 | ||||
-rw-r--r-- | mysql-test/t/archive.test | 21 | ||||
-rw-r--r-- | storage/archive/azio.c | 22 | ||||
-rw-r--r-- | storage/archive/ha_archive.cc | 37 | ||||
-rw-r--r-- | storage/archive/ha_archive.h | 1 |
5 files changed, 95 insertions, 12 deletions
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 685e1e5ba4b..028c8b32f87 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12775,3 +12775,29 @@ a 1 2 DROP TABLE t1; +# +# Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a int) ENGINE=ARCHIVE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES (1); +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +FLUSH TABLES; +INSERT INTO t1 VALUES (2); +SELECT * FROM t1 ORDER BY a; +a +1 +2 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index a3665e5f455..c3a080612a9 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1701,3 +1701,24 @@ SELECT * FROM t1; REPAIR TABLE t1 EXTENDED; SELECT * FROM t1; DROP TABLE t1; + + +--echo # +--echo # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a int) ENGINE=ARCHIVE; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES (1); +OPTIMIZE TABLE t1; +let $MYSQLD_DATADIR= `select @@datadir`; +remove_file $MYSQLD_DATADIR/test/t1.frm; +FLUSH TABLES; +INSERT INTO t1 VALUES (2); +SELECT * FROM t1 ORDER BY a; +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/storage/archive/azio.c b/storage/archive/azio.c index c1dd6e6f38c..1e2753027dc 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -31,7 +31,7 @@ int az_open(azio_stream *s, const char *path, int Flags, File fd); int do_flush(azio_stream *file, int flush); int get_byte(azio_stream *s); void check_header(azio_stream *s); -void write_header(azio_stream *s); +int write_header(azio_stream *s); int destroy(azio_stream *s); void putLong(File file, uLong x); uLong getLong(azio_stream *s); @@ -155,7 +155,7 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd) } -void write_header(azio_stream *s) +int write_header(azio_stream *s) { char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE]; char *ptr= buffer; @@ -191,8 +191,8 @@ void write_header(azio_stream *s) *(ptr + AZ_DIRTY_POS)= (unsigned char)s->dirty; /* Start of Data Block Index Block */ /* Always begin at the begining, and end there as well */ - my_pwrite(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0, - MYF(0)); + return my_pwrite(s->file, (uchar*) buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, + 0, MYF(MY_NABP)) ? 1 : 0; } /* =========================================================================== @@ -838,19 +838,19 @@ int azwrite_frm(azio_stream *s, char *blob, unsigned int length) s->frm_length= length; s->start+= length; - my_pwrite(s->file, (uchar*) blob, s->frm_length, s->frm_start_pos, MYF(0)); - - write_header(s); - my_seek(s->file, 0, MY_SEEK_END, MYF(0)); + if (my_pwrite(s->file, (uchar*) blob, s->frm_length, + s->frm_start_pos, MYF(MY_NABP)) || + write_header(s) || + (my_seek(s->file, 0, MY_SEEK_END, MYF(0)) == MY_FILEPOS_ERROR)) + return 1; return 0; } int azread_frm(azio_stream *s, char *blob) { - my_pread(s->file, (uchar*) blob, s->frm_length, s->frm_start_pos, MYF(0)); - - return 0; + return my_pread(s->file, (uchar*) blob, s->frm_length, + s->frm_start_pos, MYF(MY_NABP)) ? 1 : 0; } diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 63848370ff1..ef907b035b5 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -613,6 +613,34 @@ int ha_archive::close(void) } +/** + Copy a frm blob between streams. + + @param src The source stream. + @param dst The destination stream. + + @return Zero on success, non-zero otherwise. +*/ + +int ha_archive::frm_copy(azio_stream *src, azio_stream *dst) +{ + int rc= 0; + char *frm_ptr; + + if (!(frm_ptr= (char *) my_malloc(src->frm_length, MYF(0)))) + return HA_ERR_OUT_OF_MEM; + + /* Write file offset is set to the end of the file. */ + if (azread_frm(src, frm_ptr) || + azwrite_frm(dst, frm_ptr, src->frm_length)) + rc= my_errno ? my_errno : HA_ERR_INTERNAL_ERROR; + + my_free(frm_ptr); + + return rc; +} + + /* We create our data file here. The format is pretty simple. You can read about the format of the data file above. @@ -1345,10 +1373,10 @@ int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt) */ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) { - DBUG_ENTER("ha_archive::optimize"); int rc= 0; azio_stream writer; char writer_filename[FN_REFLEN]; + DBUG_ENTER("ha_archive::optimize"); init_archive_reader(); @@ -1366,6 +1394,13 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR|O_BINARY))) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + /* + Transfer the embedded FRM so that the file can be discoverable. + Write file offset is set to the end of the file. + */ + if ((rc= frm_copy(&archive, &writer))) + goto error; + /* An extended rebuild is a lot more effort. We open up each row and re-record it. Any dead rows are removed (aka rows that may have been partially recorded). diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index 94842203f16..b258b403c3c 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -75,6 +75,7 @@ class ha_archive: public handler archive_record_buffer *create_record_buffer(unsigned int length); void destroy_record_buffer(archive_record_buffer *r); + int frm_copy(azio_stream *src, azio_stream *dst); public: ha_archive(handlerton *hton, TABLE_SHARE *table_arg); |