Commit 2faf503e authored by Michael Widenius's avatar Michael Widenius

Automatic merge with main tree

Fixed that mysql-test-run --skip-from starts from the given test

mysql-test/lib/mtr_cases.pl:
  Moved testing of $opt_start_from to mysql-test-run.pl because tests are now run per suite and the old way would rerun not wanted tests
mysql-test/mysql-test-run.pl:
  Fixed that mysql-test-run --skip-from starts from the given test
parents 32718418 8ecda6cd
......@@ -513,19 +513,10 @@ sub collect_one_test_case($$$$$$$$$) {
my $suite_opts= shift;
my $path= "$testdir/$elem";
# ----------------------------------------------------------------------
# Skip some tests silently
# ----------------------------------------------------------------------
if ( $::opt_start_from and $tname lt $::opt_start_from )
{
return;
}
my $name= basename($suite) . ".$tname";
my $tinfo= {};
$tinfo->{'name'}= basename($suite) . ".$tname";
$tinfo->{'name'}= $name;
$tinfo->{'result_file'}= "$resdir/$tname.result";
$tinfo->{'component_id'} = $component_id;
push(@$cases, $tinfo);
......@@ -534,7 +525,7 @@ sub collect_one_test_case($$$$$$$$$) {
# Skip some tests but include in list, just mark them to skip
# ----------------------------------------------------------------------
if ( $skip_test and $tname =~ /$skip_test/o )
if ( $skip_test and ($tname =~ /$skip_test/o || $name =~ /$skip_test/o))
{
$tinfo->{'skip'}= 1;
return;
......
......@@ -3391,6 +3391,24 @@ sub run_testcase_check_skip_test($)
{
my ($tinfo)= @_;
# ----------------------------------------------------------------------
# Skip some tests silently
# ----------------------------------------------------------------------
if ( $::opt_start_from )
{
if ($tinfo->{'name'} eq $::opt_start_from )
{
## Found parting test. Run this test and all tests after this one
$::opt_start_from= "";
}
else
{
$tinfo->{'result'}= 'MTR_RES_SKIPPED';
return 1;
}
}
# ----------------------------------------------------------------------
# If marked to skip, just print out and return.
# Note that a test case not marked as 'skip' can still be
......
......@@ -167,10 +167,10 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
int res= pagecache_write(share->pagecache,
&bitmap->file, bitmap->page, 0,
(uchar*) bitmap->map, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_WRITE, PAGECACHE_PIN,
PAGECACHE_LOCK_LEFT_UNLOCKED, PAGECACHE_PIN,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE);
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
page_link.unlock= PAGECACHE_LOCK_LEFT_UNLOCKED;
page_link.changed= 1;
push_dynamic(&bitmap->pinned_pages, (void*) &page_link);
DBUG_RETURN(res);
......@@ -281,6 +281,14 @@ my_bool _ma_bitmap_end(MARIA_SHARE *share)
by this thread (ie, checking the changed flag is ok). The reason we
check it again in the mutex is that if someone else did a flush at the
same time, we don't have to do the write.
This is also ok for _ma_scan_init_block_record() which does not want to
miss rows: it cares only for committed rows, that is, rows for which there
was a commit before our transaction started; as commit and transaction's
start are protected by the same LOCK_trn_list mutex, we see memory at
least as new as at other transaction's commit time, so if the committed
rows caused bitmap->changed to be true, we see it; if we see 0 it really
means a flush happened since then. So, it's ok to read without bitmap's
mutex.
RETURN
0 ok
......@@ -305,38 +313,6 @@ my_bool _ma_bitmap_flush(MARIA_SHARE *share)
}
/*
@brief Send updated bitmap to the page cache if bitmap is free
@note
This is used by reader threads which don't unpin things
*/
my_bool _ma_bitmap_wait_or_flush(MARIA_SHARE *share)
{
my_bool res= 0;
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
DBUG_ENTER("_ma_bitmap_flush");
if (bitmap->changed)
{
pthread_mutex_lock(&bitmap->bitmap_lock);
while (bitmap->non_flushable && bitmap->changed)
{
DBUG_PRINT("info", ("waiting for bitmap to be flushable"));
pthread_cond_wait(&bitmap->bitmap_cond, &bitmap->bitmap_lock);
}
if (bitmap->changed)
{
bitmap->changed= 0;
res= write_changed_bitmap(share, bitmap);
}
pthread_mutex_unlock(&bitmap->bitmap_lock);
}
DBUG_RETURN(res);
}
/**
Dirty-page filtering criteria for bitmap pages
......@@ -386,8 +362,11 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
unpinned. We keep the mutex to preserve this situation, and flush to the
file.
*/
res= write_changed_bitmap(share, bitmap);
bitmap->changed= FALSE;
if (bitmap->changed)
{
res= write_changed_bitmap(share, bitmap);
bitmap->changed= FALSE;
}
/*
We do NOT use FLUSH_KEEP_LAZY because we must be sure that bitmap
pages have been flushed. That's a condition of correctness of
......@@ -424,6 +403,8 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
@return Operation status
@retval 0 ok
@note This unpins pages pinned by other threads.
*/
static void _ma_bitmap_unpin_all(MARIA_SHARE *share)
......@@ -437,7 +418,7 @@ static void _ma_bitmap_unpin_all(MARIA_SHARE *share)
while (pinned_page-- != page_link)
pagecache_unlock_by_link(share->pagecache, pinned_page->link,
pinned_page->unlock, PAGECACHE_UNPIN,
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, TRUE);
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, TRUE, TRUE);
bitmap->pinned_pages.elements= 0;
DBUG_VOID_RETURN;
}
......@@ -2139,8 +2120,8 @@ my_bool _ma_bitmap_set_full_page_bits(MARIA_HA *info,
function first waits for the flush to be done.
@note
info->non_flushable_state is set to 1 if we have incremented
bitmap->info->non_flushable and not yet decremented it.
this sets info->non_flushable_state to 1 if we have incremented
bitmap->non_flushable and not yet decremented it.
@param share Table's share
@param non_flushable_inc Increment of MARIA_FILE_BITMAP::non_flushable
......@@ -2151,20 +2132,21 @@ void _ma_bitmap_flushable(MARIA_HA *info, int non_flushable_inc)
{
MARIA_SHARE *share= info->s;
MARIA_FILE_BITMAP *bitmap;
DBUG_ENTER("_ma_bitmap_flushable");
/*
Not transactional tables are never automaticly flushed and needs no
protection
*/
if (!share->now_transactional)
return;
DBUG_VOID_RETURN;
bitmap= &share->bitmap;
if (non_flushable_inc == -1)
{
pthread_mutex_lock(&bitmap->bitmap_lock);
DBUG_ASSERT((int) bitmap->non_flushable > 0 &&
info->non_flushable_state == 1);
DBUG_ASSERT((int) bitmap->non_flushable > 0);
DBUG_ASSERT(info->non_flushable_state == 1);
info->non_flushable_state= 0;
if (--bitmap->non_flushable == 0)
{
......@@ -2182,14 +2164,15 @@ void _ma_bitmap_flushable(MARIA_HA *info, int non_flushable_inc)
}
DBUG_PRINT("info", ("bitmap->non_flushable: %u", bitmap->non_flushable));
pthread_mutex_unlock(&bitmap->bitmap_lock);
return;
DBUG_VOID_RETURN;
}
DBUG_ASSERT(non_flushable_inc == 1 && info->non_flushable_state == 0);
DBUG_ASSERT(non_flushable_inc == 1);
DBUG_ASSERT(info->non_flushable_state == 0);
/* It is a read without mutex because only an optimization */
if (unlikely(bitmap->flush_all_requested))
{
/*
_ma_bitmap_flush_all() is waiting for the bitmap to become
Some other thread is waiting for the bitmap to become
flushable. Not the moment to make the bitmap unflushable or more
unflushable; let's rather back off and wait. If we didn't do this, with
multiple writers, there may always be one thread causing the bitmap to
......@@ -2214,6 +2197,7 @@ void _ma_bitmap_flushable(MARIA_HA *info, int non_flushable_inc)
bitmap->non_flushable++;
info->non_flushable_state= 1;
DBUG_PRINT("info", ("bitmap->non_flushable: %u", bitmap->non_flushable));
DBUG_VOID_RETURN;
}
......@@ -2321,10 +2305,10 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
goto err;
}
if (info->s->now_transactional)
/* This duplicates ma_bitmap_flushable(-1) except it already has mutex */
if (info->non_flushable_state)
{
DBUG_ASSERT((int) bitmap->non_flushable >= 0 &&
info->non_flushable_state);
DBUG_ASSERT((int) bitmap->non_flushable >= 0);
info->non_flushable_state= 0;
if (--bitmap->non_flushable == 0)
{
......
......@@ -1964,7 +1964,7 @@ static my_bool write_tail(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link->link,
PAGECACHE_LOCK_WRITE_TO_READ,
PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
LSN_IMPOSSIBLE, 1, FALSE);
DBUG_ASSERT(page_link->changed);
page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK;
res= 0;
......@@ -3026,7 +3026,7 @@ static my_bool write_block_record(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link->link,
PAGECACHE_LOCK_WRITE_TO_READ,
PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
LSN_IMPOSSIBLE, 1, FALSE);
page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK;
page_link->changed= 1;
}
......@@ -4025,7 +4025,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link.link,
lock_at_write,
PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
LSN_IMPOSSIBLE, 1, FALSE);
page_link.unlock= lock_at_unpin;
set_dynamic(&info->pinned_pages, (void*) &page_link,
info->pinned_pages.elements-1);
......@@ -4982,10 +4982,12 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info)
info->scan.bitmap_pos= info->scan.bitmap_end;
info->scan.bitmap_page= (pgcache_page_no_t) 0 - share->bitmap.pages_covered;
/*
We have to flush bitmap as we will read the bitmap from the page cache
while scanning rows
We need to flush what's in memory (bitmap.map) to page cache otherwise, as
we are going to read bitmaps from page cache in table scan (see
_ma_scan_block_record()), we may miss recently inserted rows (bitmap page
in page cache would be too old).
*/
DBUG_RETURN(_ma_bitmap_wait_or_flush(info->s));
DBUG_RETURN(_ma_bitmap_flush(info->s));
}
......@@ -5141,7 +5143,9 @@ restart_record_read:
if (end_of_data > info->scan.dir_end ||
offset < PAGE_HEADER_SIZE || length < share->base.min_block_length)
{
DBUG_ASSERT(0);
DBUG_ASSERT(!(end_of_data > info->scan.dir_end));
DBUG_ASSERT(!(offset < PAGE_HEADER_SIZE));
DBUG_ASSERT(!(length < share->base.min_block_length));
goto err;
}
#endif
......@@ -6033,7 +6037,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(0);
}
......@@ -6123,7 +6127,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
_ma_mark_file_crashed(share);
DBUG_RETURN((my_errno= error));
}
......@@ -6193,7 +6197,7 @@ uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn,
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(0);
}
......@@ -6221,7 +6225,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
_ma_mark_file_crashed(share);
DBUG_RETURN((my_errno= error));
......@@ -6325,7 +6329,7 @@ uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
goto err;
}
if (lsn_korr(buff) >= lsn)
......@@ -6334,7 +6338,7 @@ uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
}
else
{
......@@ -6474,7 +6478,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
goto err;
}
/*
......@@ -6494,7 +6498,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
continue;
}
}
......
......@@ -182,7 +182,6 @@ maria_page_get_lsn(uchar *page, pgcache_page_no_t page_no, uchar* data_ptr);
my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
my_bool _ma_bitmap_end(MARIA_SHARE *share);
my_bool _ma_bitmap_flush(MARIA_SHARE *share);
my_bool _ma_bitmap_wait_or_flush(MARIA_SHARE *share);
my_bool _ma_bitmap_flush_all(MARIA_SHARE *share);
void _ma_bitmap_reset_cache(MARIA_SHARE *share);
my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
......
......@@ -3184,7 +3184,7 @@ static my_bool maria_zerofill_index(HA_CHECK *param, MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
_ma_check_print_error(param,
"Page %9s: Got error %d when reading index file",
llstr(pos, llbuff), my_errno);
......@@ -3218,7 +3218,7 @@ static my_bool maria_zerofill_index(HA_CHECK *param, MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
LSN_IMPOSSIBLE, 1, FALSE);
}
if (flush_pagecache_blocks(share->pagecache, &share->kfile,
FLUSH_FORCE_WRITE))
......@@ -3342,7 +3342,7 @@ static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
LSN_IMPOSSIBLE, 1, FALSE);
}
DBUG_RETURN(_ma_bitmap_flush(share) ||
flush_pagecache_blocks(share->pagecache, &info->dfile,
......@@ -3352,7 +3352,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(1);
}
......
......@@ -70,7 +70,7 @@ void _ma_unpin_all_pages(MARIA_HA *info, LSN undo_lsn)
pagecache_unlock_by_link(info->s->pagecache, pinned_page->link,
pinned_page->unlock, PAGECACHE_UNPIN,
info->trn->rec_lsn, undo_lsn,
pinned_page->changed);
pinned_page->changed, FALSE);
}
info->pinned_pages.elements= 0;
......@@ -700,7 +700,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(result);
}
......@@ -779,7 +779,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(result);
}
......@@ -1047,7 +1047,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, 0, FALSE);
if (result)
_ma_mark_file_crashed(share);
DBUG_RETURN(result);
......
......@@ -3028,7 +3028,7 @@ static void translog_free_link(PAGECACHE_BLOCK_LINK *direct_link)
if (direct_link)
pagecache_unlock_by_link(log_descriptor.pagecache, direct_link,
PAGECACHE_LOCK_READ_UNLOCK, PAGECACHE_UNPIN,
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, 0);
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, 0, FALSE);
DBUG_VOID_RETURN;
}
......
......@@ -267,16 +267,21 @@ static void info_unlink(PAGECACHE_PIN_INFO *node)
list the list where to find the thread
thread thread ID (reference to the st_my_thread_var
of the thread)
any return any thread of the list
RETURN
0 - the thread was not found
pointer to the information node of the thread in the list
pointer to the information node of the thread in the list, or, if 'any',
to any thread of the list.
*/
static PAGECACHE_PIN_INFO *info_find(PAGECACHE_PIN_INFO *list,
struct st_my_thread_var *thread)
struct st_my_thread_var *thread,
my_bool any)
{
register PAGECACHE_PIN_INFO *i= list;
if (any)
return i;
for(; i != 0; i= i->next)
if (i->thread == thread)
return i;
......@@ -2150,18 +2155,22 @@ static void add_pin(PAGECACHE_BLOCK_LINK *block)
DBUG_VOID_RETURN;
}
static void remove_pin(PAGECACHE_BLOCK_LINK *block)
static void remove_pin(PAGECACHE_BLOCK_LINK *block, my_bool any
#ifdef DBUG_OFF
__attribute__((unused))
#endif
)
{
DBUG_ENTER("remove_pin");
DBUG_PRINT("enter", ("block: 0x%lx pins: %u",
DBUG_PRINT("enter", ("block: 0x%lx pins: %u any: %d",
(ulong) block,
block->pins));
block->pins, (int)any));
PCBLOCK_INFO(block);
DBUG_ASSERT(block->pins > 0);
block->pins--;
#ifndef DBUG_OFF
{
PAGECACHE_PIN_INFO *info= info_find(block->pin_list, my_thread_var);
PAGECACHE_PIN_INFO *info= info_find(block->pin_list, my_thread_var, any);
DBUG_ASSERT(info != 0);
info_unlink(info);
my_free((uchar*) info, MYF(0));
......@@ -2183,7 +2192,7 @@ static void info_remove_lock(PAGECACHE_BLOCK_LINK *block)
{
PAGECACHE_LOCK_INFO *info=
(PAGECACHE_LOCK_INFO *)info_find((PAGECACHE_PIN_INFO *)block->lock_list,
my_thread_var);
my_thread_var, FALSE);
DBUG_ASSERT(info != 0);
info_unlink((PAGECACHE_PIN_INFO *)info);
my_free((uchar*)info, MYF(0));
......@@ -2192,7 +2201,7 @@ static void info_change_lock(PAGECACHE_BLOCK_LINK *block, my_bool wl)
{
PAGECACHE_LOCK_INFO *info=
(PAGECACHE_LOCK_INFO *)info_find((PAGECACHE_PIN_INFO *)block->lock_list,
my_thread_var);
my_thread_var, FALSE);
DBUG_ASSERT(info != 0);
DBUG_ASSERT(info->write_lock != wl);
info->write_lock= wl;
......@@ -2448,6 +2457,8 @@ static void release_rdlock(PAGECACHE_BLOCK_LINK *block)
@param lock lock change mode
@param pin pinchange mode
@param file File handler requesting pin
@param any allow unpinning block pinned by any thread; possible
only if not locked, see pagecache_unlock_by_link()
@retval 0 OK
@retval 1 Try to lock the block failed
......@@ -2456,7 +2467,8 @@ static void release_rdlock(PAGECACHE_BLOCK_LINK *block)
static my_bool make_lock_and_pin(PAGECACHE *pagecache,
PAGECACHE_BLOCK_LINK *block,
enum pagecache_page_lock lock,
enum pagecache_page_pin pin)
enum pagecache_page_pin pin,
my_bool any)
{
DBUG_ENTER("make_lock_and_pin");
......@@ -2465,16 +2477,20 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
if (block)
{
DBUG_PRINT("enter", ("block: 0x%lx (%u) wrlocks: %u rdlocks: %u "
"rdlocks_q: %u pins: %u lock: %s pin: %s",
"rdlocks_q: %u pins: %u lock: %s pin: %s any %d",
(ulong)block, PCBLOCK_NUMBER(pagecache, block),
block->wlocks, block->rlocks, block->rlocks_queue,
block->pins,
page_cache_page_lock_str[lock],
page_cache_page_pin_str[pin]));
page_cache_page_pin_str[pin], (int)any));
PCBLOCK_INFO(block);
}
#endif
DBUG_ASSERT(!any ||
((lock == PAGECACHE_LOCK_LEFT_UNLOCKED) &&
(pin == PAGECACHE_UNPIN)));
switch (lock) {
case PAGECACHE_LOCK_WRITE: /* free -> write */
/* Writelock and pin the buffer */
......@@ -2500,7 +2516,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
case PAGECACHE_LOCK_LEFT_READLOCKED: /* read -> read */
if (pin == PAGECACHE_UNPIN)
{
remove_pin(block);
remove_pin(block, FALSE);
}
if (lock == PAGECACHE_LOCK_WRITE_TO_READ)
{
......@@ -2529,7 +2545,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
case PAGECACHE_LOCK_LEFT_UNLOCKED: /* free -> free */
if (pin == PAGECACHE_UNPIN)
{
remove_pin(block);
remove_pin(block, any);
}
/* fall through */
case PAGECACHE_LOCK_LEFT_WRITELOCKED: /* write -> write */
......@@ -2793,7 +2809,7 @@ void pagecache_unlock(PAGECACHE *pagecache,
(ulong) block));
}
if (make_lock_and_pin(pagecache, block, lock, pin))
if (make_lock_and_pin(pagecache, block, lock, pin, FALSE))
{
DBUG_ASSERT(0); /* should not happend */
}
......@@ -2863,7 +2879,7 @@ void pagecache_unpin(PAGECACHE *pagecache,
*/
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_LEFT_READLOCKED,
PAGECACHE_UNPIN))
PAGECACHE_UNPIN, FALSE))
DBUG_ASSERT(0); /* should not happend */
remove_reader(block);
......@@ -2886,15 +2902,22 @@ void pagecache_unpin(PAGECACHE *pagecache,
@brief Unlock/unpin page and put LSN stamp if it need
(uses direct block/page pointer)
@param pagecache pointer to a page cache data structure
@param link direct link to page (returned by read or write)
@param lock lock change
@param pin pin page
@param pagecache pointer to a page cache data structure
@param link direct link to page (returned by read or write)
@param lock lock change
@param pin pin page
@param first_REDO_LSN_for_page do not set it if it is LSN_IMPOSSIBLE (0)
@param lsn if it is not LSN_IMPOSSIBLE and it is bigger then
LSN on the page it will be written on the page
@param was_changed should be true if the page was write locked with
direct link giving and the page was changed
@param lsn if it is not LSN_IMPOSSIBLE and it is bigger then
LSN on the page it will be written on the page
@param was_changed should be true if the page was write locked with
direct link giving and the page was changed
@param any allow unpinning block pinned by any thread; possible
only if not locked
@note 'any' is a hack so that _ma_bitmap_unpin_all() is allowed to unpin
non-locked bitmap pages pinned by other threads. Because it always uses
PAGECACHE_LOCK_LEFT_UNLOCKED and PAGECACHE_UNPIN
(see write_changed_bitmap()), the hack is limited to these conditions.
*/
void pagecache_unlock_by_link(PAGECACHE *pagecache,
......@@ -2902,7 +2925,8 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
enum pagecache_page_lock lock,
enum pagecache_page_pin pin,
LSN first_REDO_LSN_for_page,
LSN lsn, my_bool was_changed)
LSN lsn, my_bool was_changed,
my_bool any)
{
DBUG_ENTER("pagecache_unlock_by_link");
DBUG_PRINT("enter", ("block: 0x%lx fd: %u page: %lu changed: %d %s %s",
......@@ -2922,7 +2946,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
if (pin == PAGECACHE_PIN_LEFT_UNPINNED &&
lock == PAGECACHE_LOCK_READ_UNLOCK)
{
if (make_lock_and_pin(pagecache, block, lock, pin))
if (make_lock_and_pin(pagecache, block, lock, pin, FALSE))
DBUG_ASSERT(0); /* should not happend */
DBUG_VOID_RETURN;
}
......@@ -2976,7 +3000,7 @@ void pagecache_unlock_by_link(PAGECACHE *pagecache,
(ulong) block));
}
if (make_lock_and_pin(pagecache, block, lock, pin))
if (make_lock_and_pin(pagecache, block, lock, pin, any))
DBUG_ASSERT(0); /* should not happend */
/*
......@@ -3039,7 +3063,7 @@ void pagecache_unpin_by_link(PAGECACHE *pagecache,
*/
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_LEFT_READLOCKED,
PAGECACHE_UNPIN))
PAGECACHE_UNPIN, FALSE))
DBUG_ASSERT(0); /* should not happend */
/*
......@@ -3190,7 +3214,7 @@ restart:
block->type == PAGECACHE_EMPTY_PAGE)
block->type= type;
if (make_lock_and_pin(pagecache, block, lock, pin))
if (make_lock_and_pin(pagecache, block, lock, pin, FALSE))
{
/*
We failed to write lock the block, cache is unlocked,
......@@ -3334,7 +3358,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache,
/* Cache is locked, so we can relese page before freeing it */
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN))
PAGECACHE_UNPIN, FALSE))
DBUG_ASSERT(0);
DBUG_ASSERT(block->hash_link->requests > 0);
page_link->requests--;
......@@ -3396,7 +3420,7 @@ my_bool pagecache_delete_by_link(PAGECACHE *pagecache,
make_lock_and_pin() can't fail here, because we are keeping pin on the
block and it can't be evicted (which is cause of lock fail and retry)
*/
if (make_lock_and_pin(pagecache, block, lock, pin))
if (make_lock_and_pin(pagecache, block, lock, pin, FALSE))
DBUG_ASSERT(0);
/*
......@@ -3514,7 +3538,7 @@ restart:
if (pin == PAGECACHE_PIN)
reg_requests(pagecache, block, 1);
DBUG_ASSERT(block != 0);
if (make_lock_and_pin(pagecache, block, lock, pin))
if (make_lock_and_pin(pagecache, block, lock, pin, FALSE))
{
/*
We failed to writelock the block, cache is unlocked, and last write
......@@ -3736,7 +3760,7 @@ restart:
write_lock_change_table[lock].new_lock,
(need_lock_change ?
write_pin_change_table[pin].new_pin :
pin)))
pin), FALSE))
{
/*
We failed to writelock the block, cache is unlocked, and last write
......@@ -3823,7 +3847,7 @@ restart:
*/
if (make_lock_and_pin(pagecache, block,
write_lock_change_table[lock].unlock_lock,
write_pin_change_table[pin].unlock_pin))
write_pin_change_table[pin].unlock_pin, FALSE))
DBUG_ASSERT(0);
}
......@@ -4034,7 +4058,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
DBUG_ASSERT(block->wlocks == 0);
DBUG_ASSERT(block->pins == 0);
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE, PAGECACHE_PIN))
PAGECACHE_LOCK_WRITE, PAGECACHE_PIN, FALSE))
DBUG_ASSERT(0);
DBUG_ASSERT(block->pins == 1);
......@@ -4068,7 +4092,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN))
PAGECACHE_UNPIN, FALSE))
DBUG_ASSERT(0);
pagecache->global_cache_write++;
......
......@@ -242,7 +242,8 @@ extern void pagecache_unlock_by_link(PAGECACHE *pagecache,
enum pagecache_page_lock lock,
enum pagecache_page_pin pin,
LSN first_REDO_LSN_for_page,
LSN lsn, my_bool was_changed);
LSN lsn, my_bool was_changed,
my_bool any);
extern void pagecache_unpin(PAGECACHE *pagecache,
PAGECACHE_FILE *file,
pgcache_page_no_t pageno,
......
......@@ -104,7 +104,7 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
else /* otherwise it stays in cache: */
pagecache_unlock_by_link(share->pagecache, page_link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_UNPIN,
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, FALSE);
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, FALSE, FALSE);
}
my_free(buff, MYF(0));
......
......@@ -114,7 +114,7 @@ void reader(int num)
check_page(buff, num);
pagecache_unlock_by_link(&pagecache, link,
PAGECACHE_LOCK_READ_UNLOCK,
PAGECACHE_UNPIN, 0, 0, 0);
PAGECACHE_UNPIN, 0, 0, 0, FALSE);
{
int lim= rand() % read_sleep_limit;
int j;
......@@ -149,7 +149,7 @@ void writer(int num)
check_page(buff, num);
pagecache_unlock_by_link(&pagecache, link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, 0, 0, 1);
PAGECACHE_UNPIN, 0, 0, 1, FALSE);
SLEEP;
}
}
......
......@@ -391,7 +391,7 @@ int simple_pin_no_lock_test()
&link, LSN_IMPOSSIBLE);
pagecache_unlock_by_link(&pagecache, link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_PIN_LEFT_PINNED, 0, 0, 1);
PAGECACHE_PIN_LEFT_PINNED, 0, 0, 1, FALSE);
if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
{
diag("Did not get error in flush_pagecache_blocks 3\n");
......
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