Fix a race condition that caused pg_database_size() and pg_tablespace_size()
to fail if an object was removed between calls to ReadDir() and stat().
Per discussion in pgsql-hackers.
http://archives.postgresql.org/pgsql-hackers/2007-03/msg00671.php
--
Michael Fuhr
Index: src/backend/utils/adt/dbsize.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/dbsize.c,v
retrieving revision 1.11
diff -c -r1.11 dbsize.c
*** src/backend/utils/adt/dbsize.c 27 Feb 2007 23:48:07 -0000 1.11
--- src/backend/utils/adt/dbsize.c 11 Mar 2007 04:33:55 -0000
***************
*** 52,61 ****
snprintf(filename, MAXPGPATH, "%s/%s", path, direntry->d_name);
if (stat(filename, &fst) < 0)
! ereport(ERROR,
! (errcode_for_file_access(),
! errmsg("could not stat file \"%s\": %m", filename)));
!
dirsize += fst.st_size;
}
--- 52,65 ----
snprintf(filename, MAXPGPATH, "%s/%s", path, direntry->d_name);
if (stat(filename, &fst) < 0)
! {
! if (errno == ENOENT)
! continue;
! else
! ereport(ERROR,
! (errcode_for_file_access(),
! errmsg("could not stat file \"%s\": %m", filename)));
! }
dirsize += fst.st_size;
}
***************
*** 174,182 ****
snprintf(pathname, MAXPGPATH, "%s/%s", tblspcPath, direntry->d_name);
if (stat(pathname, &fst) < 0)
! ereport(ERROR,
! (errcode_for_file_access(),
! errmsg("could not stat file \"%s\": %m", pathname)));
if (fst.st_mode & S_IFDIR)
totalsize += db_dir_size(pathname);
--- 178,191 ----
snprintf(pathname, MAXPGPATH, "%s/%s", tblspcPath, direntry->d_name);
if (stat(pathname, &fst) < 0)
! {
! if (errno == ENOENT)
! continue;
! else
! ereport(ERROR,
! (errcode_for_file_access(),
! errmsg("could not stat file \"%s\": %m", pathname)));
! }
if (fst.st_mode & S_IFDIR)
totalsize += db_dir_size(pathname);
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend