From 24257638695a89687fdeca3632c3dc0db3ee2ee7 Mon Sep 17 00:00:00 2001 From: Guilhem Bichot Date: Mon, 30 Jun 2008 11:25:14 +0200 Subject: [PATCH] Fix for BUG#37288 "Maria - zerofill corrupts table". Testcase is running ma_test_recovery.pl on Windows. storage/maria/ma_blockrec.c: comment storage/maria/ma_check.c: When zerofilling the data file, _ma_compact_block_page() may increase free space in a page so bitmap page needs to be corrected. --- storage/maria/ma_blockrec.c | 23 ++++++++++++----------- storage/maria/ma_check.c | 16 ++++++++++------ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index 3ae49c37b48..10d454d4286 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -1345,21 +1345,22 @@ static void calc_record_size(MARIA_HA *info, const uchar *record, } -/* +/** Compact page by removing all space between rows - IMPLEMENTATION - Move up all rows to start of page. - Move blocks that are directly after each other with one memmove. + Moves up all rows to start of page. Moves blocks that are directly after + each other with one memmove. - SYNOPSIS - _ma_compact_block_page() - buff Page to compact - block_size Size of page - rownr Put empty data after this row - extend_block If 1, extend the block at 'rownr' to cover the + @note if rownr is the last row in the page, and extend_block is false, + caller has to make sure to update bitmap page afterwards to reflect freed + space. + + @param buff Page to compact + @param block_size Size of page + @param rownr Put empty data after this row + @param extend_block If 1, extend the block at 'rownr' to cover the whole block. - min_read_from If <> 0, remove all trid's that are less than this + @param min_read_from If <> 0, remove all trid's that are less than this */ void _ma_compact_block_page(uchar *buff, uint block_size, uint rownr, diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index b6c37affee0..141c0289f2b 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -3308,11 +3308,16 @@ static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info, bzero(buff, LSN_SIZE); if (max_entry != 0) { + my_bool is_head_page= (page_type == HEAD_PAGE); dir= dir_entry_pos(buff, block_size, max_entry - 1); _ma_compact_block_page(buff, block_size, max_entry -1, 0, - page_type == HEAD_PAGE ? ~(TrID) 0 : 0, - page_type == HEAD_PAGE ? + is_head_page ? ~(TrID) 0 : 0, + is_head_page ? share->base.min_block_length : 0); + /* compactation may have increased free space */ + if (_ma_bitmap_set(info, page, is_head_page, + uint2korr(buff + EMPTY_SPACE_OFFSET))) + goto err; /* Zerofill the not used part */ offset= uint2korr(dir) + uint2korr(dir+2); @@ -3334,10 +3339,9 @@ static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info, PAGECACHE_UNPIN, LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, 1); } - if (flush_pagecache_blocks(share->pagecache, &info->dfile, - FLUSH_FORCE_WRITE)) - DBUG_RETURN(1); - DBUG_RETURN(0); + DBUG_RETURN(_ma_bitmap_flush(share) || + flush_pagecache_blocks(share->pagecache, &info->dfile, + FLUSH_FORCE_WRITE)); err: pagecache_unlock_by_link(share->pagecache, page_link.link,