⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trx0roll.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (!ins_undo || ins_undo->empty) {		undo = upd_undo;	} else if (!upd_undo || upd_undo->empty) {		undo = ins_undo;	} else if (ut_dulint_cmp(upd_undo->top_undo_no,				 ins_undo->top_undo_no) > 0) {		undo = upd_undo;	} else {		undo = ins_undo;	}	if (!undo || undo->empty			|| (ut_dulint_cmp(limit, undo->top_undo_no) > 0)) {	    	if ((trx->undo_no_arr)->n_used == 0) {			/* Rollback is ending */						mutex_enter(&(rseg->mutex));			trx_roll_try_truncate(trx);			mutex_exit(&(rseg->mutex));		}		mutex_exit(&(trx->undo_mutex));		return(NULL);	}	if (undo == ins_undo) {		is_insert = TRUE;	} else {		is_insert = FALSE;	}		*roll_ptr = trx_undo_build_roll_ptr(is_insert, (undo->rseg)->id,					undo->top_page_no, undo->top_offset);	mtr_start(&mtr);	undo_rec = trx_roll_pop_top_rec(trx, undo, &mtr);	undo_no = trx_undo_rec_get_undo_no(undo_rec);	ut_ad(ut_dulint_cmp(ut_dulint_add(undo_no, 1), trx->undo_no) == 0);	/* We print rollback progress info if we are in a crash recovery	and the transaction has at least 1000 row operations to undo. */	if (trx == trx_roll_crash_recv_trx && trx_roll_max_undo_no > 1000) {	  	progress_pct = 100 - (ulint)				((ut_conv_dulint_to_longlong(undo_no) * 100)				/ trx_roll_max_undo_no);		if (progress_pct != trx_roll_progress_printed_pct) {			if (trx_roll_progress_printed_pct == 0) {				fprintf(stderr,"\nInnoDB: Progress in percents: %lu", (ulong) progress_pct);			} else {				fprintf(stderr,				" %lu", (ulong) progress_pct);			}			fflush(stderr);			trx_roll_progress_printed_pct = progress_pct;		}	}	trx->undo_no = undo_no;	if (!trx_undo_arr_store_info(trx, undo_no)) {		/* A query thread is already processing this undo log record */		mutex_exit(&(trx->undo_mutex));		mtr_commit(&mtr);				goto try_again;	}	undo_rec_copy = trx_undo_rec_copy(undo_rec, heap);		mutex_exit(&(trx->undo_mutex));	mtr_commit(&mtr);		return(undo_rec_copy);}/************************************************************************Reserves an undo log record for a query thread to undo. This should becalled if the query thread gets the undo log record not using the popfunction above. */ibooltrx_undo_rec_reserve(/*=================*/			/* out: TRUE if succeeded */	trx_t*	trx,	/* in: transaction */	dulint	undo_no)/* in: undo number of the record */{	ibool	ret;		mutex_enter(&(trx->undo_mutex));	ret = trx_undo_arr_store_info(trx, undo_no);		mutex_exit(&(trx->undo_mutex));	return(ret);}/***********************************************************************Releases a reserved undo record. */voidtrx_undo_rec_release(/*=================*/	trx_t*	trx,	/* in: transaction */	dulint	undo_no)/* in: undo number */{	trx_undo_arr_t*	arr;		mutex_enter(&(trx->undo_mutex));	arr = trx->undo_no_arr;	trx_undo_arr_remove_info(arr, undo_no);	mutex_exit(&(trx->undo_mutex));}/*************************************************************************Starts a rollback operation. */	voidtrx_rollback(/*=========*/	trx_t*		trx,	/* in: transaction */	trx_sig_t*	sig,	/* in: signal starting the rollback */	que_thr_t**	next_thr)/* in/out: next query thread to run;				if the value which is passed in is				a pointer to a NULL pointer, then the				calling function can start running				a new query thread; if the passed value is				NULL, the parameter is ignored */{	que_t*		roll_graph;	que_thr_t*	thr;/*	que_thr_t*	thr2; */#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&kernel_mutex));#endif /* UNIV_SYNC_DEBUG */	ut_ad((trx->undo_no_arr == NULL) || ((trx->undo_no_arr)->n_used == 0));		/* Initialize the rollback field in the transaction */	if (sig->type == TRX_SIG_TOTAL_ROLLBACK) {		trx->roll_limit = ut_dulint_zero;	} else if (sig->type == TRX_SIG_ROLLBACK_TO_SAVEPT) {				trx->roll_limit = (sig->savept).least_undo_no;	} else if (sig->type == TRX_SIG_ERROR_OCCURRED) {		trx->roll_limit = trx->last_sql_stat_start.least_undo_no;	} else {		ut_error;	}	ut_a(ut_dulint_cmp(trx->roll_limit, trx->undo_no) <= 0);	trx->pages_undone = 0;	if (trx->undo_no_arr == NULL) {		trx->undo_no_arr = trx_undo_arr_create();	}		/* Build a 'query' graph which will perform the undo operations */	roll_graph = trx_roll_graph_build(trx);	trx->graph = roll_graph;	trx->que_state = TRX_QUE_ROLLING_BACK;	thr = que_fork_start_command(roll_graph);	ut_ad(thr);/*	thr2 = que_fork_start_command(roll_graph);	ut_ad(thr2); */		if (next_thr && (*next_thr == NULL)) {		*next_thr = thr;/*		srv_que_task_enqueue_low(thr2); */	} else {		srv_que_task_enqueue_low(thr);/*		srv_que_task_enqueue_low(thr2); */	}}/********************************************************************Builds an undo 'query' graph for a transaction. The actual rollback isperformed by executing this query graph like a query subprocedure call.The reply about the completion of the rollback will be sent by thisgraph. */que_t*trx_roll_graph_build(/*=================*/			/* out, own: the query graph */	trx_t*	trx)	/* in: trx handle */{	mem_heap_t*	heap;	que_fork_t*	fork;	que_thr_t*	thr;/*	que_thr_t*	thr2; */#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&kernel_mutex));#endif /* UNIV_SYNC_DEBUG */	heap = mem_heap_create(512);	fork = que_fork_create(NULL, NULL, QUE_FORK_ROLLBACK, heap);	fork->trx = trx;	thr = que_thr_create(fork, heap);/*	thr2 = que_thr_create(fork, heap); */	thr->child = row_undo_node_create(trx, thr, heap);  /*	thr2->child = row_undo_node_create(trx, thr2, heap); */	return(fork);}/*************************************************************************Finishes error processing after the necessary partial rollback has beendone. */staticvoidtrx_finish_error_processing(/*========================*/	trx_t*	trx)	/* in: transaction */{	trx_sig_t*	sig;	trx_sig_t*	next_sig;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&kernel_mutex));#endif /* UNIV_SYNC_DEBUG */	sig = UT_LIST_GET_FIRST(trx->signals);	while (sig != NULL) {		next_sig = UT_LIST_GET_NEXT(signals, sig);		if (sig->type == TRX_SIG_ERROR_OCCURRED) {			trx_sig_remove(trx, sig);		}		sig = next_sig;	}	trx->que_state = TRX_QUE_RUNNING;}/*************************************************************************Finishes a partial rollback operation. */staticvoidtrx_finish_partial_rollback_off_kernel(/*===================================*/	trx_t*		trx,	/* in: transaction */	que_thr_t**	next_thr)/* in/out: next query thread to run;				if the value which is passed in is a pointer				to a NULL pointer, then the calling function				can start running a new query thread; if this				parameter is NULL, it is ignored */{	trx_sig_t*	sig;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&kernel_mutex));#endif /* UNIV_SYNC_DEBUG */	sig = UT_LIST_GET_FIRST(trx->signals);	/* Remove the signal from the signal queue and send reply message	to it */	trx_sig_reply(sig, next_thr);	trx_sig_remove(trx, sig);	trx->que_state = TRX_QUE_RUNNING;}/********************************************************************Finishes a transaction rollback. */voidtrx_finish_rollback_off_kernel(/*===========================*/	que_t*		graph,	/* in: undo graph which can now be freed */	trx_t*		trx,	/* in: transaction */	que_thr_t**	next_thr)/* in/out: next query thread to run;				if the value which is passed in is				a pointer to a NULL pointer, then the   				calling function can start running				a new query thread; if this parameter is				NULL, it is ignored */{	trx_sig_t*	sig;	trx_sig_t*	next_sig;	#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&kernel_mutex));#endif /* UNIV_SYNC_DEBUG */	ut_a(trx->undo_no_arr == NULL || trx->undo_no_arr->n_used == 0);	/* Free the memory reserved by the undo graph */	que_graph_free(graph);	sig = UT_LIST_GET_FIRST(trx->signals);	if (sig->type == TRX_SIG_ROLLBACK_TO_SAVEPT) {		trx_finish_partial_rollback_off_kernel(trx, next_thr);		return;	} else if (sig->type == TRX_SIG_ERROR_OCCURRED) {		trx_finish_error_processing(trx);		return;	}#ifdef UNIV_DEBUG	if (lock_print_waits) {					fprintf(stderr, "Trx %lu rollback finished\n",						(ulong) ut_dulint_get_low(trx->id));	}#endif /* UNIV_DEBUG */	trx_commit_off_kernel(trx);	/* Remove all TRX_SIG_TOTAL_ROLLBACK signals from the signal queue and	send reply messages to them */	trx->que_state = TRX_QUE_RUNNING;		while (sig != NULL) {		next_sig = UT_LIST_GET_NEXT(signals, sig);		if (sig->type == TRX_SIG_TOTAL_ROLLBACK) {			trx_sig_reply(sig, next_thr);			trx_sig_remove(trx, sig);		}		sig = next_sig;	}}/*************************************************************************Creates a rollback command node struct. */roll_node_t*roll_node_create(/*=============*/				/* out, own: rollback node struct */	mem_heap_t*	heap)	/* in: mem heap where created */{	roll_node_t*	node;	node = mem_heap_alloc(heap, sizeof(roll_node_t));	node->common.type = QUE_NODE_ROLLBACK;	node->state = ROLL_NODE_SEND;	node->partial = FALSE;		return(node);}/***************************************************************Performs an execution step for a rollback command node in a query graph. */que_thr_t*trx_rollback_step(/*==============*/				/* out: query thread to run next, or NULL */	que_thr_t*	thr)	/* in: query thread */{	roll_node_t*	node;	ibool		success;	ulint		sig_no;	trx_savept_t*	savept;		node = thr->run_node;	ut_ad(que_node_get_type(node) == QUE_NODE_ROLLBACK);	if (thr->prev_node == que_node_get_parent(node)) {		node->state = ROLL_NODE_SEND;	}	if (node->state == ROLL_NODE_SEND) {		mutex_enter(&kernel_mutex);		node->state = ROLL_NODE_WAIT;		if (node->partial) {			sig_no = TRX_SIG_ROLLBACK_TO_SAVEPT;			savept = &(node->savept);		} else {			sig_no = TRX_SIG_TOTAL_ROLLBACK;			savept = NULL;		}		/* Send a rollback signal to the transaction */		success = trx_sig_send(thr_get_trx(thr),					sig_no, TRX_SIG_SELF,					thr, savept, NULL);		thr->state = QUE_THR_SIG_REPLY_WAIT;				mutex_exit(&kernel_mutex);		if (!success) {			/* Error in delivering the rollback signal */			que_thr_handle_error(thr, DB_ERROR, NULL, 0);		}		return(NULL);	}	ut_ad(node->state == ROLL_NODE_WAIT);			thr->run_node = que_node_get_parent(node);		return(thr);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -