Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit025584a

Browse files
committed
Change how a base backup decides which files have checksums.
Previously, it thought that any plain file located under global, base,or a tablespace directory had checksums unless it was in a short listof excluded files. Now, it thinks that files in those directories havechecksums if parse_filename_for_nontemp_relation says that they arerelation files. (Temporary relation files don't matter because they'reexcluded from the backup anyway.)This changes the behavior if you have stray files not managed byPostgreSQL in the relevant directories. Previously, you'd get somekind of checksum-related complaint if such files existed, assumingthat the cluster had checksums enabled and that the base backupwasn't run with NOVERIFY_CHECKSUMS. Now, you won't get thosecomplaints any more. That seems like an improvement to me, becausethose files were presumably not created by PostgreSQL and so thereis no reason to think that they would be checksummed like aPostgreSQL relation file. (If we want to complain about such files,we should complain about them existing at all, not just about theirchecksums.)The point of this change is to make the code more consistent.sendDir() was already calling parse_filename_for_nontemp_relation()as part of an effort to determine which files to include in thebackup. So, it already had the information about whether a certainfile was a relation file. sendFile() then used a separate method,embodied in is_checksummed_file(), to make what is essentiallythe same determination. It's better not to make the same decisionusing two different methods, especially in closely-related code.Patch by me. Reviewed by Dilip Kumar and Álvaro Herrera. Thanksalso to Jakub Wartak and Peter Eisentraut for comments, suggestions,and testing on the larger patch set of which this is a part.Discussion:http://postgr.es/m/CAFiTN-snhaKkWhi2Gz5i3cZeKefun6sYL==wBoqqnTXxX4_mFA@mail.gmail.comDiscussion:http://postgr.es/m/202311141312.u4qx5gtpvfq3@alvherre.pgsql
1 parent519fc1b commit025584a

File tree

1 file changed

+55
-117
lines changed

1 file changed

+55
-117
lines changed

‎src/backend/backup/basebackup.c

Lines changed: 55 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ static int64 sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeo
8282
backup_manifest_info*manifest,Oidspcoid);
8383
staticboolsendFile(bbsink*sink,constchar*readfilename,constchar*tarfilename,
8484
structstat*statbuf,boolmissing_ok,
85-
Oiddboid,Oidspcoid,
85+
Oiddboid,Oidspcoid,RelFileNumberrelfilenumber,
86+
unsignedsegno,
8687
backup_manifest_info*manifest);
8788
staticoff_tread_file_data_into_buffer(bbsink*sink,
8889
constchar*readfilename,intfd,
@@ -104,7 +105,6 @@ static void convert_link_to_directory(const char *pathbuf, struct stat *statbuf)
104105
staticvoidperform_base_backup(basebackup_options*opt,bbsink*sink);
105106
staticvoidparse_basebackup_options(List*options,basebackup_options*opt);
106107
staticintcompareWalFileNames(constListCell*a,constListCell*b);
107-
staticboolis_checksummed_file(constchar*fullpath,constchar*filename);
108108
staticintbasebackup_read_file(intfd,char*buf,size_tnbytes,off_toffset,
109109
constchar*filename,boolpartial_read_ok);
110110

@@ -213,23 +213,6 @@ static const struct exclude_list_item excludeFiles[] =
213213
{NULL, false}
214214
};
215215

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-
staticconststructexclude_list_itemnoChecksumFiles[]= {
223-
{"pg_control", false},
224-
{"pg_filenode.map", false},
225-
{"pg_internal.init", true},
226-
{"PG_VERSION", false},
227-
#ifdefEXEC_BACKEND
228-
{"config_exec_params", true},
229-
#endif
230-
{NULL, false}
231-
};
232-
233216
/*
234217
* Actually do a base backup for the specified tablespaces.
235218
*
@@ -356,7 +339,8 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
356339
errmsg("could not stat file \"%s\": %m",
357340
XLOG_CONTROL_FILE)));
358341
sendFile(sink,XLOG_CONTROL_FILE,XLOG_CONTROL_FILE,&statbuf,
359-
false,InvalidOid,InvalidOid,&manifest);
342+
false,InvalidOid,InvalidOid,
343+
InvalidRelFileNumber,0,&manifest);
360344
}
361345
else
362346
{
@@ -625,7 +609,8 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
625609
errmsg("could not stat file \"%s\": %m",pathbuf)));
626610

627611
sendFile(sink,pathbuf,pathbuf,&statbuf, false,
628-
InvalidOid,InvalidOid,&manifest);
612+
InvalidOid,InvalidOid,InvalidRelFileNumber,0,
613+
&manifest);
629614

630615
/* unconditionally mark file as archived */
631616
StatusFilePath(pathbuf,fname,".done");
@@ -1166,7 +1151,8 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
11661151
structstatstatbuf;
11671152
int64size=0;
11681153
constchar*lastDir;/* Split last dir from parent path. */
1169-
boolisDbDir= false;/* Does this directory contain relations? */
1154+
boolisRelationDir= false;/* Does directory contain relations? */
1155+
Oiddboid=InvalidOid;
11701156

11711157
/*
11721158
* 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,
11931179
strncmp(lastDir- (sizeof(TABLESPACE_VERSION_DIRECTORY)-1),
11941180
TABLESPACE_VERSION_DIRECTORY,
11951181
sizeof(TABLESPACE_VERSION_DIRECTORY)-1)==0))
1196-
isDbDir= true;
1182+
{
1183+
isRelationDir= true;
1184+
dboid=atooid(lastDir+1);
1185+
}
11971186
}
1187+
elseif (strcmp(path,"./global")==0)
1188+
isRelationDir= true;
11981189

11991190
dir=AllocateDir(path);
12001191
while ((de=ReadDir(dir,path))!=NULL)
12011192
{
12021193
intexcludeIdx;
12031194
boolexcludeFound;
1204-
RelFileNumberrelNumber;
1205-
ForkNumberrelForkNum;
1206-
unsignedsegno;
1195+
RelFileNumberrelfilenumber=InvalidRelFileNumber;
1196+
ForkNumberrelForkNum=InvalidForkNumber;
1197+
unsignedsegno=0;
1198+
boolisRelationFile= false;
12071199

12081200
/* Skip special stuff */
12091201
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,
12511243
if (excludeFound)
12521244
continue;
12531245

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+
12541256
/* 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)
12581258
{
1259-
/* Never exclude init forks */
1260-
if (relForkNum!=INIT_FORKNUM)
1261-
{
1262-
charinitForkFile[MAXPGPATH];
1259+
charinitForkFile[MAXPGPATH];
12631260

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);
12711267

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);
12771273

1278-
continue;
1279-
}
1274+
continue;
12801275
}
12811276
}
12821277

12831278
/* 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))
12851280
{
12861281
elog(DEBUG2,
12871282
"temporary relation file \"%s\" excluded from backup",
@@ -1420,8 +1415,8 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
14201415

14211416
if (!sizeonly)
14221417
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);
14251420

14261421
if (sent||sizeonly)
14271422
{
@@ -1443,40 +1438,6 @@ sendDir(bbsink *sink, const char *path, int basepathlen, bool sizeonly,
14431438
returnsize;
14441439
}
14451440

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-
staticbool
1453-
is_checksummed_file(constchar*fullpath,constchar*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-
intexcludeIdx;
1461-
1462-
/* Compare file against noChecksumFiles skip list */
1463-
for (excludeIdx=0;noChecksumFiles[excludeIdx].name!=NULL;excludeIdx++)
1464-
{
1465-
intcmplen=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-
14801441
/*
14811442
* Given the member, write the TAR header & send the file.
14821443
*
@@ -1491,15 +1452,14 @@ is_checksummed_file(const char *fullpath, const char *filename)
14911452
staticbool
14921453
sendFile(bbsink*sink,constchar*readfilename,constchar*tarfilename,
14931454
structstat*statbuf,boolmissing_ok,Oiddboid,Oidspcoid,
1455+
RelFileNumberrelfilenumber,unsignedsegno,
14941456
backup_manifest_info*manifest)
14951457
{
14961458
intfd;
14971459
BlockNumberblkno=0;
14981460
intchecksum_failures=0;
14991461
off_tcnt;
15001462
pgoff_tbytes_done=0;
1501-
intsegmentno=0;
1502-
char*segmentpath;
15031463
boolverify_checksum= false;
15041464
pg_checksum_contextchecksum_ctx;
15051465

@@ -1525,36 +1485,14 @@ sendFile(bbsink *sink, const char *readfilename, const char *tarfilename,
15251485
*/
15261486
Assert((sink->bbs_buffer_length %BLCKSZ)==0);
15271487

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;
15581496

15591497
/*
15601498
* 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,
15691507
/* Try to read some more data. */
15701508
cnt=read_file_data_into_buffer(sink,readfilename,fd,bytes_done,
15711509
remaining,
1572-
blkno+segmentno*RELSEG_SIZE,
1510+
blkno+segno*RELSEG_SIZE,
15731511
verify_checksum,
15741512
&checksum_failures);
15751513

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp