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

📄 log0trsh.c

📁 Mysql for Windows最新源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************Recovery(c) 1997 Innobase OyCreated 9/20/1997 Heikki Tuuri*******************************************************/#include "log0recv.h"#ifdef UNIV_NONINL#include "log0recv.ic"#endif#include "mem0mem.h"#include "buf0buf.h"#include "buf0flu.h"#include "srv0srv.h"/* Size of block reads when the log groups are scanned forward to doroll-forward */#define RECV_SCAN_SIZE		(4 * UNIV_PAGE_SIZE)/* Size of block reads when the log groups are scanned backwards to synchronizethem */#define RECV_BACK_SCAN_SIZE	(4 * UNIV_PAGE_SIZE)recv_sys_t*	recv_sys = NULL;recv_recover_page(block->frame, block->space, block->offset);/************************************************************Creates the recovery system. */voidrecv_sys_create(void)/*=================*/{	ut_a(recv_sys == NULL);	recv_sys = mem_alloc(sizeof(recv_t));	mutex_create(&(recv_sys->mutex));	recv_sys->hash = NULL;	recv_sys->heap = NULL;}/************************************************************Inits the recovery system for a recovery operation. */voidrecv_sys_init(void)/*===============*/{	recv_sys->hash = hash_create(buf_pool_get_curr_size() / 64);	recv_sys->heap = mem_heap_create_in_buffer(256);}/************************************************************Empties the recovery system. */voidrecv_sys_empty(void)/*================*/{	mutex_enter(&(recv_sys->mutex));	hash_free(recv_sys->hash);	mem_heap_free(recv_sys->heap);	recv_sys->hash = NULL;	recv_sys->heap = NULL;	mutex_exit(&(recv_sys->mutex));}/***********************************************************For recovery purposes copies the log buffer to a group to synchronize logdata. */staticvoidrecv_log_buf_flush(/*===============*/	log_group_t*	group,		/* in: log group */	dulint		start_lsn,	/* in: start lsn of the log data in					the log buffer; must be divisible by					OS_FILE_LOG_BLOCK_SIZE */	dulint		end_lsn)	/* in: end lsn of the log data in the					log buffer; must be divisible by					OS_FILE_LOG_BLOCK_SIZE */{	ulint	len;		ut_ad(mutex_own(&(log_sys->mutex)));	len = ut_dulint_minus(end_lsn, start_lsn);		log_group_write_buf(LOG_RECOVER, group, log_sys->buf, len, start_lsn,									0);}/***********************************************************Compares two buffers containing log segments and determines the highest lsnwhere they match, if any. */staticdulintrecv_log_bufs_cmp(/*==============*/				/* out: if no match found, ut_dulint_zero or				if start_lsn == LOG_START_LSN, returns				LOG_START_LSN; otherwise the highest matching				lsn */	byte*	recv_buf,	/* in: buffer containing valid log data */	byte*	buf,		/* in: buffer of data from a possibly				incompletely written log group */	dulint	start_lsn,	/* in: buffer start lsn, must be divisible				by OS_FILE_LOG_BLOCK_SIZE and must be >=				LOG_START_LSN */	dulint	end_lsn,	/* in: buffer end lsn, must be divisible				by OS_FILE_LOG_BLOCK_SIZE */	dulint	recovered_lsn)	/* in: recovery succeeded up to this lsn */{	ulint	len;	ulint	offset;	byte*	log_block1;	byte*	log_block2;	ulint	no;	ulint	data_len;	ut_ad(ut_dulint_cmp(start_lsn, LOG_START_LSN) >= 0);	if (ut_dulint_cmp(end_lsn, recovered_lsn) > 0) {		end_lsn = ut_dulint_align_up(recovered_lsn,						OS_FILE_LOG_BLOCK_SIZE);	}	len = ut_dulint_minus(end_lsn, start_lsn);	if (len == 0) {		goto no_match;	}		ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);	log_block1 = recv_buf + len;	log_block2 = buf + len;		for (;;) {		log_block1 -= OS_FILE_LOG_BLOCK_SIZE;		log_block2 -= OS_FILE_LOG_BLOCK_SIZE;		no = log_block_get_hdr_no(log_block1);		ut_a(no == log_block_get_trl_no(log_block1));		if ((no == log_block_get_hdr_no(log_block2))		    && (no == log_block_get_trl_no(log_block2))) {		    	/* Match found if the block is not corrupted */		    	data_len = log_block_get_data_len(log_block2);		    	if (0 == ut_memcmp(log_block1 + LOG_BLOCK_DATA,		    			   log_block2 + LOG_BLOCK_DATA,		    			   data_len - LOG_BLOCK_DATA)) {		    		/* Match found */				return(ut_dulint_add(start_lsn,						log_block2 - buf + data_len));			}		}		if (log_block1 == recv_buf) {			/* No match found */			break;		}    			}no_match:	if (ut_dulint_cmp(start_lsn, LOG_START_LSN) == 0) {		return(LOG_START_LSN);	}	return(ut_dulint_zero);}/************************************************************Copies a log segment from the most up-to-date log group to the other loggroup, so that it contains the latest log data. */staticvoidrecv_copy_group(/*============*/	log_group_t*	up_to_date_group,	/* in: the most up-to-date						log group */	log_group_t*	group,			/* in: copy to this log group */	dulint_lsn	recovered_lsn)		/* in: recovery succeeded up						to this lsn */{	dulint		start_lsn;	dulint		end_lsn;	dulint		match;	byte*		buf;	byte*		buf1;	ut_ad(mutex_own(&(log_sys->mutex)));	if (0 == ut_dulint_cmp(LOG_START_LSN, recovered_lsn)) {		return;	}						ut_ad(RECV_BACK_SCAN_SIZE <= log_sys->buf_size);	buf1 = mem_alloc(2 * RECV_BACK_SCAN_SIZE);	buf = ut_align(buf, RECV_BACK_SCAN_SIZE););	end_lsn = ut_dulint_align_up(recovered_lsn, RECV_BACK_SCAN_SIZE);	match = ut_dulint_zero;    	for (;;) {		if (ut_dulint_cmp(ut_dulint_add(LOG_START_LSN,					RECV_BACK_SCAN_SIZE), end_lsn) >= 0) {			start_lsn = LOG_START_LSN;		} else {    			start_lsn = ut_dulint_subtract(end_lsn,							RECV_BACK_SCAN_SIZE);		}		log_group_read_log_seg(LOG_RECOVER, buf, group, start_lsn,								end_lsn);		log_group_read_log_seg(LOG_RECOVER, log_sys->buf,					up_to_date_group, start_lsn, end_lsn);		match = recv_log_bufs_cmp(log_sys->buf, buf, start_lsn,						end_lsn, recovered_lsn);		if (ut_dulint_cmp(match, recovered_lsn) != 0) {			recv_log_buf_flush(group, start_lsn, end_lsn);		}						if (!ut_dulint_zero(match)) {			mem_free(buf1);			return;		}		end_lsn = start_lsn;	}}/************************************************************Copies a log segment from the most up-to-date log group to the other loggroups, so that they all contain the latest log data. Also writes the infoabout the latest checkpoint to the groups, and inits the fields in the groupmemory structs to up-to-date values. */voidrecv_synchronize_groups(/*====================*/	log_group_t*	up_to_date_group,	/* in: the most up-to-date						log group */	dulint_lsn	recovered_lsn,		/* in: recovery succeeded up						to this lsn */	log_group_t*	max_checkpoint_group)	/* in: the group with the most						recent checkpoint info */{	log_group_t*	group;	ut_ad(mutex_own(&(log_sys->mutex)));	group = UT_LIST_GET_FIRST(log_sys->log_groups);	while (group) {		if (group != up_to_date_group) {			/* Copy log data */			recv_copy_group(group, up_to_date_group,								recovered_lsn);		}		if (group != max_checkpoint_group) {					/* Copy the checkpoint info to the group */			log_group_checkpoint(group);			mutex_exit(&(log_sys->mutex));			/* Wait for the checkpoint write to complete */			rw_lock_s_lock(&(log_sys->checkpoint_lock));			rw_lock_s_unlock(&(log_sys->checkpoint_lock));			mutex_enter(&(log_sys->mutex));		}		/* Update the fields in the group struct to correspond to		recovered_lsn */		log_group_set_fields(group, recovered_lsn);		group = UT_LIST_GET_NEXT(log_groups, group);	}	}/************************************************************Looks for the maximum consistent checkpoint from the log groups. */staticulintrecv_find_max_checkpoint(/*=====================*/					/* out: error code or DB_SUCCESS */	log_group_t**	max_group,	/* out: max group */	ulint*		max_field)	/* out: LOG_CHECKPOINT_1 or					LOG_CHECKPOINT_2 */{	log_group_t*	group;	dulint		max_no;

⌨️ 快捷键说明

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