Below is the list of changes that have just been committed into a local
maria repository of monty. When monty does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-03-08 02:07:03+02:00, monty@stripped +4 -0
Fix for #Bug35048 "maria table corruption reported when transactional=0
Problem was that page in bitmap was marked as full even if there was free places in page directory
mysql-test/r/maria.result@stripped, 2008-03-08 02:06:57+02:00, monty@stripped +18 -0
Test case for problem with head/tail page with 255 entries
(Bug 35048 "maria table corruption reported when transactional=0)
mysql-test/t/maria.test@stripped, 2008-03-08 02:06:57+02:00, monty@stripped +35 -0
Test case for problem with head/tail page with 255 entries
(Bug 35048 "maria table corruption reported when transactional=0)
storage/maria/ma_blockrec.c@stripped, 2008-03-08 02:06:57+02:00, monty@stripped +42 -3
Fix to ensure that bitmap is marked 'full' when the head/tail page directory is full
storage/maria/ma_check.c@stripped, 2008-03-08 02:06:57+02:00, monty@stripped +13 -7
Better check when directory for head/tail pages are marked full (The page directory can't hold a row tail + blob tails)
diff -Nrup a/mysql-test/r/maria.result b/mysql-test/r/maria.result
--- a/mysql-test/r/maria.result 2008-02-15 19:29:51 +02:00
+++ b/mysql-test/r/maria.result 2008-03-08 02:06:57 +02:00
@@ -2254,3 +2254,21 @@ t1 CREATE TABLE `t1` (
`c` char(1) DEFAULT NULL
) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1
drop table t1;
+create table t1 (i int auto_increment not null primary key) transactional=0;
+check table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+delete from t1 where i = 10;
+check table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+create table t1 (i int auto_increment not null primary key);
+check table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+delete from t1 where i = 10;
+check table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
diff -Nrup a/mysql-test/t/maria.test b/mysql-test/t/maria.test
--- a/mysql-test/t/maria.test 2008-02-15 19:29:51 +02:00
+++ b/mysql-test/t/maria.test 2008-03-08 02:06:57 +02:00
@@ -1455,6 +1455,41 @@ alter table t1 engine=maria;
show create table t1;
drop table t1;
+#
+# Test problems with small rows and row_type=page
+# Bug 35048 "maria table corruption reported when transactional=0"
+#
+
+create table t1 (i int auto_increment not null primary key) transactional=0;
+
+let $i=510;
+--disable_query_log
+while ($i)
+{
+ dec $i;
+ insert into t1 values (null);
+}
+--enable_query_log
+check table t1 extended;
+delete from t1 where i = 10;
+check table t1 extended;
+drop table t1;
+
+create table t1 (i int auto_increment not null primary key);
+
+let $i=510;
+--disable_query_log
+while ($i)
+{
+ dec $i;
+ insert into t1 values (null);
+}
+--enable_query_log
+check table t1 extended;
+delete from t1 where i = 10;
+check table t1 extended;
+drop table t1;
+
# End of 5.1 tests
--disable_result_log
diff -Nrup a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
--- a/storage/maria/ma_blockrec.c 2008-02-26 22:32:01 +02:00
+++ b/storage/maria/ma_blockrec.c 2008-03-08 02:06:57 +02:00
@@ -692,6 +692,34 @@ static void check_directory(uchar *buff,
/**
+ @brief Calculate if there is enough entries on the page
+*/
+
+my_bool enough_free_entries(uchar *buff, uint block_size, uint wanted_entries)
+{
+ uint entries= (uint) buff[DIR_COUNT_OFFSET];
+ uint needed_free_entries, free_entry;
+
+ if (entries + wanted_entries <= MAX_ROWS_PER_PAGE)
+ return 1;
+
+ /* Check if enough free entries in free list */
+ needed_free_entries= entries + wanted_entries - MAX_ROWS_PER_PAGE;
+
+ free_entry= (uint) buff[DIR_FREE_OFFSET];
+ while (free_entry != END_OF_DIR_FREE_LIST)
+ {
+ uchar *dir;
+ if (!--needed_free_entries)
+ return 1;
+ dir= dir_entry_pos(buff, block_size, free_entry);
+ free_entry= dir[3];
+ }
+ return 0; /* Not enough entries */
+}
+
+
+/**
@brief Extend a record area to fit a given size block
@fn extend_area_on_page()
@@ -1029,6 +1057,7 @@ static uchar *find_free_position(uchar *
DBUG_RETURN(dir);
}
/* No free places in dir; create a new one */
+
/* Check if there is place for the directory entry */
if (max_entry == MAX_ROWS_PER_PAGE)
DBUG_RETURN(0);
@@ -1801,8 +1830,8 @@ static my_bool write_tail(MARIA_HA *info
during _ma_bitmap_find_place() allocate more entries on the tail page
than it can hold
*/
- block->empty_space= ((uint) (row_pos.buff)[DIR_COUNT_OFFSET] <=
- MAX_ROWS_PER_PAGE - 1 - share->base.blobs ?
+ block->empty_space= (enough_free_entries(row_pos.buff, share->block_size,
+ 1 + share->base.blobs) ?
empty_space : 0);
block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
@@ -2587,7 +2616,8 @@ static my_bool write_block_record(MARIA_
int2store(page_buff + EMPTY_SPACE_OFFSET, row_pos->empty_space);
/* Mark in bitmaps how the current page was actually used */
head_block->empty_space= row_pos->empty_space;
- if (page_buff[DIR_COUNT_OFFSET] == MAX_ROWS_PER_PAGE)
+ if (page_buff[DIR_COUNT_OFFSET] == MAX_ROWS_PER_PAGE &&
+ page_buff[DIR_FREE_OFFSET] == END_OF_DIR_FREE_LIST)
head_block->empty_space= 0; /* Page is full */
head_block->used|= BLOCKUSED_USED;
@@ -3881,6 +3911,15 @@ static my_bool delete_head_or_tail(MARIA
info->pinned_pages.elements-1);
DBUG_PRINT("info", ("empty_space: %u", empty_space));
+
+ /*
+ If there is not enough space for all possible tails, mark the
+ page full
+ */
+ if (!head && !enough_free_entries(buff, share->block_size,
+ 1 + share->base.blobs))
+ empty_space= 0;
+
DBUG_RETURN(_ma_bitmap_set(info, page, head, empty_space));
}
diff -Nrup a/storage/maria/ma_check.c b/storage/maria/ma_check.c
--- a/storage/maria/ma_check.c 2008-02-26 22:32:01 +02:00
+++ b/storage/maria/ma_check.c 2008-03-08 02:06:57 +02:00
@@ -1442,7 +1442,7 @@ end:
static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
my_off_t page_pos, uchar *page,
uint row_count, uint head_empty,
- uint *real_rows_found)
+ uint *real_rows_found, uint *free_slots_found)
{
uint empty, last_row_end, row, first_dir_entry, free_entry, block_size;
uint free_entries, prev_free_entry;
@@ -1495,6 +1495,7 @@ static int check_page_layout(HA_CHECK *p
free_entry= dir[3];
free_entries++;
}
+ *free_slots_found= free_entries;
/* Check directry */
dir_entry= page+ block_size - PAGE_SUFFIX_SIZE;
@@ -1694,7 +1695,7 @@ static int check_block_record(HA_CHECK *
uint block_size= share->block_size;
ha_rows full_page_count, tail_count;
my_bool full_dir;
- uint offset_page, offset;
+ uint offset_page, offset, free_count;
LINT_INIT(full_dir);
@@ -1791,7 +1792,11 @@ static int check_block_record(HA_CHECK *
row_count * DIR_ENTRY_SIZE);
if (empty_space < share->bitmap.sizes[3])
param->lost+= empty_space;
- full_dir= row_count == MAX_ROWS_PER_PAGE;
+ if (check_page_layout(param, info, pos, page_buff, row_count,
+ empty_space, &real_row_count, &free_count))
+ goto err;
+ full_dir= (row_count == MAX_ROWS_PER_PAGE &&
+ page_buff[DIR_FREE_OFFSET] == END_OF_DIR_FREE_LIST);
break;
case TAIL_PAGE:
row_count= ((uchar*) page_buff)[DIR_COUNT_OFFSET];
@@ -1799,9 +1804,13 @@ static int check_block_record(HA_CHECK *
param->used+= block_size - empty_space;
param->link_used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
row_count * DIR_ENTRY_SIZE);
- full_dir= row_count == MAX_ROWS_PER_PAGE;
if (empty_space < share->bitmap.sizes[6])
param->lost+= empty_space;
+ if (check_page_layout(param, info, pos, page_buff, row_count,
+ empty_space, &real_row_count, &free_count))
+ goto err;
+ full_dir= (row_count - free_count >= MAX_ROWS_PER_PAGE -
+ share->base.blobs);
break;
case BLOB_PAGE:
full_page_count++;
@@ -1830,9 +1839,6 @@ static int check_block_record(HA_CHECK *
if ((enum en_page_type) page_type == BLOB_PAGE)
continue;
param->empty+= empty_space;
- if (check_page_layout(param, info, pos, page_buff, row_count,
- empty_space, &real_row_count))
- goto err;
if ((enum en_page_type) page_type == TAIL_PAGE)
{
tail_count+= real_row_count;
| Thread |
|---|
| • bk commit into maria tree (monty:1.2613) | monty | 8 Mar |