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

📄 log0log.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	log_group_t*	group)	/* in: log group */{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	return(offset + LOG_FILE_HDR_SIZE		* (1 + offset / (group->file_size - LOG_FILE_HDR_SIZE)));}/**********************************************************Calculates the offset of an lsn within a log group. */staticulintlog_group_calc_lsn_offset(/*======================*/				/* out: offset within the log group */	dulint		lsn,	/* in: lsn, must be within 4 GB of				group->lsn */	log_group_t*	group)	/* in: log group */{        dulint	        gr_lsn;       	ib_longlong     gr_lsn_size_offset;	ib_longlong	difference;	ib_longlong	group_size;	ib_longlong	offset;	#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	/* If total log file size is > 2 GB we can easily get overflows	with 32-bit integers. Use 64-bit integers instead. */	gr_lsn = group->lsn;	gr_lsn_size_offset = (ib_longlong)	               log_group_calc_size_offset(group->lsn_offset, group);	group_size = (ib_longlong) log_group_get_capacity(group);	if (ut_dulint_cmp(lsn, gr_lsn) >= 0) {					difference = (ib_longlong) ut_dulint_minus(lsn, gr_lsn);	} else {		difference = (ib_longlong) ut_dulint_minus(gr_lsn, lsn);		difference = difference % group_size;		difference = group_size - difference;	}	offset = (gr_lsn_size_offset + difference) % group_size;	ut_a(offset < (((ib_longlong) 1) << 32)); /* offset must be < 4 GB */	/* fprintf(stderr,		"Offset is %lu gr_lsn_offset is %lu difference is %lu\n",	       (ulint)offset,(ulint)gr_lsn_size_offset, (ulint)difference);	*/	return(log_group_calc_real_offset((ulint)offset, group));}/***********************************************************************Calculates where in log files we find a specified lsn. */ulintlog_calc_where_lsn_is(/*==================*/						/* out: log file number */	ib_longlong*	log_file_offset,	/* out: offset in that file						(including the header) */	dulint		first_header_lsn,	/* in: first log file start						lsn */	dulint		lsn,			/* in: lsn whose position to						determine */	ulint		n_log_files,		/* in: total number of log						files */	ib_longlong	log_file_size)		/* in: log file size						(including the header) */{	ib_longlong	ib_lsn;	ib_longlong	ib_first_header_lsn;	ib_longlong	capacity	= log_file_size - LOG_FILE_HDR_SIZE;	ulint		file_no;	ib_longlong	add_this_many;		ib_lsn = ut_conv_dulint_to_longlong(lsn);	ib_first_header_lsn = ut_conv_dulint_to_longlong(first_header_lsn);	if (ib_lsn < ib_first_header_lsn) {		add_this_many = 1 + (ib_first_header_lsn - ib_lsn)				/ (capacity * (ib_longlong)n_log_files);		ib_lsn += add_this_many		          * capacity * (ib_longlong)n_log_files;	}	ut_a(ib_lsn >= ib_first_header_lsn);		file_no = ((ulint)((ib_lsn - ib_first_header_lsn) / capacity))			  % n_log_files;	*log_file_offset = (ib_lsn - ib_first_header_lsn) % capacity;	*log_file_offset = *log_file_offset + LOG_FILE_HDR_SIZE;	return(file_no);}/************************************************************Sets the field values in group to correspond to a given lsn. For this functionto work, the values must already be correctly initialized to correspond tosome lsn, for instance, a checkpoint lsn. */voidlog_group_set_fields(/*=================*/	log_group_t*	group,	/* in: group */	dulint		lsn)	/* in: lsn for which the values should be				set */{	group->lsn_offset = log_group_calc_lsn_offset(lsn, group);	group->lsn = lsn;}/*********************************************************************Calculates the recommended highest values for lsn - last_checkpoint_lsn,lsn - buf_get_oldest_modification(), and lsn - max_archive_lsn_age. */staticiboollog_calc_max_ages(void)/*===================*/			/* out: error value FALSE if the smallest log group is			too small to accommodate the number of OS threads in			the database server */{	log_group_t*	group;	ulint		margin;	ulint		free;	ibool		success		= TRUE;	ulint		smallest_capacity;		ulint		archive_margin;	ulint		smallest_archive_margin;#ifdef UNIV_SYNC_DEBUG	ut_ad(!mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	mutex_enter(&(log_sys->mutex));	group = UT_LIST_GET_FIRST(log_sys->log_groups);	ut_ad(group);	smallest_capacity = ULINT_MAX;	smallest_archive_margin = ULINT_MAX;	while (group) {		if (log_group_get_capacity(group) < smallest_capacity) {			smallest_capacity = log_group_get_capacity(group);		}		archive_margin = log_group_get_capacity(group)				- (group->file_size - LOG_FILE_HDR_SIZE)				- LOG_ARCHIVE_EXTRA_MARGIN;		if (archive_margin < smallest_archive_margin) {			smallest_archive_margin = archive_margin;		}			group = UT_LIST_GET_NEXT(log_groups, group);	}		/* Add extra safety */	smallest_capacity = smallest_capacity - smallest_capacity / 10;	/* For each OS thread we must reserve so much free space in the	smallest log group that it can accommodate the log entries produced	by single query steps: running out of free log space is a serious	system error which requires rebooting the database. */		free = LOG_CHECKPOINT_FREE_PER_THREAD * (10 + srv_thread_concurrency)						+ LOG_CHECKPOINT_EXTRA_FREE;	if (free >= smallest_capacity / 2) {		success = FALSE;		goto failure;	} else {		margin = smallest_capacity - free;	}	margin = ut_min(margin, log_sys->adm_checkpoint_interval);	margin = margin - margin / 10;	/* Add still some extra safety */	log_sys->log_group_capacity = smallest_capacity;	log_sys->max_modified_age_async = margin				- margin / LOG_POOL_PREFLUSH_RATIO_ASYNC;	log_sys->max_modified_age_sync = margin				- margin / LOG_POOL_PREFLUSH_RATIO_SYNC;	log_sys->max_checkpoint_age_async = margin - margin					/ LOG_POOL_CHECKPOINT_RATIO_ASYNC;	log_sys->max_checkpoint_age = margin;#ifdef UNIV_LOG_ARCHIVE	log_sys->max_archived_lsn_age = smallest_archive_margin;	log_sys->max_archived_lsn_age_async = smallest_archive_margin						- smallest_archive_margin /						  LOG_ARCHIVE_RATIO_ASYNC;#endif /* UNIV_LOG_ARCHIVE */failure:	mutex_exit(&(log_sys->mutex));	if (!success) {		fprintf(stderr,"InnoDB: Error: ib_logfiles are too small for innodb_thread_concurrency %lu.\n""InnoDB: The combined size of ib_logfiles should be bigger than\n""InnoDB: 200 kB * innodb_thread_concurrency.\n""InnoDB: To get mysqld to start up, set innodb_thread_concurrency in my.cnf\n""InnoDB: to a lower value, for example, to 8. After an ERROR-FREE shutdown\n""InnoDB: of mysqld you can adjust the size of ib_logfiles, as explained in\n""InnoDB: http://dev.mysql.com/doc/mysql/en/Adding_and_removing.html\n""InnoDB: Cannot continue operation. Calling exit(1).\n",			(ulong)srv_thread_concurrency);		exit(1);	}	return(success);}/**********************************************************Initializes the log. */voidlog_init(void)/*==========*/{	byte*	buf;	log_sys = mem_alloc(sizeof(log_t));	mutex_create(&(log_sys->mutex));	mutex_set_level(&(log_sys->mutex), SYNC_LOG);	mutex_enter(&(log_sys->mutex));	/* Start the lsn from one log block from zero: this way every	log record has a start lsn != zero, a fact which we will use */		log_sys->lsn = LOG_START_LSN;	ut_a(LOG_BUFFER_SIZE >= 16 * OS_FILE_LOG_BLOCK_SIZE);	ut_a(LOG_BUFFER_SIZE >= 4 * UNIV_PAGE_SIZE);	buf = ut_malloc(LOG_BUFFER_SIZE + OS_FILE_LOG_BLOCK_SIZE);	log_sys->buf = ut_align(buf, OS_FILE_LOG_BLOCK_SIZE);	log_sys->buf_size = LOG_BUFFER_SIZE;	memset(log_sys->buf, '\0', LOG_BUFFER_SIZE);	log_sys->max_buf_free = log_sys->buf_size / LOG_BUF_FLUSH_RATIO				- LOG_BUF_FLUSH_MARGIN;	log_sys->check_flush_or_checkpoint = TRUE;	UT_LIST_INIT(log_sys->log_groups);	log_sys->n_log_ios = 0;		log_sys->n_log_ios_old = log_sys->n_log_ios;	log_sys->last_printout_time = time(NULL);	/*----------------------------*/		log_sys->buf_next_to_write = 0;	log_sys->write_lsn = ut_dulint_zero;	log_sys->current_flush_lsn = ut_dulint_zero;	log_sys->flushed_to_disk_lsn = ut_dulint_zero;	log_sys->written_to_some_lsn = log_sys->lsn;	log_sys->written_to_all_lsn = log_sys->lsn;		log_sys->n_pending_writes = 0;	log_sys->no_flush_event = os_event_create(NULL);	os_event_set(log_sys->no_flush_event);	log_sys->one_flushed_event = os_event_create(NULL);	os_event_set(log_sys->one_flushed_event);	/*----------------------------*/	log_sys->adm_checkpoint_interval = ULINT_MAX;	log_sys->next_checkpoint_no = ut_dulint_zero;	log_sys->last_checkpoint_lsn = log_sys->lsn;	log_sys->n_pending_checkpoint_writes = 0; 	rw_lock_create(&(log_sys->checkpoint_lock));	rw_lock_set_level(&(log_sys->checkpoint_lock), SYNC_NO_ORDER_CHECK);	log_sys->checkpoint_buf = ut_align(				mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE),						OS_FILE_LOG_BLOCK_SIZE);	memset(log_sys->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);	/*----------------------------*/#ifdef UNIV_LOG_ARCHIVE	/* Under MySQL, log archiving is always off */	log_sys->archiving_state = LOG_ARCH_OFF;	log_sys->archived_lsn = log_sys->lsn;	log_sys->next_archived_lsn = ut_dulint_zero;	log_sys->n_pending_archive_ios = 0;	rw_lock_create(&(log_sys->archive_lock));	rw_lock_set_level(&(log_sys->archive_lock), SYNC_NO_ORDER_CHECK);	log_sys->archive_buf = NULL;			/* ut_align(				ut_malloc(LOG_ARCHIVE_BUF_SIZE					  + OS_FILE_LOG_BLOCK_SIZE),						OS_FILE_LOG_BLOCK_SIZE); */	log_sys->archive_buf_size = 0;	/* memset(log_sys->archive_buf, '\0', LOG_ARCHIVE_BUF_SIZE); */	log_sys->archiving_on = os_event_create(NULL);#endif /* UNIV_LOG_ARCHIVE */	/*----------------------------*/	log_block_init(log_sys->buf, log_sys->lsn);	log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);	log_sys->buf_free = LOG_BLOCK_HDR_SIZE;	log_sys->lsn = ut_dulint_add(LOG_START_LSN, LOG_BLOCK_HDR_SIZE);		mutex_exit(&(log_sys->mutex));#ifdef UNIV_LOG_DEBUG	recv_sys_create();	recv_sys_init(FALSE, buf_pool_get_curr_size());	recv_sys->parse_start_lsn = log_sys->lsn;	recv_sys->scanned_lsn = log_sys->lsn;	recv_sys->scanned_checkpoint_no = 0;	recv_sys->recovered_lsn = log_sys->lsn;	recv_sys->limit_lsn = ut_dulint_max;#endif}/**********************************************************************Inits a log group to the log system. */voidlog_group_init(/*===========*/	ulint	id,			/* in: group id */	ulint	n_files,		/* in: number of log files */	ulint	file_size,		/* in: log file size in bytes */	ulint	space_id,		/* in: space id of the file space					which contains the log files of this					group */	ulint	archive_space_id __attribute__((unused)))					/* in: space id of the file space					which contains some archived log					files for this group; currently, only					for the first log group this is					used */{	ulint	i;		log_group_t*	group;	group = mem_alloc(sizeof(log_group_t));	group->id = id;	group->n_files = n_files;	group->file_size = file_size;	group->space_id = space_id;	group->state = LOG_GROUP_OK;	group->lsn = LOG_START_LSN;	group->lsn_offset = LOG_FILE_HDR_SIZE;	group->n_pending_writes = 0;	group->file_header_bufs = mem_alloc(sizeof(byte*) * n_files);#ifdef UNIV_LOG_ARCHIVE	group->archive_file_header_bufs = mem_alloc(sizeof(byte*) * n_files);#endif /* UNIV_LOG_ARCHIVE */	for (i = 0; i < n_files; i++) {		*(group->file_header_bufs + i) = ut_align(			mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),						OS_FILE_LOG_BLOCK_SIZE);		memset(*(group->file_header_bufs + i), '\0',							LOG_FILE_HDR_SIZE);#ifdef UNIV_LOG_ARCHIVE		*(group->archive_file_header_bufs + i) = ut_align(			mem_alloc(LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE),						OS_FILE_LOG_BLOCK_SIZE);		memset(*(group->archive_file_header_bufs + i), '\0',							LOG_FILE_HDR_SIZE);#endif /* UNIV_LOG_ARCHIVE */	}	#ifdef UNIV_LOG_ARCHIVE	group->archive_space_id = archive_space_id;	group->archived_file_no = 0;	group->archived_offset = 0;#endif /* UNIV_LOG_ARCHIVE */	group->checkpoint_buf = ut_align(				mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE),						OS_FILE_LOG_BLOCK_SIZE);		memset(group->checkpoint_buf, '\0', OS_FILE_LOG_BLOCK_SIZE);	UT_LIST_ADD_LAST(log_groups, log_sys->log_groups, group);	ut_a(log_calc_max_ages());}		/**********************************************************************Does the unlockings needed in flush i/o completion. */UNIV_INLINEvoidlog_flush_do_unlocks(/*=================*/	ulint	code)	/* in: any ORed combination of LOG_UNLOCK_FLUSH_LOCK			and LOG_UNLOCK_NONE_FLUSHED_LOCK */{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	/* NOTE that we must own the log mutex when doing the setting of the	events: this is because transactions will wait for these events to	be set, and at that moment the log flush they were waiting for must	have ended. If the log mutex were not reserved here, the i/o-thread	calling this function might be preempted for a while, and when it	resumed execution, it might be that a new flush had been started, and	this function would erroneously signal the NEW flush as completed.		Thus, the changes in the state of these events are performed	atomically in conjunction with the changes in the state of	log_sys->n_pending_writes etc. */ 	if (code & LOG_UNLOCK_NONE_FLUSHED_LOCK) {		os_event_set(log_sys->one_flushed_event);	}	if (code & LOG_UNLOCK_FLUSH_LOCK) {		os_event_set(log_sys->no_flush_event);	}}/**********************************************************************Checks if a flush is completed for a log group and does the completionroutine if yes. */UNIV_INLINEulintlog_group_check_flush_completion(/*=============================*/				/* out: LOG_UNLOCK_NONE_FLUSHED_LOCK or 0 */	log_group_t*	group)	/* in: log group */{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	if (!log_sys->one_flushed && group->n_pending_writes == 0) {#ifdef UNIV_DEBUG		if (log_debug_writes) {			fprintf(stderr,				"Log flushed first to group %lu\n", (ulong) group->id);		}#endif /* UNIV_DEBUG */		log_sys->written_to_some_lsn = log_sys->write_lsn;		log_sys->one_flushed = TRUE;		return(LOG_UNLOCK_NONE_FLUSHED_LOCK);	}#ifdef UNIV_DEBUG	if (log_debug_writes && (group->n_pending_writes == 0)) {

⌨️ 快捷键说明

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