summaryrefslogtreecommitdiff
path: root/storage/maria/ma_bitmap.c
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2011-08-15 16:39:53 +0300
committerMichael Widenius <monty@askmonty.org>2011-08-15 16:39:53 +0300
commitb95d2778aa9d4abe5331f9e6f593fd05e1cb2de6 (patch)
tree40153c18c10f129f5f0042c67ef32c6f16bb33b8 /storage/maria/ma_bitmap.c
parenteeb04a339f2bf6eb64e87cf98869a03340bbd7c6 (diff)
downloadmariadb-git-b95d2778aa9d4abe5331f9e6f593fd05e1cb2de6.tar.gz
Fixes bugs found by testcase for lp:815022 and lp:726374 "ma_blockrec.c:3000: write_block_record: Assertion `cur_block[1].page_count == 0' failed with a multi-index Aria workload"
The issues was: - For some tables with a lot of not packed fields, we didn't allocate enough memory in head page which caused DBUG_ASSERT's - Removed wrong DBUG_ASSERT() - Fixed a problem with underflow() where it generates a key page where all keys didn't fit. - Max key length is now limited by block_size/3 (was block_size /2). This is required for underflow() to work with packed keys. mysql-test/lib/v1/mysql-test-run.pl: Remove --alignment=8 as this doesn't work on 64 bit systems mysql-test/suite/maria/r/small_blocksize.result: Test case for Aria bug mysql-test/suite/maria/t/small_blocksize-master.opt: Test case for Aria bug mysql-test/suite/maria/t/small_blocksize.test: Test case for Aria bug storage/maria/ha_maria.cc: Fixed comment storage/maria/ma_bitmap.c: Fixed wrong variable usage in find_where_to_split_row() where we allocated too little memory for head page. We did not take into account space for head extents (long VARCHAR) when trying to split row on head page. This caused us to allocate too little space from bitmap which lead to ASSERT failures later. storage/maria/ma_blockrec.c: Made some argument const (to ensure they was not accidently changed) Removed wrong DBUG_ASSERT() storage/maria/ma_blockrec.h: Removed not used variable storage/maria/ma_delete.c: Added my_afree() in case of error More comments and DBUG_ASSERT() for underflow() storage/maria/ma_open.c: Make keyinfo->underflow_block_length smaller for packed keys. This has to be done as for long packed keys, underflow() otherwise generates a key page where all keys didn't fit. storage/maria/ma_page.c: New DBUG_ASSERT() storage/maria/ma_write.c: Fixed comment storage/maria/maria_def.h: We have to have space for at least 3 keys on a key page. (Otherwise the underflow() code doesn't work for packed keys, even when we have an underflow() for an empty key page)
Diffstat (limited to 'storage/maria/ma_bitmap.c')
-rw-r--r--storage/maria/ma_bitmap.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index ac3d23b7079..a98ef71604d 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -1853,7 +1853,7 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size,
find_where_to_split_row()
share Maria share
row Information of what is in the row (from calc_record_size())
- extents_length Number of bytes needed to store all extents
+ extents Max number of extents we have to store in header
split_size Free size on the page (The head length must be less
than this)
@@ -1862,7 +1862,7 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size,
*/
static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row,
- uint extents_length, uint split_size)
+ uint extents, uint split_size)
{
uint *lengths, *lengths_end;
/*
@@ -1872,19 +1872,20 @@ static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row,
- One extent
*/
uint row_length= (row->min_length +
- size_to_store_key_length(extents_length) +
+ size_to_store_key_length(extents) +
ROW_EXTENT_SIZE);
- DBUG_ASSERT(row_length < split_size);
+ DBUG_ASSERT(row_length <= split_size);
+
/*
Store first in all_field_lengths the different parts that are written
to the row. This needs to be in same order as in
ma_block_rec.c::write_block_record()
*/
- row->null_field_lengths[-3]= extents_length;
+ row->null_field_lengths[-3]= extents * ROW_EXTENT_SIZE;
row->null_field_lengths[-2]= share->base.fixed_not_null_fields_length;
row->null_field_lengths[-1]= row->field_lengths_length;
for (lengths= row->null_field_lengths - EXTRA_LENGTH_FIELDS,
- lengths_end= (lengths + share->base.pack_fields - share->base.blobs +
+ lengths_end= (lengths + share->base.fields - share->base.blobs +
EXTRA_LENGTH_FIELDS); lengths < lengths_end; lengths++)
{
if (row_length + *lengths > split_size)
@@ -2040,18 +2041,19 @@ my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
head_length+= ELEMENTS_RESERVED_FOR_MAIN_PART * ROW_EXTENT_SIZE;
/* The first segment size is stored in 'row_length' */
- row_length= find_where_to_split_row(share, row, extents_length,
+ row_length= find_where_to_split_row(share, row, row->extents_count +
+ ELEMENTS_RESERVED_FOR_MAIN_PART-1,
max_page_size);
full_page_size= MAX_TAIL_SIZE(share->block_size);
position= 0;
- if (head_length - row_length <= full_page_size)
+ rest_length= head_length - row_length;
+ if (rest_length <= full_page_size)
position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */
if (find_head(info, row_length, position))
goto abort;
row->space_on_head_page= row_length;
- rest_length= head_length - row_length;
if (write_rest_of_head(info, position, rest_length))
goto abort;
@@ -2137,16 +2139,22 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
/* Allocate enough space */
head_length+= ELEMENTS_RESERVED_FOR_MAIN_PART * ROW_EXTENT_SIZE;
- /* The first segment size is stored in 'row_length' */
- row_length= find_where_to_split_row(share, row, extents_length, free_size);
+ /*
+ The first segment size is stored in 'row_length'
+ We have to add ELEMENTS_RESERVED_FOR_MAIN_PART here as the extent
+ information may be up to this size when the header splits.
+ */
+ row_length= find_where_to_split_row(share, row, row->extents_count +
+ ELEMENTS_RESERVED_FOR_MAIN_PART-1,
+ free_size);
position= 0;
- if (head_length - row_length < MAX_TAIL_SIZE(share->block_size))
+ rest_length= head_length - row_length;
+ if (rest_length <= MAX_TAIL_SIZE(share->block_size))
position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */
use_head(info, page, row_length, position);
row->space_on_head_page= row_length;
- rest_length= head_length - row_length;
if (write_rest_of_head(info, position, rest_length))
goto abort;