Commit 131a6a57 authored by unknown's avatar unknown

merge

parents 7f3631c2 c9b0c5a1
...@@ -1059,7 +1059,7 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) ...@@ -1059,7 +1059,7 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
since last call. since last call.
*/ */
pthread_mutex_unlock(&share->intern_lock); pthread_mutex_unlock(&share->intern_lock);
_ma_remove_not_visible_states_with_lock(share); _ma_remove_not_visible_states_with_lock(share, FALSE);
pthread_mutex_lock(&share->intern_lock); pthread_mutex_lock(&share->intern_lock);
if (share->in_checkpoint & MARIA_CHECKPOINT_SHOULD_FREE_ME) if (share->in_checkpoint & MARIA_CHECKPOINT_SHOULD_FREE_ME)
......
...@@ -125,22 +125,30 @@ int maria_close(register MARIA_HA *info) ...@@ -125,22 +125,30 @@ int maria_close(register MARIA_HA *info)
} }
#endif #endif
DBUG_ASSERT(share->now_transactional == share->base.born_transactional); DBUG_ASSERT(share->now_transactional == share->base.born_transactional);
if (share->in_checkpoint == MARIA_CHECKPOINT_LOOKS_AT_ME) /*
We assign -1 because checkpoint does not need to flush (in case we
have concurrent checkpoint if no then we do not need it here also)
*/
share->kfile.file= -1;
/*
Remember share->history for future opens
We have to unlock share->intern_lock then lock it after
LOCK_trn_list (trnman_lock()) to avoid dead locks.
*/
pthread_mutex_unlock(&share->intern_lock);
_ma_remove_not_visible_states_with_lock(share, TRUE);
pthread_mutex_lock(&share->intern_lock);
if (share->in_checkpoint & MARIA_CHECKPOINT_LOOKS_AT_ME)
{ {
share->kfile.file= -1; /* because Checkpoint does not need to flush */
/* we cannot my_free() the share, Checkpoint would see a bad pointer */ /* we cannot my_free() the share, Checkpoint would see a bad pointer */
share->in_checkpoint|= MARIA_CHECKPOINT_SHOULD_FREE_ME; share->in_checkpoint|= MARIA_CHECKPOINT_SHOULD_FREE_ME;
} }
else else
share_can_be_freed= TRUE; share_can_be_freed= TRUE;
/*
Remember share->history for future opens
Here we take share->intern_lock followed by trans_lock but this is
safe as no other thread one can use 'share' here.
*/
share->state_history= _ma_remove_not_visible_states(share->state_history,
1, 0);
if (share->state_history) if (share->state_history)
{ {
MARIA_STATE_HISTORY_CLOSED *history; MARIA_STATE_HISTORY_CLOSED *history;
......
...@@ -166,7 +166,6 @@ MARIA_STATE_HISTORY ...@@ -166,7 +166,6 @@ MARIA_STATE_HISTORY
if (all && parent == &org_history->next) if (all && parent == &org_history->next)
{ {
DBUG_ASSERT(trnman_is_locked == 0);
/* There is only one state left. Delete this if it's visible for all */ /* There is only one state left. Delete this if it's visible for all */
if (last_trid < trnman_get_min_trid()) if (last_trid < trnman_get_min_trid())
{ {
...@@ -181,6 +180,11 @@ MARIA_STATE_HISTORY ...@@ -181,6 +180,11 @@ MARIA_STATE_HISTORY
/** /**
@brief Remove not used state history @brief Remove not used state history
@param share Maria table information
@param all 1 if we should delete the first state if it's
visible for all. For the moment this is only used
on close() of table.
@notes @notes
share and trnman are not locked. share and trnman are not locked.
...@@ -189,13 +193,18 @@ MARIA_STATE_HISTORY ...@@ -189,13 +193,18 @@ MARIA_STATE_HISTORY
takes share->intern_lock. takes share->intern_lock.
*/ */
void _ma_remove_not_visible_states_with_lock(MARIA_SHARE *share) void _ma_remove_not_visible_states_with_lock(MARIA_SHARE *share,
my_bool all)
{ {
my_bool is_lock_trman;
if ((is_lock_trman= trman_is_inited()))
trnman_lock(); trnman_lock();
pthread_mutex_lock(&share->intern_lock); pthread_mutex_lock(&share->intern_lock);
share->state_history= _ma_remove_not_visible_states(share->state_history, 0, share->state_history= _ma_remove_not_visible_states(share->state_history,
1); all, 1);
pthread_mutex_unlock(&share->intern_lock); pthread_mutex_unlock(&share->intern_lock);
if (is_lock_trman)
trnman_unlock(); trnman_unlock();
} }
......
...@@ -78,6 +78,7 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit, ...@@ -78,6 +78,7 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
my_bool _ma_row_visible_always(MARIA_HA *info); my_bool _ma_row_visible_always(MARIA_HA *info);
my_bool _ma_row_visible_non_transactional_table(MARIA_HA *info); my_bool _ma_row_visible_non_transactional_table(MARIA_HA *info);
my_bool _ma_row_visible_transactional_table(MARIA_HA *info); my_bool _ma_row_visible_transactional_table(MARIA_HA *info);
void _ma_remove_not_visible_states_with_lock(struct st_maria_share *share); void _ma_remove_not_visible_states_with_lock(struct st_maria_share *share,
my_bool all);
void _ma_remove_table_from_trnman(struct st_maria_share *share, TRN *trn); void _ma_remove_table_from_trnman(struct st_maria_share *share, TRN *trn);
void _ma_reset_history(struct st_maria_share *share); void _ma_reset_history(struct st_maria_share *share);
...@@ -353,7 +353,7 @@ typedef struct st_maria_share ...@@ -353,7 +353,7 @@ typedef struct st_maria_share
PAGECACHE_FILE kfile; /* Shared keyfile */ PAGECACHE_FILE kfile; /* Shared keyfile */
File data_file; /* Shared data file */ File data_file; /* Shared data file */
int mode; /* mode of file on open */ int mode; /* mode of file on open */
uint reopen; /* How many times reopened */ uint reopen; /* How many times opened */
uint in_trans; /* Number of references by trn */ uint in_trans; /* Number of references by trn */
uint w_locks, r_locks, tot_locks; /* Number of read/write locks */ uint w_locks, r_locks, tot_locks; /* Number of read/write locks */
uint block_size; /* block_size of keyfile & data file*/ uint block_size; /* block_size of keyfile & data file*/
......
...@@ -881,6 +881,7 @@ my_bool trnman_exists_active_transactions(TrID min_id, TrID max_id, ...@@ -881,6 +881,7 @@ my_bool trnman_exists_active_transactions(TrID min_id, TrID max_id,
if (!trnman_is_locked) if (!trnman_is_locked)
pthread_mutex_lock(&LOCK_trn_list); pthread_mutex_lock(&LOCK_trn_list);
safe_mutex_assert_owner(&LOCK_trn_list);
for (trn= active_list_min.next; trn != &active_list_max; trn= trn->next) for (trn= active_list_min.next; trn != &active_list_max; trn= trn->next)
{ {
if (trn->trid > min_id && trn->trid < max_id) if (trn->trid > min_id && trn->trid < max_id)
...@@ -904,6 +905,7 @@ void trnman_lock() ...@@ -904,6 +905,7 @@ void trnman_lock()
pthread_mutex_lock(&LOCK_trn_list); pthread_mutex_lock(&LOCK_trn_list);
} }
/** /**
unlock transaction list unlock transaction list
*/ */
...@@ -912,3 +914,13 @@ void trnman_unlock() ...@@ -912,3 +914,13 @@ void trnman_unlock()
{ {
pthread_mutex_unlock(&LOCK_trn_list); pthread_mutex_unlock(&LOCK_trn_list);
} }
/**
Is trman initialized
*/
my_bool trman_is_inited()
{
return (short_trid_to_active_trn != NULL);
}
...@@ -69,5 +69,6 @@ my_bool trnman_exists_active_transactions(TrID min_id, TrID max_id, ...@@ -69,5 +69,6 @@ my_bool trnman_exists_active_transactions(TrID min_id, TrID max_id,
#define transid_korr(P) uint6korr(P) #define transid_korr(P) uint6korr(P)
void trnman_lock(); void trnman_lock();
void trnman_unlock(); void trnman_unlock();
my_bool trman_is_inited();
C_MODE_END C_MODE_END
#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