Commit 094d92e2 authored by unknown's avatar unknown

Prevent reenabling logging by thread which tries to lock table used by bulk insert.

      Scenario of the BUG#40731 ("Maria: hang (probably in page cache) under concurrency"):
      T1: Disable logging for the table
      T1: Start inserting into the table
      T2: Tries to lock the table so waits.
      T2: Tries unlock and relock during the process see that the table has disabled logging and reenables it
      T1: Got DBUG_ASSERT because suddenly start use table with transaction switched on which is not expected during bulk insert

storage/maria/ma_pagecache.c:
  Page type print added for debugging purposes.
storage/maria/ma_recovery.c:
  Check that it was this thred which switched off logging (transactional mode).
storage/maria/maria_def.h:
  Flag for controling which thread switched off transactiona mode for the table added.
parent f36a9625
......@@ -99,7 +99,7 @@
DBUG_PRINT("info", \
("block: 0x%lx fd: %lu page: %lu s: %0x hshL: " \
" 0x%lx req: %u/%u wrlocks: %u rdlocks %u " \
"rdlocks_q: %u pins: %u status: %u", \
"rdlocks_q: %u pins: %u status: %u type: %s", \
(ulong)(B), \
(ulong)((B)->hash_link ? \
(B)->hash_link->file.file : \
......@@ -114,7 +114,8 @@
(B)->hash_link->requests : \
0), \
block->wlocks, block->rlocks, block->rlocks_queue, \
(uint)(B)->pins, (uint)(B)->status))
(uint)(B)->pins, (uint)(B)->status, \
page_cache_page_type_str[(B)->type]))
/* TODO: put it to my_static.c */
my_bool my_disable_flush_pagecache_blocks= 0;
......
......@@ -3243,6 +3243,7 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
*/
share->state.common= *info->state;
info->state= &share->state.common;
info->switched_transactional= TRUE;
/*
Some code in ma_blockrec.c assumes a trn even if !now_transactional but in
......@@ -3273,8 +3274,10 @@ my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages)
MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_reenable_logging_for_table");
if (share->now_transactional == share->base.born_transactional)
if (share->now_transactional == share->base.born_transactional ||
!info->switched_transactional)
DBUG_RETURN(0);
info->switched_transactional= FALSE;
if ((share->now_transactional= share->base.born_transactional))
{
......
......@@ -548,6 +548,8 @@ struct st_maria_handler
/* If info->keyread_buff has to be re-read for rnext */
my_bool keyread_buff_used;
my_bool once_flags; /* For MARIA_MRG */
/* For bulk insert enable/disable transactions control */
my_bool switched_transactional;
#ifdef __WIN__
my_bool owned_by_merge; /* This Maria table is part of a merge union */
#endif
......
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