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

📄 trx0rec.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************Transaction undo log record(c) 1996 Innobase OyCreated 3/26/1996 Heikki Tuuri*******************************************************/#include "trx0rec.h"#ifdef UNIV_NONINL#include "trx0rec.ic"#endif#include "fsp0fsp.h"#include "mach0data.h"#include "trx0rseg.h"#include "trx0trx.h"#include "trx0undo.h"#include "dict0dict.h"#include "ut0mem.h"#include "row0upd.h"#include "que0que.h"#include "trx0purge.h"#include "row0row.h"/*=========== UNDO LOG RECORD CREATION AND DECODING ====================*//**************************************************************************Writes the mtr log entry of the inserted undo log record on the undo logpage. */UNIV_INLINEvoidtrx_undof_page_add_undo_rec_log(/*============================*/	page_t* undo_page,	/* in: undo log page */	ulint	old_free,	/* in: start offset of the inserted entry */	ulint	new_free,	/* in: end offset of the entry */	mtr_t*	mtr)		/* in: mtr */{	byte*		log_ptr;	const byte*	log_end;	ulint		len;	log_ptr = mlog_open(mtr, 11 + 13 + MLOG_BUF_MARGIN);	if (log_ptr == NULL) {		return;	}	log_end = &log_ptr[11 + 13 + MLOG_BUF_MARGIN];	log_ptr = mlog_write_initial_log_record_fast(undo_page,					MLOG_UNDO_INSERT, log_ptr, mtr);	len = new_free - old_free - 4;	mach_write_to_2(log_ptr, len);	log_ptr += 2;	if (log_ptr + len <= log_end) {		memcpy(log_ptr, undo_page + old_free + 2, len);		mlog_close(mtr, log_ptr + len);	} else {		mlog_close(mtr, log_ptr);		mlog_catenate_string(mtr, undo_page + old_free + 2, len);	}}	/***************************************************************Parses a redo log record of adding an undo log record. */byte*trx_undo_parse_add_undo_rec(/*========================*/			/* out: end of log record or NULL */	byte*	ptr,	/* in: buffer */	byte*	end_ptr,/* in: buffer end */	page_t*	page)	/* in: page or NULL */{	ulint	len;	byte*	rec;	ulint	first_free;	if (end_ptr < ptr + 2) {		return(NULL);	}	len = mach_read_from_2(ptr);	ptr += 2;	if (end_ptr < ptr + len) {		return(NULL);	}		if (page == NULL) {		return(ptr + len);	}		first_free = mach_read_from_2(page + TRX_UNDO_PAGE_HDR							+ TRX_UNDO_PAGE_FREE);	rec = page + first_free;		mach_write_to_2(rec, first_free + 4 + len);	mach_write_to_2(rec + 2 + len, first_free);	mach_write_to_2(page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE,							first_free + 4 + len);	ut_memcpy(rec + 2, ptr, len);	return(ptr + len);}	/**************************************************************************Calculates the free space left for extending an undo log record. */UNIV_INLINEulinttrx_undo_left(/*==========*/			/* out: bytes left */	page_t* page,	/* in: undo log page */	byte*	ptr)	/* in: pointer to page */{	/* The '- 10' is a safety margin, in case we have some small	calculation error below */	return(UNIV_PAGE_SIZE - (ptr - page) - 10 - FIL_PAGE_DATA_END);}/**************************************************************************Reports in the undo log of an insert of a clustered index record. */staticulinttrx_undo_page_report_insert(/*========================*/					/* out: offset of the inserted entry					on the page if succeed, 0 if fail */	page_t* 	undo_page,	/* in: undo log page */	trx_t*		trx,		/* in: transaction */	dict_index_t*	index,		/* in: clustered index */	dtuple_t*	clust_entry,	/* in: index entry which will be					inserted to the clustered index */	mtr_t*		mtr)		/* in: mtr */{	ulint		first_free;	byte*		ptr;	ulint		len;	dfield_t*	field;	ulint		flen;	ulint		i;		ut_ad(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR				+ TRX_UNDO_PAGE_TYPE) == TRX_UNDO_INSERT);	first_free = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR							+ TRX_UNDO_PAGE_FREE);	ptr = undo_page + first_free;		ut_ad(first_free <= UNIV_PAGE_SIZE);	if (trx_undo_left(undo_page, ptr) < 30) {		/* NOTE: the value 30 must be big enough such that the general		fields written below fit on the undo log page */		return(0);	}	/* Reserve 2 bytes for the pointer to the next undo log record */	ptr += 2;			/* Store first some general parameters to the undo log */ 	mach_write_to_1(ptr, TRX_UNDO_INSERT_REC);	ptr++;	len = mach_dulint_write_much_compressed(ptr, trx->undo_no);	ptr += len;	len = mach_dulint_write_much_compressed(ptr, (index->table)->id);	ptr += len;	/*----------------------------------------*/	/* Store then the fields required to uniquely determine the record	to be inserted in the clustered index */	for (i = 0; i < dict_index_get_n_unique(index); i++) {		field = dtuple_get_nth_field(clust_entry, i);		flen = dfield_get_len(field);		if (trx_undo_left(undo_page, ptr) < 5) {			return(0);		}		len = mach_write_compressed(ptr, flen); 		ptr += len;		if (flen != UNIV_SQL_NULL) {			if (trx_undo_left(undo_page, ptr) < flen) {				return(0);			}			ut_memcpy(ptr, dfield_get_data(field), flen);			ptr += flen;		}	}	if (trx_undo_left(undo_page, ptr) < 2) {		return(0);	}	/*----------------------------------------*/	/* Write pointers to the previous and the next undo log records */	if (trx_undo_left(undo_page, ptr) < 2) {		return(0);	}	mach_write_to_2(ptr, first_free);	ptr += 2;	mach_write_to_2(undo_page + first_free, ptr - undo_page);	mach_write_to_2(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE,							ptr - undo_page);	/* Write the log entry to the REDO log of this change in the UNDO								 log */	trx_undof_page_add_undo_rec_log(undo_page, first_free,							ptr - undo_page, mtr);	return(first_free);	}/**************************************************************************Reads from an undo log record the general parameters. */byte*trx_undo_rec_get_pars(/*==================*/					/* out: remaining part of undo log					record after reading these values */	trx_undo_rec_t*	undo_rec,	/* in: undo log record */	ulint*		type,		/* out: undo record type:					TRX_UNDO_INSERT_REC, ... */	ulint*		cmpl_info,	/* out: compiler info, relevant only					for update type records */	ibool*		updated_extern,	/* out: TRUE if we updated an					externally stored fild */	dulint*		undo_no,	/* out: undo log record number */	dulint*		table_id)	/* out: table id */{	byte*		ptr;	ulint		len;	ulint		type_cmpl;	ptr = undo_rec + 2;	type_cmpl = mach_read_from_1(ptr);	ptr++;	if (type_cmpl & TRX_UNDO_UPD_EXTERN) {		*updated_extern = TRUE;		type_cmpl -= TRX_UNDO_UPD_EXTERN;	} else {		*updated_extern = FALSE;	}	*type = type_cmpl & (TRX_UNDO_CMPL_INFO_MULT - 1);	*cmpl_info = type_cmpl / TRX_UNDO_CMPL_INFO_MULT;	*undo_no = mach_dulint_read_much_compressed(ptr); 			len = mach_dulint_get_much_compressed_size(*undo_no);	ptr += len;	*table_id = mach_dulint_read_much_compressed(ptr); 			len = mach_dulint_get_much_compressed_size(*table_id);	ptr += len;	return(ptr);}/**************************************************************************Reads from an undo log record a stored column value. */staticbyte*trx_undo_rec_get_col_val(/*=====================*/			/* out: remaining part of undo log record after			reading these values */	byte*	ptr,	/* in: pointer to remaining part of undo log record */	byte**	field,	/* out: pointer to stored field */	ulint*	len)	/* out: length of the field, or UNIV_SQL_NULL */{	*len = mach_read_compressed(ptr); 	ptr += mach_get_compressed_size(*len);	*field = ptr;		if (*len != UNIV_SQL_NULL) {		if (*len >= UNIV_EXTERN_STORAGE_FIELD) {			ptr += (*len - UNIV_EXTERN_STORAGE_FIELD);		} else {			ptr += *len;		}	}	return(ptr);}/***********************************************************************Builds a row reference from an undo log record. */byte*trx_undo_rec_get_row_ref(/*=====================*/				/* out: pointer to remaining part of undo				record */	byte*		ptr,	/* in: remaining part of a copy of an undo log				record, at the start of the row reference;				NOTE that this copy of the undo log record must				be preserved as long as the row reference is				used, as we do NOT copy the data in the				record! */	dict_index_t*	index,	/* in: clustered index */	dtuple_t**	ref,	/* out, own: row reference */	mem_heap_t*	heap)	/* in: memory heap from which the memory				needed is allocated */{	dfield_t*	dfield;	byte*		field;	ulint		len;	ulint		ref_len;	ulint		i;		ut_ad(index && ptr && ref && heap);	ut_a(index->type & DICT_CLUSTERED);		ref_len = dict_index_get_n_unique(index);	*ref = dtuple_create(heap, ref_len);	dict_index_copy_types(*ref, index, ref_len);	for (i = 0; i < ref_len; i++) {		dfield = dtuple_get_nth_field(*ref, i);		ptr = trx_undo_rec_get_col_val(ptr, &field, &len);		dfield_set_data(dfield, field, len);	}	return(ptr);}	/***********************************************************************Skips a row reference from an undo log record. */byte*trx_undo_rec_skip_row_ref(/*======================*/				/* out: pointer to remaining part of undo				record */	byte*		ptr,	/* in: remaining part in update undo log				record, at the start of the row reference */	dict_index_t*	index)	/* in: clustered index */{	byte*	field;	ulint	len;	ulint	ref_len;	ulint	i;		ut_ad(index && ptr);	ut_a(index->type & DICT_CLUSTERED);		ref_len = dict_index_get_n_unique(index);	for (i = 0; i < ref_len; i++) {		ptr = trx_undo_rec_get_col_val(ptr, &field, &len);	}	return(ptr);}	/**************************************************************************Reports in the undo log of an update or delete marking of a clustered indexrecord. */staticulinttrx_undo_page_report_modify(/*========================*/					/* out: byte offset of the inserted					undo log entry on the page if succeed,					0 if fail */	page_t* 	undo_page,	/* in: undo log page */	trx_t*		trx,		/* in: transaction */	dict_index_t*	index,		/* in: clustered index where update or					delete marking is done */	rec_t*		rec,		/* in: clustered index record which					has NOT yet been modified */	const ulint*	offsets,	/* in: rec_get_offsets(rec, index) */	upd_t*		update,		/* in: update vector which tells the					columns to be updated; in the case of					a delete, this should be set to NULL */	ulint		cmpl_info,	/* in: compiler info on secondary					index updates */	mtr_t*		mtr)		/* in: mtr */{	dict_table_t*	table;	upd_field_t*	upd_field;	dict_col_t*	col;	ulint		first_free;	byte*		ptr;	ulint		len;	byte* 		field;	ulint		flen;	ulint		pos;	dulint		roll_ptr;	dulint		trx_id;	ulint		bits;	ulint		col_no;	byte*		old_ptr;	ulint		type_cmpl;	byte*		type_cmpl_ptr;	ulint		i;		ut_a(index->type & DICT_CLUSTERED);	ut_ad(rec_offs_validate(rec, index, offsets));	ut_ad(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR				+ TRX_UNDO_PAGE_TYPE) == TRX_UNDO_UPDATE);	table = index->table;		first_free = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR						+ TRX_UNDO_PAGE_FREE);	ptr = undo_page + first_free;							ut_ad(first_free <= UNIV_PAGE_SIZE);	if (trx_undo_left(undo_page, ptr) < 50) {		/* NOTE: the value 50 must be big enough so that the general		fields written below fit on the undo log page */		return(0);	}	/* Reserve 2 bytes for the pointer to the next undo log record */	ptr += 2;	/* Store first some general parameters to the undo log */	if (update) {		if (rec_get_deleted_flag(rec, table->comp)) {			type_cmpl = TRX_UNDO_UPD_DEL_REC;		} else {			type_cmpl = TRX_UNDO_UPD_EXIST_REC;		}	} else {		type_cmpl = TRX_UNDO_DEL_MARK_REC;	}	type_cmpl = type_cmpl | (cmpl_info * TRX_UNDO_CMPL_INFO_MULT);	mach_write_to_1(ptr, type_cmpl);		type_cmpl_ptr = ptr;

⌨️ 快捷键说明

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