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

📄 log0log.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
		log_flush_do_unlocks(unlock);	mutex_exit(&(log_sys->mutex));	return;	do_waits:	mutex_exit(&(log_sys->mutex));	if (wait == LOG_WAIT_ONE_GROUP) {		os_event_wait(log_sys->one_flushed_event);	} else if (wait == LOG_WAIT_ALL_GROUPS) {		os_event_wait(log_sys->no_flush_event);	} else {		ut_ad(wait == LOG_NO_WAIT);	}			}/********************************************************************Does a syncronous flush of the log buffer to disk. */voidlog_buffer_flush_to_disk(void)/*==========================*/{	dulint	lsn;	mutex_enter(&(log_sys->mutex));	lsn = log_sys->lsn;	mutex_exit(&(log_sys->mutex));	log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE);}/********************************************************************Tries to establish a big enough margin of free space in the log buffer, suchthat a new log entry can be catenated without an immediate need for a flush. */staticvoidlog_flush_margin(void)/*==================*/{	ibool	do_flush	= FALSE;	log_t*	log		= log_sys;	dulint	lsn;	mutex_enter(&(log->mutex));	if (log->buf_free > log->max_buf_free) {				if (log->n_pending_writes > 0) {			/* A flush is running: hope that it will provide enough			free space */		} else {			do_flush = TRUE;			lsn = log->lsn;		}	}	mutex_exit(&(log->mutex));	if (do_flush) {		log_write_up_to(lsn, LOG_NO_WAIT, FALSE);	}}/********************************************************************Advances the smallest lsn for which there are unflushed dirty blocks in thebuffer pool. NOTE: this function may only be called if the calling thread ownsno synchronization objects! */iboollog_preflush_pool_modified_pages(/*=============================*/				/* out: FALSE if there was a flush batch of				the same type running, which means that we				could not start this flush batch */	dulint	new_oldest,	/* in: try to advance oldest_modified_lsn				at least to this lsn */	ibool	sync)		/* in: TRUE if synchronous operation is				desired */{	ulint	n_pages;	if (recv_recovery_on) {		/* If the recovery is running, we must first apply all		log records to their respective file pages to get the		right modify lsn values to these pages: otherwise, there		might be pages on disk which are not yet recovered to the		current lsn, and even after calling this function, we could		not know how up-to-date the disk version of the database is,		and we could not make a new checkpoint on the basis of the		info on the buffer pool only. */			recv_apply_hashed_log_recs(TRUE);	}	n_pages = buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX, new_oldest);	if (sync) {		buf_flush_wait_batch_end(BUF_FLUSH_LIST);	}	if (n_pages == ULINT_UNDEFINED) {		return(FALSE);	}	return(TRUE);}/**********************************************************Completes a checkpoint. */staticvoidlog_complete_checkpoint(void)/*=========================*/{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	ut_ad(log_sys->n_pending_checkpoint_writes == 0);	log_sys->next_checkpoint_no			= ut_dulint_add(log_sys->next_checkpoint_no, 1);	log_sys->last_checkpoint_lsn = log_sys->next_checkpoint_lsn;	rw_lock_x_unlock_gen(&(log_sys->checkpoint_lock), LOG_CHECKPOINT);}/**********************************************************Completes an asynchronous checkpoint info write i/o to a log file. */staticvoidlog_io_complete_checkpoint(void)/*============================*/{	mutex_enter(&(log_sys->mutex));	ut_ad(log_sys->n_pending_checkpoint_writes > 0);		log_sys->n_pending_checkpoint_writes--;	if (log_sys->n_pending_checkpoint_writes == 0) {		log_complete_checkpoint();	}			mutex_exit(&(log_sys->mutex));}/***********************************************************************Writes info to a checkpoint about a log group. */staticvoidlog_checkpoint_set_nth_group_info(/*==============================*/	byte*	buf,	/* in: buffer for checkpoint info */	ulint	n,	/* in: nth slot */	ulint	file_no,/* in: archived file number */	ulint	offset)	/* in: archived file offset */{	ut_ad(n < LOG_MAX_N_GROUPS);	mach_write_to_4(buf + LOG_CHECKPOINT_GROUP_ARRAY			+ 8 * n + LOG_CHECKPOINT_ARCHIVED_FILE_NO, file_no);	mach_write_to_4(buf + LOG_CHECKPOINT_GROUP_ARRAY			+ 8 * n + LOG_CHECKPOINT_ARCHIVED_OFFSET, offset);}/***********************************************************************Gets info from a checkpoint about a log group. */voidlog_checkpoint_get_nth_group_info(/*==============================*/	byte*	buf,	/* in: buffer containing checkpoint info */	ulint	n,	/* in: nth slot */	ulint*	file_no,/* out: archived file number */	ulint*	offset)	/* out: archived file offset */{	ut_ad(n < LOG_MAX_N_GROUPS);	*file_no = mach_read_from_4(buf + LOG_CHECKPOINT_GROUP_ARRAY				+ 8 * n + LOG_CHECKPOINT_ARCHIVED_FILE_NO);	*offset = mach_read_from_4(buf + LOG_CHECKPOINT_GROUP_ARRAY				+ 8 * n + LOG_CHECKPOINT_ARCHIVED_OFFSET);}/**********************************************************Writes the checkpoint info to a log group header. */staticvoidlog_group_checkpoint(/*=================*/	log_group_t*	group)	/* in: log group */{	log_group_t*	group2;#ifdef UNIV_LOG_ARCHIVE	dulint	archived_lsn;	dulint	next_archived_lsn;#endif /* UNIV_LOG_ARCHIVE */	ulint	write_offset;	ulint	fold;	byte*	buf;	ulint	i;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	ut_a(LOG_CHECKPOINT_SIZE <= OS_FILE_LOG_BLOCK_SIZE);		buf = group->checkpoint_buf;		mach_write_to_8(buf + LOG_CHECKPOINT_NO, log_sys->next_checkpoint_no);	mach_write_to_8(buf + LOG_CHECKPOINT_LSN,						log_sys->next_checkpoint_lsn);	mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,			log_group_calc_lsn_offset(					log_sys->next_checkpoint_lsn, group));									mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, log_sys->buf_size);#ifdef UNIV_LOG_ARCHIVE	if (log_sys->archiving_state == LOG_ARCH_OFF) {		archived_lsn = ut_dulint_max;	} else {		archived_lsn = log_sys->archived_lsn;		if (0 != ut_dulint_cmp(archived_lsn,					log_sys->next_archived_lsn)) {			next_archived_lsn = log_sys->next_archived_lsn;			/* For debugging only */		}		}	mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);#else /* UNIV_LOG_ARCHIVE */	mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, ut_dulint_max);#endif /* UNIV_LOG_ARCHIVE */	for (i = 0; i < LOG_MAX_N_GROUPS; i++) {		log_checkpoint_set_nth_group_info(buf, i, 0, 0);	}		group2 = UT_LIST_GET_FIRST(log_sys->log_groups);	while (group2) {		log_checkpoint_set_nth_group_info(buf, group2->id,#ifdef UNIV_LOG_ARCHIVE						group2->archived_file_no,						group2->archived_offset#else /* UNIV_LOG_ARCHIVE */						0, 0#endif /* UNIV_LOG_ARCHIVE */						);		group2 = UT_LIST_GET_NEXT(log_groups, group2);	}	fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1);	mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_1, fold);	fold = ut_fold_binary(buf + LOG_CHECKPOINT_LSN,			LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);	mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_2, fold);	/* Starting from InnoDB-3.23.50, we also write info on allocated	size in the tablespace */	mach_write_to_4(buf + LOG_CHECKPOINT_FSP_FREE_LIMIT,						log_fsp_current_free_limit);	mach_write_to_4(buf + LOG_CHECKPOINT_FSP_MAGIC_N,					LOG_CHECKPOINT_FSP_MAGIC_N_VAL);	/* We alternate the physical place of the checkpoint info in the first	log file */		if (ut_dulint_get_low(log_sys->next_checkpoint_no) % 2 == 0) {		write_offset = LOG_CHECKPOINT_1;	} else {		write_offset = LOG_CHECKPOINT_2;	}						if (log_do_write) {		if (log_sys->n_pending_checkpoint_writes == 0) {				rw_lock_x_lock_gen(&(log_sys->checkpoint_lock),							LOG_CHECKPOINT);		}		log_sys->n_pending_checkpoint_writes++;		log_sys->n_log_ios++;				/* We send as the last parameter the group machine address		added with 1, as we want to distinguish between a normal log		file write and a checkpoint field write */				fil_io(OS_FILE_WRITE | OS_FILE_LOG, FALSE, group->space_id,				write_offset / UNIV_PAGE_SIZE,				write_offset % UNIV_PAGE_SIZE,				OS_FILE_LOG_BLOCK_SIZE,				buf, ((byte*)group + 1));		ut_ad(((ulint)group & 0x1UL) == 0);	}}/**********************************************************Writes info to a buffer of a log group when log files are created inbackup restoration. */voidlog_reset_first_header_and_checkpoint(/*==================================*/	byte*	hdr_buf,/* in: buffer which will be written to the start			of the first log file */	dulint	start)	/* in: lsn of the start of the first log file;			we pretend that there is a checkpoint at			start + LOG_BLOCK_HDR_SIZE */{	ulint	fold;	byte*	buf;	dulint	lsn;		mach_write_to_4(hdr_buf + LOG_GROUP_ID, 0);	mach_write_to_8(hdr_buf + LOG_FILE_START_LSN, start);	lsn = ut_dulint_add(start, LOG_BLOCK_HDR_SIZE);	/* Write the label of ibbackup --restore */	strcpy((char*) hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,				"ibbackup ");	ut_sprintf_timestamp(			(char*) hdr_buf + (LOG_FILE_WAS_CREATED_BY_HOT_BACKUP						+ (sizeof "ibbackup ") - 1));	buf = hdr_buf + LOG_CHECKPOINT_1;		mach_write_to_8(buf + LOG_CHECKPOINT_NO, ut_dulint_zero);	mach_write_to_8(buf + LOG_CHECKPOINT_LSN, lsn);	mach_write_to_4(buf + LOG_CHECKPOINT_OFFSET,				LOG_FILE_HDR_SIZE + LOG_BLOCK_HDR_SIZE);									mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, 2 * 1024 * 1024);	mach_write_to_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN, ut_dulint_max);	fold = ut_fold_binary(buf, LOG_CHECKPOINT_CHECKSUM_1);	mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_1, fold);	fold = ut_fold_binary(buf + LOG_CHECKPOINT_LSN,			LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);	mach_write_to_4(buf + LOG_CHECKPOINT_CHECKSUM_2, fold);	/* Starting from InnoDB-3.23.50, we should also write info on	allocated size in the tablespace, but unfortunately we do not	know it here */}/**********************************************************Reads a checkpoint info from a log group header to log_sys->checkpoint_buf. */voidlog_group_read_checkpoint_info(/*===========================*/	log_group_t*	group,	/* in: log group */	ulint		field)	/* in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	log_sys->n_log_ios++;		fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, group->space_id,			field / UNIV_PAGE_SIZE, field % UNIV_PAGE_SIZE,			OS_FILE_LOG_BLOCK_SIZE, log_sys->checkpoint_buf, NULL);}/**********************************************************Writes checkpoint info to groups. */voidlog_groups_write_checkpoint_info(void)/*==================================*/{	log_group_t*	group;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	group = UT_LIST_GET_FIRST(log_sys->log_groups);	while (group) {		log_group_checkpoint(group);		group = UT_LIST_GET_NEXT(log_groups, group);	}}/**********************************************************Makes a checkpoint. Note that this function does not flush dirtyblocks from the buffer pool: it only checks what is lsn of the oldestmodification in the pool, and writes information about the lsn inlog files. Use log_make_checkpoint_at to flush also the pool. */iboollog_checkpoint(/*===========*/				/* out: TRUE if success, FALSE if a checkpoint				write was already running */	ibool	sync,		/* in: TRUE if synchronous operation is				desired */	ibool	write_always)	/* in: the function normally checks if the				the new checkpoint would have a greater				lsn than the previous one: if not, then no				physical write is done; by setting this				parameter TRUE, a physical write will always be				made to log files */{	dulint	oldest_lsn;	if (recv_recovery_is_on()) {		recv_apply_hashed_log_recs(TRUE);	}	if (srv_unix_file_flush_method != SRV_UNIX_NOSYNC) {	        fil_flush_file_spaces(FIL_TABLESPACE);	}	mutex_enter(&(log_sys->mutex));	oldest_lsn = log_buf_pool_get_oldest_modification();	mutex_exit(&(log_sys->mutex));	/* Because log also contains headers and dummy log records,	if the buffer pool contains no dirty buffers, oldest_lsn	gets the value log_sys->lsn from the previous function,	and we must make sure that the log is flushed up to that	lsn. If there are dirty buffers in the buffer pool, then our	write-ahead-logging algorithm ensures that the log has been flushed	up to oldest_lsn. */	log_write_up_to(oldest_lsn, LOG_WAIT_ALL_GROUPS, TRUE);	mutex_enter(&(log_sys->mutex));	if (!write_always && ut_dulint_cmp(			log_sys->last_checkpoint_lsn, oldest_lsn) >= 0) {		mutex_exit(&(log_sys->mutex));		return(TRUE);	}	ut_ad(ut_dulint_cmp(log_sys->written_to_all_lsn, oldest_lsn) >= 0);		if (log_sys->n_pending_checkpoint_writes > 0) {		/* A checkpoint write is running */		mutex_exit(&(log_sys->mutex));		if (sync) {			/* Wait for the checkpoint write to complete */			rw_lock_s_lock(&(log_sys->checkpoint_lock));			rw_lock_s_unlock(&(log_sys->checkpoint_lock));		}		return(FALSE);	}	log_sys->next_checkpoint_lsn = oldest_lsn;#ifdef UNIV_DEBUG	if (log_debug_writes) {		fprintf(stderr, "Making checkpoint no %lu at lsn %lu %lu\n",			(ulong) ut_dulint_get_low(log_sys->next_checkpoint_no),			(ulong) ut_dulint_get_high(oldest_lsn),			(ulong) ut_dulint_get_low(oldest_lsn));	}#endif /* UNIV_DEBUG */	log_groups_write_checkpoint_info();	mutex_exit(&(log_sys->mutex));	if (sync) {

⌨️ 快捷键说明

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