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

📄 log0recv.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	        /* The address hash table is externally chained */		recv_addr = hash_get_nth_cell(recv_sys->addr_hash, i)->node;		while (recv_addr != NULL) {			if (!fil_tablespace_exists_in_mem(recv_addr->space)) {/*				fprintf(stderr,"InnoDB: Warning: cannot apply log record to tablespace %lu page %lu,\n""InnoDB: because tablespace with that id does not exist.\n",				      recv_addr->space, recv_addr->page_no);*/				recv_addr->state = RECV_PROCESSED;				ut_a(recv_sys->n_addrs);				recv_sys->n_addrs--;				goto skip_this_recv_addr;			}			/* We simulate a page read made by the buffer pool, to			make sure the recovery apparatus works ok, for			example, the buf_frame_align() function. We must init			the block corresponding to buf_pool->frame_zero			(== page). */			buf_page_init_for_backup_restore(recv_addr->space,						recv_addr->page_no,						buf_block_align(page));			/* Extend the tablespace's last file if the page_no			does not fall inside its bounds; we assume the last			file is auto-extending, and ibbackup copied the file			when it still was smaller */			success = fil_extend_space_to_desired_size(						&actual_size,						recv_addr->space,						recv_addr->page_no + 1);			if (!success) {			  fprintf(stderr,"InnoDB: Fatal error: cannot extend tablespace %lu to hold %lu pages\n",				     recv_addr->space, recv_addr->page_no);				     				exit(1);			}			/* Read the page from the tablespace file using the			fil0fil.c routines */			error = fil_io(OS_FILE_READ, TRUE, recv_addr->space,					recv_addr->page_no, 0, UNIV_PAGE_SIZE,					page, NULL);			if (error != DB_SUCCESS) {			  fprintf(stderr,"InnoDB: Fatal error: cannot read from tablespace %lu page number %lu\n",				     (ulong) recv_addr->space, (ulong) recv_addr->page_no);				     				exit(1);			}			/* Apply the log records to this page */			recv_recover_page(TRUE, FALSE, page, recv_addr->space,						       recv_addr->page_no);			/* Write the page back to the tablespace file using the			fil0fil.c routines */			buf_flush_init_for_writing(page,				mach_read_from_8(page + FIL_PAGE_LSN),				recv_addr->space, recv_addr->page_no);			error = fil_io(OS_FILE_WRITE, TRUE, recv_addr->space,					recv_addr->page_no, 0, UNIV_PAGE_SIZE,					page, NULL);skip_this_recv_addr:			recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);		}		if ((100 * i) / n_hash_cells				!= (100 * (i + 1)) / n_hash_cells) {			fprintf(stderr, "%lu ",                                (ulong) ((100 * i) / n_hash_cells));			fflush(stderr);		}	}	recv_sys_empty_hash();}#ifdef notdefined/***********************************************************************In the debug version, updates the replica of a file page, based on a logrecord. */staticvoidrecv_update_replicate(/*==================*/	byte	type,	/* in: log record type */	ulint	space,	/* in: space id */	ulint	page_no,/* in: page number */	byte*	body,	/* in: log record body */	byte*	end_ptr)/* in: log record end */{	page_t*	replica;	mtr_t	mtr;	byte*	ptr;	mtr_start(&mtr);	mtr_set_log_mode(&mtr, MTR_LOG_NONE);	replica = buf_page_get(space + RECV_REPLICA_SPACE_ADD, page_no,							RW_X_LATCH, &mtr);#ifdef UNIV_SYNC_DEBUG	buf_page_dbg_add_level(replica, SYNC_NO_ORDER_CHECK);#endif /* UNIV_SYNC_DEBUG */								ptr = recv_parse_or_apply_log_rec_body(type, body, end_ptr, replica,									&mtr);	ut_a(ptr == end_ptr);	/* Notify the buffer manager that the page has been updated */	buf_flush_recv_note_modification(buf_block_align(replica),					log_sys->old_lsn, log_sys->old_lsn);	/* Make sure that committing mtr does not call log routines, as	we currently own the log mutex */		mtr.modifications = FALSE;	mtr_commit(&mtr);}/***********************************************************************Checks that two strings are identical. */staticvoidrecv_check_identical(/*=================*/	byte*	str1,	/* in: first string */	byte*	str2,	/* in: second string */	ulint	len)	/* in: length of strings */{	ulint	i;	for (i = 0; i < len; i++) {		if (str1[i] != str2[i]) {			fprintf(stderr,				"Strings do not match at offset %lu\n", i);			ut_print_buf(str1 + i, 16);			fprintf(stderr, "\n");			ut_print_buf(str2 + i, 16);			ut_error;		}	}}				/***********************************************************************In the debug version, checks that the replica of a file page is identicalto the original page. */staticvoidrecv_compare_replicate(/*===================*/	ulint	space,	/* in: space id */	ulint	page_no)/* in: page number */{	page_t*	replica;	page_t*	page;	mtr_t	mtr;	mtr_start(&mtr);	mutex_enter(&(buf_pool->mutex));	page = buf_page_hash_get(space, page_no)->frame;	mutex_exit(&(buf_pool->mutex));	replica = buf_page_get(space + RECV_REPLICA_SPACE_ADD, page_no,							RW_X_LATCH, &mtr);#ifdef UNIV_SYNC_DEBUG	buf_page_dbg_add_level(replica, SYNC_NO_ORDER_CHECK);#endif /* UNIV_SYNC_DEBUG */	recv_check_identical(page + FIL_PAGE_DATA,			replica + FIL_PAGE_DATA,			PAGE_HEADER + PAGE_MAX_TRX_ID - FIL_PAGE_DATA);	recv_check_identical(page + PAGE_HEADER + PAGE_MAX_TRX_ID + 8,			replica + PAGE_HEADER + PAGE_MAX_TRX_ID + 8,			UNIV_PAGE_SIZE - FIL_PAGE_DATA_END			- PAGE_HEADER - PAGE_MAX_TRX_ID - 8);	mtr_commit(&mtr);}/***********************************************************************Checks that a replica of a space is identical to the original space. */voidrecv_compare_spaces(/*================*/	ulint	space1,	/* in: space id */	ulint	space2,	/* in: space id */	ulint	n_pages)/* in: number of pages */{	page_t*	replica;	page_t*	page;	mtr_t	mtr;	page_t*	frame;	ulint	page_no;	replica = buf_frame_alloc();	page = buf_frame_alloc();	for (page_no = 0; page_no < n_pages; page_no++) {			mtr_start(&mtr);		frame = buf_page_get_gen(space1, page_no, RW_S_LATCH, NULL,						BUF_GET_IF_IN_POOL,						__FILE__, __LINE__,						&mtr);		if (frame) {#ifdef UNIV_SYNC_DEBUG			buf_page_dbg_add_level(frame, SYNC_NO_ORDER_CHECK);#endif /* UNIV_SYNC_DEBUG */			ut_memcpy(page, frame, UNIV_PAGE_SIZE);		} else {			/* Read it from file */			fil_io(OS_FILE_READ, TRUE, space1, page_no, 0,						UNIV_PAGE_SIZE, page, NULL);		}		frame = buf_page_get_gen(space2, page_no, RW_S_LATCH, NULL,						BUF_GET_IF_IN_POOL,						__FILE__, __LINE__,						&mtr);		if (frame) {#ifdef UNIV_SYNC_DEBUG			buf_page_dbg_add_level(frame, SYNC_NO_ORDER_CHECK);#endif /* UNIV_SYNC_DEBUG */			ut_memcpy(replica, frame, UNIV_PAGE_SIZE);		} else {			/* Read it from file */			fil_io(OS_FILE_READ, TRUE, space2, page_no, 0,				UNIV_PAGE_SIZE, replica, NULL);		}				recv_check_identical(page + FIL_PAGE_DATA,			replica + FIL_PAGE_DATA,			PAGE_HEADER + PAGE_MAX_TRX_ID - FIL_PAGE_DATA);		recv_check_identical(page + PAGE_HEADER + PAGE_MAX_TRX_ID + 8,			replica + PAGE_HEADER + PAGE_MAX_TRX_ID + 8,			UNIV_PAGE_SIZE - FIL_PAGE_DATA_END			- PAGE_HEADER - PAGE_MAX_TRX_ID - 8);		mtr_commit(&mtr);	}	buf_frame_free(replica);	buf_frame_free(page);}/***********************************************************************Checks that a replica of a space is identical to the original space. Disablesibuf operations and flushes and invalidates the buffer pool pages after thetest. This function can be used to check the recovery before dict or trxsystems are initialized. */voidrecv_compare_spaces_low(/*====================*/	ulint	space1,	/* in: space id */	ulint	space2,	/* in: space id */	ulint	n_pages)/* in: number of pages */{	mutex_enter(&(log_sys->mutex));	recv_apply_hashed_log_recs(FALSE);		mutex_exit(&(log_sys->mutex));	recv_compare_spaces(space1, space2, n_pages);}#endif /* UNIV_LOG_REPLICATE *//***********************************************************************Tries to parse a single log record and returns its length. */staticulintrecv_parse_log_rec(/*===============*/			/* out: length of the record, or 0 if the record was			not complete */	byte*	ptr,	/* in: pointer to a buffer */	byte*	end_ptr,/* in: pointer to the buffer end */	byte*	type,	/* out: type */	ulint*	space,	/* out: space id */	ulint*	page_no,/* out: page number */	byte**	body)	/* out: log record body start */{	byte*	new_ptr;	*body = NULL;	if (ptr == end_ptr) {		return(0);	}	if (*ptr == MLOG_MULTI_REC_END) {			*type = *ptr;		return(1);	}	if (*ptr == MLOG_DUMMY_RECORD) {		*type = *ptr;		*space = ULINT_UNDEFINED - 1; /* For debugging */		return(1);	}	new_ptr = mlog_parse_initial_log_record(ptr, end_ptr, type, space,								page_no);	*body = new_ptr;	if (UNIV_UNLIKELY(!new_ptr)) {	        return(0);	}	/* Check that page_no is sensible */	if (UNIV_UNLIKELY(*page_no > 0x8FFFFFFFUL)) {		recv_sys->found_corrupt_log = TRUE;		return(0);	}	new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr,								NULL, NULL);	if (UNIV_UNLIKELY(new_ptr == NULL)) {		return(0);	}	if (*page_no > recv_max_parsed_page_no) {		recv_max_parsed_page_no = *page_no;	}		return(new_ptr - ptr);}/***********************************************************Calculates the new value for lsn when more data is added to the log. */staticdulintrecv_calc_lsn_on_data_add(/*======================*/	dulint	lsn,	/* in: old lsn */	ulint	len)	/* in: this many bytes of data is added, log block			headers not included */{	ulint	frag_len;	ulint	lsn_len;		frag_len = (ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE)		   					- LOG_BLOCK_HDR_SIZE;	ut_ad(frag_len < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE		      					- LOG_BLOCK_TRL_SIZE);	lsn_len = len + ((len + frag_len)		    	 / (OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE		      					- LOG_BLOCK_TRL_SIZE))		     	 * (LOG_BLOCK_HDR_SIZE + LOG_BLOCK_TRL_SIZE);	return(ut_dulint_add(lsn, lsn_len));}/***********************************************************Checks that the parser recognizes incomplete initial segments of a logrecord as incomplete. */voidrecv_check_incomplete_log_recs(/*===========================*/	byte*	ptr,	/* in: pointer to a complete log record */	ulint	len)	/* in: length of the log record */{	ulint	i;	byte	type;	ulint	space;	ulint	page_no;	byte*	body;		for (i = 0; i < len; i++) {		ut_a(0 == recv_parse_log_rec(ptr, ptr + i, &type, &space,							&page_no, &body));	}}		/***********************************************************Prints diagnostic info of corrupt log. */staticvoidrecv_report_corrupt_log(/*====================*/	byte*	ptr,	/* in: pointer to corrupt log record */	byte	type,	/* in: type of the record */	ulint	space,	/* in: space id, this may also be garbage */	ulint	page_no)/* in: page number, this may also be garbage */{	fprintf(stderr,"InnoDB: ############### CORRUPT LOG RECORD FOUND\n""InnoDB: Log record type %lu, space id %lu, page number %lu\n""InnoDB: Log parsing proceeded successfully up to %lu %lu\n""InnoDB: Previous log record type %lu, is multi %lu\n""InnoDB: Recv offset %lu, prev %lu\n",	(ulong) type, (ulong) space, (ulong) page_no,	(ulong) ut_dulint_get_high(recv_sys->recovered_lsn),        (ulong) ut_dulint_get_low(recv_sys->recovered_lsn),	(ulong) recv_previous_parsed_rec_type,	(ulong) recv_previous_parsed_rec_is_multi,	(ulong) (ptr - recv_sys->buf),	(ulong) recv_previous_parsed_rec_offset);	if ((ulint)(ptr - recv_sys->buf + 100)					> recv_previous_parsed_rec_offset	    && (ulint)(ptr - recv_sys->buf + 100					- recv_previous_parsed_rec_offset)	       < 200000) {		fputs("InnoDB: Hex dump of corrupt log starting 100 bytes before the start\n""InnoDB: of the previous log rec,\n""InnoDB: and ending 100 bytes after the start of the corrupt rec:\n",			stderr); 		ut_print_buf(stderr,		     recv_sys->buf + recv_previous_parsed_rec_offset - 100,		     ptr - recv_sys->buf + 200 -					recv_previous_parsed_rec_offset);		putc('\n', stderr);	}	fputs(	"InnoDB: WARNING: the log file may have been corrupt and it\n"	"InnoDB: is possible that the log scan did not proceed\n"	"InnoDB: far enough in recovery! Please run CHECK TABLE\n"	"InnoDB: on your InnoDB tables to check that they are ok!\n"	"InnoDB: If mysqld crashes after this recovery, look at\n"	"InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n"	"InnoDB: about forcing recovery.\n", stderr);	fflush(stderr);}/***********************************************************Parses log records from a buffer and stores them to a hash table to waitmerging to file pages. */staticiboolrecv_parse_log_recs(/*================*/				/* out: currently always returns FALSE */	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*	ptr;	byte*	end_ptr;	ulint	single_rec;	ulint	len;	ulint	total_len;	dulint	new_recovered_lsn;	dulint	old_lsn;	byte	type;	ulint	space;	ulint	page_no;	byte*	body;	ulint	n_recs;	#ifdef UNIV_SYNC_DEBUG	ut_ad(mutex_own(&(log_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */	ut_ad(!ut_dulint_is_zero(recv_sys->parse_start_lsn));loop:	ptr = recv_sys->buf + recv_sys->recovered_offset;	end_ptr = recv_sys->buf + recv_sys->len;

⌨️ 快捷键说明

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