Пример #1
0
/**********************************************************************
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;
}
Пример #2
0
/**
 * 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);
}