summaryrefslogtreecommitdiff
path: root/storage/archive/ha_archive.cc
diff options
context:
space:
mode:
authorunknown <brian@zim.(none)>2007-01-12 20:05:55 -0800
committerunknown <brian@zim.(none)>2007-01-12 20:05:55 -0800
commit8c2c5767253f87dabd3e664f82921036fc250418 (patch)
tree331a9db00950e865627b24ba321ad89f8003ebcc /storage/archive/ha_archive.cc
parenteb7cd8bd29ada02992d33b6cfe8315733ae61485 (diff)
downloadmariadb-git-8c2c5767253f87dabd3e664f82921036fc250418.tar.gz
Final cleanup for new archive internal format. All new headers work.
storage/archive/archive_reader.c: Added version bit to solve the issue of hitting old archive files when reading them. storage/archive/azio.c: Set the compression back on. storage/archive/ha_archive.cc: Cleaned up memory allocation ( a bit more logical and less tricky ). Fixed bug in not setting autoincrement correctly and cleaned up memory usage for optimize storage/archive/ha_archive.h: Clean up.
Diffstat (limited to 'storage/archive/ha_archive.cc')
-rw-r--r--storage/archive/ha_archive.cc150
1 files changed, 56 insertions, 94 deletions
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 99d83939388..a87e856a0e5 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -460,7 +460,8 @@ int ha_archive::open(const char *name, int mode, uint open_options)
DBUG_ASSERT(share);
- record_buffer= create_record_buffer(table->s->reclength);
+ record_buffer= create_record_buffer(table->s->reclength +
+ ARCHIVE_ROW_HEADER_SIZE);
if (!record_buffer)
{
@@ -642,9 +643,12 @@ int ha_archive::real_write_row(byte *buf, azio_stream *writer)
}
-/* Calculate max length needed for row */
+/*
+ Calculate max length needed for row. This includes
+ the bytes required for the length in the header.
+*/
-int ha_archive::max_row_length(const byte *buf)
+uint32 ha_archive::max_row_length(const byte *buf)
{
ulonglong length= table->s->reclength + table->s->fields*2;
length+= ARCHIVE_ROW_HEADER_SIZE;
@@ -654,26 +658,23 @@ int ha_archive::max_row_length(const byte *buf)
ptr != end ;
ptr++)
{
- Field_blob *blob= ((Field_blob*) table->field[*ptr]);
- length+= blob->get_length((char*) buf + blob->offset())+2;
+ length += 2 + ((Field_blob*) table->field[*ptr])->get_length();
}
return length;
}
-unsigned int ha_archive::pack_row(const byte *record)
+unsigned int ha_archive::pack_row(byte *record)
{
byte *ptr;
+ ulonglong full_length;
DBUG_ENTER("ha_archive::pack_row");
- if (table->s->blob_fields)
- {
- if (fix_rec_buff(max_row_length(record)))
- DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
- }
+ if (fix_rec_buff(max_row_length(record)))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
/* Copy null bits */
memcpy(record_buffer->buffer+ARCHIVE_ROW_HEADER_SIZE,
@@ -681,8 +682,10 @@ unsigned int ha_archive::pack_row(const byte *record)
ptr= record_buffer->buffer + table->s->null_bytes + ARCHIVE_ROW_HEADER_SIZE;
for (Field **field=table->field ; *field ; field++)
+ {
ptr=(byte*) (*field)->pack((char*) ptr,
- (char*) record + (*field)->offset());
+ (char*) record + (*field)->offset(record));
+ }
int4store(record_buffer->buffer, (int)(ptr - record_buffer->buffer -
ARCHIVE_ROW_HEADER_SIZE));
@@ -715,12 +718,16 @@ int ha_archive::write_row(byte *buf)
if (share->crashed)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
+ if (!share->archive_write_open)
+ if (init_archive_writer())
+ DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
+
ha_statistic_increment(&SSV::ha_write_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
pthread_mutex_lock(&share->mutex);
- if (table->next_number_field)
+ if (table->next_number_field && record == table->record[0])
{
KEY *mkey= &table->s->key_info[0]; // We only support one key right now
update_auto_increment();
@@ -736,7 +743,6 @@ int ha_archive::write_row(byte *buf)
rc= HA_ERR_FOUND_DUPP_KEY;
goto error;
}
-
/*
Bad news, this will cause a search for the unique value which is very
expensive since we will have to do a table scan which will lock up
@@ -785,7 +791,8 @@ int ha_archive::write_row(byte *buf)
else
{
if (temp_auto > share->archive_write.auto_increment)
- stats.auto_increment_value= share->archive_write.auto_increment= temp_auto;
+ stats.auto_increment_value= share->archive_write.auto_increment=
+ temp_auto;
}
}
@@ -793,10 +800,6 @@ int ha_archive::write_row(byte *buf)
Notice that the global auto_increment has been increased.
In case of a failed row write, we will never try to reuse the value.
*/
- if (!share->archive_write_open)
- if (init_archive_writer())
- DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
-
share->rows_recorded++;
rc= real_write_row(buf, &(share->archive_write));
error:
@@ -972,20 +975,27 @@ int ha_archive::get_row(azio_stream *file_to_read, byte *buf)
}
/* Reallocate buffer if needed */
-bool ha_archive::fix_rec_buff(int length)
+bool ha_archive::fix_rec_buff(unsigned int length)
{
- if (! record_buffer->buffer ||
- length > (record_buffer->length + ARCHIVE_ROW_HEADER_SIZE))
+ DBUG_ENTER("ha_archive::fix_rec_buff");
+ DBUG_PRINT("ha_archive", ("Fixing %u for %u",
+ length, record_buffer->length));
+ DBUG_ASSERT(record_buffer->buffer);
+
+ if (length > record_buffer->length);
{
byte *newptr;
if (!(newptr=(byte*) my_realloc((gptr) record_buffer->buffer,
- length + ARCHIVE_ROW_HEADER_SIZE,
+ length,
MYF(MY_ALLOW_ZERO_PTR))))
- return 1; /* purecov: inspected */
+ DBUG_RETURN(1);
record_buffer->buffer= newptr;
record_buffer->length= length;
}
- return 0;
+
+ DBUG_ASSERT(length <= record_buffer->length);
+
+ DBUG_RETURN(0);
}
int ha_archive::unpack_row(azio_stream *file_to_read, char *record)
@@ -1011,6 +1021,7 @@ int ha_archive::unpack_row(azio_stream *file_to_read, char *record)
DBUG_PRINT("ha_archive",("Unpack row length %u -> %u", row_len,
(unsigned int)table->s->reclength));
fix_rec_buff(row_len);
+ DBUG_ASSERT(row_len <= record_buffer->length);
read= azread(file_to_read, record_buffer->buffer, row_len, &error);
@@ -1026,7 +1037,7 @@ int ha_archive::unpack_row(azio_stream *file_to_read, char *record)
memcpy(record, ptr, table->s->null_bytes);
ptr+= table->s->null_bytes;
for (Field **field=table->field ; *field ; field++)
- ptr= (*field)->unpack(record + (*field)->offset(), ptr);
+ ptr= (*field)->unpack(record + (*field)->offset(table->record[0]), ptr);
DBUG_RETURN(0);
}
@@ -1052,6 +1063,10 @@ int ha_archive::get_row_version2(azio_stream *file_to_read, byte *buf)
read= azread(file_to_read, buf, table->s->reclength, &error);
+ /* If we read nothing we are at the end of the file */
+ if (read == 0)
+ DBUG_RETURN(HA_ERR_END_OF_FILE);
+
if (read != table->s->reclength)
{
DBUG_PRINT("ha_archive::get_row_version2", ("Read %u bytes expected %u",
@@ -1063,10 +1078,6 @@ int ha_archive::get_row_version2(azio_stream *file_to_read, byte *buf)
if (error == Z_STREAM_ERROR || error == Z_DATA_ERROR )
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
- /* If we read nothing we are at the end of the file */
- if (read == 0)
- DBUG_RETURN(HA_ERR_END_OF_FILE);
-
/*
If the record is the wrong size, the file is probably damaged, unless
we are dealing with a delayed insert or a bulk insert.
@@ -1209,15 +1220,9 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
char writer_filename[FN_REFLEN];
/* Open up the writer if we haven't yet */
+ /* Flush any waiting data */
if (share->archive_write_open)
- {
- /* Flush any waiting data */
azflush(&(share->archive_write), Z_SYNC_FLUSH);
- }
- else
- {
- init_archive_writer();
- }
/* Lets create a file to contain the new data */
fn_format(writer_filename, share->table_name, "", ARN,
@@ -1236,29 +1241,6 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
if (1)
{
DBUG_PRINT("ha_archive", ("archive extended rebuild"));
- byte *buf;
- archive_record_buffer *write_buffer, *read_buffer, *original_buffer;
-
- original_buffer= record_buffer;
-
- /*
- First we create a buffer that we can use for reading rows, and can pass
- to get_row().
- */
- if (!(buf= (byte*) my_malloc(table->s->reclength, MYF(MY_WME))))
- {
- rc= HA_ERR_OUT_OF_MEM;
- goto error;
- }
-
- read_buffer= create_record_buffer(record_buffer->length);
- write_buffer= create_record_buffer(record_buffer->length);
-
- if (!write_buffer || !read_buffer)
- {
- rc= HA_ERR_OUT_OF_MEM;
- goto error;
- }
/*
Now we will rewind the archive file so that we are positioned at the
@@ -1274,12 +1256,11 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
{
share->rows_recorded= 0;
stats.auto_increment_value= share->archive_write.auto_increment= 0;
- record_buffer= read_buffer;
+ my_bitmap_map *org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
- while (!(rc= get_row(&archive, buf)))
+ while (!(rc= get_row(&archive, table->record[0])))
{
- record_buffer= write_buffer;
- real_write_row(buf, &writer);
+ real_write_row(table->record[0], &writer);
/*
Long term it should be possible to optimize this so that
it is not called on each row.
@@ -1288,31 +1269,24 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
{
Field *field= table->found_next_number_field;
ulonglong auto_value=
- (ulonglong) field->val_int((char*)(buf +
+ (ulonglong) field->val_int((char*)(table->record[0] +
field->offset(table->record[0])));
if (share->archive_write.auto_increment < auto_value)
stats.auto_increment_value= share->archive_write.auto_increment=
auto_value;
}
- record_buffer= read_buffer;
}
- share->rows_recorded= archive.rows;
- stats.auto_increment_value= share->archive_write.auto_increment=
- writer.auto_increment= archive.auto_increment;
- DBUG_PRINT("ha_archive", ("auto to save %llu", writer.auto_increment));
+ dbug_tmp_restore_column_map(table->read_set, org_bitmap);
+ share->rows_recorded= writer.rows;
}
+
DBUG_PRINT("info", ("recovered %llu archive rows",
(unsigned long long)share->rows_recorded));
DBUG_PRINT("ha_archive", ("recovered %llu archive rows",
(unsigned long long)share->rows_recorded));
- record_buffer= original_buffer;
- destroy_record_buffer(read_buffer);
- destroy_record_buffer(write_buffer);
-
- my_free((char*)buf, MYF(0));
if (rc && rc != HA_ERR_END_OF_FILE)
goto error;
}
@@ -1322,29 +1296,16 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
// now we close both our writer and our reader for the rename
azclose(&(share->archive_write));
+ share->archive_write_open= 0;
azclose(&archive);
// make the file we just wrote be our data file
rc = my_rename(writer_filename,share->data_file_name,MYF(0));
- /*
- now open the shared writer back up
- we don't check rc here because we want to open the file back up even
- if the optimize failed but we will return rc below so that we will
- know it failed.
- We also need to reopen our read descriptor since it has changed.
- */
- DBUG_PRINT("ha_archive", ("Reopening archive data file"));
- if (!azopen(&(share->archive_write), share->data_file_name,
- O_RDWR|O_BINARY) ||
- !azopen(&archive, share->data_file_name, O_RDONLY|O_BINARY))
- {
- DBUG_PRINT("ha_archive", ("Could not open archive write file"));
- rc= HA_ERR_CRASHED_ON_USAGE;
- }
DBUG_RETURN(rc);
error:
+ DBUG_PRINT("ha_archive", ("Failed to recover, error was %d", rc));
azclose(&writer);
DBUG_RETURN(rc);
@@ -1437,10 +1398,11 @@ int ha_archive::info(uint flag)
stats.delete_length= 0;
stats.index_file_length=0;
- /*
if (flag & HA_STATUS_AUTO)
- stats.auto_increment_value= share->archive_write.auto_increment;
-*/
+ {
+ azflush(&archive, Z_SYNC_FLUSH);
+ stats.auto_increment_value= archive.auto_increment;
+ }
DBUG_RETURN(0);
}
@@ -1555,7 +1517,7 @@ bool ha_archive::check_and_repair(THD *thd)
DBUG_RETURN(repair(thd, &check_opt));
}
-archive_record_buffer *ha_archive::create_record_buffer(ulonglong length)
+archive_record_buffer *ha_archive::create_record_buffer(unsigned int length)
{
DBUG_ENTER("ha_archive::create_record_buffer");
archive_record_buffer *r;