/********************************************************************** Takes a block out of the LRU list and page hash table and sets the block state to BUF_BLOCK_REMOVE_HASH. */ static void buf_LRU_block_remove_hashed_page( /*=============================*/ buf_block_t* block) /* in: block, must contain a file page and be in a state where it can be freed; there may or may not be a hash index to the page */ { ut_ad(mutex_own(&(buf_pool->mutex))); ut_ad(mutex_own(&block->mutex)); ut_ad(block); ut_a(block->state == BUF_BLOCK_FILE_PAGE); ut_a(block->io_fix == 0); ut_a(block->buf_fix_count == 0); ut_a(ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) == 0); buf_LRU_remove_block(block); buf_pool->freed_page_clock += 1; /* Note that if AWE is enabled the block may not have a frame at all */ buf_block_modify_clock_inc(block); if (block != buf_page_hash_get(block->space, block->offset)) { fprintf(stderr, "InnoDB: Error: page %lu %lu not found" " in the hash table\n", (ulong) block->space, (ulong) block->offset); if (buf_page_hash_get(block->space, block->offset)) { fprintf(stderr, "InnoDB: In hash table we find block" " %p of %lu %lu which is not %p\n", (void*) buf_page_hash_get (block->space, block->offset), (ulong) buf_page_hash_get (block->space, block->offset)->space, (ulong) buf_page_hash_get (block->space, block->offset)->offset, (void*) block); } #ifdef UNIV_DEBUG buf_print(); buf_LRU_print(); buf_validate(); buf_LRU_validate(); #endif ut_a(0); } HASH_DELETE(buf_block_t, hash, buf_pool->page_hash, buf_page_address_fold(block->space, block->offset), block); UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE); block->state = BUF_BLOCK_REMOVE_HASH; }
/** * Commit this transaction * * @param tx is a pointer to the transaction descriptor */ void stm_commit(stm_tx_t *tx) { stm_word_t commit_version; DPRINTF("\tstm commit start: %p\n", tx); /* Check status */ assert(tx->status == TX_ACTIVE); if (tx->nr_uniq_writes==0) { /* No need to acquire, validate or extend anything in read only mode */ tx->status = TX_COMMITTED; } else { /* Try to acquire all locks */ buf_acquire_all_locks(tx); /* Increment the counter and get the newest version */ commit_version = GLOBAL_VERSION_INC+2; /* Special case: if max_version + 2 == commit_version we do not need to validate */ if ((tx->max_version)+2 != commit_version) { /* Before we can write back we need to validate the read set */ if (unlikely(!buf_validate(tx))) { /* This is the end of this function since stm_retry never returns */ DPRINTF("\tstm commit validate failed: %p\n", tx); stm_retry(tx); } } /* The locks are acquired and the read set validated */ tx->status = TX_COMMITTED; /* Write the write buffer back to the shared memory */ #if defined(ADAPTIVENESS) && defined(WRITEBACK) && defined(WRITETHROUGH) if (!tx->writethrough) buf_write_back(tx); #elif defined(WRITEBACK) buf_write_back(tx); #endif buf_release_all_locks(tx, commit_version); } /* Free the memory which was freed during the transaction */ mem_free_memory(tx); /* Reset the buffer */ buf_reset(tx); DPRINTF("\tstm commit done: %p\n", tx); #ifdef ADAPTIVENESS tx->adaptcommits++; #endif #ifdef GLOBAL_STATS tx->commits++; #endif #ifdef STATS tx->nb_tot_reads+=tx->nb_reads; tx->nb_tot_writes+=tx->nb_writes; if (tx->nb_writes>tx->nb_max_writes) tx->nb_max_writes = tx->nb_writes; if (tx->nb_writes<tx->nb_min_writes) tx->nb_min_writes = tx->nb_writes; if (tx->nb_reads>tx->nb_max_reads) tx->nb_max_reads = tx->nb_reads; if (tx->nb_reads<tx->nb_min_reads) tx->nb_min_reads = tx->nb_reads; #endif /* Check status */ assert(tx->status == TX_COMMITTED); }