summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2005-04-14 22:27:15 +0300
committerunknown <heikki@hundin.mysql.fi>2005-04-14 22:27:15 +0300
commitce22ebd02dcb85f9b88b934162c0ec52e6dd1658 (patch)
treef8c2f86049402c07fd5dbce15096e707406885c9 /innobase
parent78bdb7d50d259175229195ec37614f84099cd6be (diff)
downloadmariadb-git-ce22ebd02dcb85f9b88b934162c0ec52e6dd1658.tar.gz
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
Diffstat (limited to 'innobase')
-rw-r--r--innobase/fil/fil0fil.c70
1 files changed, 51 insertions, 19 deletions
diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c
index 0f5941ca0d9..773bd709fb7 100644
--- a/innobase/fil/fil0fil.c
+++ b/innobase/fil/fil0fil.c
@@ -2924,6 +2924,44 @@ func_exit:
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,36 +3058,29 @@ 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);
}
if (0 != os_file_closedir(dbdir)) {
- fputs(
+ fputs(
"InnoDB: Warning: could not close database directory ", stderr);
- ut_print_filename(stderr, dbpath);
- putc('\n', 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 @@ next_datadir_item:
return(DB_ERROR);
}
- return(DB_SUCCESS);
+ return(err);
}
/************************************************************************