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 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 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) ...@@ -4187,6 +4187,7 @@ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block)
DBUG_ASSERT(block->rlocks == 0); DBUG_ASSERT(block->rlocks == 0);
DBUG_ASSERT(block->rlocks_queue == 0); DBUG_ASSERT(block->rlocks_queue == 0);
DBUG_ASSERT(block->pins == 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; block->status= 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
block->type= PAGECACHE_EMPTY_PAGE; block->type= PAGECACHE_EMPTY_PAGE;
...@@ -4515,6 +4516,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, ...@@ -4515,6 +4516,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
KEYCACHE_DBUG_ASSERT(count<= pagecache->blocks_used); 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 */ /* Allocate a new buffer only if its bigger than the one we have */
if (count > FLUSH_CACHE && if (count > FLUSH_CACHE &&
!(cache= !(cache=
...@@ -4552,22 +4554,24 @@ restart: ...@@ -4552,22 +4554,24 @@ restart:
DBUG_ASSERT(filter_res == FLUSH_FILTER_OK); 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 We care only for the blocks for which flushing was not
other threads to use it for new pages and interfere with initiated by other threads as a result of page swapping
our sequence of flushing dirty file pages
*/ */
block->status|= PCBLOCK_IN_FLUSH;
if (! (block->status & PCBLOCK_IN_SWITCH)) if (! (block->status & PCBLOCK_IN_SWITCH))
{ {
/* /*
We care only for the blocks for which flushing was not Mark the block with BLOCK_IN_FLUSH in order not to let
initiated by other threads as a result of page swapping 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); reg_requests(pagecache, block, 1);
if (type != FLUSH_IGNORE_CHANGED) if (type != FLUSH_IGNORE_CHANGED)
{ {
*pos++= block;
/* It's not a temporary file */ /* It's not a temporary file */
if (pos == end) if (pos == end)
{ {
...@@ -4587,7 +4591,6 @@ restart: ...@@ -4587,7 +4591,6 @@ restart:
*/ */
goto restart; goto restart;
} }
*pos++= block;
} }
else 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