diff options
author | unknown <brian@brian-akers-computer.local> | 2004-09-21 03:33:22 +0200 |
---|---|---|
committer | unknown <brian@brian-akers-computer.local> | 2004-09-21 03:33:22 +0200 |
commit | 764ea714f4c22c50bcfefc89cb1bbba951437f58 (patch) | |
tree | ebc56ee71ecca22bf7468f81657d523ca7a66169 /sql/examples | |
parent | 52683755d3572722bdd32ffe7ae2e6d237d6066d (diff) | |
download | mariadb-git-764ea714f4c22c50bcfefc89cb1bbba951437f58.tar.gz |
The major change for this changeset is the addition of code to handle:
OPTIMIZE TABLE <archive table>
This recompresses the table, thus removing any additional gzip headers caused by opening/closing or flushing the table.
mysql-test/r/archive.result:
Added optimize test case for archive engine.
mysql-test/t/archive.test:
Added test case for OPTIMIZE table <archive table>
sql/examples/ha_archive.cc:
The big change was the addition of optimize() call to allow tables to be recompressed (so if you have been reading/writing/reading/writing and ending up with larger files then you should, this will solve it). Though adding this feature is going to make it a real headache to add row level locking.
Also fixed bug reported by JD where storage engine code was not functioning (this of course was because I didn't check for the propper return value for hash_init). Removed BROKEN_GZIP ifdef since there was no way to enable it.
sql/examples/ha_archive.h:
Added optimize() method.
Diffstat (limited to 'sql/examples')
-rw-r--r-- | sql/examples/ha_archive.cc | 69 | ||||
-rw-r--r-- | sql/examples/ha_archive.h | 2 |
2 files changed, 57 insertions, 14 deletions
diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc index c004330932c..e71ae05734a 100644 --- a/sql/examples/ha_archive.cc +++ b/sql/examples/ha_archive.cc @@ -70,7 +70,6 @@ Allow users to set compression level. Add truncate table command. Implement versioning, should be easy. - Implement optimize so we can fix broken tables. Allow for errors, find a way to mark bad rows. See if during an optimize you can make the table smaller. Talk to the gzip guys, come up with a writable format so that updates are doable @@ -88,6 +87,7 @@ static int archive_init= 0; /* The file extension */ #define ARZ ".ARZ" +#define ARN ".ARN" /* Used for hash table that tracks open tables. @@ -117,7 +117,7 @@ static ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table) if (!archive_init) { VOID(pthread_mutex_init(&archive_mutex,MY_MUTEX_INIT_FAST)); - if (!hash_init(&archive_open_tables,system_charset_info,32,0,0, + if (hash_init(&archive_open_tables,system_charset_info,32,0,0, (hash_get_key) archive_get_key,0,0)) { pthread_mutex_unlock(&LOCK_mysql_create_db); @@ -205,7 +205,7 @@ static int free_share(ARCHIVE_SHARE *share) We just implement one additional file extension. */ const char **ha_archive::bas_ext() const -{ static const char *ext[]= { ARZ, NullS }; return ext; } +{ static const char *ext[]= { ARZ, ARN, NullS }; return ext; } /* @@ -322,6 +322,11 @@ err: /* Look at ha_archive::open() for an explanation of the row format. Here we just write out the row. + + Wondering about start_bulk_insert()? We don't implement it for + archive since it optimizes for lots of writes. The only save + for implementing start_bulk_insert() is that we could skip + setting dirty to true each time. */ int ha_archive::write_row(byte * buf) { @@ -380,17 +385,7 @@ int ha_archive::rnd_init(bool scan) pthread_mutex_lock(&share->mutex); if (share->dirty == TRUE) { -/* I was having problems with OSX, but it worked for 10.3 so I am wrapping this with and ifdef */ -#ifdef BROKEN_GZFLUSH - gzclose(share->archive_write); - if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL) - { - pthread_mutex_unlock(&share->mutex); - DBUG_RETURN(errno ? errno : -1); - } -#else gzflush(share->archive_write, Z_SYNC_FLUSH); -#endif share->dirty= FALSE; } pthread_mutex_unlock(&share->mutex); @@ -504,6 +499,54 @@ int ha_archive::rnd_pos(byte * buf, byte *pos) DBUG_RETURN(get_row(buf)); } +/* + The table can become fragmented if data was inserted, read, and then + inserted again. What we do is open up the file and recompress it completely. + */ +int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) +{ + DBUG_ENTER("ha_archive::optimize"); + int read; // Bytes read, gzread() returns int + gzFile reader, writer; + char block[IO_SIZE]; + char writer_filename[FN_REFLEN]; + + /* Lets create a file to contain the new data */ + fn_format(writer_filename,share->table_name,"",ARN, MY_REPLACE_EXT|MY_UNPACK_FILENAME); + + /* Closing will cause all data waiting to be flushed, to be flushed */ + gzclose(share->archive_write); + + if ((reader= gzopen(share->data_file_name, "rb")) == NULL) + DBUG_RETURN(-1); + + if ((writer= gzopen(writer_filename, "wb")) == NULL) + { + gzclose(reader); + DBUG_RETURN(-1); + } + + while (read= gzread(reader, block, IO_SIZE)) + gzwrite(writer, block, read); + + gzclose(reader); + gzclose(writer); + + my_rename(writer_filename,share->data_file_name,MYF(0)); + + /* + We reopen the file in case some IO is waiting to go through. + In theory the table is closed right after this operation, + but it is possible for IO to still happen. + I may be being a bit too paranoid right here. + */ + if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL) + DBUG_RETURN(errno ? errno : -1); + share->dirty= FALSE; + + DBUG_RETURN(0); +} + /****************************************************************************** Everything below here is default, please look at ha_example.cc for diff --git a/sql/examples/ha_archive.h b/sql/examples/ha_archive.h index f08353a5d6c..cf7becc5bc0 100644 --- a/sql/examples/ha_archive.h +++ b/sql/examples/ha_archive.h @@ -112,7 +112,7 @@ public: int external_lock(THD *thd, int lock_type); ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); - + int optimize(THD* thd, HA_CHECK_OPT* check_opt); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); }; |