60
60
#include "sys/mman.h"
61
61
#endif
62
62
63
+ #include "catalog/catalog.h"
63
64
#include "common/username.h"
64
65
#include "mb/pg_wchar.h"
65
66
#include "getaddrinfo.h"
@@ -218,6 +219,7 @@ static char **filter_lines_with_token(char **lines, const char *token);
218
219
static char * * readfile (const char * path );
219
220
static void writefile (char * path , char * * lines );
220
221
static void walkdir (char * path , void (* action ) (char * fname , bool isdir ));
222
+ static void walktblspc_links (char * path , void (* action ) (char * fname , bool isdir ));
221
223
static void pre_sync_fname (char * fname , bool isdir );
222
224
static void fsync_fname (char * fname , bool isdir );
223
225
static FILE * popen_check (const char * command , const char * mode );
@@ -587,6 +589,55 @@ walkdir(char *path, void (*action) (char *fname, bool isdir))
587
589
(* action ) (path , true);
588
590
}
589
591
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
+
590
641
/*
591
642
* Hint to the OS that it should get ready to fsync() this file.
592
643
*/
@@ -2375,6 +2426,7 @@ static void
2375
2426
perform_fsync (void )
2376
2427
{
2377
2428
char pdir [MAXPGPATH ];
2429
+ char pg_tblspc [MAXPGPATH ];
2378
2430
2379
2431
fputs (_ ("syncing data to disk ... " ), stdout );
2380
2432
fflush (stdout );
@@ -2393,19 +2445,26 @@ perform_fsync(void)
2393
2445
/* first the parent of the PGDATA directory */
2394
2446
pre_sync_fname (pdir , true);
2395
2447
2396
- /* then recursively through the directory */
2448
+ /* then recursively through the data directory */
2397
2449
walkdir (pg_data , pre_sync_fname );
2398
2450
2451
+ /* now do the same thing for everything under pg_tblspc */
2452
+ snprintf (pg_tblspc , MAXPGPATH , "%s/pg_tblspc" , pg_data );
2453
+ walktblspc_links (pg_tblspc , pre_sync_fname );
2454
+
2399
2455
/*
2400
2456
* Now, do the fsync()s in the same order.
2401
2457
*/
2402
2458
2403
2459
/* first the parent of the PGDATA directory */
2404
2460
fsync_fname (pdir , true);
2405
2461
2406
- /* then recursively through the directory */
2462
+ /* then recursively through the data directory */
2407
2463
walkdir (pg_data , fsync_fname );
2408
2464
2465
+ /* and now the same for all tablespaces */
2466
+ walktblspc_links (pg_tblspc , fsync_fname );
2467
+
2409
2468
check_ok ();
2410
2469
}
2411
2470
0 commit comments