create-database-fsync-dirs-context.diff

text/x-patch

Filename: create-database-fsync-dirs-context.diff
Type: text/x-patch
Part: 0
Message: Re: [COMMITTERS] Re: pgsql: Speed up CREATE DATABASE by deferring the fsyncs until after

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
File+
src/port/copydir.c 34 1
*** a/src/port/copydir.c
--- b/src/port/copydir.c
***************
*** 37,43 ****
  
  
  static void copy_file(char *fromfile, char *tofile);
! static void fsync_fname(char *fname);
  
  
  /*
--- 37,43 ----
  
  
  static void copy_file(char *fromfile, char *tofile);
! static void fsync_fname(char *fname, bool isdir);
  
  
  /*
***************
*** 121,132 **** copydir(char *fromdir, char *todir, bool recurse)
  					 errmsg("could not stat file \"%s\": %m", tofile)));
  
  		if (S_ISREG(fst.st_mode))
! 			fsync_fname(tofile);
  	}
  	FreeDir(xldir);
  
- #ifdef NOTYET
- 
  	/*
  	 * It's important to fsync the destination directory itself as individual
  	 * file fsyncs don't guarantee that the directory entry for the file is
--- 121,130 ----
  					 errmsg("could not stat file \"%s\": %m", tofile)));
  
  		if (S_ISREG(fst.st_mode))
! 			fsync_fname(tofile, false);
  	}
  	FreeDir(xldir);
  
  	/*
  	 * It's important to fsync the destination directory itself as individual
  	 * file fsyncs don't guarantee that the directory entry for the file is
***************
*** 135,142 **** copydir(char *fromdir, char *todir, bool recurse)
  	 *
  	 * However we can't do this just yet, it has portability issues.
  	 */
! 	fsync_fname(todir);
! #endif
  }
  
  /*
--- 133,139 ----
  	 *
  	 * However we can't do this just yet, it has portability issues.
  	 */
! 	fsync_fname(todir, true);
  }
  
  /*
***************
*** 216,235 **** copy_file(char *fromfile, char *tofile)
  
  /*
   * fsync a file
   */
  static void
! fsync_fname(char *fname)
  {
! 	int			fd = BasicOpenFile(fname,
! 								   O_RDWR | PG_BINARY,
! 								   S_IRUSR | S_IWUSR);
! 
! 	if (fd < 0)
  		ereport(ERROR,
  				(errcode_for_file_access(),
  				 errmsg("could not open file \"%s\": %m", fname)));
  
! 	if (pg_fsync(fd) != 0)
  		ereport(ERROR,
  				(errcode_for_file_access(),
  				 errmsg("could not fsync file \"%s\": %m", fname)));
--- 213,256 ----
  
  /*
   * fsync a file
+  *
+  * Try to fsync directories but ignore errors that indicate the OS
+  * just doesn't allow/require fsyncing directories.
   */
  static void
! fsync_fname(char *fname, bool isdir)
  {
! 	int			fd;
! 	int 		returncode;;
! 
! 	if (!isdir)
! 		fd = BasicOpenFile(fname,
! 						   O_RDWR | PG_BINARY,
! 						   S_IRUSR | S_IWUSR);
! 	else
! 		fd = BasicOpenFile(fname,
! 						   O_RDONLY | PG_BINARY,
! 						   S_IRUSR | S_IWUSR);
! 
! 	/* Some OSs don't allow us to open directories at all */
! 	if (fd < 0 && isdir && errno == EISDIR)
! 		return;
! 
! 	else if (fd < 0)
  		ereport(ERROR,
  				(errcode_for_file_access(),
  				 errmsg("could not open file \"%s\": %m", fname)));
  
! 	returncode = pg_fsync(fd);
! 	
! 	/* Some OSs don't allow us to fsync directories */
! 	if (returncode != 0 && isdir && errno == EBADF)
! 	{
! 		close(fd);
! 		return;
! 	}
! 
! 	if (returncode != 0)
  		ereport(ERROR,
  				(errcode_for_file_access(),
  				 errmsg("could not fsync file \"%s\": %m", fname)));