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

📄 log0log.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************Database log(c) 1995-1997 Innobase OyCreated 12/9/1995 Heikki Tuuri*******************************************************/#include "log0log.h"#ifdef UNIV_NONINL#include "log0log.ic"#endif#include "mem0mem.h"#include "buf0buf.h"#include "buf0flu.h"#include "srv0srv.h"#include "log0recv.h"#include "fil0fil.h"#include "dict0boot.h"#include "srv0srv.h"#include "srv0start.h"#include "trx0sys.h"#include "trx0trx.h"/*General philosophy of InnoDB redo-logs:1) Every change to a contents of a data page must be donethrough mtr, which in mtr_commit() writes log recordsto the InnoDB redo log.2) Normally these changes are performed using a mlog_write_ulint()or similar function.3) In some page level operations only a code number of a c-function and its parameters are written to the log to reduce the size of the log.  3a) You should not add parameters to these kind of functions  (e.g. trx_undo_header_create(), trx_undo_insert_header_reuse())  3b) You should not add such functionality which either change  working when compared with the old or are dependent on data  outside of the page. These kind of functions should implement  self-contained page transformation and it should be unchanged  if you don't have very essential reasons to change log  semantics or format.*//* Current free limit of space 0; protected by the log sys mutex; 0 meansuninitialized */ulint	log_fsp_current_free_limit		= 0;/* Global log system variable */log_t*	log_sys	= NULL;#ifdef UNIV_DEBUGibool	log_do_write = TRUE;ibool	log_debug_writes = FALSE;#endif /* UNIV_DEBUG *//* These control how often we print warnings if the last checkpoint is tooold */ibool	log_has_printed_chkp_warning = FALSE;time_t	log_last_warning_time;#ifdef UNIV_LOG_ARCHIVE/* Pointer to this variable is used as the i/o-message when we do i/o to anarchive */byte	log_archive_io;#endif /* UNIV_LOG_ARCHIVE *//* A margin for free space in the log buffer before a log entry is catenated */#define LOG_BUF_WRITE_MARGIN 	(4 * OS_FILE_LOG_BLOCK_SIZE)/* Margins for free space in the log buffer after a log entry is catenated */#define LOG_BUF_FLUSH_RATIO	2#define LOG_BUF_FLUSH_MARGIN	(LOG_BUF_WRITE_MARGIN + 4 * UNIV_PAGE_SIZE)/* Margin for the free space in the smallest log group, before a new querystep which modifies the database, is started */#define LOG_CHECKPOINT_FREE_PER_THREAD	(4 * UNIV_PAGE_SIZE)#define LOG_CHECKPOINT_EXTRA_FREE	(8 * UNIV_PAGE_SIZE)/* This parameter controls asynchronous making of a new checkpoint; the valueshould be bigger than LOG_POOL_PREFLUSH_RATIO_SYNC */#define LOG_POOL_CHECKPOINT_RATIO_ASYNC	32/* This parameter controls synchronous preflushing of modified buffer pages */#define LOG_POOL_PREFLUSH_RATIO_SYNC	16/* The same ratio for asynchronous preflushing; this value should be less thanthe previous */#define LOG_POOL_PREFLUSH_RATIO_ASYNC	8/* Extra margin, in addition to one log file, used in archiving */#define LOG_ARCHIVE_EXTRA_MARGIN	(4 * UNIV_PAGE_SIZE)/* This parameter controls asynchronous writing to the archive */#define LOG_ARCHIVE_RATIO_ASYNC		16/* Codes used in unlocking flush latches */#define LOG_UNLOCK_NONE_FLUSHED_LOCK	1#define LOG_UNLOCK_FLUSH_LOCK		2/* States of an archiving operation */#define	LOG_ARCHIVE_READ	1#define	LOG_ARCHIVE_WRITE	2/**********************************************************Completes a checkpoint write i/o to a log file. */staticvoidlog_io_complete_checkpoint(void);/*============================*/#ifdef UNIV_LOG_ARCHIVE/**********************************************************Completes an archiving i/o. */staticvoidlog_io_complete_archive(void);/*=========================*/#endif /* UNIV_LOG_ARCHIVE *//********************************************************************Sets the global variable log_fsp_current_free_limit. Also makes a checkpoint,so that we know that the limit has been written to a log checkpoint fieldon disk. */voidlog_fsp_current_free_limit_set_and_checkpoint(/*==========================================*/	ulint	limit)	/* in: limit to set */{	ibool	success;	mutex_enter(&(log_sys->mutex));	log_fsp_current_free_limit = limit;	mutex_exit(&(log_sys->mutex));	/* Try to make a synchronous checkpoint */		success = FALSE;	while (!success) {		success = log_checkpoint(TRUE, TRUE);	}}/********************************************************************Returns the oldest modified block lsn in the pool, or log_sys->lsn if noneexists. */staticdulintlog_buf_pool_get_oldest_modification(void)/*======================================*/{	dulint	lsn;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	lsn = buf_pool_get_oldest_modification();	if (ut_dulint_is_zero(lsn)) {		lsn = log_sys->lsn;	}	return(lsn);}/****************************************************************Opens the log for log_write_low. The log must be closed with log_close andreleased with log_release. */dulintlog_reserve_and_open(/*=================*/			/* out: start lsn of the log record */	ulint	len)	/* in: length of data to be catenated */{	log_t*	log			= log_sys;	ulint	len_upper_limit;#ifdef UNIV_LOG_ARCHIVE	ulint	archived_lsn_age;	ulint	dummy;#endif /* UNIV_LOG_ARCHIVE */#ifdef UNIV_DEBUG	ulint	count			= 0;#endif /* UNIV_DEBUG */	ut_a(len < log->buf_size / 2);loop:	mutex_enter(&(log->mutex));		/* Calculate an upper limit for the space the string may take in the	log buffer */	len_upper_limit = LOG_BUF_WRITE_MARGIN + (5 * len) / 4;	if (log->buf_free + len_upper_limit > log->buf_size) {		mutex_exit(&(log->mutex));		/* Not enough free space, do a syncronous flush of the log		buffer */		log_buffer_flush_to_disk();                srv_log_waits++;		ut_ad(++count < 50);		goto loop;	}#ifdef UNIV_LOG_ARCHIVE	if (log->archiving_state != LOG_ARCH_OFF) {			archived_lsn_age = ut_dulint_minus(log->lsn,							log->archived_lsn);		if (archived_lsn_age + len_upper_limit						> log->max_archived_lsn_age) {			/* Not enough free archived space in log groups: do a			synchronous archive write batch: */				mutex_exit(&(log->mutex));				ut_ad(len_upper_limit <= log->max_archived_lsn_age);				log_archive_do(TRUE, &dummy);				ut_ad(++count < 50);				goto loop;		}	}#endif /* UNIV_LOG_ARCHIVE */#ifdef UNIV_LOG_DEBUG	log->old_buf_free = log->buf_free;	log->old_lsn = log->lsn;#endif		return(log->lsn);}/****************************************************************Writes to the log the string given. It is assumed that the caller holds thelog mutex. */voidlog_write_low(/*==========*/	byte*	str,		/* in: string */	ulint	str_len)	/* in: string length */{	log_t*	log	= log_sys;	ulint	len;	ulint	data_len;	byte*	log_block;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log->mutex)));#endif /* UNIV_SYNC_DEBUG */part_loop:	/* Calculate a part length */	data_len = (log->buf_free % OS_FILE_LOG_BLOCK_SIZE) + str_len;	if (data_len <= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {	    	/* The string fits within the current log block */	    	    	len = str_len;	} else {		data_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE;			    	len = OS_FILE_LOG_BLOCK_SIZE			- (log->buf_free % OS_FILE_LOG_BLOCK_SIZE)	    		- LOG_BLOCK_TRL_SIZE;	}	ut_memcpy(log->buf + log->buf_free, str, len);	str_len -= len;	str = str + len;	log_block = ut_align_down(log->buf + log->buf_free,						OS_FILE_LOG_BLOCK_SIZE);	log_block_set_data_len(log_block, data_len);	if (data_len == OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {		/* This block became full */		log_block_set_data_len(log_block, OS_FILE_LOG_BLOCK_SIZE);		log_block_set_checkpoint_no(log_block,						log_sys->next_checkpoint_no);		len += LOG_BLOCK_HDR_SIZE + LOG_BLOCK_TRL_SIZE;		log->lsn = ut_dulint_add(log->lsn, len);		/* Initialize the next block header */		log_block_init(log_block + OS_FILE_LOG_BLOCK_SIZE, log->lsn);	} else {		log->lsn = ut_dulint_add(log->lsn, len);	}	log->buf_free += len;	ut_ad(log->buf_free <= log->buf_size);	if (str_len > 0) {		goto part_loop;	}                srv_log_write_requests++;}/****************************************************************Closes the log. */dulintlog_close(void)/*===========*/			/* out: lsn */{	byte*	log_block;	ulint	first_rec_group;	dulint	oldest_lsn;	dulint	lsn;	log_t*	log	= log_sys;	ulint	checkpoint_age;#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log->mutex)));#endif /* UNIV_SYNC_DEBUG */	lsn = log->lsn;		log_block = ut_align_down(log->buf + log->buf_free,						OS_FILE_LOG_BLOCK_SIZE);	first_rec_group = log_block_get_first_rec_group(log_block);	if (first_rec_group == 0) {		/* We initialized a new log block which was not written		full by the current mtr: the next mtr log record group		will start within this block at the offset data_len */		log_block_set_first_rec_group(log_block,			 		log_block_get_data_len(log_block));	}	if (log->buf_free > log->max_buf_free) {		log->check_flush_or_checkpoint = TRUE;	}	checkpoint_age = ut_dulint_minus(lsn, log->last_checkpoint_lsn);	if (checkpoint_age >= log->log_group_capacity) {		/* TODO: split btr_store_big_rec_extern_fields() into small		steps so that we can release all latches in the middle, and		call log_free_check() to ensure we never write over log written		after the latest checkpoint. In principle, we should split all		big_rec operations, but other operations are smaller. */		if (!log_has_printed_chkp_warning		    || difftime(time(NULL), log_last_warning_time) > 15) {		        log_has_printed_chkp_warning = TRUE;			log_last_warning_time = time(NULL);					        ut_print_timestamp(stderr);			fprintf(stderr,"  InnoDB: ERROR: the age of the last checkpoint is %lu,\n""InnoDB: which exceeds the log group capacity %lu.\n""InnoDB: If you are using big BLOB or TEXT rows, you must set the\n""InnoDB: combined size of log files at least 10 times bigger than the\n""InnoDB: largest such row.\n",				(ulong) checkpoint_age,				(ulong) log->log_group_capacity);		}	}	if (checkpoint_age <= log->max_modified_age_async) {		goto function_exit;	}	oldest_lsn = buf_pool_get_oldest_modification();	if (ut_dulint_is_zero(oldest_lsn)	    || (ut_dulint_minus(lsn, oldest_lsn)					> log->max_modified_age_async)	    || checkpoint_age > log->max_checkpoint_age_async) {		log->check_flush_or_checkpoint = TRUE;	}function_exit:#ifdef UNIV_LOG_DEBUG	log_check_log_recs(log->buf + log->old_buf_free,			log->buf_free - log->old_buf_free, log->old_lsn);#endif	return(lsn);}#ifdef UNIV_LOG_ARCHIVE/**********************************************************Pads the current log block full with dummy log records. Used in producingconsistent archived log files. */staticvoidlog_pad_current_log_block(void)/*===========================*/{	byte	b		= MLOG_DUMMY_RECORD;	ulint	pad_length;	ulint	i;	dulint	lsn;		/* We retrieve lsn only because otherwise gcc crashed on HP-UX */	lsn = log_reserve_and_open(OS_FILE_LOG_BLOCK_SIZE);	pad_length = OS_FILE_LOG_BLOCK_SIZE			- (log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE)			- LOG_BLOCK_TRL_SIZE;	for (i = 0; i < pad_length; i++) {		log_write_low(&b, 1);	}	lsn = log_sys->lsn;			log_close();	log_release();	ut_a((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE)						== LOG_BLOCK_HDR_SIZE);}#endif /* UNIV_LOG_ARCHIVE *//**********************************************************Calculates the data capacity of a log group, when the log file headers are notincluded. */ulintlog_group_get_capacity(/*===================*/				/* out: capacity in bytes */	log_group_t*	group)	/* in: log group */{#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	return((group->file_size - LOG_FILE_HDR_SIZE) * group->n_files); }/**********************************************************Calculates the offset within a log group, when the log file headers are notincluded. */UNIV_INLINEulintlog_group_calc_size_offset(/*=======================*/				/* out: size offset (<= offset) */	ulint		offset,	/* in: real offset within the log group */	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));}/**********************************************************Calculates the offset within a log group, when the log file headers areincluded. */UNIV_INLINEulintlog_group_calc_real_offset(/*=======================*/				/* out: real offset (>= offset) */	ulint		offset,	/* in: size offset within the log group */

⌨️ 快捷键说明

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