mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 13:32:33 +01:00
This updates archive to use new header information in az files and makes way for combining the meta data file with the AZ file.
This commit is contained in:
parent
4eba36ee3b
commit
f85acb894c
4 changed files with 134 additions and 94 deletions
|
@ -18,6 +18,7 @@
|
|||
#include <string.h>
|
||||
|
||||
static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
|
||||
static int const az_magic[2] = {0xfe, 0x03}; /* az magic header */
|
||||
|
||||
/* gzip flag byte */
|
||||
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
|
||||
|
@ -66,6 +67,7 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd)
|
|||
s->crc = crc32(0L, Z_NULL, 0);
|
||||
s->transparent = 0;
|
||||
s->mode = 'r';
|
||||
s->version = (unsigned char)az_magic[1]; /* this needs to be a define to version */
|
||||
|
||||
if (Flags & O_WRONLY || Flags & O_APPEND)
|
||||
s->mode = 'w';
|
||||
|
@ -112,20 +114,24 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd)
|
|||
return Z_NULL;
|
||||
}
|
||||
if (s->mode == 'w') {
|
||||
char buffer[10];
|
||||
/* Write a very simple .gz header:
|
||||
*/
|
||||
buffer[0] = gz_magic[0];
|
||||
buffer[1] = gz_magic[1];
|
||||
buffer[2] = Z_DEFLATED;
|
||||
buffer[3] = 0 /*flags*/;
|
||||
buffer[4] = 0;
|
||||
buffer[5] = 0;
|
||||
buffer[6] = 0;
|
||||
buffer[7] = 0 /*time*/;
|
||||
buffer[8] = 0 /*xflags*/;
|
||||
buffer[9] = 0x03;
|
||||
s->start = 10L;
|
||||
char buffer[AZHEADER_SIZE];
|
||||
char *ptr;
|
||||
/* Write a very simple .gz header: */
|
||||
bzero(buffer, AZHEADER_SIZE);
|
||||
buffer[0] = az_magic[0];
|
||||
buffer[1] = az_magic[1];
|
||||
buffer[2] = (unsigned char)0; /* Reserved for block size */
|
||||
buffer[3] = (unsigned char)0; /* Compression Type */
|
||||
ptr= buffer + 4;
|
||||
int4store(ptr, 0LL); /* FRM Block */
|
||||
ptr+= sizeof(unsigned long);
|
||||
int4store(ptr, 0LL); /* Meta Block */
|
||||
ptr+= sizeof(unsigned long);
|
||||
int4store(ptr, (unsigned long)AZHEADER_SIZE); /* Start of Data Block Index Block */
|
||||
ptr+= sizeof(unsigned long);
|
||||
|
||||
s->start = AZHEADER_SIZE;
|
||||
s->version = (unsigned char)az_magic[1];
|
||||
my_write(s->file, buffer, (uint)s->start, MYF(0));
|
||||
/* We use 10L instead of ftell(s->file) to because ftell causes an
|
||||
* fflush on some systems. This version of the library doesn't use
|
||||
|
@ -218,13 +224,11 @@ void check_header(azio_stream *s)
|
|||
}
|
||||
|
||||
/* Peek ahead to check the gzip magic header */
|
||||
if (s->stream.next_in[0] != gz_magic[0] ||
|
||||
s->stream.next_in[1] != gz_magic[1]) {
|
||||
s->transparent = 1;
|
||||
return;
|
||||
}
|
||||
if ( s->stream.next_in[0] == gz_magic[0] && s->stream.next_in[1] == gz_magic[1])
|
||||
{
|
||||
s->stream.avail_in -= 2;
|
||||
s->stream.next_in += 2;
|
||||
s->version= (unsigned char)2;
|
||||
|
||||
/* Check the rest of the gzip header */
|
||||
method = get_byte(s);
|
||||
|
@ -253,6 +257,20 @@ void check_header(azio_stream *s)
|
|||
for (len = 0; len < 2; len++) (void)get_byte(s);
|
||||
}
|
||||
s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
|
||||
}
|
||||
else if ( s->stream.next_in[0] == az_magic[0] && s->stream.next_in[1] == az_magic[1])
|
||||
{
|
||||
s->stream.avail_in -= 2;
|
||||
s->stream.next_in += 2;
|
||||
for (len = 0; len < (AZHEADER_SIZE-2); len++) (void)get_byte(s);
|
||||
s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->transparent = 1;
|
||||
s->version = (unsigned char)0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
|
@ -668,10 +686,12 @@ int azclose (azio_stream *s)
|
|||
|
||||
if (s == NULL) return Z_STREAM_ERROR;
|
||||
|
||||
|
||||
if (s->mode == 'w') {
|
||||
#ifdef NO_GZCOMPRESS
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
|
||||
if (do_flush (s, Z_FINISH) != Z_OK)
|
||||
return destroy(s);
|
||||
|
||||
|
@ -681,3 +701,42 @@ int azclose (azio_stream *s)
|
|||
}
|
||||
return destroy(s);
|
||||
}
|
||||
|
||||
/*
|
||||
This function reads the header of meta block and returns whether or not it was successful.
|
||||
*rows will contain the current number of rows in the data file upon success.
|
||||
*/
|
||||
int az_read_meta_block(char *meta_start, unsigned long *rows,
|
||||
unsigned long long *auto_increment,
|
||||
unsigned long long *forced_flushes)
|
||||
{
|
||||
unsigned char *ptr= meta_start;
|
||||
ulonglong check_point;
|
||||
|
||||
DBUG_ENTER("ha_archive::read_meta_file");
|
||||
|
||||
/*
|
||||
Parse out the meta data, we ignore version at the moment
|
||||
*/
|
||||
|
||||
*rows= (unsigned long long)uint8korr(ptr);
|
||||
ptr+= sizeof(unsigned long long); // Move past rows
|
||||
check_point= uint8korr(ptr);
|
||||
ptr+= sizeof(unsigned long long); // Move past check_point
|
||||
*auto_increment= uint8korr(ptr);
|
||||
ptr+= sizeof(unsigned long long); // Move past auto_increment
|
||||
*forced_flushes= uint8korr(ptr);
|
||||
ptr+= sizeof(unsigned long long); // Move past forced_flush
|
||||
|
||||
DBUG_PRINT("ha_archive::read_meta_file", ("Rows %llu",
|
||||
(long long unsigned)*rows));
|
||||
DBUG_PRINT("ha_archive::read_meta_file", ("Checkpoint %llu",
|
||||
(long long unsigned) check_point));
|
||||
DBUG_PRINT("ha_archive::read_meta_file", ("Auto-Increment %llu",
|
||||
(long long unsigned)*auto_increment));
|
||||
DBUG_PRINT("ha_archive::read_meta_file", ("Forced Flushes %llu",
|
||||
(long long unsigned)*forced_flushes));
|
||||
DBUG_PRINT("ha_archive::read_meta_file", ("Dirty %d", (int)(*ptr)));
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
This libary has been modified for use by the MySQL Archive Engine.
|
||||
-Brian Aker
|
||||
*/
|
||||
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 1.2.3, July 18th, 2005
|
||||
|
||||
|
@ -38,6 +40,16 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Start of MySQL Specific Information */
|
||||
|
||||
/*
|
||||
ulonglong + ulonglong + ulonglong + ulonglong + uchar
|
||||
*/
|
||||
#define AZMETA_BUFFER_SIZE sizeof(ulonglong) \
|
||||
+ sizeof(ulonglong) + sizeof(ulonglong) + sizeof(ulonglong) \
|
||||
+ sizeof(uchar)
|
||||
|
||||
#define AZHEADER_SIZE 16
|
||||
|
||||
/*
|
||||
The 'zlib' compression library provides in-memory compression and
|
||||
|
@ -171,6 +183,7 @@ typedef struct azio_stream {
|
|||
my_off_t out; /* bytes out of deflate or inflate */
|
||||
int back; /* one character push-back */
|
||||
int last; /* true if push-back is last character */
|
||||
unsigned char version; /* Version */
|
||||
} azio_stream;
|
||||
|
||||
/* basic functions */
|
||||
|
|
|
@ -250,11 +250,17 @@ int ha_archive::read_data_header(azio_stream *file_to_read)
|
|||
if (azrewind(file_to_read) == -1)
|
||||
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
|
||||
|
||||
if (file_to_read->version >= 3)
|
||||
DBUG_RETURN(0);
|
||||
/* Everything below this is just legacy to version 2< */
|
||||
|
||||
DBUG_PRINT("ha_archive", ("Reading legacy data header"));
|
||||
|
||||
ret= azread(file_to_read, data_buffer, DATA_BUFFER_SIZE, &error);
|
||||
|
||||
if (ret != DATA_BUFFER_SIZE)
|
||||
{
|
||||
DBUG_PRINT("ha_archive", ("Reading, expected %lu got %lu",
|
||||
DBUG_PRINT("ha_archive", ("Reading, expected %d got %lu",
|
||||
DATA_BUFFER_SIZE, ret));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
@ -268,9 +274,6 @@ int ha_archive::read_data_header(azio_stream *file_to_read)
|
|||
DBUG_PRINT("ha_archive", ("Check %u", data_buffer[0]));
|
||||
DBUG_PRINT("ha_archive", ("Version %u", data_buffer[1]));
|
||||
|
||||
share->data_version= (uchar)data_buffer[1];
|
||||
DBUG_PRINT("ha_archive", ("Set Version %u", share->data_version));
|
||||
|
||||
if ((data_buffer[0] != (uchar)ARCHIVE_CHECK_HEADER) &&
|
||||
(data_buffer[1] != (uchar)ARCHIVE_VERSION))
|
||||
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
|
||||
|
@ -278,29 +281,6 @@ int ha_archive::read_data_header(azio_stream *file_to_read)
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
This method writes out the header of a datafile and returns whether or not it was successful.
|
||||
*/
|
||||
int ha_archive::write_data_header(azio_stream *file_to_write)
|
||||
{
|
||||
uchar data_buffer[DATA_BUFFER_SIZE];
|
||||
DBUG_ENTER("ha_archive::write_data_header");
|
||||
|
||||
data_buffer[0]= (uchar)ARCHIVE_CHECK_HEADER;
|
||||
data_buffer[1]= (uchar)ARCHIVE_VERSION;
|
||||
|
||||
if (azwrite(file_to_write, &data_buffer, DATA_BUFFER_SIZE) !=
|
||||
DATA_BUFFER_SIZE)
|
||||
goto error;
|
||||
DBUG_PRINT("ha_archive", ("Check %u", (uint)data_buffer[0]));
|
||||
DBUG_PRINT("ha_archive", ("Version %u", (uint)data_buffer[1]));
|
||||
|
||||
DBUG_RETURN(0);
|
||||
error:
|
||||
DBUG_PRINT("ha_archive", ("Could not write full data header"));
|
||||
DBUG_RETURN(errno);
|
||||
}
|
||||
|
||||
/*
|
||||
This method reads the header of a meta file and returns whether or not it was successful.
|
||||
*rows will contain the current number of rows in the data file upon success.
|
||||
|
@ -616,6 +596,9 @@ int ha_archive::open(const char *name, int mode, uint open_options)
|
|||
DBUG_RETURN(rc);
|
||||
}
|
||||
|
||||
DBUG_ASSERT(share);
|
||||
|
||||
|
||||
record_buffer= create_record_buffer(table->s->reclength);
|
||||
|
||||
if (!record_buffer)
|
||||
|
@ -694,6 +677,7 @@ int ha_archive::create(const char *name, TABLE *table_arg,
|
|||
File create_file; // We use to create the datafile and the metafile
|
||||
char name_buff[FN_REFLEN];
|
||||
int error;
|
||||
azio_stream create_stream; /* Archive file we are working with */
|
||||
DBUG_ENTER("ha_archive::create");
|
||||
|
||||
stats.auto_increment_value= (create_info->auto_increment_value ?
|
||||
|
@ -762,18 +746,13 @@ int ha_archive::create(const char *name, TABLE *table_arg,
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
if (!azdopen(&archive, create_file, O_WRONLY|O_BINARY))
|
||||
if (!azdopen(&create_stream, create_file, O_WRONLY|O_BINARY))
|
||||
{
|
||||
error= errno;
|
||||
goto error2;
|
||||
}
|
||||
if (write_data_header(&archive))
|
||||
{
|
||||
error= errno;
|
||||
goto error3;
|
||||
}
|
||||
|
||||
if (azclose(&archive))
|
||||
if (azclose(&create_stream))
|
||||
{
|
||||
error= errno;
|
||||
goto error2;
|
||||
|
@ -781,9 +760,6 @@ int ha_archive::create(const char *name, TABLE *table_arg,
|
|||
|
||||
DBUG_RETURN(0);
|
||||
|
||||
error3:
|
||||
/* We already have an error, so ignore results of azclose. */
|
||||
(void)azclose(&archive);
|
||||
error2:
|
||||
my_close(create_file, MYF(0));
|
||||
delete_table(name);
|
||||
|
@ -1140,8 +1116,9 @@ int ha_archive::get_row(azio_stream *file_to_read, byte *buf)
|
|||
int rc;
|
||||
DBUG_ENTER("ha_archive::get_row");
|
||||
DBUG_PRINT("ha_archive", ("Picking version for get_row() %d -> %d",
|
||||
share->data_version, ARCHIVE_VERSION));
|
||||
if (share->data_version == ARCHIVE_VERSION)
|
||||
(uchar)file_to_read->version,
|
||||
ARCHIVE_VERSION));
|
||||
if (file_to_read->version == ARCHIVE_VERSION)
|
||||
rc= get_row_version3(file_to_read, buf);
|
||||
else
|
||||
rc= get_row_version2(file_to_read, buf);
|
||||
|
@ -1437,13 +1414,6 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
|
|||
*/
|
||||
rc= read_data_header(&archive);
|
||||
|
||||
/*
|
||||
Assuming now error from rewinding the archive file, we now write out the
|
||||
new header for out data file.
|
||||
*/
|
||||
if (!rc)
|
||||
rc= write_data_header(&writer);
|
||||
|
||||
/*
|
||||
On success of writing out the new header, we now fetch each row and
|
||||
insert it into the new archive file.
|
||||
|
|
|
@ -50,7 +50,6 @@ typedef struct st_archive_share {
|
|||
ulonglong mean_rec_length;
|
||||
char real_path[FN_REFLEN];
|
||||
uint meta_version;
|
||||
uint data_version;
|
||||
} ARCHIVE_SHARE;
|
||||
|
||||
/*
|
||||
|
@ -137,7 +136,6 @@ public:
|
|||
int init_archive_writer();
|
||||
bool auto_repair() const { return 1; } // For the moment we just do this
|
||||
int read_data_header(azio_stream *file_to_read);
|
||||
int write_data_header(azio_stream *file_to_write);
|
||||
void position(const byte *record);
|
||||
int info(uint);
|
||||
void update_create_info(HA_CREATE_INFO *create_info);
|
||||
|
|
Loading…
Reference in a new issue