Exemplo n.º 1
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);
}
Exemplo n.º 2
0
/*******************************************************************//**
Fills the "lock_data" member of i_s_locks_row_t object.
If memory can not be allocated then FALSE is returned.
@return	FALSE if allocation fails */
static
ibool
fill_lock_data(
/*===========*/
	const char**		lock_data,/*!< out: "lock_data" to fill */
	const lock_t*		lock,	/*!< in: lock used to find the data */
	ulint			heap_no,/*!< in: rec num used to find the data */
	trx_i_s_cache_t*	cache)	/*!< in/out: cache where to store
					volatile data */
{
	mtr_t			mtr;

	const buf_block_t*	block;
	const page_t*		page;
	const rec_t*		rec;

	ut_a(lock_get_type(lock) == LOCK_REC);

	mtr_start(&mtr);

	block = buf_page_try_get(lock_rec_get_space_id(lock),
				 lock_rec_get_page_no(lock),
				 &mtr);

	if (block == NULL) {

		*lock_data = NULL;

		mtr_commit(&mtr);

		return(TRUE);
	}

	page = (const page_t*) buf_block_get_frame(block);

	rec = page_find_rec_with_heap_no(page, heap_no);

	if (page_rec_is_infimum(rec)) {

		*lock_data = ha_storage_put_str_memlim(
			cache->storage, "infimum pseudo-record",
			MAX_ALLOWED_FOR_STORAGE(cache));
	} else if (page_rec_is_supremum(rec)) {

		*lock_data = ha_storage_put_str_memlim(
			cache->storage, "supremum pseudo-record",
			MAX_ALLOWED_FOR_STORAGE(cache));
	} else {

		const dict_index_t*	index;
		ulint			n_fields;
		mem_heap_t*		heap;
		ulint			offsets_onstack[REC_OFFS_NORMAL_SIZE];
		ulint*			offsets;
		char			buf[TRX_I_S_LOCK_DATA_MAX_LEN];
		ulint			buf_used;
		ulint			i;

		rec_offs_init(offsets_onstack);
		offsets = offsets_onstack;

		index = lock_rec_get_index(lock);

		n_fields = dict_index_get_n_unique(index);

		ut_a(n_fields > 0);

		heap = NULL;
		offsets = rec_get_offsets(rec, index, offsets, n_fields,
					  &heap);

		/* format and store the data */

		buf_used = 0;
		for (i = 0; i < n_fields; i++) {

			buf_used += put_nth_field(
				buf + buf_used, sizeof(buf) - buf_used,
				i, index, rec, offsets) - 1;
		}

		*lock_data = (const char*) ha_storage_put_memlim(
			cache->storage, buf, buf_used + 1,
			MAX_ALLOWED_FOR_STORAGE(cache));

		if (UNIV_UNLIKELY(heap != NULL)) {

			/* this means that rec_get_offsets() has created a new
			heap and has stored offsets in it; check that this is
			really the case and free the heap */
			ut_a(offsets != offsets_onstack);
			mem_heap_free(heap);
		}
	}

	mtr_commit(&mtr);

	if (*lock_data == NULL) {

		return(FALSE);
	}

	return(TRUE);
}
Exemplo n.º 3
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 */
{
	const char*	stmt;
	size_t		stmt_len;
	const char*	s;

	ut_ad(mutex_own(&kernel_mutex));

	row->trx_id = trx->id;
	row->trx_started = (ib_time_t) trx->start_time;
	row->trx_state = trx_get_que_state_str(trx);
	row->requested_lock_row = requested_lock_row;
	ut_ad(requested_lock_row == NULL
	      || i_s_locks_row_validate(requested_lock_row));

	if (trx->wait_lock != NULL) {
		ut_a(requested_lock_row != NULL);
		row->trx_wait_started = (ib_time_t) trx->wait_started;
	} else {
		ut_a(requested_lock_row == NULL);
		row->trx_wait_started = 0;
	}

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

	if (trx->mysql_thd == NULL) {
		/* 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;
		row->trx_query = NULL;
		goto thd_done;
	}

	row->trx_mysql_thread_id = thd_get_thread_id(trx->mysql_thd);
	stmt = innobase_get_stmt(trx->mysql_thd, &stmt_len);

	if (stmt != NULL) {
		char	query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];

		if (stmt_len > TRX_I_S_TRX_QUERY_MAX_LEN) {
			stmt_len = TRX_I_S_TRX_QUERY_MAX_LEN;
		}

		memcpy(query, stmt, stmt_len);
		query[stmt_len] = '\0';

		row->trx_query = ha_storage_put_memlim(
			cache->storage, query, stmt_len + 1,
			MAX_ALLOWED_FOR_STORAGE(cache));

		row->trx_query_cs = innobase_get_charset(trx->mysql_thd);

		if (row->trx_query == NULL) {

			return(FALSE);
		}
	} else {

		row->trx_query = NULL;
	}

thd_done:
	s = trx->op_info;

	if (s != NULL && s[0] != '\0') {

		TRX_I_S_STRING_COPY(s, row->trx_operation_state,
				    TRX_I_S_TRX_OP_STATE_MAX_LEN, cache);

		if (row->trx_operation_state == NULL) {

			return(FALSE);
		}
	} else {

		row->trx_operation_state = NULL;
	}

	row->trx_tables_in_use = trx->n_mysql_tables_in_use;

	row->trx_tables_locked = trx->mysql_n_tables_locked;

	row->trx_lock_structs = UT_LIST_GET_LEN(trx->trx_locks);

	row->trx_lock_memory_bytes = mem_heap_get_size(trx->lock_heap);

	row->trx_rows_locked = lock_number_of_rows_locked(trx);

	row->trx_rows_modified = trx->undo_no;

	row->trx_concurrency_tickets = trx->n_tickets_to_enter_innodb;

	switch (trx->isolation_level) {
	case TRX_ISO_READ_UNCOMMITTED:
		row->trx_isolation_level = "READ UNCOMMITTED";
		break;
	case TRX_ISO_READ_COMMITTED:
		row->trx_isolation_level = "READ COMMITTED";
		break;
	case TRX_ISO_REPEATABLE_READ:
		row->trx_isolation_level = "REPEATABLE READ";
		break;
	case TRX_ISO_SERIALIZABLE:
		row->trx_isolation_level = "SERIALIZABLE";
		break;
	/* Should not happen as TRX_ISO_READ_COMMITTED is default */
	default:
		row->trx_isolation_level = "UNKNOWN";
	}

	row->trx_unique_checks = (ibool) trx->check_unique_secondary;

	row->trx_foreign_key_checks = (ibool) trx->check_foreigns;

	s = trx->detailed_error;

	if (s != NULL && s[0] != '\0') {

		TRX_I_S_STRING_COPY(s,
				    row->trx_foreign_key_error,
				    TRX_I_S_TRX_FK_ERROR_MAX_LEN, cache);

		if (row->trx_foreign_key_error == NULL) {

			return(FALSE);
		}
	} else {
		row->trx_foreign_key_error = NULL;
	}

	row->trx_has_search_latch = (ibool) trx->has_search_latch;

	row->trx_search_latch_timeout = trx->search_latch_timeout;

	return(TRUE);
}