Example #1
0
int
trx_weight_cmp(
/*===========*/
			/* out: <0, 0 or >0; similar to strcmp(3) */
	trx_t*	a,	/* in: the first transaction to be compared */
	trx_t*	b)	/* in: the second transaction to be compared */
{
	ibool	a_notrans_edit;
	ibool	b_notrans_edit;

	/* If mysql_thd is NULL for a transaction we assume that it has
	not edited non-transactional tables. */

	a_notrans_edit = a->mysql_thd != NULL
	    && thd_has_edited_nontrans_tables(a->mysql_thd);

	b_notrans_edit = b->mysql_thd != NULL
	    && thd_has_edited_nontrans_tables(b->mysql_thd);

	if (a_notrans_edit && !b_notrans_edit) {

		return(1);
	}

	if (!a_notrans_edit && b_notrans_edit) {

		return(-1);
	}

	/* Either both had edited non-transactional tables or both had
	not, we fall back to comparing the number of altered/locked
	rows. */

#if 0
	fprintf(stderr,
		"%s TRX_WEIGHT(a): %lld+%lu, TRX_WEIGHT(b): %lld+%lu\n",
		__func__,
		ut_conv_dulint_to_longlong(a->undo_no),
		UT_LIST_GET_LEN(a->trx_locks),
		ut_conv_dulint_to_longlong(b->undo_no),
		UT_LIST_GET_LEN(b->trx_locks));
#endif

#define TRX_WEIGHT(t)	\
	ut_dulint_add((t)->undo_no, UT_LIST_GET_LEN((t)->trx_locks))

	return(ut_dulint_cmp(TRX_WEIGHT(a), TRX_WEIGHT(b)));
}
/***************************************************************//**
Builds an index definition row to insert.
@return	DB_SUCCESS or error code */
static
ulint
dict_build_index_def_step(
/*======================*/
	que_thr_t*	thr,	/*!< in: query thread */
	ind_node_t*	node)	/*!< in: index create node */
{
	dict_table_t*	table;
	dict_index_t*	index;
	dtuple_t*	row;
	trx_t*		trx;

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

	trx = thr_get_trx(thr);

	index = node->index;

	table = dict_table_get_low(index->table_name);

	if (table == NULL) {
		return(DB_TABLE_NOT_FOUND);
	}

	trx->table_id = table->id;

	node->table = table;

	ut_ad((UT_LIST_GET_LEN(table->indexes) > 0)
	      || dict_index_is_clust(index));

	dict_hdr_get_new_id(NULL, &index->id, NULL);

	/* Inherit the space id from the table; we store all indexes of a
	table in the same tablespace */

	index->space = table->space;
	node->page_no = FIL_NULL;
	row = dict_create_sys_indexes_tuple(index, node->heap);
	node->ind_row = row;

	ins_node_set_new_row(node->ind_def, row);

	/* Note that the index was created by this transaction. */
	index->trx_id = (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);

	return(DB_SUCCESS);
}
Example #3
0
/**********************************************************************//**
This function is used to find number of prepared transactions and
their transaction objects for a recovery.
@return	number of prepared transactions stored in xid_list */
UNIV_INTERN
int
trx_recover_for_mysql(
/*==================*/
	XID*	xid_list,	/*!< in/out: prepared transactions */
	ulint	len)		/*!< in: number of slots in xid_list */
{
	trx_t*	trx;
	ulint	count = 0;

	ut_ad(xid_list);
	ut_ad(len);

	/* We should set those transactions which are in the prepared state
	to the xid_list */

	mutex_enter(&kernel_mutex);

	trx = UT_LIST_GET_FIRST(trx_sys->trx_list);

	while (trx) {
		if (trx->conc_state == TRX_PREPARED) {
			xid_list[count] = trx->xid;

			if (count == 0) {
				ut_print_timestamp(stderr);
				fprintf(stderr,
					"  InnoDB: Starting recovery for"
					" XA transactions...\n");
			}

			ut_print_timestamp(stderr);
			fprintf(stderr,
				"  InnoDB: Transaction " TRX_ID_FMT " in"
				" prepared state after recovery\n",
				TRX_ID_PREP_PRINTF(trx->id));

			ut_print_timestamp(stderr);
			fprintf(stderr,
				"  InnoDB: Transaction contains changes"
				" to %lu rows\n",
				(ulong) ut_conv_dulint_to_longlong(
					trx->undo_no));

			count++;

			if (count == len) {
				break;
			}
		}

		trx = UT_LIST_GET_NEXT(trx_list, trx);
	}

	mutex_exit(&kernel_mutex);

	if (count > 0){
		ut_print_timestamp(stderr);
		fprintf(stderr,
			"  InnoDB: %lu transactions in prepared state"
			" after recovery\n",
			(ulong) count);
	}

	return ((int) count);
}
Example #4
0
/*******************************************************************//**
Fills i_s_trx_row_t object.
If memory can not be allocated then FALSE is returned.
@return	FALSE if allocation fails */
static
ibool
fill_trx_row(
/*=========*/
	i_s_trx_row_t*		row,		/*!< out: result object
						that's filled */
	const trx_t*		trx,		/*!< in: transaction to
						get data from */
	const i_s_locks_row_t*	requested_lock_row,/*!< in: pointer to the
						corresponding row in
						innodb_locks if trx is
						waiting or NULL if trx
						is not waiting */
	trx_i_s_cache_t*	cache)		/*!< in/out: cache into
						which to copy volatile
						strings */
{
	row->trx_id = trx_get_id(trx);
	row->trx_started = (ib_time_t) trx->start_time;
	row->trx_state = trx_get_que_state_str(trx);

	if (trx->wait_lock != NULL) {

		ut_a(requested_lock_row != NULL);

		row->requested_lock_row = requested_lock_row;
		row->trx_wait_started = (ib_time_t) trx->wait_started;
	} else {

		ut_a(requested_lock_row == NULL);

		row->requested_lock_row = NULL;
		row->trx_wait_started = 0;
	}

	row->trx_weight = (ullint) ut_conv_dulint_to_longlong(TRX_WEIGHT(trx));

	if (trx->mysql_thd != NULL) {
		row->trx_mysql_thread_id
			= thd_get_thread_id(trx->mysql_thd);
	} else {
		/* For internal transactions e.g., purge and transactions
		being recovered at startup there is no associated MySQL
		thread data structure. */
		row->trx_mysql_thread_id = 0;
	}

	if (trx->mysql_query_str != NULL && *trx->mysql_query_str != NULL) {

		if (strlen(*trx->mysql_query_str)
		    > TRX_I_S_TRX_QUERY_MAX_LEN) {

			char	query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];

			memcpy(query, *trx->mysql_query_str,
			       TRX_I_S_TRX_QUERY_MAX_LEN);
			query[TRX_I_S_TRX_QUERY_MAX_LEN] = '\0';

			row->trx_query = ha_storage_put_memlim(
				cache->storage, query,
				TRX_I_S_TRX_QUERY_MAX_LEN + 1,
				MAX_ALLOWED_FOR_STORAGE(cache));
		} else {

			row->trx_query = ha_storage_put_str_memlim(
				cache->storage, *trx->mysql_query_str,
				MAX_ALLOWED_FOR_STORAGE(cache));
		}

		if (row->trx_query == NULL) {

			return(FALSE);
		}
	} else {

		row->trx_query = NULL;
	}

	return(TRUE);
}