Commit 9653feb1 authored by Guilhem Bichot's avatar Guilhem Bichot

Callers of translog_deassign_id_from_share() need intern_lock.

Assert that keys don't point to bitmap pages.

storage/maria/ma_blockrec.h:
  assertion
storage/maria/ma_locking.c:
  With concurrent INSERTs, it is possible that two threads enter _ma_mark_file_changed()
  at the same time, so they should serialize their access to the "changed" state/share
  members; another reason is that this function may call _ma_update_state_lsns_sub()
  which may call translog_deassign_id_from_share() (I saw it during testing of
  online backup) which requires the intern_lock mutex.
  As INSERTs only change from "not changed" to "changed", we can first check without mutex:
  if it says "changed", some other thread has set or is setting the variables now,
  we don't need to do it; if it says "not changed", we serialize and re-check.
parent 554eb6c2
...@@ -122,6 +122,7 @@ static inline MARIA_RECORD_POS ma_recordpos(pgcache_page_no_t page, ...@@ -122,6 +122,7 @@ static inline MARIA_RECORD_POS ma_recordpos(pgcache_page_no_t page,
uint dir_entry) uint dir_entry)
{ {
DBUG_ASSERT(dir_entry <= 255); DBUG_ASSERT(dir_entry <= 255);
DBUG_ASSERT(page > 0); /* page 0 is bitmap, not data page */
return (MARIA_RECORD_POS) (((ulonglong) page << 8) | dir_entry); return (MARIA_RECORD_POS) (((ulonglong) page << 8) | dir_entry);
} }
......
...@@ -391,9 +391,15 @@ int _ma_mark_file_changed(MARIA_HA *info) ...@@ -391,9 +391,15 @@ int _ma_mark_file_changed(MARIA_HA *info)
{ {
uchar buff[3]; uchar buff[3];
register MARIA_SHARE *share= info->s; register MARIA_SHARE *share= info->s;
int error= 1;
DBUG_ENTER("_ma_mark_file_changed"); DBUG_ENTER("_ma_mark_file_changed");
if (!(share->state.changed & STATE_CHANGED) || ! share->global_changed) #define _MA_ALREADY_MARKED_FILE_CHANGED \
((share->state.changed & STATE_CHANGED) && share->global_changed)
if (_MA_ALREADY_MARKED_FILE_CHANGED)
DBUG_RETURN(0);
pthread_mutex_lock(&share->intern_lock); /* recheck under mutex */
if (! _MA_ALREADY_MARKED_FILE_CHANGED)
{ {
share->state.changed|=(STATE_CHANGED | STATE_NOT_ANALYZED | share->state.changed|=(STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_OPTIMIZED_KEYS); STATE_NOT_OPTIMIZED_KEYS);
...@@ -420,7 +426,7 @@ int _ma_mark_file_changed(MARIA_HA *info) ...@@ -420,7 +426,7 @@ int _ma_mark_file_changed(MARIA_HA *info)
sizeof(share->state.header) + sizeof(share->state.header) +
MARIA_FILE_OPEN_COUNT_OFFSET, MARIA_FILE_OPEN_COUNT_OFFSET,
MYF(MY_NABP))) MYF(MY_NABP)))
DBUG_RETURN(1); goto err;
} }
/* Set uuid of file if not yet set (zerofilled file) */ /* Set uuid of file if not yet set (zerofilled file) */
if (share->base.born_transactional && if (share->base.born_transactional &&
...@@ -432,11 +438,15 @@ int _ma_mark_file_changed(MARIA_HA *info) ...@@ -432,11 +438,15 @@ int _ma_mark_file_changed(MARIA_HA *info)
_ma_update_state_lsns_sub(share, LSN_IMPOSSIBLE, _ma_update_state_lsns_sub(share, LSN_IMPOSSIBLE,
trnman_get_min_trid(), trnman_get_min_trid(),
TRUE, TRUE))) TRUE, TRUE)))
DBUG_RETURN(1); goto err;
share->state.changed|= STATE_NOT_MOVABLE; share->state.changed|= STATE_NOT_MOVABLE;
} }
} }
DBUG_RETURN(0); error= 0;
err:
pthread_mutex_unlock(&share->intern_lock);
DBUG_RETURN(error);
#undef _MA_ALREADY_MARKED_FILE_CHANGED
} }
/* /*
......
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