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

📄 btr0cur.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
		ut_min(page_get_free_space_of_empty(page_is_comp(page)) / 2,		REC_MAX_DATA_SIZE)) {		/* The record is so big that we have to store some fields		externally on separate database pages */		                big_rec_vec = dtuple_convert_big_rec(index, entry, NULL, 0);		if (big_rec_vec == NULL) {					return(DB_TOO_BIG_RECORD);		}		goto calculate_sizes_again;	}	/* If there have been many consecutive inserts, and we are on the leaf	level, check if we have to split the page to reserve enough free space	for future updates of records. */	type = index->type;		if ((type & DICT_CLUSTERED)	    && (dict_tree_get_space_reserve(index->tree) + rec_size > max_size)	    && (page_get_n_recs(page) >= 2)	    && (0 == level)	    && (btr_page_get_split_rec_to_right(cursor, &dummy_rec)	        || btr_page_get_split_rec_to_left(cursor, &dummy_rec))) {	        if (big_rec_vec) {			dtuple_convert_back_big_rec(index, entry, big_rec_vec);		}		return(DB_FAIL);	}		if (!(((max_size >= rec_size)	       && (max_size >= BTR_CUR_PAGE_REORGANIZE_LIMIT))	      || (page_get_max_insert_size(page, 1) >= rec_size)	      || (page_get_n_recs(page) <= 1))) {	        if (big_rec_vec) {			dtuple_convert_back_big_rec(index, entry, big_rec_vec);		}		return(DB_FAIL);	}        /* Check locks and write to the undo log, if specified */        err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &inherit);	if (err != DB_SUCCESS) {	        if (big_rec_vec) {			dtuple_convert_back_big_rec(index, entry, big_rec_vec);		}		return(err);	}	page_cursor = btr_cur_get_page_cur(cursor);	reorg = FALSE;	/* Now, try the insert */	*rec = page_cur_insert_rec_low(page_cursor, entry, index,							NULL, NULL, mtr);	if (UNIV_UNLIKELY(!(*rec))) {		/* If the record did not fit, reorganize */		btr_page_reorganize(page, index, mtr);		ut_ad(page_get_max_insert_size(page, 1) == max_size);				reorg = TRUE;		page_cur_search(page, index, entry, PAGE_CUR_LE, page_cursor);		*rec = page_cur_tuple_insert(page_cursor, entry, index, mtr);		if (UNIV_UNLIKELY(!*rec)) {			fputs("InnoDB: Error: cannot insert tuple ", stderr);			dtuple_print(stderr, entry);			fputs(" into ", stderr);			dict_index_name_print(stderr, thr_get_trx(thr), index);			fprintf(stderr, "\nInnoDB: max insert size %lu\n",				(ulong) max_size);			ut_error;		}	}#ifdef BTR_CUR_HASH_ADAPT	if (!reorg && (0 == level) && (cursor->flag == BTR_CUR_HASH)) {		btr_search_update_hash_node_on_insert(cursor);	} else {		btr_search_update_hash_on_insert(cursor);	}#endif	if (!(flags & BTR_NO_LOCKING_FLAG) && inherit) {		lock_update_insert(*rec);	}/*	fprintf(stderr, "Insert into page %lu, max ins size %lu,"		" rec %lu ind type %lu\n",			buf_frame_get_page_no(page), max_size,					rec_size + PAGE_DIR_SLOT_SIZE, type);*/		if (!(type & DICT_CLUSTERED)) {		/* We have added a record to page: update its free bits */		ibuf_update_free_bits_if_full(cursor->index, page, max_size,					rec_size + PAGE_DIR_SLOT_SIZE);	}	*big_rec = big_rec_vec;	return(DB_SUCCESS);}/*****************************************************************Performs an insert on a page of an index tree. It is assumed that mtrholds an x-latch on the tree and on the cursor page. If the insert ismade on the leaf level, to avoid deadlocks, mtr must also own x-latchesto brothers of page, if those brothers exist. */ulintbtr_cur_pessimistic_insert(/*=======================*/				/* out: DB_SUCCESS or error number */	ulint		flags,	/* in: undo logging and locking flags: if not				zero, the parameter thr should be				specified; if no undo logging is specified,				then the caller must have reserved enough				free extents in the file space so that the				insertion will certainly succeed */	btr_cur_t*	cursor,	/* in: cursor after which to insert;				cursor stays valid */	dtuple_t*	entry,	/* in: entry to insert */	rec_t**		rec,	/* out: pointer to inserted record if				succeed */	big_rec_t**	big_rec,/* out: big rec vector whose fields have to				be stored externally by the caller, or				NULL */	que_thr_t*	thr,	/* in: query thread or NULL */	mtr_t*		mtr)	/* in: mtr */{	dict_index_t*	index		= cursor->index;	big_rec_t*	big_rec_vec	= NULL;	page_t*		page;	ulint		err;	ibool		dummy_inh;	ibool		success;	ulint		n_extents	= 0;	ulint		n_reserved;		ut_ad(dtuple_check_typed(entry));	*big_rec = NULL;	page = btr_cur_get_page(cursor);	ut_ad(mtr_memo_contains(mtr,				dict_tree_get_lock(btr_cur_get_tree(cursor)),							MTR_MEMO_X_LOCK));	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),							MTR_MEMO_PAGE_X_FIX));	/* Try first an optimistic insert; reset the cursor flag: we do not	assume anything of how it was positioned */	cursor->flag = BTR_CUR_BINARY;	err = btr_cur_optimistic_insert(flags, cursor, entry, rec, big_rec,								thr, mtr);	if (err != DB_FAIL) {		return(err);	}	/* Retry with a pessimistic insert. Check locks and write to undo log,	if specified */	err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &dummy_inh);	if (err != DB_SUCCESS) {		return(err);	}	if (!(flags & BTR_NO_UNDO_LOG_FLAG)) {			/* First reserve enough free space for the file segments		of the index tree, so that the insert will not fail because		of lack of space */		n_extents = cursor->tree_height / 16 + 3;		success = fsp_reserve_free_extents(&n_reserved, index->space,						n_extents, FSP_NORMAL, mtr);		if (!success) {			err = DB_OUT_OF_FILE_SPACE;			return(err);		}	}	if (rec_get_converted_size(index, entry) >=		ut_min(page_get_free_space_of_empty(page_is_comp(page)) / 2,		REC_MAX_DATA_SIZE)) {		/* The record is so big that we have to store some fields		externally on separate database pages */		                big_rec_vec = dtuple_convert_big_rec(index, entry, NULL, 0);		if (big_rec_vec == NULL) {					if (n_extents > 0) {			        fil_space_release_free_extents(index->space,								n_reserved);			}			return(DB_TOO_BIG_RECORD);		}	}	if (dict_tree_get_page(index->tree)					== buf_frame_get_page_no(page)) {		/* The page is the root page */		*rec = btr_root_raise_and_insert(cursor, entry, mtr);	} else {		*rec = btr_page_split_and_insert(cursor, entry, mtr);	}	btr_cur_position(index, page_rec_get_prev(*rec), cursor);	#ifdef BTR_CUR_ADAPT	btr_search_update_hash_on_insert(cursor);#endif	if (!(flags & BTR_NO_LOCKING_FLAG)) {		lock_update_insert(*rec);	}	err = DB_SUCCESS;	if (n_extents > 0) {		fil_space_release_free_extents(index->space, n_reserved);	}	*big_rec = big_rec_vec;	return(err);}/*==================== B-TREE UPDATE =========================*//*****************************************************************For an update, checks the locks and does the undo logging. */UNIV_INLINEulintbtr_cur_upd_lock_and_undo(/*======================*/				/* out: DB_SUCCESS, DB_WAIT_LOCK, or error				number */	ulint		flags,	/* in: undo logging and locking flags */	btr_cur_t*	cursor,	/* in: cursor on record to update */	upd_t*		update,	/* in: update vector */	ulint		cmpl_info,/* in: compiler info on secondary index				updates */	que_thr_t*	thr,	/* in: query thread */	dulint*		roll_ptr)/* out: roll pointer */{	dict_index_t*	index;	rec_t*		rec;	ulint		err;		ut_ad(cursor && update && thr && roll_ptr);	rec = btr_cur_get_rec(cursor);	index = cursor->index;		if (!(index->type & DICT_CLUSTERED)) {		/* We do undo logging only when we update a clustered index		record */		return(lock_sec_rec_modify_check_and_lock(flags, rec, index,									thr));	}	/* Check if we have to wait for a lock: enqueue an explicit lock	request if yes */	err = DB_SUCCESS;	if (!(flags & BTR_NO_LOCKING_FLAG)) {		mem_heap_t*	heap		= NULL;		ulint		offsets_[REC_OFFS_NORMAL_SIZE];		*offsets_ = (sizeof offsets_) / sizeof *offsets_;		err = lock_clust_rec_modify_check_and_lock(flags, rec, index,			rec_get_offsets(rec, index, offsets_,				ULINT_UNDEFINED, &heap), thr);		if (UNIV_LIKELY_NULL(heap)) {			mem_heap_free(heap);		}		if (err != DB_SUCCESS) {			return(err);		}	}	/* Append the info about the update in the undo log */	err = trx_undo_report_row_operation(flags, TRX_UNDO_MODIFY_OP, thr,						index, NULL, update,						cmpl_info, rec, roll_ptr);	return(err);}/***************************************************************Writes a redo log record of updating a record in-place. */UNIV_INLINEvoidbtr_cur_update_in_place_log(/*========================*/	ulint		flags,		/* in: flags */	rec_t*		rec,		/* in: record */	dict_index_t*	index,		/* in: index where cursor positioned */	upd_t*		update,		/* in: update vector */	trx_t*		trx,		/* in: transaction */	dulint		roll_ptr,	/* in: roll ptr */	mtr_t*		mtr)		/* in: mtr */{	byte*	log_ptr;	page_t*	page	= ut_align_down(rec, UNIV_PAGE_SIZE);	ut_ad(flags < 256);	ut_ad(!!page_is_comp(page) == index->table->comp);	log_ptr = mlog_open_and_write_index(mtr, rec, index, page_is_comp(page)			? MLOG_COMP_REC_UPDATE_IN_PLACE			: MLOG_REC_UPDATE_IN_PLACE,			1 + DATA_ROLL_PTR_LEN + 14 + 2 + MLOG_BUF_MARGIN);	if (!log_ptr) {		/* Logging in mtr is switched off during crash recovery */		return;	}	/* The code below assumes index is a clustered index: change index to	the clustered index if we are updating a secondary index record (or we	could as well skip writing the sys col values to the log in this case	because they are not needed for a secondary index record update) */	index = dict_table_get_first_index(index->table);	mach_write_to_1(log_ptr, flags);	log_ptr++;	log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr,									mtr);	mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));	log_ptr += 2;	row_upd_index_write_log(update, log_ptr, mtr);}	/***************************************************************Parses a redo log record of updating a record in-place. */byte*btr_cur_parse_update_in_place(/*==========================*/				/* out: end of log record or NULL */	byte*		ptr,	/* in: buffer */	byte*		end_ptr,/* in: buffer end */	page_t*		page,	/* in: page or NULL */	dict_index_t*	index)	/* in: index corresponding to page */{	ulint	flags;	rec_t*	rec;	upd_t*	update;	ulint	pos;	dulint	trx_id;	dulint	roll_ptr;	ulint	rec_offset;	mem_heap_t* heap;	ulint*	offsets;	if (end_ptr < ptr + 1) {		return(NULL);	}		flags = mach_read_from_1(ptr);	ptr++;	ptr = row_upd_parse_sys_vals(ptr, end_ptr, &pos, &trx_id, &roll_ptr);	if (ptr == NULL) {		return(NULL);	}	if (end_ptr < ptr + 2) {		return(NULL);	}	rec_offset = mach_read_from_2(ptr);	ptr += 2;	ut_a(rec_offset <= UNIV_PAGE_SIZE);	heap = mem_heap_create(256);		ptr = row_upd_index_parse(ptr, end_ptr, heap, &update);	if (!ptr || !page) {		goto func_exit;	}	ut_a((ibool)!!page_is_comp(page) == index->table->comp);	rec = page + rec_offset;		/* We do not need to reserve btr_search_latch, as the page is only	being recovered, and there cannot be a hash index to it. */	offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);	if (!(flags & BTR_KEEP_SYS_FLAG)) {		row_upd_rec_sys_fields_in_recovery(rec, offsets,			pos, trx_id, roll_ptr);	}	row_upd_rec_in_place(rec, offsets, update);func_exit:	mem_heap_free(heap);	return(ptr);}/*****************************************************************Updates a record when the update causes no size changes in its fields.We assume here that the ordering fields of the record do not change. */ulintbtr_cur_update_in_place(/*====================*/				/* out: DB_SUCCESS or error number */	ulint		flags,	/* in: undo logging and locking flags */	btr_cur_t*	cursor,	/* in: cursor on the record to update;				cursor stays valid and positioned on the				same record */	upd_t*		update,	/* in: update vector */	ulint		cmpl_info,/* in: compiler info on secondary index				updates */	que_thr_t*	thr,	/* in: query thread */	mtr_t*		mtr)	/* in: mtr */{	dict_index_t*	index;	buf_block_t*	block;	ulint		err;	rec_t*		rec;	dulint		roll_ptr	= ut_dulint_zero;	trx_t*		trx;	ulint		was_delete_marked;	mem_heap_t*	heap		= NULL;	ulint		offsets_[REC_OFFS_NORMAL_SIZE];	ulint*		offsets		= offsets_;	*offsets_ = (sizeof offsets_) / sizeof *offsets_;	rec = btr_cur_get_rec(cursor);	index = cursor->index;	ut_ad(!!page_rec_is_comp(rec) == index->table->comp);	trx = thr_get_trx(thr);	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);#ifdef UNIV_DEBUG	if (btr_cur_print_record_ops && thr) {		btr_cur_trx_report(trx, index, "update ");		rec_print_new(stderr, rec, offsets);	}#endif /* UNIV_DEBUG */	/* Do lock checking and undo logging */	err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,							thr, &roll_ptr);

⌨️ 快捷键说明

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