summaryrefslogtreecommitdiff
path: root/storage/maria/ma_blockrec.c
diff options
context:
space:
mode:
authorGuilhem Bichot <guilhem@mysql.com>2009-01-15 16:14:47 +0100
committerGuilhem Bichot <guilhem@mysql.com>2009-01-15 16:14:47 +0100
commita955efc40c965dd8b19a18b2eef439d9166bb132 (patch)
tree99901febf7c780ea7c9223f3762061c83493be37 /storage/maria/ma_blockrec.c
parentae3aaa5eb67ccaec2c106ff975360f861e1b2b00 (diff)
downloadmariadb-git-a955efc40c965dd8b19a18b2eef439d9166bb132.tar.gz
Fix for BUG#41493 "Maria: two recovery failures (wrong logging of BLOB pages)" and some more debugging
output related to this. mysql-test/suite/maria/r/maria-recovery3.result: result update mysql-test/suite/maria/t/maria-recovery3.test: Test for bug; before the fix, the "CHECK TABLE EXTENDED" would mention a bad bitmap, because the REDO_INSERT_ROW_BLOBS was containing a page number which was actually the one of a tail, so execution of this record would mark the tail page as full in bitmap (like if it were a blob page), though it wasn't full. Also, the assertion added around ma_blockrec.c:6580 in the present revision fired. storage/maria/ma_blockrec.c: - fix for BUG#41493: if we found out that logging was not needed at this point (blob_length==0 i.e. tail page), then we forgot to increment tmp_block, so in the second iteration (assuming two BLOB columns), we would log the page range of the first iteration (i.e. the tail page's number) for this second BLOB, which would cause Recovery to overwrite the tail page with the second BLOB. - assert when marking the table corrupted during REDO phase; this catches some problems earlier otherwise they get caught only when a later record wants to use the table. - _ma_apply_redo_insert_row_blobs() now fills some synthetic info about the blobs and pages involved in a REDO_INSERT_ROW_BLOBS record, for inclusion into maria_recovery.trace: number of blobs, of ranges, first and last page (does not tell about any gaps in the middle, but good enough for now). It also asserts that it's not overwriting a tail/head page (which happened in the bug). storage/maria/ma_blockrec.h: new prototype for _ma_apply_redo_insert_row_blobs storage/maria/ma_recovery.c: Print info got from _ma_apply_redo_insert_row_blobs() to maria_recovery.trace (so far this file had mentioned what head and tail pages a record touched, but not blob pages).
Diffstat (limited to 'storage/maria/ma_blockrec.c')
-rw-r--r--storage/maria/ma_blockrec.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index b8538a52cb0..0b338e633d7 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -3146,8 +3146,8 @@ static my_bool write_block_record(MARIA_HA *info,
log_pos= store_page_range(log_pos, tmp_block, block_size,
blob_length, &extents);
- tmp_block+= tmp_block->sub_blocks;
}
+ tmp_block+= tmp_block->sub_blocks;
}
}
@@ -6182,6 +6182,7 @@ err:
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0, FALSE);
_ma_mark_file_crashed(share);
+ DBUG_ASSERT(0); /* catch recovery errors early */
DBUG_RETURN((my_errno= error));
}
@@ -6280,6 +6281,7 @@ err:
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0, FALSE);
_ma_mark_file_crashed(share);
+ DBUG_ASSERT(0);
DBUG_RETURN((my_errno= error));
}
@@ -6337,6 +6339,7 @@ uint _ma_apply_redo_free_blocks(MARIA_HA *info,
if (res)
{
_ma_mark_file_crashed(share);
+ DBUG_ASSERT(0);
DBUG_RETURN(res);
}
}
@@ -6420,6 +6423,7 @@ uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
err:
_ma_mark_file_crashed(share);
+ DBUG_ASSERT(0);
DBUG_RETURN(1);
}
@@ -6431,6 +6435,10 @@ err:
@parma lsn LSN to put on pages
@param header Header (with FILEID)
@param redo_lsn REDO record's LSN
+ @param[out] number_of_blobs Number of blobs found in log record
+ @param[out] number_of_ranges Number of ranges found
+ @param[out] first_page First page touched
+ @param[out] last_page Last page touched
@note Write full pages (full head & blob pages)
@@ -6441,13 +6449,18 @@ err:
uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
LSN lsn, const uchar *header,
- LSN redo_lsn)
+ LSN redo_lsn,
+ uint * const number_of_blobs,
+ uint * const number_of_ranges,
+ pgcache_page_no_t * const first_page,
+ pgcache_page_no_t * const last_page)
{
MARIA_SHARE *share= info->s;
const uchar *data;
uint data_size= FULL_PAGE_SIZE(share->block_size);
uint blob_count, ranges;
uint16 sid;
+ pgcache_page_no_t first_page2= ULONGLONG_MAX, last_page2= 0;
DBUG_ENTER("_ma_apply_redo_insert_row_blobs");
share->state.changed|= (STATE_CHANGED | STATE_NOT_ZEROFILLED |
@@ -6455,9 +6468,9 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
sid= fileid_korr(header);
header+= FILEID_STORE_SIZE;
- ranges= pagerange_korr(header);
+ *number_of_ranges= ranges= pagerange_korr(header);
header+= PAGERANGE_STORE_SIZE;
- blob_count= pagerange_korr(header);
+ *number_of_blobs= blob_count= pagerange_korr(header);
header+= PAGERANGE_STORE_SIZE;
DBUG_ASSERT(ranges >= blob_count);
@@ -6495,6 +6508,8 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
enum pagecache_page_pin unpin_method;
uint length;
+ set_if_smaller(first_page2, page);
+ set_if_bigger(last_page2, page);
if (_ma_redo_not_needed_for_page(sid, redo_lsn, page, FALSE))
continue;
@@ -6545,15 +6560,22 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
}
else
{
+#ifndef DBUG_OFF
+ uchar found_page_type= (buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK);
+#endif
if (lsn_korr(buff) >= lsn)
{
/* Already applied */
+ DBUG_PRINT("info", ("already applied %llu >= %llu",
+ lsn_korr(buff), lsn));
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0, FALSE);
continue;
}
+ DBUG_ASSERT((found_page_type == (uchar) BLOB_PAGE) ||
+ (found_page_type == (uchar) UNALLOCATED_PAGE));
}
unlock_method= PAGECACHE_LOCK_WRITE_UNLOCK;
unpin_method= PAGECACHE_UNPIN;
@@ -6595,10 +6617,13 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
goto err;
}
}
+ *first_page= first_page2;
+ *last_page= last_page2;
DBUG_RETURN(0);
err:
_ma_mark_file_crashed(share);
+ DBUG_ASSERT(0);
DBUG_RETURN(1);
}