6060#include "sys/mman.h"
6161#endif
6262
63+ #include "catalog/catalog.h"
6364#include "common/username.h"
6465#include "mb/pg_wchar.h"
6566#include "getaddrinfo.h"
@@ -218,6 +219,7 @@ static char **filter_lines_with_token(char **lines, const char *token);
218219static char * * readfile (const char * path );
219220static void writefile (char * path , char * * lines );
220221static void walkdir (char * path , void (* action ) (char * fname , bool isdir ));
222+ static void walktblspc_links (char * path , void (* action ) (char * fname , bool isdir ));
221223static void pre_sync_fname (char * fname , bool isdir );
222224static void fsync_fname (char * fname , bool isdir );
223225static FILE * popen_check (const char * command , const char * mode );
@@ -587,6 +589,55 @@ walkdir(char *path, void (*action) (char *fname, bool isdir))
587589 (* action ) (path , true);
588590}
589591
592+ /*
593+ * walktblspc_links: call walkdir on each entry under the given
594+ * pg_tblspc directory, or do nothing if pg_tblspc doesn't exist.
595+ */
596+ static void
597+ walktblspc_links (char * path , void (* action ) (char * fname , bool isdir ))
598+ {
599+ DIR * dir ;
600+ struct dirent * direntry ;
601+ char subpath [MAXPGPATH ];
602+
603+ dir = opendir (path );
604+ if (dir == NULL )
605+ {
606+ if (errno == ENOENT )
607+ return ;
608+ fprintf (stderr , _ ("%s: could not open directory \"%s\": %s\n" ),
609+ progname , path , strerror (errno ));
610+ exit_nicely ();
611+ }
612+
613+ while (errno = 0 , (direntry = readdir (dir )) != NULL )
614+ {
615+ if (strcmp (direntry -> d_name , "." ) == 0 ||
616+ strcmp (direntry -> d_name , ".." ) == 0 )
617+ continue ;
618+
619+ /* fsync the version specific tablespace subdirectory */
620+ snprintf (subpath , sizeof (subpath ), "%s/%s/%s" ,
621+ path , direntry -> d_name , TABLESPACE_VERSION_DIRECTORY );
622+
623+ walkdir (subpath , action );
624+ }
625+
626+ if (errno )
627+ {
628+ fprintf (stderr , _ ("%s: could not read directory \"%s\": %s\n" ),
629+ progname , path , strerror (errno ));
630+ exit_nicely ();
631+ }
632+
633+ if (closedir (dir ))
634+ {
635+ fprintf (stderr , _ ("%s: could not close directory \"%s\": %s\n" ),
636+ progname , path , strerror (errno ));
637+ exit_nicely ();
638+ }
639+ }
640+
590641/*
591642 * Hint to the OS that it should get ready to fsync() this file.
592643 */
@@ -2377,6 +2428,7 @@ static void
23772428perform_fsync (void )
23782429{
23792430 char pdir [MAXPGPATH ];
2431+ char pg_tblspc [MAXPGPATH ];
23802432
23812433 fputs (_ ("syncing data to disk ... " ), stdout );
23822434 fflush (stdout );
@@ -2395,19 +2447,26 @@ perform_fsync(void)
23952447 /* first the parent of the PGDATA directory */
23962448 pre_sync_fname (pdir , true);
23972449
2398- /* then recursively through the directory */
2450+ /* then recursively through the data directory */
23992451 walkdir (pg_data , pre_sync_fname );
24002452
2453+ /* now do the same thing for everything under pg_tblspc */
2454+ snprintf (pg_tblspc , MAXPGPATH , "%s/pg_tblspc" , pg_data );
2455+ walktblspc_links (pg_tblspc , pre_sync_fname );
2456+
24012457 /*
24022458 * Now, do the fsync()s in the same order.
24032459 */
24042460
24052461 /* first the parent of the PGDATA directory */
24062462 fsync_fname (pdir , true);
24072463
2408- /* then recursively through the directory */
2464+ /* then recursively through the data directory */
24092465 walkdir (pg_data , fsync_fname );
24102466
2467+ /* and now the same for all tablespaces */
2468+ walktblspc_links (pg_tblspc , fsync_fname );
2469+
24112470 check_ok ();
24122471}
24132472
0 commit comments