Commit 5a169d9a 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 af7aa15f
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
DBUG_PRINT("info", \ DBUG_PRINT("info", \
("block: 0x%lx fd: %lu page: %lu s: %0x hshL: " \ ("block: 0x%lx fd: %lu page: %lu s: %0x hshL: " \
" 0x%lx req: %u/%u wrlocks: %u rdlocks %u " \ " 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), \
(ulong)((B)->hash_link ? \ (ulong)((B)->hash_link ? \
(B)->hash_link->file.file : \ (B)->hash_link->file.file : \
...@@ -114,7 +114,8 @@ ...@@ -114,7 +114,8 @@
(B)->hash_link->requests : \ (B)->hash_link->requests : \
0), \ 0), \
block->wlocks, block->rlocks, block->rlocks_queue, \ 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 */ /* TODO: put it to my_static.c */
my_bool my_disable_flush_pagecache_blocks= 0; my_bool my_disable_flush_pagecache_blocks= 0;
......
...@@ -3243,6 +3243,7 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info, ...@@ -3243,6 +3243,7 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
*/ */
share->state.common= *info->state; share->state.common= *info->state;
info->state= &share->state.common; info->state= &share->state.common;
info->switched_transactional= TRUE;
/* /*
Some code in ma_blockrec.c assumes a trn even if !now_transactional but in 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) ...@@ -3273,8 +3274,10 @@ my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages)
MARIA_SHARE *share= info->s; MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_reenable_logging_for_table"); 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); DBUG_RETURN(0);
info->switched_transactional= FALSE;
if ((share->now_transactional= share->base.born_transactional)) if ((share->now_transactional= share->base.born_transactional))
{ {
......
...@@ -548,6 +548,8 @@ struct st_maria_handler ...@@ -548,6 +548,8 @@ struct st_maria_handler
/* If info->keyread_buff has to be re-read for rnext */ /* If info->keyread_buff has to be re-read for rnext */
my_bool keyread_buff_used; my_bool keyread_buff_used;
my_bool once_flags; /* For MARIA_MRG */ my_bool once_flags; /* For MARIA_MRG */
/* For bulk insert enable/disable transactions control */
my_bool switched_transactional;
#ifdef __WIN__ #ifdef __WIN__
my_bool owned_by_merge; /* This Maria table is part of a merge union */ my_bool owned_by_merge; /* This Maria table is part of a merge union */
#endif #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