Commit f134f91f authored by unknown's avatar unknown

Flush status differentiation between error and skipping pinned pages.


storage/maria/ma_checkpoint.c:
  React only on errors during the flush.
parent 1bc5e3b9
......@@ -673,8 +673,7 @@ pthread_handler_t ma_checkpoint_background(void *arg)
dfile, FLUSH_KEEP_LAZY,
filter_flush_data_file_evenly,
&filter_param);
/* note that it may just be a pinned page */
if (unlikely(res))
if (unlikely(res & PCFLUSH_ERROR))
fprintf(stderr, "Maria engine: warning - background page flush"
" failed\n");
if (filter_param.max_pages == 0) /* bunch all flushed, sleep */
......@@ -696,7 +695,7 @@ pthread_handler_t ma_checkpoint_background(void *arg)
dfile, FLUSH_KEEP_LAZY,
filter_flush_data_file_evenly,
&filter_param);
if (unlikely(res))
if (unlikely(res & PCFLUSH_ERROR))
fprintf(stderr, "Maria engine: warning - background page flush"
" failed\n");
if (filter_param.max_pages == 0) /* bunch all flushed, sleep */
......@@ -1149,20 +1148,16 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
flushed, as the REDOs about it will be skipped, it will wrongly not be
recovered. If bitmap pages had a rec_lsn it would be different.
*/
/**
@todo we ignore the error because it may be just due a pinned page;
we should rather fix the function below to distinguish between
pinned page and write error. Then we can turn the warning into an
error.
*/
if (((filter_param.is_data_file= TRUE),
flush_pagecache_blocks_with_filter(maria_pagecache,
&dfile, FLUSH_KEEP,
filter, &filter_param)) ||
(flush_pagecache_blocks_with_filter(maria_pagecache,
&dfile, FLUSH_KEEP,
filter, &filter_param) &
PCFLUSH_ERROR)) ||
((filter_param.is_data_file= FALSE),
flush_pagecache_blocks_with_filter(maria_pagecache,
&kfile, FLUSH_KEEP,
filter, &filter_param)))
(flush_pagecache_blocks_with_filter(maria_pagecache,
&kfile, FLUSH_KEEP,
filter, &filter_param) &
PCFLUSH_ERROR)))
fprintf(stderr, "Maria engine: warning - checkpoint page flush"
" failed\n"); /** @todo improve */
/*
......
......@@ -3512,21 +3512,37 @@ static int cmp_sec_link(PAGECACHE_BLOCK_LINK **a, PAGECACHE_BLOCK_LINK **b)
}
/*
Flush a portion of changed blocks to disk,
free used blocks if requested
/**
@brief Flush a portion of changed blocks to disk, free used blocks
if requested
@param pagecache This page cache reference.
@param file File which should be flushed
@param cache Beginning of array of the block.
@param end Reference to the block after last in the array.
@param flush_type Type of the flush.
@param first_errno Where to store first errno of the flush.
@return Operation status
@retval PCFLUSH_OK OK
@retval PCFLUSH_ERROR There was errors during the flush process.
@retval PCFLUSH_PINNED Pinned blocks was met and skipped.
@retval PCFLUSH_PINNED_AND_ERROR PCFLUSH_ERROR and PCFLUSH_PINNED.
*/
static int flush_cached_blocks(PAGECACHE *pagecache,
PAGECACHE_FILE *file,
PAGECACHE_BLOCK_LINK **cache,
PAGECACHE_BLOCK_LINK **end,
enum flush_type type)
enum flush_type type,
int *first_errno)
{
int rc= PCFLUSH_OK;
int error;
int last_errno= 0;
uint count= (uint) (end-cache);
DBUG_ENTER("flush_cached_blocks");
*first_errno= 0;
/* Don't lock the cache during the flush */
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
......@@ -3551,7 +3567,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
PCBLOCK_INFO(block);
/* undo the mark put by flush_pagecache_blocks_int(): */
block->status&= ~PCBLOCK_IN_FLUSH;
last_errno= -1;
rc|= PCFLUSH_PINNED;
unreg_request(pagecache, block, 1);
continue;
}
......@@ -3592,8 +3608,8 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
if (error)
{
block->status|= PCBLOCK_ERROR;
if (!last_errno)
last_errno= errno ? errno : -1;
if (!*first_errno)
*first_errno= errno ? errno : -1;
}
#ifdef THREAD
/*
......@@ -3618,7 +3634,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
unreg_request(pagecache, block, 1);
}
}
DBUG_RETURN(last_errno);
DBUG_RETURN(rc);
}
......@@ -3646,8 +3662,10 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
this situation.
@return Operation status
@retval 0 OK
@retval 1 Error
@retval PCFLUSH_OK OK
@retval PCFLUSH_ERROR There was errors during the flush process.
@retval PCFLUSH_PINNED Pinned blocks was met and skipped.
@retval PCFLUSH_PINNED_AND_ERROR PCFLUSH_ERROR and PCFLUSH_PINNED.
*/
static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
......@@ -3658,6 +3676,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
{
PAGECACHE_BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache;
int last_errno= 0;
int rc= PCFLUSH_OK;
DBUG_ENTER("flush_pagecache_blocks_int");
DBUG_PRINT("enter",("file: %d blocks_used: %lu blocks_changed: %lu",
file->file, pagecache->blocks_used, pagecache->blocks_changed));
......@@ -3818,8 +3837,9 @@ restart:
This happens only if there is not enough
memory for the big block
*/
if ((error= flush_cached_blocks(pagecache, file, cache,
end,type)))
if ((rc|= flush_cached_blocks(pagecache, file, cache,
end, type, &error)) &
PCFLUSH_ERROR)
last_errno=error;
DBUG_PRINT("info", ("restarting..."));
/*
......@@ -3853,7 +3873,8 @@ restart:
}
if (pos != cache)
{
if ((error= flush_cached_blocks(pagecache, file, cache, pos, type)))
if ((rc|= flush_cached_blocks(pagecache, file, cache, pos, type,
&error)) & PCFLUSH_ERROR)
last_errno= error;
}
/* Wait until list of blocks in switch is empty */
......@@ -3931,8 +3952,8 @@ restart:
if (cache != cache_buff)
my_free((uchar*) cache, MYF(0));
if (last_errno)
errno=last_errno; /* Return first error */
DBUG_RETURN(last_errno != 0);
errno= last_errno; /* Return first error */
DBUG_RETURN(rc);
}
......@@ -3949,8 +3970,10 @@ restart:
the block will be passed too.
@return Operation status
@retval 0 OK
@retval 1 Error
@retval PCFLUSH_OK OK
@retval PCFLUSH_ERROR There was errors during the flush process.
@retval PCFLUSH_PINNED Pinned blocks was met and skipped.
@retval PCFLUSH_PINNED_AND_ERROR PCFLUSH_ERROR and PCFLUSH_PINNED.
*/
int flush_pagecache_blocks_with_filter(PAGECACHE *pagecache,
......
......@@ -243,6 +243,20 @@ extern void pagecache_unpin(PAGECACHE *pagecache,
extern void pagecache_unpin_by_link(PAGECACHE *pagecache,
PAGECACHE_BLOCK_LINK *link,
LSN lsn);
/* Results of flush operation (bit field in fact) */
/* The flush is done. */
#define PCFLUSH_OK 0
/* There was errors during the flush process. */
#define PCFLUSH_ERROR 1
/* Pinned blocks was met and skipped. */
#define PCFLUSH_PINNED 2
/* PCFLUSH_ERROR and PCFLUSH_PINNED. */
#define PCFLUSH_PINNED_AND_ERROR (PCFLUSH_ERROR|PCFLUSH_PINNED)
#define flush_pagecache_blocks(A,B,C) \
flush_pagecache_blocks_with_filter(A,B,C,NULL,NULL)
extern int flush_pagecache_blocks_with_filter(PAGECACHE *keycache,
......
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