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

📄 trx0rec.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
	first_free = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR							+ TRX_UNDO_PAGE_FREE);	memset(undo_page + first_free, 0xff,		(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END) - first_free);	mlog_write_initial_log_record(undo_page, MLOG_UNDO_ERASE_END, mtr);}	/***************************************************************Parses a redo log record of erasing of an undo page end. */byte*trx_undo_parse_erase_page_end(/*==========================*/			/* out: end of log record or NULL */	byte*	ptr,	/* in: buffer */	byte*	end_ptr __attribute__((unused)), /* in: buffer end */	page_t*	page,	/* in: page or NULL */	mtr_t*	mtr)	/* in: mtr or NULL */{	ut_ad(ptr && end_ptr);	if (page == NULL) {		return(ptr);	}	trx_undo_erase_page_end(page, mtr);	return(ptr);}/***************************************************************************Writes information to an undo log about an insert, update, or a delete markingof a clustered index record. This information is used in a rollback of thetransaction and in consistent reads that must look to the history of thistransaction. */ulinttrx_undo_report_row_operation(/*==========================*/					/* out: DB_SUCCESS or error code */	ulint		flags,		/* in: if BTR_NO_UNDO_LOG_FLAG bit is					set, does nothing */	ulint		op_type,	/* in: TRX_UNDO_INSERT_OP or					TRX_UNDO_MODIFY_OP */	que_thr_t*	thr,		/* in: query thread */	dict_index_t*	index,		/* in: clustered index */	dtuple_t*	clust_entry,	/* in: in the case of an insert,					index entry to insert into the					clustered index, otherwise NULL */	upd_t*		update,		/* in: in the case of an update,					the update vector, otherwise NULL */	ulint		cmpl_info,	/* in: compiler info on secondary					index updates */	rec_t*		rec,		/* in: in case of an update or delete					marking, the record in the clustered					index, otherwise NULL */	dulint*		roll_ptr)	/* out: rollback pointer to the					inserted undo log record,					ut_dulint_zero if BTR_NO_UNDO_LOG					flag was specified */{	trx_t*		trx;	trx_undo_t*	undo;	page_t*		undo_page;	ulint		offset;	ulint		page_no;	ibool		is_insert;	trx_rseg_t*	rseg;	mtr_t		mtr;	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	ulint*		offsets		= offsets_;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	ut_a(index->type & DICT_CLUSTERED);	if (flags & BTR_NO_UNDO_LOG_FLAG) {		*roll_ptr = ut_dulint_zero;		return(DB_SUCCESS);	}			ut_ad(thr);	ut_ad((op_type != TRX_UNDO_INSERT_OP)	      || (clust_entry && !update && !rec));		trx = thr_get_trx(thr);	rseg = trx->rseg;		mutex_enter(&(trx->undo_mutex));	/* If the undo log is not assigned yet, assign one */	if (op_type == TRX_UNDO_INSERT_OP) {		if (trx->insert_undo == NULL) {			trx_undo_assign_undo(trx, TRX_UNDO_INSERT);		}		undo = trx->insert_undo;		is_insert = TRUE;	} else {		ut_ad(op_type == TRX_UNDO_MODIFY_OP);		if (trx->update_undo == NULL) {			trx_undo_assign_undo(trx, TRX_UNDO_UPDATE);		}		undo = trx->update_undo;		is_insert = FALSE;	}	if (undo == NULL) {		/* Did not succeed: out of space */		mutex_exit(&(trx->undo_mutex));		return(DB_OUT_OF_FILE_SPACE);	}	page_no = undo->last_page_no;		mtr_start(&mtr);	for (;;) {		undo_page = buf_page_get_gen(undo->space, page_no,						RW_X_LATCH, undo->guess_page,						BUF_GET,						__FILE__, __LINE__,						&mtr);#ifdef UNIV_SYNC_DEBUG		buf_page_dbg_add_level(undo_page, SYNC_TRX_UNDO_PAGE);#endif /* UNIV_SYNC_DEBUG */		if (op_type == TRX_UNDO_INSERT_OP) {			offset = trx_undo_page_report_insert(undo_page, trx,							index, clust_entry,							&mtr);		} else {			offsets = rec_get_offsets(rec, index, offsets,						ULINT_UNDEFINED, &heap);			offset = trx_undo_page_report_modify(undo_page, trx,				index, rec, offsets, update, cmpl_info, &mtr);		}		if (offset == 0) {			/* The record did not fit on the page. We erase the			end segment of the undo log page and write a log			record of it: this is to ensure that in the debug			version the replicate page constructed using the log			records stays identical to the original page */			trx_undo_erase_page_end(undo_page, &mtr);		}				mtr_commit(&mtr);		if (offset != 0) {			/* Success */			break;		}		ut_ad(page_no == undo->last_page_no);				/* We have to extend the undo log by one page */		mtr_start(&mtr);		/* When we add a page to an undo log, this is analogous to		a pessimistic insert in a B-tree, and we must reserve the		counterpart of the tree latch, which is the rseg mutex. */		mutex_enter(&(rseg->mutex));				page_no = trx_undo_add_page(trx, undo, &mtr);		mutex_exit(&(rseg->mutex));				if (page_no == FIL_NULL) {			/* Did not succeed: out of space */			mutex_exit(&(trx->undo_mutex));			mtr_commit(&mtr);			if (UNIV_LIKELY_NULL(heap)) {				mem_heap_free(heap);			}			return(DB_OUT_OF_FILE_SPACE);		}	}	undo->empty = FALSE;	undo->top_page_no = page_no;	undo->top_offset  = offset;	undo->top_undo_no = trx->undo_no;	undo->guess_page = undo_page;	UT_DULINT_INC(trx->undo_no);		mutex_exit(&(trx->undo_mutex));	*roll_ptr = trx_undo_build_roll_ptr(is_insert, rseg->id, page_no,								offset);	if (UNIV_LIKELY_NULL(heap)) {		mem_heap_free(heap);	}	return(DB_SUCCESS);}/*============== BUILDING PREVIOUS VERSION OF A RECORD ===============*//**********************************************************************Copies an undo record to heap. This function can be called if we know thatthe undo log record exists. */trx_undo_rec_t*trx_undo_get_undo_rec_low(/*======================*/					/* out, own: copy of the record */	dulint		roll_ptr,	/* in: roll pointer to record */	mem_heap_t*	heap)		/* in: memory heap where copied */{	trx_undo_rec_t*	undo_rec;	ulint		rseg_id;	ulint		page_no;	ulint		offset;	page_t*		undo_page;	trx_rseg_t*	rseg;	ibool		is_insert;	mtr_t		mtr;		trx_undo_decode_roll_ptr(roll_ptr, &is_insert, &rseg_id, &page_no,								&offset);	rseg = trx_rseg_get_on_id(rseg_id);	mtr_start(&mtr);		undo_page = trx_undo_page_get_s_latched(rseg->space, page_no, &mtr);		undo_rec = trx_undo_rec_copy(undo_page + offset, heap);	mtr_commit(&mtr);	return(undo_rec);}/**********************************************************************Copies an undo record to heap. */ulinttrx_undo_get_undo_rec(/*==================*/					/* out: DB_SUCCESS, or					DB_MISSING_HISTORY if the undo log					has been truncated and we cannot					fetch the old version; NOTE: the					caller must have latches on the					clustered index page and purge_view */	dulint		roll_ptr,	/* in: roll pointer to record */	dulint		trx_id,		/* in: id of the trx that generated					the roll pointer: it points to an					undo log of this transaction */	trx_undo_rec_t** undo_rec,	/* out, own: copy of the record */	mem_heap_t*	heap)		/* in: memory heap where copied */{#ifdef UNIV_SYNC_DEBUG	ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));#endif /* UNIV_SYNC_DEBUG */	if (!trx_purge_update_undo_must_exist(trx_id)) {	    	/* It may be that the necessary undo log has already been		deleted */		return(DB_MISSING_HISTORY);	}	*undo_rec = trx_undo_get_undo_rec_low(roll_ptr, heap);		return(DB_SUCCESS);}/***********************************************************************Build a previous version of a clustered index record. This function checksthat the caller has a latch on the index page of the clustered index recordand an s-latch on the purge_view. This guarantees that the stack of versionsis locked. */ulinttrx_undo_prev_version_build(/*========================*/				/* out: DB_SUCCESS, or DB_MISSING_HISTORY if				the previous version is not >= purge_view,				which means that it may have been removed,				DB_ERROR if corrupted record */	rec_t*		index_rec,/* in: clustered index record in the				index tree */	mtr_t*		index_mtr __attribute__((unused)),                                /* in: mtr which contains the latch to				index_rec page and purge_view */	rec_t*		rec,	/* in: version of a clustered index record */	dict_index_t*	index,	/* in: clustered index */	ulint*		offsets,/* in: rec_get_offsets(rec, index) */	mem_heap_t*	heap,	/* in: memory heap from which the memory				needed is allocated */	rec_t**		old_vers)/* out, own: previous version, or NULL if				rec is the first inserted version, or if				history data has been deleted */{	trx_undo_rec_t*	undo_rec;	dtuple_t*	entry;	dulint		rec_trx_id;	ulint		type;	dulint		undo_no;	dulint		table_id;	dulint		trx_id;	dulint		roll_ptr;	dulint		old_roll_ptr;	upd_t*		update;	byte*		ptr;	ulint		info_bits;	ulint		cmpl_info;	ibool		dummy_extern;	byte*		buf;	ulint		err;#ifdef UNIV_SYNC_DEBUG	ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));#endif /* UNIV_SYNC_DEBUG */	ut_ad(mtr_memo_contains(index_mtr, buf_block_align(index_rec), 						MTR_MEMO_PAGE_S_FIX) ||	      mtr_memo_contains(index_mtr, buf_block_align(index_rec), 						MTR_MEMO_PAGE_X_FIX));	ut_ad(rec_offs_validate(rec, index, offsets));	if (!(index->type & DICT_CLUSTERED)) {		fprintf(stderr, "InnoDB: Error: trying to access"			" update undo rec for non-clustered index %s\n"			"InnoDB: Submit a detailed bug report to"			" http://bugs.mysql.com\n"			"InnoDB: index record ", index->name);		rec_print(stderr, index_rec, index);		fputs("\n"			"InnoDB: record version ", stderr);		rec_print_new(stderr, rec, offsets);		putc('\n', stderr);   		return(DB_ERROR);   	}		roll_ptr = row_get_rec_roll_ptr(rec, index, offsets);	old_roll_ptr = roll_ptr;		*old_vers = NULL;	if (trx_undo_roll_ptr_is_insert(roll_ptr)) {		/* The record rec is the first inserted version */		return(DB_SUCCESS);	} 	rec_trx_id = row_get_rec_trx_id(rec, index, offsets);		err = trx_undo_get_undo_rec(roll_ptr, rec_trx_id, &undo_rec, heap);	if (err != DB_SUCCESS) {		return(err);	}	ptr = trx_undo_rec_get_pars(undo_rec, &type, &cmpl_info,					&dummy_extern, &undo_no, &table_id);	ptr = trx_undo_update_rec_get_sys_cols(ptr, &trx_id, &roll_ptr,								&info_bits);	ptr = trx_undo_rec_skip_row_ref(ptr, index);	ptr = trx_undo_update_rec_get_update(ptr, index, type, trx_id,				roll_ptr, info_bits, NULL, heap, &update);	if (ut_dulint_cmp(table_id, index->table->id) != 0) {		ptr = NULL;		fprintf(stderr,"InnoDB: Error: trying to access update undo rec for table %s\n""InnoDB: but the table id in the undo record is wrong\n""InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n""InnoDB: Run also CHECK TABLE %s\n",			index->table_name, index->table_name);	}	if (ptr == NULL) {		/* The record was corrupted, return an error; these printfs		should catch an elusive bug in row_vers_old_has_index_entry */		fprintf(stderr,		"InnoDB: table %s, index %s, n_uniq %lu\n"		"InnoDB: undo rec address %p, type %lu cmpl_info %lu\n"		"InnoDB: undo rec table id %lu %lu, index table id %lu %lu\n"		"InnoDB: dump of 150 bytes in undo rec: ",			index->table_name, index->name,			(ulong) dict_index_get_n_unique(index),			undo_rec, (ulong) type, (ulong) cmpl_info,			(ulong) ut_dulint_get_high(table_id),			(ulong) ut_dulint_get_low(table_id),			(ulong) ut_dulint_get_high(index->table->id),			(ulong) ut_dulint_get_low(index->table->id));		ut_print_buf(stderr, undo_rec, 150);		fputs("\n"			"InnoDB: index record ", stderr);		rec_print(stderr, index_rec, index);		fputs("\n"			"InnoDB: record version ", stderr);		rec_print_new(stderr, rec, offsets);		fprintf(stderr, "\n"	"InnoDB: Record trx id %lu %lu, update rec trx id %lu %lu\n"	"InnoDB: Roll ptr in rec %lu %lu, in update rec %lu %lu\n",		 	(ulong) ut_dulint_get_high(rec_trx_id),		 	(ulong) ut_dulint_get_low(rec_trx_id),		 	(ulong) ut_dulint_get_high(trx_id),		 	(ulong) ut_dulint_get_low(trx_id),		 	(ulong) ut_dulint_get_high(old_roll_ptr),		 	(ulong) ut_dulint_get_low(old_roll_ptr),		 	(ulong) ut_dulint_get_high(roll_ptr),		 	(ulong) ut_dulint_get_low(roll_ptr));		 		trx_purge_sys_print();		return(DB_ERROR);	}	if (row_upd_changes_field_size_or_external(index, offsets, update)) {		ulint*	ext_vect;		ulint	n_ext_vect;		/* We have to set the appropriate extern storage bits in the		old version of the record: the extern bits in rec for those		fields that update does NOT update, as well as the the bits for		those fields that update updates to become externally stored		fields. Store the info to ext_vect: */		ext_vect = mem_alloc(sizeof(ulint)				* rec_offs_n_fields(offsets));		n_ext_vect = btr_push_update_extern_fields(ext_vect, offsets,								update);		entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec,								     heap);		row_upd_index_replace_new_col_vals(entry, index, update, heap);		buf = mem_heap_alloc(heap,					rec_get_converted_size(index, entry));		*old_vers = rec_convert_dtuple_to_rec(buf, index, entry);		/* Now set the extern bits in the old version of the record */		rec_set_field_extern_bits(*old_vers, index,						ext_vect, n_ext_vect, NULL);		mem_free(ext_vect);	} else {		buf = mem_heap_alloc(heap, rec_offs_size(offsets));		*old_vers = rec_copy(buf, rec, offsets);		rec_offs_make_valid(*old_vers, index, offsets);		row_upd_rec_in_place(*old_vers, offsets, update);	}	return(DB_SUCCESS);}

⌨️ 快捷键说明

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