示例#1
0
/***********************************************************//**
Undoes a row operation in a table. This is a high-level function used
in SQL execution graphs.
@return	query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_undo_step(
/*==========*/
	que_thr_t*	thr)	/*!< in: query thread */
{
	ulint		err;
	undo_node_t*	node;
	trx_t*		trx;

	ut_ad(thr);

	srv_activity_count++;

	trx = thr_get_trx(thr);

	node = thr->run_node;

	ut_ad(que_node_get_type(node) == QUE_NODE_UNDO);

	err = row_undo(node, thr);

	trx->error_state = err;

	if (err != DB_SUCCESS) {
		/* SQL error detected */

		fprintf(stderr, "InnoDB: Fatal error %lu in rollback.\n",
			(ulong) err);

		if (err == DB_OUT_OF_FILE_SPACE) {
			fprintf(stderr,
				"InnoDB: Error 13 means out of tablespace.\n"
				"InnoDB: Consider increasing"
				" your tablespace.\n");

			exit(1);
		}

		ut_error;

		return(NULL);
	}

	return(thr);
}
示例#2
0
文件: row0purge.c 项目: Canos/mysql
/***********************************************************//**
Does the purge operation for a single undo log record. This is a high-level
function used in an SQL execution graph.
@return	query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_purge_step(
    /*===========*/
    que_thr_t*	thr)	/*!< in: query thread */
{
    purge_node_t*	node;

    ut_ad(thr);

    node = thr->run_node;

    ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);

    row_purge(node, thr);

    return(thr);
}
示例#3
0
/***********************************************************//**
Performs an execution step for a commit type node in a query graph.
@return	query thread to run next, or NULL */
UNIV_INTERN
que_thr_t*
trx_commit_step(
/*============*/
	que_thr_t*	thr)	/*!< in: query thread */
{
	commit_node_t*	node;
	que_thr_t*	next_thr;

	node = thr->run_node;

	ut_ad(que_node_get_type(node) == QUE_NODE_COMMIT);

	if (thr->prev_node == que_node_get_parent(node)) {
		node->state = COMMIT_NODE_SEND;
	}

	if (node->state == COMMIT_NODE_SEND) {
		mutex_enter(&kernel_mutex);

		node->state = COMMIT_NODE_WAIT;

		next_thr = NULL;

		thr->state = QUE_THR_SIG_REPLY_WAIT;

		/* Send the commit signal to the transaction */

		trx_sig_send(thr_get_trx(thr), TRX_SIG_COMMIT, TRX_SIG_SELF,
			     thr, NULL, &next_thr);

		mutex_exit(&kernel_mutex);

		return(next_thr);
	}

	ut_ad(node->state == COMMIT_NODE_WAIT);

	node->state = COMMIT_NODE_SEND;

	thr->run_node = que_node_get_parent(node);

	return(thr);
}
示例#4
0
void
row_upd_in_place_in_select(
/*=======================*/
	sel_node_t*	sel_node,	/* in: select node */
	que_thr_t*	thr,		/* in: query thread */
	mtr_t*		mtr)		/* in: mtr */
{
	upd_node_t*	node;
	btr_pcur_t*	pcur;
	btr_cur_t*	btr_cur;
	ulint		err;

	ut_ad(sel_node->select_will_do_update);
	ut_ad(sel_node->latch_mode == BTR_MODIFY_LEAF);
	ut_ad(sel_node->asc);

	node = que_node_get_parent(sel_node);

	ut_ad(que_node_get_type(node) == QUE_NODE_UPDATE);

	pcur = node->pcur;
	btr_cur = btr_pcur_get_btr_cur(pcur);

	/* Copy the necessary columns from clust_rec and calculate the new
	values to set */

	row_upd_copy_columns(btr_pcur_get_rec(pcur),
					UT_LIST_GET_FIRST(node->columns));
	row_upd_eval_new_vals(node->update);

	ut_ad(FALSE == rec_get_deleted_flag(btr_pcur_get_rec(pcur)));
	
	ut_ad(node->cmpl_info & UPD_NODE_NO_SIZE_CHANGE);
	ut_ad(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE);
	ut_ad(node->select_will_do_update);

	err = btr_cur_update_in_place(BTR_NO_LOCKING_FLAG, btr_cur,
						node->update, node->cmpl_info,
						thr, mtr);
	ut_ad(err == DB_SUCCESS);
}
示例#5
0
que_thr_t*
row_purge_step(
/*===========*/
				/* out: query thread to run next or NULL */
	que_thr_t*	thr)	/* in: query thread */
{
	purge_node_t*	node;
	ulint		err;

	ut_ad(thr);
	
	node = thr->run_node;

	ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);

	err = row_purge(node, thr);

	ut_ad(err == DB_SUCCESS);

	return(thr);
} 
示例#6
0
que_thr_t*
dict_create_index_step(
/*===================*/
				/* out: query thread to run next or NULL */
	que_thr_t*	thr)	/* in: query thread */
{
	ind_node_t*	node;
	ulint		err	= DB_ERROR;
	trx_t*		trx;

	ut_ad(thr);
	ut_ad(mutex_own(&(dict_sys->mutex)));

	trx = thr_get_trx(thr);

	node = thr->run_node;

	ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_INDEX);

	if (thr->prev_node == que_node_get_parent(node)) {
		node->state = INDEX_BUILD_INDEX_DEF;
	}

	if (node->state == INDEX_BUILD_INDEX_DEF) {
		/* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */
		err = dict_build_index_def_step(thr, node);

		if (err != DB_SUCCESS) {

			goto function_exit;
		}

		node->state = INDEX_BUILD_FIELD_DEF;
		node->field_no = 0;

		thr->run_node = node->ind_def;

		return(thr);
	}

	if (node->state == INDEX_BUILD_FIELD_DEF) {

		if (node->field_no < (node->index)->n_fields) {

			err = dict_build_field_def_step(node);

			if (err != DB_SUCCESS) {

				goto function_exit;
			}

			node->field_no++;

			thr->run_node = node->field_def;

			return(thr);
		} else {
			node->state = INDEX_CREATE_INDEX_TREE;
		}
	}

	if (node->state == INDEX_CREATE_INDEX_TREE) {

		err = dict_create_index_tree_step(node);

		if (err != DB_SUCCESS) {

			goto function_exit;
		}

		node->state = INDEX_COMMIT_WORK;
	}

	if (node->state == INDEX_COMMIT_WORK) {

		/* Index was correctly defined: do NOT commit the transaction
		(CREATE INDEX does NOT currently do an implicit commit of
		the current transaction) */

		node->state = INDEX_ADD_TO_CACHE;

		/* thr->run_node = node->commit_node;

		return(thr); */
	}

	if (node->state == INDEX_ADD_TO_CACHE) {

		dict_index_add_to_cache(node->table, node->index,
					node->page_no);

		err = DB_SUCCESS;
	}

function_exit:
	trx->error_state = err;

	if (err == DB_SUCCESS) {
		/* Ok: do nothing */

	} else if (err == DB_LOCK_WAIT) {

		return(NULL);
	} else {
		/* SQL error detected */

		return(NULL);
	}

	thr->run_node = que_node_get_parent(node);

	return(thr);
}
示例#7
0
que_thr_t*
row_upd_step(
/*=========*/
				/* out: query thread to run next or NULL */
	que_thr_t*	thr)	/* in: query thread */
{
	upd_node_t*	node;
	sel_node_t*	sel_node;
	que_node_t*	parent;
	ulint		err		= DB_SUCCESS;
	trx_t*		trx;

	ut_ad(thr);
	
	trx = thr_get_trx(thr);

	trx_start_if_not_started(trx);

	node = thr->run_node;
	
	sel_node = node->select;

	parent = que_node_get_parent(node);
	
	ut_ad(que_node_get_type(node) == QUE_NODE_UPDATE);
	
	if (thr->prev_node == parent) {
		node->state = UPD_NODE_SET_IX_LOCK;
	}

	if (node->state == UPD_NODE_SET_IX_LOCK) {

		if (!node->has_clust_rec_x_lock) {
			/* It may be that the current session has not yet
			started its transaction, or it has been committed: */

			err = lock_table(0, node->table, LOCK_IX, thr);

			if (err != DB_SUCCESS) {

				goto error_handling;
			}
		}
	
		node->state = UPD_NODE_UPDATE_CLUSTERED;

		if (node->searched_update) {
			/* Reset the cursor */
			sel_node->state = SEL_NODE_OPEN;
		
			/* Fetch a row to update */
		
			thr->run_node = sel_node;
	
			return(thr);
		}
	}

	/* sel_node is NULL if we are in the MySQL interface */
	
	if (sel_node && (sel_node->state != SEL_NODE_FETCH)) {

		if (!node->searched_update) {
			/* An explicit cursor should be positioned on a row
			to update */

			ut_error;
			
			err = DB_ERROR;

			goto error_handling;
		}

		ut_ad(sel_node->state == SEL_NODE_NO_MORE_ROWS);

		/* No more rows to update, or the select node performed the
		updates directly in-place */

		thr->run_node = parent;
	
		return(thr);
	}

	/* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */
	
	err = row_upd(node, thr);

error_handling:
	trx->error_state = err;

	if (err == DB_SUCCESS) {
		/* Ok: do nothing */
	} else if (err == DB_LOCK_WAIT) {

		return(NULL);
	} else {
		return(NULL);
	}

	/* DO THE TRIGGER ACTIONS HERE */

	if (node->searched_update) {
		/* Fetch next row to update */

		thr->run_node = sel_node;
	} else {
		/* It was an explicit cursor update */

		thr->run_node = parent;
	}

	node->state = UPD_NODE_UPDATE_CLUSTERED;

	return(thr);
} 
示例#8
0
/***********************************************************//**
Creates a table. This is a high-level function used in SQL execution graphs.
@return	query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_table_step(
    /*===================*/
    que_thr_t*	thr)	/*!< in: query thread */
{
    tab_node_t*	node;
    ulint		err	= DB_ERROR;
    trx_t*		trx;

    ut_ad(thr);
    ut_ad(mutex_own(&(dict_sys->mutex)));

    trx = thr_get_trx(thr);

    node = thr->run_node;

    ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_TABLE);

    if (thr->prev_node == que_node_get_parent(node)) {
        node->state = TABLE_BUILD_TABLE_DEF;
    }

    if (node->state == TABLE_BUILD_TABLE_DEF) {

        /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */

        err = dict_build_table_def_step(thr, node);

        if (err != DB_SUCCESS) {

            goto function_exit;
        }

        node->state = TABLE_BUILD_COL_DEF;
        node->col_no = 0;

        thr->run_node = node->tab_def;

        return(thr);
    }

    if (node->state == TABLE_BUILD_COL_DEF) {

        if (node->col_no < (node->table)->n_def) {

            err = dict_build_col_def_step(node);

            if (err != DB_SUCCESS) {

                goto function_exit;
            }

            node->col_no++;

            thr->run_node = node->col_def;

            return(thr);
        } else {
            node->state = TABLE_COMMIT_WORK;
        }
    }

    if (node->state == TABLE_COMMIT_WORK) {

        /* Table was correctly defined: do NOT commit the transaction
        (CREATE TABLE does NOT do an implicit commit of the current
        transaction) */

        node->state = TABLE_ADD_TO_CACHE;

        /* thr->run_node = node->commit_node;

        return(thr); */
    }

    if (node->state == TABLE_ADD_TO_CACHE) {

        dict_table_add_to_cache(node->table, node->heap);

        err = DB_SUCCESS;
    }

function_exit:
    trx->error_state = err;

    if (err == DB_SUCCESS) {
        /* Ok: do nothing */

    } else if (err == DB_LOCK_WAIT) {

        return(NULL);
    } else {
        /* SQL error detected */

        return(NULL);
    }

    thr->run_node = que_node_get_parent(node);

    return(thr);
}
示例#9
0
/***********************************************************//**
Creates an index. This is a high-level function used in SQL execution
graphs.
@return	query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_index_step(
/*===================*/
	que_thr_t*	thr)	/*!< in: query thread */
{
	ind_node_t*	node;
	ulint		err	= DB_ERROR;
	trx_t*		trx;

	ut_ad(thr);
	ut_ad(mutex_own(&(dict_sys->mutex)));

	trx = thr_get_trx(thr);

	node = thr->run_node;

	ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_INDEX);

	if (thr->prev_node == que_node_get_parent(node)) {
		node->state = INDEX_BUILD_INDEX_DEF;
	}

	if (node->state == INDEX_BUILD_INDEX_DEF) {
		/* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */
		err = dict_build_index_def_step(thr, node);

		if (err != DB_SUCCESS) {

			goto function_exit;
		}

		node->state = INDEX_BUILD_FIELD_DEF;
		node->field_no = 0;

		thr->run_node = node->ind_def;

		return(thr);
	}

	if (node->state == INDEX_BUILD_FIELD_DEF) {

		if (node->field_no < (node->index)->n_fields) {

			err = dict_build_field_def_step(node);

			if (err != DB_SUCCESS) {

				goto function_exit;
			}

			node->field_no++;

			thr->run_node = node->field_def;

			return(thr);
		} else {
			node->state = INDEX_ADD_TO_CACHE;
		}
	}

	if (node->state == INDEX_ADD_TO_CACHE) {

		index_id_t	index_id = node->index->id;

//		err = dict_index_add_to_cache(
//			node->table, node->index, FIL_NULL,
//			trx_is_strict(trx)
//			|| dict_table_get_format(node->table)
//			>= DICT_TF_FORMAT_ZIP);  //z- //因为trx_is_strict!/为什么ha_innodb__.cc中的stub无效呢?;----2011-09-20-10-02;
err=DB_SUCCESS; //z+ //zlq  //----2011-10-12-21-05--21-07;

		node->index = dict_index_get_if_in_cache_low(index_id);
//		ut_a(!node->index == (err != DB_SUCCESS));  //z- //zlqlxm //2011-10-13

		if (err != DB_SUCCESS) {

			goto function_exit;
		}

		node->state = INDEX_CREATE_INDEX_TREE;
	}

	if (node->state == INDEX_CREATE_INDEX_TREE) {

		err = dict_create_index_tree_step(node);

		if (err != DB_SUCCESS) {
			dict_index_remove_from_cache(node->table, node->index);
			node->index = NULL;

			goto function_exit;
		}

		node->index->page = node->page_no;
		node->state = INDEX_COMMIT_WORK;
	}

	if (node->state == INDEX_COMMIT_WORK) {

		/* Index was correctly defined: do NOT commit the transaction
		(CREATE INDEX does NOT currently do an implicit commit of
		the current transaction) */

		node->state = INDEX_CREATE_INDEX_TREE;

		/* thr->run_node = node->commit_node;

		return(thr); */
	}

function_exit:
	trx->error_state = err;

	if (err == DB_SUCCESS) {
		/* Ok: do nothing */

	} else if (err == DB_LOCK_WAIT) {

		return(NULL);
	} else {
		/* SQL error detected */

		return(NULL);
	}

	thr->run_node = que_node_get_parent(node);

	return(thr);
}