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

📄 trx0undo.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
				header page */	mtr_t*		mtr)	/* in: mtr which does not have a latch to any				undo log page; the caller must have reserved				the rollback segment mutex */{	ulint	last_page_no;	ut_ad(undo->hdr_page_no != page_no);#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(trx->undo_mutex)));#endif /* UNIV_SYNC_DEBUG */	last_page_no = trx_undo_free_page(undo->rseg, FALSE, undo->space,					undo->hdr_page_no, page_no, mtr);		undo->last_page_no = last_page_no;	undo->size--;}/************************************************************************Empties an undo log header page of undo records for that undo log. Otherundo logs may still have records on that page, if it is an update undo log. */staticvoidtrx_undo_empty_header_page(/*=======================*/	ulint	space,		/* in: space */	ulint	hdr_page_no,	/* in: header page number */	ulint	hdr_offset,	/* in: header offset */	mtr_t*	mtr)		/* in: mtr */{	page_t*		header_page;	trx_ulogf_t*	log_hdr;	ulint		end;		header_page = trx_undo_page_get(space, hdr_page_no, mtr);	log_hdr = header_page + hdr_offset;	end = trx_undo_page_get_end(header_page, hdr_page_no, hdr_offset);	mlog_write_ulint(log_hdr + TRX_UNDO_LOG_START, end, MLOG_2BYTES, mtr);}/***************************************************************************Truncates an undo log from the end. This function is used during a rollbackto free space from an undo log. */voidtrx_undo_truncate_end(/*==================*/	trx_t*		trx,	/* in: transaction whose undo log it is */	trx_undo_t*	undo,	/* in: undo log */	dulint		limit)	/* in: all undo records with undo number				>= this value should be truncated */{	page_t*		undo_page;	ulint		last_page_no;	trx_undo_rec_t* rec;	trx_undo_rec_t* trunc_here;	trx_rseg_t*	rseg;	mtr_t		mtr;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(trx->undo_mutex)));	ut_ad(mutex_own(&(trx->rseg->mutex)));#endif /* UNIV_SYNC_DEBUG */	rseg = trx->rseg;		 	for (;;) {		mtr_start(&mtr);		trunc_here = NULL;			last_page_no = undo->last_page_no;		undo_page = trx_undo_page_get(undo->space, last_page_no, &mtr);		rec = trx_undo_page_get_last_rec(undo_page, undo->hdr_page_no,							undo->hdr_offset);		for (;;) {			if (rec == NULL) {				if (last_page_no == undo->hdr_page_no) {					goto function_exit;				}								trx_undo_free_page_in_rollback(trx, undo,							last_page_no, &mtr);				break;			}			if (ut_dulint_cmp(trx_undo_rec_get_undo_no(rec), limit)			    >= 0) {			    	/* Truncate at least this record off, maybe			    	more */			    	trunc_here = rec;			} else {				goto function_exit;			}			rec = trx_undo_page_get_prev_rec(rec,							undo->hdr_page_no,							undo->hdr_offset);		}		mtr_commit(&mtr);	}function_exit:	if (trunc_here) {		mlog_write_ulint(undo_page + TRX_UNDO_PAGE_HDR							+ TRX_UNDO_PAGE_FREE,				trunc_here - undo_page, MLOG_2BYTES, &mtr);	}	mtr_commit(&mtr);}/***************************************************************************Truncates an undo log from the start. This function is used during a purgeoperation. */voidtrx_undo_truncate_start(/*====================*/	trx_rseg_t* rseg,	/* in: rollback segment */	ulint	space,		/* in: space id of the log */	ulint	hdr_page_no,	/* in: header page number */	ulint	hdr_offset,	/* in: header offset on the page */	dulint	limit)		/* in: all undo pages with undo numbers <				this value should be truncated; NOTE that				the function only frees whole pages; the				header page is not freed, but emptied, if				all the records there are < limit */{	page_t* 	undo_page;	trx_undo_rec_t* rec;	trx_undo_rec_t* last_rec;	ulint		page_no;	mtr_t		mtr;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(rseg->mutex)));#endif /* UNIV_SYNC_DEBUG */	if (0 == ut_dulint_cmp(limit, ut_dulint_zero)) {		return;	}loop:	mtr_start(&mtr);	rec = trx_undo_get_first_rec(space, hdr_page_no, hdr_offset,							RW_X_LATCH, &mtr);	if (rec == NULL) {		/* Already empty */		mtr_commit(&mtr);		return;	}	undo_page = buf_frame_align(rec);	last_rec = trx_undo_page_get_last_rec(undo_page, hdr_page_no,								hdr_offset);	if (ut_dulint_cmp(trx_undo_rec_get_undo_no(last_rec), limit) >= 0) {		mtr_commit(&mtr);		return;	}	page_no = buf_frame_get_page_no(undo_page);	if (page_no == hdr_page_no) {		trx_undo_empty_header_page(space, hdr_page_no, hdr_offset,									&mtr);	} else {		trx_undo_free_page(rseg, TRUE, space, hdr_page_no,								page_no, &mtr);	}	mtr_commit(&mtr);	goto loop;}/**************************************************************************Frees an undo log segment which is not in the history list. */staticvoidtrx_undo_seg_free(/*==============*/	trx_undo_t*	undo)	/* in: undo log */{	trx_rseg_t*	rseg;	fseg_header_t*	file_seg;	trx_rsegf_t*	rseg_header;	trx_usegf_t*	seg_header;	ibool		finished;	mtr_t		mtr;		finished = FALSE;		rseg = undo->rseg;	while (!finished) {		mtr_start(&mtr);#ifdef UNIV_SYNC_DEBUG		ut_ad(!mutex_own(&kernel_mutex));#endif /* UNIV_SYNC_DEBUG */		mutex_enter(&(rseg->mutex));		seg_header = trx_undo_page_get(undo->space, undo->hdr_page_no,									&mtr)			     + TRX_UNDO_SEG_HDR;		file_seg = seg_header + TRX_UNDO_FSEG_HEADER;		finished = fseg_free_step(file_seg, &mtr);		if (finished) {			/* Update the rseg header */			rseg_header = trx_rsegf_get(rseg->space, rseg->page_no,									&mtr);			trx_rsegf_set_nth_undo(rseg_header, undo->id, FIL_NULL,									&mtr);		}		mutex_exit(&(rseg->mutex));		mtr_commit(&mtr);	}}/*========== UNDO LOG MEMORY COPY INITIALIZATION =====================*//************************************************************************Creates and initializes an undo log memory object according to the valuesin the header in file, when the database is started. The memory object isinserted in the appropriate list of rseg. */statictrx_undo_t*trx_undo_mem_create_at_db_start(/*============================*/				/* out, own: the undo log memory object */	trx_rseg_t*	rseg,	/* in: rollback segment memory object */		ulint		id,	/* in: slot index within rseg */	ulint		page_no,/* in: undo log segment page number */	mtr_t*		mtr)	/* in: mtr */{	page_t*		undo_page;	trx_upagef_t*	page_header;	trx_usegf_t*	seg_header;	trx_ulogf_t*	undo_header;	trx_undo_t*	undo;	ulint		type;	ulint		state;	dulint		trx_id;	ulint		offset;	fil_addr_t	last_addr;	page_t*		last_page;	trx_undo_rec_t*	rec;	XID		xid;	ibool		xid_exists = FALSE;	if (id >= TRX_RSEG_N_SLOTS) {		fprintf(stderr,		"InnoDB: Error: undo->id is %lu\n", (ulong) id);		ut_error;	}	undo_page = trx_undo_page_get(rseg->space, page_no, mtr);	page_header = undo_page + TRX_UNDO_PAGE_HDR;	type = mtr_read_ulint(page_header + TRX_UNDO_PAGE_TYPE, MLOG_2BYTES,									mtr);	seg_header = undo_page + TRX_UNDO_SEG_HDR;	state = mach_read_from_2(seg_header + TRX_UNDO_STATE); 	offset = mach_read_from_2(seg_header + TRX_UNDO_LAST_LOG);		undo_header = undo_page + offset;	trx_id = mtr_read_dulint(undo_header + TRX_UNDO_TRX_ID, mtr);	xid_exists = mtr_read_ulint(undo_header + TRX_UNDO_XID_EXISTS, 						MLOG_1BYTE, mtr);	/* Read X/Open XA transaction identification if it exists, or	set it to NULL. */	memset(&xid, 0, sizeof(xid));	xid.formatID = -1;	if (xid_exists == TRUE) {		trx_undo_read_xid(undo_header, &xid);	} 	mutex_enter(&(rseg->mutex));	undo = trx_undo_mem_create(rseg, id, type, trx_id, &xid, 						page_no, offset);	mutex_exit(&(rseg->mutex));	undo->dict_operation = 	mtr_read_ulint(					undo_header + TRX_UNDO_DICT_TRANS,					MLOG_1BYTE, mtr);	undo->table_id = mtr_read_dulint(undo_header + TRX_UNDO_TABLE_ID, mtr);	undo->state = state;	undo->size = flst_get_len(seg_header + TRX_UNDO_PAGE_LIST, mtr);	/* If the log segment is being freed, the page list is inconsistent! */	if (state == TRX_UNDO_TO_FREE) {		goto add_to_list;	}	last_addr = flst_get_last(seg_header + TRX_UNDO_PAGE_LIST, mtr);	undo->last_page_no = last_addr.page;	undo->top_page_no = last_addr.page;	last_page = trx_undo_page_get(rseg->space, undo->last_page_no, mtr);	rec = trx_undo_page_get_last_rec(last_page, page_no, offset);	if (rec == NULL) {		undo->empty = TRUE;	} else {		undo->empty = FALSE;		undo->top_offset = rec - last_page;		undo->top_undo_no = trx_undo_rec_get_undo_no(rec);	}add_to_list:		if (type == TRX_UNDO_INSERT) {		if (state != TRX_UNDO_CACHED) {			UT_LIST_ADD_LAST(undo_list, rseg->insert_undo_list,									undo);		} else {			UT_LIST_ADD_LAST(undo_list, rseg->insert_undo_cached,									undo);		}	} else {		ut_ad(type == TRX_UNDO_UPDATE);		if (state != TRX_UNDO_CACHED) {			UT_LIST_ADD_LAST(undo_list, rseg->update_undo_list,									undo);		} else {			UT_LIST_ADD_LAST(undo_list, rseg->update_undo_cached,									undo);		}	}	return(undo);}/************************************************************************Initializes the undo log lists for a rollback segment memory copy. Thisfunction is only called when the database is started or a new rollbacksegment is created. */ulinttrx_undo_lists_init(/*================*/				/* out: the combined size of undo log segments				in pages */	trx_rseg_t*	rseg)	/* in: rollback segment memory object */	{	ulint		page_no;	trx_undo_t*	undo;	ulint		size	= 0;	trx_rsegf_t*	rseg_header;	ulint		i;	mtr_t		mtr;		UT_LIST_INIT(rseg->update_undo_list);	UT_LIST_INIT(rseg->update_undo_cached);	UT_LIST_INIT(rseg->insert_undo_list);	UT_LIST_INIT(rseg->insert_undo_cached);	mtr_start(&mtr);		rseg_header = trx_rsegf_get_new(rseg->space, rseg->page_no, &mtr);		for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {		page_no = trx_rsegf_get_nth_undo(rseg_header, i, &mtr);		/* In forced recovery: try to avoid operations which look		at database pages; undo logs are rapidly changing data, and		the probability that they are in an inconsistent state is		high */		if (page_no != FIL_NULL		    && srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {			undo = trx_undo_mem_create_at_db_start(rseg, i,								page_no, &mtr);			size += undo->size;			mtr_commit(&mtr);			mtr_start(&mtr);			rseg_header = trx_rsegf_get(rseg->space,							rseg->page_no, &mtr);		}	}	mtr_commit(&mtr);	return(size);}		/************************************************************************Creates and initializes an undo log memory object. */statictrx_undo_t*trx_undo_mem_create(/*================*/				/* out, own: the undo log memory object */	trx_rseg_t*	rseg,	/* in: rollback segment memory object */	ulint		id,	/* in: slot index within rseg */	ulint		type,	/* in: type of the log: TRX_UNDO_INSERT or				TRX_UNDO_UPDATE */	dulint		trx_id,	/* in: id of the trx for which the undo log				is created */	XID*		xid,	/* in: X/Open transaction identification */	ulint		page_no,/* in: undo log header page number */	ulint		offset)	/* in: undo log header byte offset on page */{	trx_undo_t*	undo;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(rseg->mutex)));#endif /* UNIV_SYNC_DEBUG */	if (id >= TRX_RSEG_N_SLOTS) {		fprintf(stderr,		"InnoDB: Error: undo->id is %lu\n", (ulong) id);		ut_error;	}	undo = mem_alloc(sizeof(trx_undo_t));	undo->id = id;	undo->type = type;	undo->state = TRX_UNDO_ACTIVE;	undo->del_marks = FALSE;	undo->trx_id = trx_id;	undo->xid = *xid;	undo->dict_operation = FALSE;	undo->rseg = rseg;	undo->space = rseg->space;	undo->hdr_page_no = page_no;	undo->hdr_offset = offset;	undo->last_page_no = page_no;	undo->size = 1;	undo->empty = TRUE;	undo->top_page_no = page_no;	undo->guess_page = NULL;		return(undo);}/************************************************************************Initializes a cached undo log object for new use. */

⌨️ 快捷键说明

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