@@ -82,7 +82,8 @@ static int64 sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeo
82
82
backup_manifest_info * manifest ,Oid spcoid );
83
83
static bool sendFile (bbsink * sink ,const char * readfilename ,const char * tarfilename ,
84
84
struct stat * statbuf ,bool missing_ok ,
85
- Oid dboid ,Oid spcoid ,
85
+ Oid dboid ,Oid spcoid ,RelFileNumber relfilenumber ,
86
+ unsigned segno ,
86
87
backup_manifest_info * manifest );
87
88
static off_t read_file_data_into_buffer (bbsink * sink ,
88
89
const char * readfilename ,int fd ,
@@ -104,7 +105,6 @@ static void convert_link_to_directory(const char *pathbuf, struct stat *statbuf)
104
105
static void perform_base_backup (basebackup_options * opt ,bbsink * sink );
105
106
static void parse_basebackup_options (List * options ,basebackup_options * opt );
106
107
static int compareWalFileNames (const ListCell * a ,const ListCell * b );
107
- static bool is_checksummed_file (const char * fullpath ,const char * filename );
108
108
static int basebackup_read_file (int fd ,char * buf ,size_t nbytes ,off_t offset ,
109
109
const char * filename ,bool partial_read_ok );
110
110
@@ -213,23 +213,6 @@ static const struct exclude_list_item excludeFiles[] =
213
213
{NULL , false}
214
214
};
215
215
216
- /*
217
- * List of files excluded from checksum validation.
218
- *
219
- * Note: this list should be kept in sync with what pg_checksums.c
220
- * includes.
221
- */
222
- static const struct exclude_list_item noChecksumFiles []= {
223
- {"pg_control" , false},
224
- {"pg_filenode.map" , false},
225
- {"pg_internal.init" , true},
226
- {"PG_VERSION" , false},
227
- #ifdef EXEC_BACKEND
228
- {"config_exec_params" , true},
229
- #endif
230
- {NULL , false}
231
- };
232
-
233
216
/*
234
217
* Actually do a base backup for the specified tablespaces.
235
218
*
@@ -356,7 +339,8 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
356
339
errmsg ("could not stat file \"%s\": %m" ,
357
340
XLOG_CONTROL_FILE )));
358
341
sendFile (sink ,XLOG_CONTROL_FILE ,XLOG_CONTROL_FILE ,& statbuf ,
359
- false,InvalidOid ,InvalidOid ,& manifest );
342
+ false,InvalidOid ,InvalidOid ,
343
+ InvalidRelFileNumber ,0 ,& manifest );
360
344
}
361
345
else
362
346
{
@@ -625,7 +609,8 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
625
609
errmsg ("could not stat file \"%s\": %m" ,pathbuf )));
626
610
627
611
sendFile (sink ,pathbuf ,pathbuf ,& statbuf , false,
628
- InvalidOid ,InvalidOid ,& manifest );
612
+ InvalidOid ,InvalidOid ,InvalidRelFileNumber ,0 ,
613
+ & manifest );
629
614
630
615
/* unconditionally mark file as archived */
631
616
StatusFilePath (pathbuf ,fname ,".done" );
@@ -1166,7 +1151,8 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
1166
1151
struct stat statbuf ;
1167
1152
int64 size = 0 ;
1168
1153
const char * lastDir ;/* Split last dir from parent path. */
1169
- bool isDbDir = false;/* Does this directory contain relations? */
1154
+ bool isRelationDir = false;/* Does directory contain relations? */
1155
+ Oid dboid = InvalidOid ;
1170
1156
1171
1157
/*
1172
1158
* Determine if the current path is a database directory that can contain
@@ -1193,17 +1179,23 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
1193
1179
strncmp (lastDir - (sizeof (TABLESPACE_VERSION_DIRECTORY )- 1 ),
1194
1180
TABLESPACE_VERSION_DIRECTORY ,
1195
1181
sizeof (TABLESPACE_VERSION_DIRECTORY )- 1 )== 0 ))
1196
- isDbDir = true;
1182
+ {
1183
+ isRelationDir = true;
1184
+ dboid = atooid (lastDir + 1 );
1185
+ }
1197
1186
}
1187
+ else if (strcmp (path ,"./global" )== 0 )
1188
+ isRelationDir = true;
1198
1189
1199
1190
dir = AllocateDir (path );
1200
1191
while ((de = ReadDir (dir ,path ))!= NULL )
1201
1192
{
1202
1193
int excludeIdx ;
1203
1194
bool excludeFound ;
1204
- RelFileNumber relNumber ;
1205
- ForkNumber relForkNum ;
1206
- unsigned segno ;
1195
+ RelFileNumber relfilenumber = InvalidRelFileNumber ;
1196
+ ForkNumber relForkNum = InvalidForkNumber ;
1197
+ unsigned segno = 0 ;
1198
+ bool isRelationFile = false;
1207
1199
1208
1200
/* Skip special stuff */
1209
1201
if (strcmp (de -> d_name ,"." )== 0 || strcmp (de -> d_name ,".." )== 0 )
@@ -1251,37 +1243,40 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
1251
1243
if (excludeFound )
1252
1244
continue ;
1253
1245
1246
+ /*
1247
+ * If there could be non-temporary relation files in this directory,
1248
+ * try to parse the filename.
1249
+ */
1250
+ if (isRelationDir )
1251
+ isRelationFile =
1252
+ parse_filename_for_nontemp_relation (de -> d_name ,
1253
+ & relfilenumber ,
1254
+ & relForkNum ,& segno );
1255
+
1254
1256
/* Exclude all forks for unlogged tables except the init fork */
1255
- if (isDbDir &&
1256
- parse_filename_for_nontemp_relation (de -> d_name ,& relNumber ,
1257
- & relForkNum ,& segno ))
1257
+ if (isRelationFile && relForkNum != INIT_FORKNUM )
1258
1258
{
1259
- /* Never exclude init forks */
1260
- if (relForkNum != INIT_FORKNUM )
1261
- {
1262
- char initForkFile [MAXPGPATH ];
1259
+ char initForkFile [MAXPGPATH ];
1263
1260
1264
- /*
1265
- * If any other type of fork, check if there is an init fork
1266
- * with the same RelFileNumber. If so, the file can be
1267
- * excluded.
1268
- */
1269
- snprintf (initForkFile ,sizeof (initForkFile ),"%s/%u_init" ,
1270
- path ,relNumber );
1261
+ /*
1262
+ * If any other type of fork, check if there is an init fork with
1263
+ * the same RelFileNumber. If so, the file can be excluded.
1264
+ */
1265
+ snprintf (initForkFile ,sizeof (initForkFile ),"%s/%u_init" ,
1266
+ path ,relfilenumber );
1271
1267
1272
- if (lstat (initForkFile ,& statbuf )== 0 )
1273
- {
1274
- elog (DEBUG2 ,
1275
- "unlogged relation file \"%s\" excluded from backup" ,
1276
- de -> d_name );
1268
+ if (lstat (initForkFile ,& statbuf )== 0 )
1269
+ {
1270
+ elog (DEBUG2 ,
1271
+ "unlogged relation file \"%s\" excluded from backup" ,
1272
+ de -> d_name );
1277
1273
1278
- continue ;
1279
- }
1274
+ continue ;
1280
1275
}
1281
1276
}
1282
1277
1283
1278
/* Exclude temporary relations */
1284
- if (isDbDir && looks_like_temp_rel_name (de -> d_name ))
1279
+ if (OidIsValid ( dboid ) && looks_like_temp_rel_name (de -> d_name ))
1285
1280
{
1286
1281
elog (DEBUG2 ,
1287
1282
"temporary relation file \"%s\" excluded from backup" ,
@@ -1420,8 +1415,8 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
1420
1415
1421
1416
if (!sizeonly )
1422
1417
sent = sendFile (sink ,pathbuf ,pathbuf + basepathlen + 1 ,& statbuf ,
1423
- true,isDbDir ? atooid ( lastDir + 1 ) : InvalidOid ,spcoid ,
1424
- manifest );
1418
+ true,dboid ,spcoid ,
1419
+ relfilenumber , segno , manifest );
1425
1420
1426
1421
if (sent || sizeonly )
1427
1422
{
@@ -1443,40 +1438,6 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
1443
1438
return size ;
1444
1439
}
1445
1440
1446
- /*
1447
- * Check if a file should have its checksum validated.
1448
- * We validate checksums on files in regular tablespaces
1449
- * (including global and default) only, and in those there
1450
- * are some files that are explicitly excluded.
1451
- */
1452
- static bool
1453
- is_checksummed_file (const char * fullpath ,const char * filename )
1454
- {
1455
- /* Check that the file is in a tablespace */
1456
- if (strncmp (fullpath ,"./global/" ,9 )== 0 ||
1457
- strncmp (fullpath ,"./base/" ,7 )== 0 ||
1458
- strncmp (fullpath ,"/" ,1 )== 0 )
1459
- {
1460
- int excludeIdx ;
1461
-
1462
- /* Compare file against noChecksumFiles skip list */
1463
- for (excludeIdx = 0 ;noChecksumFiles [excludeIdx ].name != NULL ;excludeIdx ++ )
1464
- {
1465
- int cmplen = strlen (noChecksumFiles [excludeIdx ].name );
1466
-
1467
- if (!noChecksumFiles [excludeIdx ].match_prefix )
1468
- cmplen ++ ;
1469
- if (strncmp (filename ,noChecksumFiles [excludeIdx ].name ,
1470
- cmplen )== 0 )
1471
- return false;
1472
- }
1473
-
1474
- return true;
1475
- }
1476
- else
1477
- return false;
1478
- }
1479
-
1480
1441
/*
1481
1442
* Given the member, write the TAR header & send the file.
1482
1443
*
@@ -1491,15 +1452,14 @@ is_checksummed_file(const char *fullpath, const char *filename)
1491
1452
static bool
1492
1453
sendFile (bbsink * sink ,const char * readfilename ,const char * tarfilename ,
1493
1454
struct stat * statbuf ,bool missing_ok ,Oid dboid ,Oid spcoid ,
1455
+ RelFileNumber relfilenumber ,unsigned segno ,
1494
1456
backup_manifest_info * manifest )
1495
1457
{
1496
1458
int fd ;
1497
1459
BlockNumber blkno = 0 ;
1498
1460
int checksum_failures = 0 ;
1499
1461
off_t cnt ;
1500
1462
pgoff_t bytes_done = 0 ;
1501
- int segmentno = 0 ;
1502
- char * segmentpath ;
1503
1463
bool verify_checksum = false;
1504
1464
pg_checksum_context checksum_ctx ;
1505
1465
@@ -1525,36 +1485,14 @@ sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
1525
1485
*/
1526
1486
Assert ((sink -> bbs_buffer_length %BLCKSZ )== 0 );
1527
1487
1528
- if (!noverify_checksums && DataChecksumsEnabled ())
1529
- {
1530
- char * filename ;
1531
-
1532
- /*
1533
- * Get the filename (excluding path). As last_dir_separator()
1534
- * includes the last directory separator, we chop that off by
1535
- * incrementing the pointer.
1536
- */
1537
- filename = last_dir_separator (readfilename )+ 1 ;
1538
-
1539
- if (is_checksummed_file (readfilename ,filename ))
1540
- {
1541
- verify_checksum = true;
1542
-
1543
- /*
1544
- * Cut off at the segment boundary (".") to get the segment number
1545
- * in order to mix it into the checksum.
1546
- */
1547
- segmentpath = strstr (filename ,"." );
1548
- if (segmentpath != NULL )
1549
- {
1550
- segmentno = atoi (segmentpath + 1 );
1551
- if (segmentno == 0 )
1552
- ereport (ERROR ,
1553
- (errmsg ("invalid segment number %d in file \"%s\"" ,
1554
- segmentno ,filename )));
1555
- }
1556
- }
1557
- }
1488
+ /*
1489
+ * If we weren't told not to verify checksums, and if checksums are
1490
+ * enabled for this cluster, and if this is a relation file, then verify
1491
+ * the checksum.
1492
+ */
1493
+ if (!noverify_checksums && DataChecksumsEnabled ()&&
1494
+ RelFileNumberIsValid (relfilenumber ))
1495
+ verify_checksum = true;
1558
1496
1559
1497
/*
1560
1498
* Loop until we read the amount of data the caller told us to expect. The
@@ -1569,7 +1507,7 @@ sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
1569
1507
/* Try to read some more data. */
1570
1508
cnt = read_file_data_into_buffer (sink ,readfilename ,fd ,bytes_done ,
1571
1509
remaining ,
1572
- blkno + segmentno * RELSEG_SIZE ,
1510
+ blkno + segno * RELSEG_SIZE ,
1573
1511
verify_checksum ,
1574
1512
& checksum_failures );
1575
1513