summaryrefslogtreecommitdiff
path: root/storage/maria/ma_locking.c
diff options
context:
space:
mode:
authorGuilhem Bichot <guilhem@mysql.com>2009-02-09 22:52:42 +0100
committerGuilhem Bichot <guilhem@mysql.com>2009-02-09 22:52:42 +0100
commit9653feb1600c84fc5e51fe102761c93b7f83de0f (patch)
treea7fbefd733111a6af98afd1f29128512c297e9f8 /storage/maria/ma_locking.c
parent554eb6c2cf00d80d283374a749ca82f1a1f13bae (diff)
downloadmariadb-git-9653feb1600c84fc5e51fe102761c93b7f83de0f.tar.gz
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.
Diffstat (limited to 'storage/maria/ma_locking.c')
-rw-r--r--storage/maria/ma_locking.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c
index 2a34d1fe9f3..9d57cd1cba3 100644
--- a/storage/maria/ma_locking.c
+++ b/storage/maria/ma_locking.c
@@ -391,9 +391,15 @@ int _ma_mark_file_changed(MARIA_HA *info)
{
uchar buff[3];
register MARIA_SHARE *share= info->s;
+ int error= 1;
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 |
STATE_NOT_OPTIMIZED_KEYS);
@@ -420,7 +426,7 @@ int _ma_mark_file_changed(MARIA_HA *info)
sizeof(share->state.header) +
MARIA_FILE_OPEN_COUNT_OFFSET,
MYF(MY_NABP)))
- DBUG_RETURN(1);
+ goto err;
}
/* Set uuid of file if not yet set (zerofilled file) */
if (share->base.born_transactional &&
@@ -432,11 +438,15 @@ int _ma_mark_file_changed(MARIA_HA *info)
_ma_update_state_lsns_sub(share, LSN_IMPOSSIBLE,
trnman_get_min_trid(),
TRUE, TRUE)))
- DBUG_RETURN(1);
+ goto err;
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
}
/*