From ab3e7f9fcfc297c47ac7f8d83cac22fbf5084aed Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Thu, 20 Jan 2011 19:26:00 +0200 Subject: Fixed bug that another thread used handler->s->id before it was recorded in the log. This fixed an assert in recovert in mi_recovery.c "cmp_translog_addr(rec->lsn, checkpoint_start) < 0" storage/maria/ma_loghandler.c: Don't assign share->id until it's recorded in the log. Had to do an extra test in translog_write_record() to not call translog_assign_id_to_share() for LOGREC_FILE_ID (which sets share->id) storage/maria/ma_recovery.c: Print comment in log for checkpoints --- storage/maria/ma_loghandler.c | 21 +++++++++++++++------ storage/maria/ma_recovery.c | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 97403920239..3e2d78d1465 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -6102,7 +6102,7 @@ my_bool translog_write_record(LSN *lsn, DBUG_RETURN(1); } - if (tbl_info) + if (tbl_info && type != LOGREC_FILE_ID) { MARIA_SHARE *share= tbl_info->s; DBUG_ASSERT(share->now_transactional); @@ -7754,6 +7754,7 @@ out: int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn) { + uint16 id; MARIA_SHARE *share= tbl_info->s; /* If you give an id to a non-BLOCK_RECORD table, you also need to release @@ -7762,13 +7763,14 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn) DBUG_ASSERT(share->data_file_type == BLOCK_RECORD); /* re-check under mutex to avoid having 2 ids for the same share */ pthread_mutex_lock(&share->intern_lock); - if (unlikely(share->id == 0)) + if (likely(share->id == 0)) { LSN lsn; LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2]; uchar log_data[FILEID_STORE_SIZE]; /* Inspired by set_short_trid() of trnman.c */ uint i= share->kfile.file % SHARE_ID_MAX + 1; + id= 0; do { my_atomic_rwlock_wrlock(&LOCK_id_to_share); @@ -7778,14 +7780,15 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn) if (id_to_share[i] == NULL && my_atomic_casptr((void **)&id_to_share[i], &tmp, share)) { - share->id= (uint16)i; + id= (uint16) i; break; } } my_atomic_rwlock_wrunlock(&LOCK_id_to_share); i= 1; /* scan the whole array */ - } while (share->id == 0); - DBUG_PRINT("info", ("id_to_share: 0x%lx -> %u", (ulong)share, share->id)); + } while (id == 0); + DBUG_PRINT("info", ("id_to_share: 0x%lx -> %u", (ulong)share, id)); + fileid_store(log_data, id); log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data; log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data); /* @@ -7807,11 +7810,17 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn) log_array[TRANSLOG_INTERNAL_PARTS + 1].length), sizeof(log_array)/sizeof(log_array[0]), - log_array, log_data, NULL))) + log_array, NULL, NULL))) { pthread_mutex_unlock(&share->intern_lock); return 1; } + /* + Now when translog record is done, we can set share->id. + If we set it before, then translog_write_record may pick up the id + before it's written to the log. + */ + share->id= id; } pthread_mutex_unlock(&share->intern_lock); return 0; diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 50e93cc1eb0..a7e97b12773 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -642,6 +642,7 @@ static void new_transaction(uint16 sid, TrID long_id, LSN undo_lsn, prototype_redo_exec_hook_dummy(CHECKPOINT) { /* the only checkpoint we care about was found via control file, ignore */ + tprint(tracef, "CHECKPOINT found\n"); return 0; } -- cgit v1.2.1