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

📄 lock0lock.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	bit_index = i % 8;	b = (ulint)*((byte*)lock + sizeof(lock_t) + byte_index);	return(ut_bit_get_nth(b, bit_index));}	/*************************************************************************/#define lock_mutex_enter_kernel()	mutex_enter(&kernel_mutex)#define lock_mutex_exit_kernel()	mutex_exit(&kernel_mutex)/*************************************************************************Checks that a transaction id is sensible, i.e., not in the future. */iboollock_check_trx_id_sanity(/*=====================*/					/* out: TRUE if ok */	dulint		trx_id,		/* in: trx id */	rec_t*		rec,		/* in: user record */	dict_index_t*	index,		/* in: index */	const ulint*	offsets,	/* in: rec_get_offsets(rec, index) */	ibool		has_kernel_mutex)/* in: TRUE if the caller owns the					kernel mutex */{	ibool	is_ok		= TRUE;		ut_ad(rec_offs_validate(rec, index, offsets));	if (!has_kernel_mutex) {		mutex_enter(&kernel_mutex);	}	/* A sanity check: the trx_id in rec must be smaller than the global	trx id counter */	if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) {		ut_print_timestamp(stderr);		fputs("  InnoDB: Error: transaction id associated"			" with record\n",			stderr);		rec_print_new(stderr, rec, offsets);		fputs("InnoDB: in ", stderr);		dict_index_name_print(stderr, NULL, index);		fprintf(stderr, "\n""InnoDB: is %lu %lu which is higher than the global trx id counter %lu %lu!\n""InnoDB: The table is corrupt. You have to do dump + drop + reimport.\n",			       (ulong) ut_dulint_get_high(trx_id),			       (ulong) ut_dulint_get_low(trx_id),			       (ulong) ut_dulint_get_high(trx_sys->max_trx_id),			       (ulong) ut_dulint_get_low(trx_sys->max_trx_id));		is_ok = FALSE;	}		if (!has_kernel_mutex) {		mutex_exit(&kernel_mutex);	}	return(is_ok);}/*************************************************************************Checks that a record is seen in a consistent read. */iboollock_clust_rec_cons_read_sees(/*==========================*/				/* out: TRUE if sees, or FALSE if an earlier				version of the record should be retrieved */	rec_t*		rec,	/* in: user record which should be read or				passed over by a read cursor */	dict_index_t*	index,	/* in: clustered index */	const ulint*	offsets,/* in: rec_get_offsets(rec, index) */	read_view_t*	view)	/* in: consistent read view */{	dulint	trx_id;	ut_ad(index->type & DICT_CLUSTERED);	ut_ad(page_rec_is_user_rec(rec));	ut_ad(rec_offs_validate(rec, index, offsets));	/* NOTE that we call this function while holding the search	system latch. To obey the latching order we must NOT reserve the	kernel mutex here! */	trx_id = row_get_rec_trx_id(rec, index, offsets);		return(read_view_sees_trx_id(view, trx_id));}/*************************************************************************Checks that a non-clustered index record is seen in a consistent read. */ulintlock_sec_rec_cons_read_sees(/*========================*/				/* out: TRUE if certainly sees, or FALSE if an				earlier version of the clustered index record				might be needed: NOTE that a non-clustered				index page contains so little information on				its modifications that also in the case FALSE,				the present version of rec may be the right,				but we must check this from the clustered				index record */	rec_t*		rec,	/* in: user record which should be read or				passed over by a read cursor */	dict_index_t*	index,	/* in: non-clustered index */	read_view_t*	view)	/* in: consistent read view */{	dulint	max_trx_id;		UT_NOT_USED(index);		ut_ad(!(index->type & DICT_CLUSTERED));	ut_ad(page_rec_is_user_rec(rec));	/* NOTE that we might call this function while holding the search	system latch. To obey the latching order we must NOT reserve the	kernel mutex here! */	if (recv_recovery_is_on()) {		return(FALSE);	}	max_trx_id = page_get_max_trx_id(buf_frame_align(rec));	if (ut_dulint_cmp(max_trx_id, view->up_limit_id) >= 0) {		return(FALSE);	}	return(TRUE);}/*************************************************************************Creates the lock system at database start. */voidlock_sys_create(/*============*/	ulint	n_cells)	/* in: number of slots in lock hash table */{	lock_sys = mem_alloc(sizeof(lock_sys_t));	lock_sys->rec_hash = hash_create(n_cells);	/* hash_create_mutexes(lock_sys->rec_hash, 2, SYNC_REC_LOCK); */	lock_latest_err_file = os_file_create_tmpfile();	ut_a(lock_latest_err_file);}/*************************************************************************Gets the size of a lock struct. */ulintlock_get_size(void)/*===============*/			/* out: size in bytes */{	return((ulint)sizeof(lock_t));}/*************************************************************************Gets the mode of a lock. */UNIV_INLINEulintlock_get_mode(/*==========*/			/* out: mode */	lock_t*	lock)	/* in: lock */{	ut_ad(lock);	return(lock->type_mode & LOCK_MODE_MASK);}/*************************************************************************Gets the wait flag of a lock. */UNIV_INLINEiboollock_get_wait(/*==========*/			/* out: TRUE if waiting */	lock_t*	lock)	/* in: lock */{	ut_ad(lock);	if (lock->type_mode & LOCK_WAIT) {		return(TRUE);	}	return(FALSE);}/*************************************************************************Gets the source table of an ALTER TABLE transaction.  The table must becovered by an IX or IS table lock. */dict_table_t*lock_get_src_table(/*===============*/				/* out: the source table of transaction,				if it is covered by an IX or IS table lock;				dest if there is no source table, and				NULL if the transaction is locking more than				two tables or an inconsistency is found */	trx_t*		trx,	/* in: transaction */	dict_table_t*	dest,	/* in: destination of ALTER TABLE */	ulint*		mode)	/* out: lock mode of the source table */{	dict_table_t*	src;	lock_t*		lock;	src = NULL;	*mode = LOCK_NONE;	for (lock = UT_LIST_GET_FIRST(trx->trx_locks);	     lock;	     lock = UT_LIST_GET_NEXT(trx_locks, lock)) {		lock_table_t*	tab_lock;		ulint		lock_mode;		if (!(lock_get_type(lock) & LOCK_TABLE)) {			/* We are only interested in table locks. */			continue;		}		tab_lock = &lock->un_member.tab_lock;		if (dest == tab_lock->table) {			/* We are not interested in the destination table. */			continue;		} else if (!src) {			/* This presumably is the source table. */			src = tab_lock->table;			if (UT_LIST_GET_LEN(src->locks) != 1 ||			    UT_LIST_GET_FIRST(src->locks) != lock) {				/* We only support the case when				there is only one lock on this table. */				return(NULL);			}		} else if (src != tab_lock->table) {			/* The transaction is locking more than			two tables (src and dest): abort */			return(NULL);		}		/* Check that the source table is locked by		LOCK_IX or LOCK_IS. */		lock_mode = lock_get_mode(lock);		switch (lock_mode) {		case LOCK_IX:		case LOCK_IS:			if (*mode != LOCK_NONE && *mode != lock_mode) {				/* There are multiple locks on src. */				return(NULL);			}			*mode = lock_mode;			break;		}	}	if (!src) {		/* No source table lock found: flag the situation to caller */		src = dest;	}	return(src);}/*************************************************************************Determine if the given table is exclusively "owned" by the giventransaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INCon the table. */iboollock_is_table_exclusive(/*====================*/				/* out: TRUE if table is only locked by trx,				with LOCK_IX, and possibly LOCK_AUTO_INC */	dict_table_t*	table,	/* in: table */	trx_t*		trx)	/* in: transaction */{	lock_t*	lock;	ibool	ok	= FALSE;	ut_ad(table && trx);	for (lock = UT_LIST_GET_FIRST(table->locks);	     lock;	     lock = UT_LIST_GET_NEXT(locks, &lock->un_member.tab_lock)) {		if (lock->trx != trx) {			/* A lock on the table is held			by some other transaction. */			return(FALSE);		}		if (!(lock_get_type(lock) & LOCK_TABLE)) {			/* We are interested in table locks only. */			continue;		}		switch (lock_get_mode(lock)) {		case LOCK_IX:			ok = TRUE;			break;		case LOCK_AUTO_INC:			/* It is allowed for trx to hold an			auto_increment lock. */			break;		default:			/* Other table locks than LOCK_IX are not allowed. */			return(FALSE);		}	}	return(ok);}/*************************************************************************Sets the wait flag of a lock and the back pointer in trx to lock. */UNIV_INLINEvoidlock_set_lock_and_trx_wait(/*=======================*/	lock_t*	lock,	/* in: lock */	trx_t*	trx)	/* in: trx */{	ut_ad(lock);	ut_ad(trx->wait_lock == NULL);		trx->wait_lock = lock; 	lock->type_mode = lock->type_mode | LOCK_WAIT;}/**************************************************************************The back pointer to a waiting lock request in the transaction is set to NULLand the wait bit in lock type_mode is reset. */UNIV_INLINEvoidlock_reset_lock_and_trx_wait(/*=========================*/	lock_t*	lock)	/* in: record lock */{	ut_ad((lock->trx)->wait_lock == lock);	ut_ad(lock_get_wait(lock));	/* Reset the back pointer in trx to this waiting lock request */	(lock->trx)->wait_lock = NULL; 	lock->type_mode = lock->type_mode & ~LOCK_WAIT;}/*************************************************************************Gets the gap flag of a record lock. */UNIV_INLINEiboollock_rec_get_gap(/*=============*/			/* out: TRUE if gap flag set */	lock_t*	lock)	/* in: record lock */{	ut_ad(lock);	ut_ad(lock_get_type(lock) == LOCK_REC);	if (lock->type_mode & LOCK_GAP) {		return(TRUE);	}	return(FALSE);}/*************************************************************************Gets the LOCK_REC_NOT_GAP flag of a record lock. */UNIV_INLINEiboollock_rec_get_rec_not_gap(/*=====================*/			/* out: TRUE if LOCK_REC_NOT_GAP flag set */	lock_t*	lock)	/* in: record lock */{	ut_ad(lock);	ut_ad(lock_get_type(lock) == LOCK_REC);	if (lock->type_mode & LOCK_REC_NOT_GAP) {		return(TRUE);	}	return(FALSE);}/*************************************************************************Gets the waiting insert flag of a record lock. */UNIV_INLINEiboollock_rec_get_insert_intention(/*==========================*/			/* out: TRUE if gap flag set */	lock_t*	lock)	/* in: record lock */{	ut_ad(lock);	ut_ad(lock_get_type(lock) == LOCK_REC);	if (lock->type_mode & LOCK_INSERT_INTENTION) {		return(TRUE);	}	return(FALSE);}/*************************************************************************Calculates if lock mode 1 is stronger or equal to lock mode 2. */UNIV_INLINEiboollock_mode_stronger_or_eq(/*=====================*/			/* out: TRUE if mode1 stronger or equal to mode2 */	ulint	mode1,	/* in: lock mode */	ulint	mode2)	/* in: lock mode */{	ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX				|| mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);	ut_ad(mode2 == LOCK_X || mode2 == LOCK_S || mode2 == LOCK_IX				|| mode2 == LOCK_IS || mode2 == LOCK_AUTO_INC);	if (mode1 == LOCK_X) {		return(TRUE);	} else if (mode1 == LOCK_AUTO_INC && mode2 == LOCK_AUTO_INC) {		return(TRUE);	} else if (mode1 == LOCK_S				&& (mode2 == LOCK_S || mode2 == LOCK_IS)) {

⌨️ 快捷键说明

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