Commit ce22ebd0 authored by unknown's avatar unknown
Browse files

fil0fil.c:

  Add fault tolerance in the scan of .ibd files at a crash recovery; formerly a single failure of readdir_get_next caused the rest of the directory to be skipped


innobase/fil/fil0fil.c:
  Add fault tolerance in the scan of .ibd files at a crash recovery; formerly a single failure of readdir_get_next caused the rest of the directory to be skipped
parent 78bdb7d5
Loading
Loading
Loading
Loading
+51 −19
Original line number Diff line number Diff line
@@ -2924,6 +2924,44 @@ fil_load_single_table_tablespace(
	mem_free(filepath);
}

/***************************************************************************
A fault-tolerant function that tries to read the next file name in the
directory. We retry 100 times if os_file_readdir_next_file() returns -1. The
idea is to read as much good data as we can and jump over bad data. */
static
int
fil_file_readdir_next_file(
/*=======================*/
				/* out: 0 if ok, -1 if error even after the
				retries, 1 if at the end of the directory */
	ulint*		err,	/* out: this is set to DB_ERROR if an error
				was encountered, otherwise not changed */
	const char*	dirname,/* in: directory name or path */
	os_file_dir_t	dir,	/* in: directory stream */
	os_file_stat_t*	info)	/* in/out: buffer where the info is returned */
{
	ulint	i;
	int	ret;

	for (i = 0; i < 100; i++) {
		ret = os_file_readdir_next_file(dirname, dir, info);

		if (ret != -1) {

			return(ret);
		}
		
		fprintf(stderr,
"InnoDB: Error: os_file_readdir_next_file() returned -1 in\n"
"InnoDB: directory %s\n"
"InnoDB: Crash recovery may have failed for some .ibd files!\n", dirname);

		*err = DB_ERROR;
	}

	return(-1);
}

/************************************************************************
At the server startup, if we need crash recovery, scans the database
directories under the MySQL datadir, looking for .ibd files. Those files are
@@ -2944,6 +2982,7 @@ fil_load_single_table_tablespaces(void)
	os_file_dir_t	dbdir;
	os_file_stat_t	dbinfo;
	os_file_stat_t	fileinfo;
	ulint		err 		= DB_SUCCESS;

	/* The datadir of MySQL is always the default directory of mysqld */

@@ -2959,7 +2998,7 @@ fil_load_single_table_tablespaces(void)
	/* Scan all directories under the datadir. They are the database
	directories of MySQL. */

	ret = os_file_readdir_next_file(fil_path_to_mysql_datadir, dir,
	ret = fil_file_readdir_next_file(&err, fil_path_to_mysql_datadir, dir,
								&dbinfo);
	while (ret == 0) {
		ulint len;
@@ -2997,7 +3036,7 @@ fil_load_single_table_tablespaces(void)
			/* We found a database directory; loop through it,
			looking for possible .ibd files in it */

			ret = os_file_readdir_next_file(dbpath, dbdir,
			ret = fil_file_readdir_next_file(&err, dbpath, dbdir,
								&fileinfo);
			while (ret == 0) {
				/* printf(
@@ -3019,7 +3058,8 @@ fil_load_single_table_tablespaces(void)
						dbinfo.name, fileinfo.name);
				}
next_file_item:
				ret = os_file_readdir_next_file(dbpath, dbdir,
				ret = fil_file_readdir_next_file(&err,
								dbpath, dbdir,
								&fileinfo);
			}

@@ -3028,27 +3068,19 @@ fil_load_single_table_tablespaces(void)
"InnoDB: Warning: could not close database directory ", stderr);
				ut_print_filename(stderr, dbpath);
				putc('\n', stderr);

				err = DB_ERROR;
			}
		}
		
next_datadir_item:
		ret = os_file_readdir_next_file(fil_path_to_mysql_datadir,
		ret = fil_file_readdir_next_file(&err,
						fil_path_to_mysql_datadir,
								dir, &dbinfo);
	}

	mem_free(dbpath);

	/* At the end of directory we should get 1 as the return value, -1
	if there was an error */
	if (ret != 1) {
		fprintf(stderr,
"InnoDB: Error: os_file_readdir_next_file returned %d in MySQL datadir\n",
							       ret);
		os_file_closedir(dir);

		return(DB_ERROR);
	}

	if (0 != os_file_closedir(dir)) {
		fprintf(stderr,
"InnoDB: Error: could not close MySQL datadir\n");
@@ -3056,7 +3088,7 @@ fil_load_single_table_tablespaces(void)
		return(DB_ERROR);
	}

	return(DB_SUCCESS);
	return(err);
}

/************************************************************************