Commit 3e77b1da authored by Michael Widenius's avatar Michael Widenius

Fixed bug in Maria page cache that caused assert if block->request != 0 in free_block()


storage/maria/ma_pagecache.c:
  - Ensure that we write also the last buffer in flush if buffer overflows.
  - Don't set PCBLOCK_IN_FLUSH if we don't flush the page
  - Added some new safety asserts.
parent 713999a4
/* Copyright (C) 2000-2008 MySQL AB
/* Copyright (C) 2000-2008 MySQL AB, 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -4187,6 +4187,7 @@ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block)
DBUG_ASSERT(block->rlocks == 0);
DBUG_ASSERT(block->rlocks_queue == 0);
DBUG_ASSERT(block->pins == 0);
DBUG_ASSERT((block->status & ~(PCBLOCK_ERROR | PCBLOCK_READ | PCBLOCK_IN_FLUSH | PCBLOCK_CHANGED | PCBLOCK_REASSIGNED)) == 0);
block->status= 0;
#ifndef DBUG_OFF
block->type= PAGECACHE_EMPTY_PAGE;
......@@ -4515,6 +4516,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
KEYCACHE_DBUG_ASSERT(count<= pagecache->blocks_used);
}
}
count++; /* Allocate one extra for easy end-of-buffer test */
/* Allocate a new buffer only if its bigger than the one we have */
if (count > FLUSH_CACHE &&
!(cache=
......@@ -4552,22 +4554,24 @@ restart:
DBUG_ASSERT(filter_res == FLUSH_FILTER_OK);
}
{
DBUG_ASSERT(!(block->status & PCBLOCK_IN_FLUSH));
/*
Mark the block with BLOCK_IN_FLUSH in order not to let
other threads to use it for new pages and interfere with
our sequence of flushing dirty file pages
We care only for the blocks for which flushing was not
initiated by other threads as a result of page swapping
*/
block->status|= PCBLOCK_IN_FLUSH;
if (! (block->status & PCBLOCK_IN_SWITCH))
{
/*
We care only for the blocks for which flushing was not
initiated by other threads as a result of page swapping
/*
Mark the block with BLOCK_IN_FLUSH in order not to let
other threads to use it for new pages and interfere with
our sequence of flushing dirty file pages
*/
block->status|= PCBLOCK_IN_FLUSH;
reg_requests(pagecache, block, 1);
if (type != FLUSH_IGNORE_CHANGED)
{
*pos++= block;
/* It's not a temporary file */
if (pos == end)
{
......@@ -4587,7 +4591,6 @@ restart:
*/
goto restart;
}
*pos++= block;
}
else
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment