Commit 8ecda6cd authored by Guilhem Bichot's avatar Guilhem Bichot

_ma_bitmap_unpin_all() needs to unpin not-locked pages which were pinned by other threads

in write_changed_bitmap(), and page cache forbids that. Here we make the page
cache more relaxed. Original patch by Sanja, simplified by me as limited to
not-locked. See comment of ma_bitmap.c.
With that, maria_stress.yy runs until hitting BUG 39665.

storage/maria/ma_bitmap.c:
  A thread which unpins bitmap pages in _ma_bitmap_unpin_all() sometimes
  hit an assertion in the page cache (info!=0 in remove_pin()) which states
  that you can unpin/unlock only what *you* have pinned/locked.
  Fixed by setting the new last parameter of pagecache_unlock_by_link()
  to TRUE in _ma_bitmap_unpin_all().
storage/maria/ma_blockrec.c:
  new prototype and splitting assertion in three (3rd one fires: BUG 39665)
storage/maria/ma_check.c:
  new prototype
storage/maria/ma_key_recover.c:
  new prototype
storage/maria/ma_loghandler.c:
  new prototype
storage/maria/ma_pagecache.c:
  Allow a thread to unpin, with pagecache_unlock_by_link(), a non-locked page pinned by others.
  This is a hack for _ma_bitmap_unpin_all() which needs to unpin pages which were
  pinned by other threads in write_changed_bitmap().
storage/maria/ma_pagecache.h:
  new prototype
storage/maria/ma_preload.c:
  new prototype
storage/maria/unittest/ma_pagecache_rwconsist.c:
  new prototype
storage/maria/unittest/ma_pagecache_single.c:
  new prototype
parent 8dc87e3e
......@@ -418,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;
}
......
......@@ -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);
......@@ -5143,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
......@@ -6035,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);
}
......@@ -6125,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));
}
......@@ -6195,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);
}
......@@ -6223,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));
......@@ -6327,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)
......@@ -6336,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
{
......@@ -6476,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;
}
/*
......@@ -6496,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;
}
}
......
......@@ -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;
}
......
This diff is collapsed.
......@@ -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