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

📄 trx0roll.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
		mutex_exit(&kernel_mutex);	if (trx == NULL) {		ut_print_timestamp(stderr);		fprintf(stderr,		"  InnoDB: Rollback of non-prepared transactions completed\n"); 		mem_heap_free(heap);		goto leave_function;	}	trx->sess = trx_dummy_sess;	if (trx->conc_state == TRX_COMMITTED_IN_MEMORY) {			fprintf(stderr, "InnoDB: Cleaning up trx with id %lu %lu\n",					(ulong) ut_dulint_get_high(trx->id),					(ulong) ut_dulint_get_low(trx->id));		trx_cleanup_at_db_startup(trx);							mem_heap_free(heap);		goto loop;	}	fork = que_fork_create(NULL, NULL, QUE_FORK_RECOVERY, heap);	fork->trx = trx;	thr = que_thr_create(fork, heap);	roll_node = roll_node_create(heap);	thr->child = roll_node;	roll_node->common.parent = thr;	mutex_enter(&kernel_mutex);		trx->graph = fork;	ut_a(thr == que_fork_start_command(fork));		trx_roll_crash_recv_trx	= trx;	trx_roll_max_undo_no = ut_conv_dulint_to_longlong(trx->undo_no);	trx_roll_progress_printed_pct = 0;	rows_to_undo = trx_roll_max_undo_no;	if (rows_to_undo > 1000000000) {		rows_to_undo = rows_to_undo / 1000000;		unit = "M";	}	ut_print_timestamp(stderr);	fprintf(stderr,"  InnoDB: Rolling back trx with id %lu %lu, %lu%s rows to undo\n",					(ulong) ut_dulint_get_high(trx->id),					(ulong) ut_dulint_get_low(trx->id),					(ulong) rows_to_undo, unit);	mutex_exit(&kernel_mutex);	trx->mysql_thread_id = os_thread_get_curr_id();	trx->mysql_process_no = os_proc_get_number();	if (trx->dict_operation) {		row_mysql_lock_data_dictionary(trx);	}	que_run_threads(thr);	mutex_enter(&kernel_mutex);	while (trx->que_state != TRX_QUE_RUNNING) {		mutex_exit(&kernel_mutex);		fprintf(stderr,		"InnoDB: Waiting for rollback of trx id %lu to end\n",					(ulong) ut_dulint_get_low(trx->id));		os_thread_sleep(100000);		mutex_enter(&kernel_mutex);	}	mutex_exit(&kernel_mutex);	if (trx->dict_operation) {		/* If the transaction was for a dictionary operation, we		drop the relevant table, if it still exists */		fprintf(stderr,"InnoDB: Dropping table with id %lu %lu in recovery if it exists\n",			(ulong) ut_dulint_get_high(trx->table_id),			(ulong) ut_dulint_get_low(trx->table_id));		table = dict_table_get_on_id_low(trx->table_id, trx);		if (table) {					fputs("InnoDB: Table found: dropping table ", stderr);			ut_print_name(stderr, trx, table->name);			fputs(" in recovery\n", stderr);			err = row_drop_table_for_mysql(table->name, trx, TRUE);			ut_a(err == (int) DB_SUCCESS);		}	}	if (trx->dict_operation) {		row_mysql_unlock_data_dictionary(trx);	}	fprintf(stderr, "\nInnoDB: Rolling back of trx id %lu %lu completed\n",					(ulong) ut_dulint_get_high(trx->id),					(ulong) ut_dulint_get_low(trx->id));	mem_heap_free(heap);	trx_roll_crash_recv_trx	= NULL;	goto loop;leave_function:	/* We count the number of threads in os_thread_exit(). A created	thread should always use that to exit and not use return() to exit. */	os_thread_exit(NULL);	/* The following is dummy code to keep the compiler happy: */#ifndef __WIN__        return(NULL);#else        return(0);#endif}	/***********************************************************************Creates an undo number array. */trx_undo_arr_t*trx_undo_arr_create(void)/*=====================*/{	trx_undo_arr_t*	arr;	mem_heap_t*	heap;	ulint		i;		heap = mem_heap_create(1024);	arr = mem_heap_alloc(heap, sizeof(trx_undo_arr_t));	arr->infos = mem_heap_alloc(heap, sizeof(trx_undo_inf_t)						* UNIV_MAX_PARALLELISM);	arr->n_cells = UNIV_MAX_PARALLELISM;	arr->n_used = 0;	arr->heap = heap;	for (i = 0; i < UNIV_MAX_PARALLELISM; i++) {		(trx_undo_arr_get_nth_info(arr, i))->in_use = FALSE;	}	return(arr);}/***********************************************************************Frees an undo number array. */voidtrx_undo_arr_free(/*==============*/	trx_undo_arr_t*	arr)	/* in: undo number array */{	ut_ad(arr->n_used == 0);	mem_heap_free(arr->heap);}/***********************************************************************Stores info of an undo log record to the array if it is not stored yet. */staticibooltrx_undo_arr_store_info(/*====================*/			/* out: FALSE if the record already existed in the			array */	trx_t*	trx,	/* in: transaction */	dulint	undo_no)/* in: undo number */{	trx_undo_inf_t*	cell;	trx_undo_inf_t*	stored_here;	trx_undo_arr_t*	arr;	ulint		n_used;	ulint		n;	ulint		i;	n = 0;	arr = trx->undo_no_arr;	n_used = arr->n_used;	stored_here = NULL;		for (i = 0;; i++) {		cell = trx_undo_arr_get_nth_info(arr, i);		if (!cell->in_use) {			if (!stored_here) {				/* Not in use, we may store here */				cell->undo_no = undo_no;				cell->in_use = TRUE;				arr->n_used++;				stored_here = cell;			}		} else {			n++;			if (0 == ut_dulint_cmp(cell->undo_no, undo_no)) {				if (stored_here) {					stored_here->in_use = FALSE;					ut_ad(arr->n_used > 0);					arr->n_used--;				}				ut_ad(arr->n_used == n_used);				return(FALSE);			}		}				if (n == n_used && stored_here) {			ut_ad(arr->n_used == 1 + n_used);			return(TRUE);		}	}}/***********************************************************************Removes an undo number from the array. */staticvoidtrx_undo_arr_remove_info(/*=====================*/	trx_undo_arr_t*	arr,	/* in: undo number array */	dulint		undo_no)/* in: undo number */{	trx_undo_inf_t*	cell;	ulint		n_used;	ulint		n;	ulint		i;	n_used = arr->n_used;	n = 0;	for (i = 0;; i++) {		cell = trx_undo_arr_get_nth_info(arr, i);		if (cell->in_use			     && 0 == ut_dulint_cmp(cell->undo_no, undo_no)) {			cell->in_use = FALSE;							ut_ad(arr->n_used > 0);			arr->n_used--;			return;		}	}}/***********************************************************************Gets the biggest undo number in an array. */staticdulinttrx_undo_arr_get_biggest(/*=====================*/				/* out: biggest value, ut_dulint_zero if				the array is empty */	trx_undo_arr_t*	arr)	/* in: undo number array */{	trx_undo_inf_t*	cell;	ulint		n_used;	dulint		biggest;	ulint		n;	ulint		i;		n = 0;	n_used = arr->n_used;	biggest = ut_dulint_zero;		for (i = 0;; i++) {		cell = trx_undo_arr_get_nth_info(arr, i);		if (cell->in_use) {			n++;			if (ut_dulint_cmp(cell->undo_no, biggest) > 0) {				biggest = cell->undo_no;			}		}				if (n == n_used) {			return(biggest);		}	}}/***************************************************************************Tries truncate the undo logs. */voidtrx_roll_try_truncate(/*==================*/	trx_t*	trx)	/* in: transaction */{	trx_undo_arr_t*	arr;	dulint		limit;	dulint		biggest;	#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(trx->undo_mutex)));	ut_ad(mutex_own(&((trx->rseg)->mutex)));#endif /* UNIV_SYNC_DEBUG */	trx->pages_undone = 0;		arr = trx->undo_no_arr;	limit = trx->undo_no;	if (arr->n_used > 0) {		biggest = trx_undo_arr_get_biggest(arr);	    	if (ut_dulint_cmp(biggest, limit) >= 0) {	    		limit = ut_dulint_add(biggest, 1);	    	}	}	if (trx->insert_undo) {		trx_undo_truncate_end(trx, trx->insert_undo, limit);	}	if (trx->update_undo) {		trx_undo_truncate_end(trx, trx->update_undo, limit);	}}/***************************************************************************Pops the topmost undo log record in a single undo log and updates the infoabout the topmost record in the undo log memory struct. */statictrx_undo_rec_t*trx_roll_pop_top_rec(/*=================*/				/* out: undo log record, the page s-latched */	trx_t*		trx,	/* in: transaction */	trx_undo_t*	undo,	/* in: undo log */	mtr_t*		mtr)	/* in: mtr */{	page_t* 	undo_page;	ulint		offset;	trx_undo_rec_t*	prev_rec;	page_t*		prev_rec_page;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(trx->undo_mutex)));#endif /* UNIV_SYNC_DEBUG */	undo_page = trx_undo_page_get_s_latched(undo->space,						undo->top_page_no, mtr);	offset = undo->top_offset;/*	fprintf(stderr, "Thread %lu undoing trx %lu undo record %lu\n",		os_thread_get_curr_id(), ut_dulint_get_low(trx->id),		ut_dulint_get_low(undo->top_undo_no)); */	prev_rec = trx_undo_get_prev_rec(undo_page + offset,					undo->hdr_page_no, undo->hdr_offset,									mtr);	if (prev_rec == NULL) {		undo->empty = TRUE;	} else {		prev_rec_page = buf_frame_align(prev_rec);			if (prev_rec_page != undo_page) {			trx->pages_undone++;		}			undo->top_page_no = buf_frame_get_page_no(prev_rec_page);		undo->top_offset  = prev_rec - prev_rec_page;		undo->top_undo_no = trx_undo_rec_get_undo_no(prev_rec);	}	return(undo_page + offset);}/************************************************************************Pops the topmost record when the two undo logs of a transaction are seenas a single stack of records ordered by their undo numbers. Inserts theundo number of the popped undo record to the array of currently processedundo numbers in the transaction. When the query thread finishes processingof this undo record, it must be released with trx_undo_rec_release. */trx_undo_rec_t*trx_roll_pop_top_rec_of_trx(/*========================*/				/* out: undo log record copied to heap, NULL				if none left, or if the undo number of the				top record would be less than the limit */	trx_t*		trx,	/* in: transaction */	dulint		limit,	/* in: least undo number we need */	dulint*		roll_ptr,/* out: roll pointer to undo record */	mem_heap_t*	heap)	/* in: memory heap where copied */{	trx_undo_t*	undo;	trx_undo_t*	ins_undo;	trx_undo_t*	upd_undo;	trx_undo_rec_t*	undo_rec;	trx_undo_rec_t*	undo_rec_copy;	dulint		undo_no;	ibool		is_insert;	trx_rseg_t*	rseg;	ulint		progress_pct;	mtr_t		mtr;		rseg = trx->rseg;try_again:	mutex_enter(&(trx->undo_mutex));	if (trx->pages_undone >= TRX_ROLL_TRUNC_THRESHOLD) {		mutex_enter(&(rseg->mutex));		trx_roll_try_truncate(trx);		mutex_exit(&(rseg->mutex));	}	ins_undo = trx->insert_undo;	upd_undo = trx->update_undo;

⌨️ 快捷键说明

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