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

📄 log0recv.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (ptr == end_ptr) {		return(FALSE);	}	single_rec = (ulint)*ptr & MLOG_SINGLE_REC_FLAG;	if (single_rec || *ptr == MLOG_DUMMY_RECORD) {		/* The mtr only modified a single page, or this is a file op */		old_lsn = recv_sys->recovered_lsn;		/* Try to parse a log record, fetching its type, space id,		page no, and a pointer to the body of the log record */		len = recv_parse_log_rec(ptr, end_ptr, &type, &space,							&page_no, &body);		if (len == 0 || recv_sys->found_corrupt_log) {			if (recv_sys->found_corrupt_log) {				recv_report_corrupt_log(ptr,						type, space, page_no);			}					return(FALSE);		}		new_recovered_lsn = recv_calc_lsn_on_data_add(old_lsn, len);		if (ut_dulint_cmp(new_recovered_lsn, recv_sys->scanned_lsn)								> 0) {			/* The log record filled a log block, and we require			that also the next log block should have been scanned			in */			return(FALSE);		}				recv_previous_parsed_rec_type = (ulint)type;		recv_previous_parsed_rec_offset = recv_sys->recovered_offset;		recv_previous_parsed_rec_is_multi = 0;		recv_sys->recovered_offset += len;		recv_sys->recovered_lsn = new_recovered_lsn;#ifdef UNIV_DEBUG		if (log_debug_writes) {			fprintf(stderr, "InnoDB: Parsed a single log rec type %lu len %lu space %lu page no %lu\n",				(ulong) type, (ulong) len, (ulong) space,				(ulong) page_no);		}#endif /* UNIV_DEBUG */		if (type == MLOG_DUMMY_RECORD) {			/* Do nothing */				} else if (store_to_hash && (type == MLOG_FILE_CREATE					     || type == MLOG_FILE_RENAME					     || type == MLOG_FILE_DELETE)) {#ifdef UNIV_HOTBACKUP			if (recv_replay_file_ops) {				/* In ibbackup --apply-log, replay an .ibd file				operation, if possible; note that				fil_path_to_mysql_datadir is set in ibbackup to				point to the datadir we should use there */							if (NULL == fil_op_log_parse_or_replay(body,						end_ptr, type, TRUE, space)) {					fprintf(stderr,"InnoDB: Error: file op log record of type %lu space %lu not complete in\n""InnoDB: the replay phase. Path %s\n", (ulint)type, space, (char*)(body + 2));					ut_a(0);				}			}#endif			/* In normal mysqld crash recovery we do not try to			replay file operations */		} else if (store_to_hash) {			recv_add_to_hash_table(type, space, page_no, body,						ptr + len, old_lsn,						recv_sys->recovered_lsn);		} else {			/* In debug checking, update a replicate page			according to the log record, and check that it			becomes identical with the original page */#ifdef UNIV_LOG_DEBUG			recv_check_incomplete_log_recs(ptr, len);#endif/* UNIV_LOG_DEBUG */#ifdef UNIV_LOG_REPLICATE			recv_update_replicate(type, space, page_no, body,								ptr + len);			recv_compare_replicate(space, page_no);#endif /* UNIV_LOG_REPLICATE */		}	} else {		/* Check that all the records associated with the single mtr		are included within the buffer */		total_len = 0;		n_recs = 0;				for (;;) {			len = recv_parse_log_rec(ptr, end_ptr, &type, &space,							&page_no, &body);			if (len == 0 || recv_sys->found_corrupt_log) {			    	if (recv_sys->found_corrupt_log) {					recv_report_corrupt_log(ptr,						type, space, page_no);			    	}			    	return(FALSE);			}			recv_previous_parsed_rec_type = (ulint)type;			recv_previous_parsed_rec_offset				= recv_sys->recovered_offset + total_len;			recv_previous_parsed_rec_is_multi = 1;			if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {				/* In debug checking, update a replicate page				according to the log record */#ifdef UNIV_LOG_DEBUG				recv_check_incomplete_log_recs(ptr, len);#endif /* UNIV_LOG_DEBUG */#ifdef UNIV_LOG_REPLICATE				recv_update_replicate(type, space, page_no,							body, ptr + len);#endif /* UNIV_LOG_REPLICATE */			}#ifdef UNIV_DEBUG			if (log_debug_writes) {				fprintf(stderr, "InnoDB: Parsed a multi log rec type %lu len %lu space %lu page no %lu\n",				(ulong) type, (ulong) len, (ulong) space,				(ulong) page_no);			}#endif /* UNIV_DEBUG */			total_len += len;			n_recs++;			ptr += len;			if (type == MLOG_MULTI_REC_END) {				/* Found the end mark for the records */				break;			}		}		new_recovered_lsn = recv_calc_lsn_on_data_add(					recv_sys->recovered_lsn, total_len);		if (ut_dulint_cmp(new_recovered_lsn, recv_sys->scanned_lsn)								> 0) {			/* The log record filled a log block, and we require			that also the next log block should have been scanned			in */			return(FALSE);		}		/* Add all the records to the hash table */		ptr = recv_sys->buf + recv_sys->recovered_offset;		for (;;) {			old_lsn = recv_sys->recovered_lsn;			len = recv_parse_log_rec(ptr, end_ptr, &type, &space,							&page_no, &body);			if (recv_sys->found_corrupt_log) {				recv_report_corrupt_log(ptr,							type, space, page_no);			}			ut_a(len != 0);			ut_a(0 == ((ulint)*ptr & MLOG_SINGLE_REC_FLAG));			recv_sys->recovered_offset += len;			recv_sys->recovered_lsn = recv_calc_lsn_on_data_add(								old_lsn, len);			if (type == MLOG_MULTI_REC_END) {				/* Found the end mark for the records */				break;			}			if (store_to_hash) {				recv_add_to_hash_table(type, space, page_no,						body, ptr + len, old_lsn,						new_recovered_lsn);#ifdef UNIV_LOG_REPLICATE			} else {				/* In debug checking, check that the replicate				page has become identical with the original				page */				recv_compare_replicate(space, page_no);#endif /* UNIV_LOG_REPLICATE */			}						ptr += len;		}	}   	goto loop;}/***********************************************************Adds data from a new log block to the parsing buffer of recv_sys ifrecv_sys->parse_start_lsn is non-zero. */staticiboolrecv_sys_add_to_parsing_buf(/*========================*/				/* out: TRUE if more data added */	byte*	log_block,	/* in: log block */	dulint	scanned_lsn)	/* in: lsn of how far we were able to find				data in this log block */{	ulint	more_len;	ulint	data_len;	ulint	start_offset;	ulint	end_offset;	ut_ad(ut_dulint_cmp(scanned_lsn, recv_sys->scanned_lsn) >= 0);	if (ut_dulint_is_zero(recv_sys->parse_start_lsn)) {		/* Cannot start parsing yet because no start point for		it found */		return(FALSE);	}	data_len = log_block_get_data_len(log_block);	if (ut_dulint_cmp(recv_sys->parse_start_lsn, scanned_lsn) >= 0) {		return(FALSE);	} else if (ut_dulint_cmp(recv_sys->scanned_lsn, scanned_lsn) >= 0) {		return(FALSE);									} else if (ut_dulint_cmp(recv_sys->parse_start_lsn,						recv_sys->scanned_lsn) > 0) {		more_len = ut_dulint_minus(scanned_lsn,						recv_sys->parse_start_lsn);	} else {		more_len = ut_dulint_minus(scanned_lsn, recv_sys->scanned_lsn);	}	if (more_len == 0) {		return(FALSE);	}		ut_ad(data_len >= more_len);	start_offset = data_len - more_len;	if (start_offset < LOG_BLOCK_HDR_SIZE) {		start_offset = LOG_BLOCK_HDR_SIZE;	}	end_offset = data_len;	if (end_offset > OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {		end_offset = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE;	}	ut_ad(start_offset <= end_offset);	if (start_offset < end_offset) {		ut_memcpy(recv_sys->buf + recv_sys->len,			log_block + start_offset, end_offset - start_offset);		recv_sys->len += end_offset - start_offset;		ut_a(recv_sys->len <= RECV_PARSING_BUF_SIZE);	}	return(TRUE);}/***********************************************************Moves the parsing buffer data left to the buffer start. */staticvoidrecv_sys_justify_left_parsing_buf(void)/*===================================*/{		ut_memmove(recv_sys->buf, recv_sys->buf + recv_sys->recovered_offset,				recv_sys->len - recv_sys->recovered_offset);	recv_sys->len -= recv_sys->recovered_offset;	recv_sys->recovered_offset = 0;}/***********************************************************Scans log from a buffer and stores new log data to the parsing buffer. Parsesand hashes the log records if new data found. */iboolrecv_scan_log_recs(/*===============*/				/* out: TRUE if limit_lsn has been reached, or				not able to scan any more in this log group */	ibool	apply_automatically,/* in: TRUE if we want this function to				apply log records automatically when the				hash table becomes full; in the hot backup tool				the tool does the applying, not this				function */	ulint	available_memory,/* in: we let the hash table of recs to grow				to this size, at the maximum */	ibool	store_to_hash,	/* in: TRUE if the records should be stored				to the hash table; this is set to FALSE if just				debug checking is needed */	byte*	buf,		/* in: buffer containing a log segment or				garbage */	ulint	len,		/* in: buffer length */	dulint	start_lsn,	/* in: buffer start lsn */	dulint*	contiguous_lsn,	/* in/out: it is known that all log groups				contain contiguous log data up to this lsn */	dulint*	group_scanned_lsn)/* out: scanning succeeded up to this lsn */{	byte*	log_block;	ulint	no;	dulint	scanned_lsn;	ibool	finished;	ulint	data_len;	ibool	more_data;	ut_ad(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);	ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);	ut_ad(len > 0);	ut_a(apply_automatically <= TRUE);	ut_a(store_to_hash <= TRUE);		finished = FALSE;		log_block = buf;	scanned_lsn = start_lsn;	more_data = FALSE;		while (log_block < buf + len && !finished) {		no = log_block_get_hdr_no(log_block);/*		fprintf(stderr, "Log block header no %lu\n", no);		fprintf(stderr, "Scanned lsn no %lu\n",				log_block_convert_lsn_to_no(scanned_lsn));*/		if (no != log_block_convert_lsn_to_no(scanned_lsn)		    || !log_block_checksum_is_ok_or_old_format(log_block)) {			if (no == log_block_convert_lsn_to_no(scanned_lsn)			    && !log_block_checksum_is_ok_or_old_format(								log_block)) {				fprintf(stderr,"InnoDB: Log block no %lu at lsn %lu %lu has\n""InnoDB: ok header, but checksum field contains %lu, should be %lu\n",				(ulong) no,				(ulong) ut_dulint_get_high(scanned_lsn),				(ulong) ut_dulint_get_low(scanned_lsn),				(ulong) log_block_get_checksum(log_block),				(ulong) log_block_calc_checksum(log_block));			}			/* Garbage or an incompletely written log block */			finished = TRUE;			break;		}		if (log_block_get_flush_bit(log_block)) {			/* This block was a start of a log flush operation:			we know that the previous flush operation must have			been completed for all log groups before this block			can have been flushed to any of the groups. Therefore,			we know that log data is contiguous up to scanned_lsn			in all non-corrupt log groups. */			if (ut_dulint_cmp(scanned_lsn, *contiguous_lsn) > 0) {				*contiguous_lsn = scanned_lsn;			}		}		data_len = log_block_get_data_len(log_block);		if ((store_to_hash || (data_len == OS_FILE_LOG_BLOCK_SIZE))		    && (ut_dulint_cmp(ut_dulint_add(scanned_lsn, data_len),						recv_sys->scanned_lsn) > 0)		    && (recv_sys->scanned_checkpoint_no > 0)		    && (log_block_get_checkpoint_no(log_block)		       < recv_sys->scanned_checkpoint_no)		    && (recv_sys->scanned_checkpoint_no			- log_block_get_checkpoint_no(log_block)			> 0x80000000UL)) {			/* Garbage from a log buffer flush which was made			before the most recent database recovery */			finished = TRUE;#ifdef UNIV_LOG_DEBUG			/* This is not really an error, but currently			we stop here in the debug version: */			ut_error;#endif			break;		}		    				if (ut_dulint_is_zero(recv_sys->parse_start_lsn)			&& (log_block_get_first_rec_group(log_block) > 0)) {			/* We found a point from which to start the parsing			of log records */			recv_sys->parse_start_lsn =				ut_dulint_add(scanned_lsn,				   log_block_get_first_rec_group(log_block));			recv_sys->scanned_lsn = recv_sys->parse_start_lsn;			recv_sys->recovered_lsn = recv_sys->parse_start_lsn;		}		scanned_lsn = ut_dulint_add(scanned_lsn, data_len);		if (ut_dulint_cmp(scanned_lsn, recv_sys->scanned_lsn) > 0) {			/* We were able to find more log data: add it to the			parsing buffer if parse_start_lsn is already			non-zero */			if (recv_sys->len + 4 * OS_FILE_LOG_BLOCK_SIZE						>= RECV_PARSING_BUF_SIZE) {				fprintf(stderr,"InnoDB: Error: log parsing buffer overflow. Recovery may have failed!\n");				recv_sys->found_corrupt_log = TRUE;			} else if (!recv_sys->found_corrupt_log) {				more_data = recv_sys_add_to_parsing_buf(						log_block, scanned_lsn);			}			recv_sys->scanned_lsn = scanned_lsn;			recv_sys->scanned_checkpoint_no =					log_block_get_checkpoint_no(log_block);		}								if (data_len < OS_FILE_LOG_BLOCK_SIZE) {			/* Log data for this group ends here */			finished = TRUE;		} else {			log_block += OS_FILE_LOG_BLOCK_SIZE;		}	}	*group_scanned_lsn = scanned_lsn;	if (recv_needed_recovery	    || (recv_is_from_backup && !recv_is_making_a_backup)) {		recv_scan_print_counter++;		if (finished || (recv_scan_print_counter % 80 == 0)) {			fprintf(stderr, "InnoDB: Doing recovery: scanned up to log sequence number %lu %lu\n",				(ulong) ut_dulint_get_high(*group_scanned_lsn),				(ulong) ut_dulint_get_low(*group_scanned_lsn));		}	}	if (more_data && !recv_sys->found_corrupt_log) {		/* Try to parse more log records */		recv_parse_log_recs(store_to_hash);		if (store_to_hash && mem_heap_get_size(recv_sys->heap)						> available_memory		    && apply_automatically) {									/* Hash table of log records has grown too big:			empty it; FALSE means no ibuf 

⌨️ 快捷键说明

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