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) ...@@ -418,7 +418,7 @@ static void _ma_bitmap_unpin_all(MARIA_SHARE *share)
while (pinned_page-- != page_link) while (pinned_page-- != page_link)
pagecache_unlock_by_link(share->pagecache, pinned_page->link, pagecache_unlock_by_link(share->pagecache, pinned_page->link,
pinned_page->unlock, PAGECACHE_UNPIN, pinned_page->unlock, PAGECACHE_UNPIN,
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, TRUE); LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, TRUE, TRUE);
bitmap->pinned_pages.elements= 0; bitmap->pinned_pages.elements= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -1964,7 +1964,7 @@ static my_bool write_tail(MARIA_HA *info, ...@@ -1964,7 +1964,7 @@ static my_bool write_tail(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link->link, pagecache_unlock_by_link(share->pagecache, page_link->link,
PAGECACHE_LOCK_WRITE_TO_READ, PAGECACHE_LOCK_WRITE_TO_READ,
PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE, PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1); LSN_IMPOSSIBLE, 1, FALSE);
DBUG_ASSERT(page_link->changed); DBUG_ASSERT(page_link->changed);
page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK; page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK;
res= 0; res= 0;
...@@ -3026,7 +3026,7 @@ static my_bool write_block_record(MARIA_HA *info, ...@@ -3026,7 +3026,7 @@ static my_bool write_block_record(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link->link, pagecache_unlock_by_link(share->pagecache, page_link->link,
PAGECACHE_LOCK_WRITE_TO_READ, PAGECACHE_LOCK_WRITE_TO_READ,
PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE, PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1); LSN_IMPOSSIBLE, 1, FALSE);
page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK; page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK;
page_link->changed= 1; page_link->changed= 1;
} }
...@@ -4025,7 +4025,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info, ...@@ -4025,7 +4025,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link.link, pagecache_unlock_by_link(share->pagecache, page_link.link,
lock_at_write, lock_at_write,
PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE, PAGECACHE_PIN_LEFT_PINNED, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1); LSN_IMPOSSIBLE, 1, FALSE);
page_link.unlock= lock_at_unpin; page_link.unlock= lock_at_unpin;
set_dynamic(&info->pinned_pages, (void*) &page_link, set_dynamic(&info->pinned_pages, (void*) &page_link,
info->pinned_pages.elements-1); info->pinned_pages.elements-1);
...@@ -5143,7 +5143,9 @@ restart_record_read: ...@@ -5143,7 +5143,9 @@ restart_record_read:
if (end_of_data > info->scan.dir_end || if (end_of_data > info->scan.dir_end ||
offset < PAGE_HEADER_SIZE || length < share->base.min_block_length) 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; goto err;
} }
#endif #endif
...@@ -6035,7 +6037,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn, ...@@ -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_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -6125,7 +6127,7 @@ err: ...@@ -6125,7 +6127,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link, pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
_ma_mark_file_crashed(share); _ma_mark_file_crashed(share);
DBUG_RETURN((my_errno= error)); DBUG_RETURN((my_errno= error));
} }
...@@ -6195,7 +6197,7 @@ uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn, ...@@ -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_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -6223,7 +6225,7 @@ err: ...@@ -6223,7 +6225,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link, pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
_ma_mark_file_crashed(share); _ma_mark_file_crashed(share);
DBUG_RETURN((my_errno= error)); DBUG_RETURN((my_errno= error));
...@@ -6327,7 +6329,7 @@ uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn, ...@@ -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_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
goto err; goto err;
} }
if (lsn_korr(buff) >= lsn) if (lsn_korr(buff) >= lsn)
...@@ -6336,7 +6338,7 @@ uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN 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_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
} }
else else
{ {
...@@ -6476,7 +6478,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, ...@@ -6476,7 +6478,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link.link, pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
goto err; goto err;
} }
/* /*
...@@ -6496,7 +6498,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, ...@@ -6496,7 +6498,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
pagecache_unlock_by_link(share->pagecache, page_link.link, pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
continue; continue;
} }
} }
......
...@@ -3184,7 +3184,7 @@ static my_bool maria_zerofill_index(HA_CHECK *param, MARIA_HA *info, ...@@ -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_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
_ma_check_print_error(param, _ma_check_print_error(param,
"Page %9s: Got error %d when reading index file", "Page %9s: Got error %d when reading index file",
llstr(pos, llbuff), my_errno); llstr(pos, llbuff), my_errno);
...@@ -3218,7 +3218,7 @@ static my_bool maria_zerofill_index(HA_CHECK *param, MARIA_HA *info, ...@@ -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_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1); LSN_IMPOSSIBLE, 1, FALSE);
} }
if (flush_pagecache_blocks(share->pagecache, &share->kfile, if (flush_pagecache_blocks(share->pagecache, &share->kfile,
FLUSH_FORCE_WRITE)) FLUSH_FORCE_WRITE))
...@@ -3342,7 +3342,7 @@ static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info, ...@@ -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_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1); LSN_IMPOSSIBLE, 1, FALSE);
} }
DBUG_RETURN(_ma_bitmap_flush(share) || DBUG_RETURN(_ma_bitmap_flush(share) ||
flush_pagecache_blocks(share->pagecache, &info->dfile, flush_pagecache_blocks(share->pagecache, &info->dfile,
...@@ -3352,7 +3352,7 @@ err: ...@@ -3352,7 +3352,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link, pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
......
...@@ -70,7 +70,7 @@ void _ma_unpin_all_pages(MARIA_HA *info, LSN undo_lsn) ...@@ -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, pagecache_unlock_by_link(info->s->pagecache, pinned_page->link,
pinned_page->unlock, PAGECACHE_UNPIN, pinned_page->unlock, PAGECACHE_UNPIN,
info->trn->rec_lsn, undo_lsn, info->trn->rec_lsn, undo_lsn,
pinned_page->changed); pinned_page->changed, FALSE);
} }
info->pinned_pages.elements= 0; info->pinned_pages.elements= 0;
...@@ -700,7 +700,7 @@ err: ...@@ -700,7 +700,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link, pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(result); DBUG_RETURN(result);
} }
...@@ -779,7 +779,7 @@ err: ...@@ -779,7 +779,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link, pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
DBUG_RETURN(result); DBUG_RETURN(result);
} }
...@@ -1047,7 +1047,7 @@ err: ...@@ -1047,7 +1047,7 @@ err:
pagecache_unlock_by_link(share->pagecache, page_link.link, pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE, PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, 0, FALSE);
if (result) if (result)
_ma_mark_file_crashed(share); _ma_mark_file_crashed(share);
DBUG_RETURN(result); DBUG_RETURN(result);
......
...@@ -3028,7 +3028,7 @@ static void translog_free_link(PAGECACHE_BLOCK_LINK *direct_link) ...@@ -3028,7 +3028,7 @@ static void translog_free_link(PAGECACHE_BLOCK_LINK *direct_link)
if (direct_link) if (direct_link)
pagecache_unlock_by_link(log_descriptor.pagecache, direct_link, pagecache_unlock_by_link(log_descriptor.pagecache, direct_link,
PAGECACHE_LOCK_READ_UNLOCK, PAGECACHE_UNPIN, PAGECACHE_LOCK_READ_UNLOCK, PAGECACHE_UNPIN,
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, 0); LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, 0, FALSE);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
This diff is collapsed.
...@@ -242,7 +242,8 @@ extern void pagecache_unlock_by_link(PAGECACHE *pagecache, ...@@ -242,7 +242,8 @@ extern void pagecache_unlock_by_link(PAGECACHE *pagecache,
enum pagecache_page_lock lock, enum pagecache_page_lock lock,
enum pagecache_page_pin pin, enum pagecache_page_pin pin,
LSN first_REDO_LSN_for_page, 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, extern void pagecache_unpin(PAGECACHE *pagecache,
PAGECACHE_FILE *file, PAGECACHE_FILE *file,
pgcache_page_no_t pageno, pgcache_page_no_t pageno,
......
...@@ -104,7 +104,7 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves) ...@@ -104,7 +104,7 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
else /* otherwise it stays in cache: */ else /* otherwise it stays in cache: */
pagecache_unlock_by_link(share->pagecache, page_link, pagecache_unlock_by_link(share->pagecache, page_link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_UNPIN, PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_UNPIN,
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, FALSE); LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, FALSE, FALSE);
} }
my_free(buff, MYF(0)); my_free(buff, MYF(0));
......
...@@ -114,7 +114,7 @@ void reader(int num) ...@@ -114,7 +114,7 @@ void reader(int num)
check_page(buff, num); check_page(buff, num);
pagecache_unlock_by_link(&pagecache, link, pagecache_unlock_by_link(&pagecache, link,
PAGECACHE_LOCK_READ_UNLOCK, PAGECACHE_LOCK_READ_UNLOCK,
PAGECACHE_UNPIN, 0, 0, 0); PAGECACHE_UNPIN, 0, 0, 0, FALSE);
{ {
int lim= rand() % read_sleep_limit; int lim= rand() % read_sleep_limit;
int j; int j;
...@@ -149,7 +149,7 @@ void writer(int num) ...@@ -149,7 +149,7 @@ void writer(int num)
check_page(buff, num); check_page(buff, num);
pagecache_unlock_by_link(&pagecache, link, pagecache_unlock_by_link(&pagecache, link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, 0, 0, 1); PAGECACHE_UNPIN, 0, 0, 1, FALSE);
SLEEP; SLEEP;
} }
} }
......
...@@ -391,7 +391,7 @@ int simple_pin_no_lock_test() ...@@ -391,7 +391,7 @@ int simple_pin_no_lock_test()
&link, LSN_IMPOSSIBLE); &link, LSN_IMPOSSIBLE);
pagecache_unlock_by_link(&pagecache, link, pagecache_unlock_by_link(&pagecache, link,
PAGECACHE_LOCK_WRITE_UNLOCK, 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)) if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE))
{ {
diag("Did not get error in flush_pagecache_blocks 3\n"); 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