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

Commit0bdffbc

Browse files
author
Artur Zakirov
committed
Merge branch 'simplify_backup_data_file' into ptrack
2 parents4cb028c +547470a commit0bdffbc

File tree

5 files changed

+649
-300
lines changed

5 files changed

+649
-300
lines changed

‎backup.c

Lines changed: 173 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,75 @@ backup_cleanup(bool fatal, void *userdata)
11051105
}
11061106
}
11071107

1108+
/* Count bytes in file */
1109+
staticlong
1110+
file_size(constchar*file)
1111+
{
1112+
longr;
1113+
FILE*f=fopen(file,"r");
1114+
1115+
if (!f)
1116+
{
1117+
elog(ERROR,"pg_probackup: could not open file \"%s\" for reading: %s\n",
1118+
file,strerror(errno));
1119+
return-1;
1120+
}
1121+
fseek(f,0,SEEK_END);
1122+
r=ftell(f);
1123+
fclose(f);
1124+
returnr;
1125+
}
1126+
1127+
/*
1128+
* Find corresponding file in previous backup.
1129+
* Compare generations and return true if we don't need full copy
1130+
* of the file, but just part of it.
1131+
*
1132+
* skip_size - size of the file in previous backup. We can skip it
1133+
* and copy just remaining part of the file.
1134+
*/
1135+
bool
1136+
backup_compressed_file_partially(pgFile*file,void*arg,size_t*skip_size)
1137+
{
1138+
boolresult= false;
1139+
pgFile*prev_file=NULL;
1140+
size_tcurrent_file_size;
1141+
backup_files_args*arguments= (backup_files_args*)arg;
1142+
1143+
if (arguments->prev_files)
1144+
{
1145+
pgFile**p= (pgFile**)parray_bsearch(arguments->prev_files,
1146+
file,pgFileComparePath);
1147+
if (p)
1148+
prev_file=*p;
1149+
1150+
/* If file's gc generation has changed since last backup, just copy it*/
1151+
if (prev_file&&prev_file->generation==file->generation)
1152+
{
1153+
current_file_size=file_size(file->path);
1154+
1155+
if (prev_file->write_size==BYTES_INVALID)
1156+
return false;
1157+
1158+
*skip_size=prev_file->write_size;
1159+
1160+
if (current_file_size >=prev_file->write_size)
1161+
{
1162+
elog(LOG,"Backup file %s partially: prev_size %lu, current_size %lu",
1163+
file->path,prev_file->write_size,current_file_size);
1164+
result= true;
1165+
}
1166+
else
1167+
elog(ERROR,"Something is wrong with %s. current_file_size %lu, prev %lu",
1168+
file->path,current_file_size,prev_file->write_size);
1169+
}
1170+
else
1171+
elog(LOG,"Copy full %s.",file->path);
1172+
}
1173+
1174+
returnresult;
1175+
}
1176+
11081177
/*
11091178
* Take differential backup at page level.
11101179
*/
@@ -1203,9 +1272,47 @@ backup_files(void *arg)
12031272
}
12041273

12051274
/* copy the file into backup */
1206-
if (!(file->is_datafile
1207-
?backup_data_file(arguments->from_root,arguments->to_root,file,arguments->lsn)
1208-
:copy_file(arguments->from_root,arguments->to_root,file)))
1275+
if (file->is_datafile)
1276+
{
1277+
if (!backup_data_file(arguments->from_root,
1278+
arguments->to_root,file,
1279+
arguments->lsn))
1280+
{
1281+
/* record as skipped file in file_xxx.txt */
1282+
file->write_size=BYTES_INVALID;
1283+
elog(LOG,"skip");
1284+
continue;
1285+
}
1286+
}
1287+
elseif (is_compressed_data_file(file))
1288+
{
1289+
size_tskip_size=0;
1290+
if (backup_compressed_file_partially(file,arguments,&skip_size))
1291+
{
1292+
/* backup cfs segment partly */
1293+
if (!copy_file_partly(arguments->from_root,
1294+
arguments->to_root,
1295+
file,skip_size))
1296+
{
1297+
/* record as skipped file in file_xxx.txt */
1298+
file->write_size=BYTES_INVALID;
1299+
elog(LOG,"skip");
1300+
continue;
1301+
}
1302+
}
1303+
elseif (!copy_file(arguments->from_root,
1304+
arguments->to_root,
1305+
file))
1306+
{
1307+
/* record as skipped file in file_xxx.txt */
1308+
file->write_size=BYTES_INVALID;
1309+
elog(LOG,"skip");
1310+
continue;
1311+
}
1312+
}
1313+
elseif (!copy_file(arguments->from_root,
1314+
arguments->to_root,
1315+
file))
12091316
{
12101317
/* record as skipped file in file_xxx.txt */
12111318
file->write_size=BYTES_INVALID;
@@ -1254,14 +1361,14 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
12541361
relative=file->path+strlen(root)+1;
12551362
if (is_pgdata&&
12561363
!path_is_prefix_of_path("base",relative)&&
1257-
/*!path_is_prefix_of_path("global", relative) &&*/
1364+
/*!path_is_prefix_of_path("global", relative) &&*///TODO What's wrong with this line?
12581365
!path_is_prefix_of_path("pg_tblspc",relative))
12591366
continue;
12601367

12611368
/* Get file name from path */
12621369
fname=last_dir_separator(relative);
12631370

1264-
/* Remove temp tables */
1371+
/* Remove temp tablesfrom the list*/
12651372
if (fname[0]=='t'&&isdigit(fname[1]))
12661373
{
12671374
pgFileFree(file);
@@ -1271,7 +1378,7 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
12711378
}
12721379

12731380
path_len=strlen(file->path);
1274-
/* Get link ptrack file torealations files */
1381+
/* Get link ptrack file torelations files */
12751382
if (path_len>6&&strncmp(file->path+(path_len-6),"ptrack",6)==0)
12761383
{
12771384
pgFile*search_file;
@@ -1280,12 +1387,15 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
12801387
while(true) {
12811388
pgFiletmp_file;
12821389
tmp_file.path=pg_strdup(file->path);
1283-
/* I hope segno not more than 999999 */
1390+
1391+
/* Segno fits into 6 digits since it is not more than 4000 */
12841392
if (segno>0)
12851393
sprintf(tmp_file.path+path_len-7,".%d",segno);
12861394
else
12871395
tmp_file.path[path_len-7]='\0';
1396+
12881397
pre_search_file= (pgFile**)parray_bsearch(list_file,&tmp_file,pgFileComparePath);
1398+
12891399
if (pre_search_file!=NULL)
12901400
{
12911401
search_file=*pre_search_file;
@@ -1299,6 +1409,7 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
12991409
segno++;
13001410
}
13011411

1412+
/* Remove ptrack file itself from backup list */
13021413
pgFileFree(file);
13031414
parray_remove(list_file,i);
13041415
i--;
@@ -1307,12 +1418,7 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
13071418

13081419
/* compress map file it is not data file */
13091420
if (path_len>4&&strncmp(file->path+(path_len-4),".cfm",4)==0)
1310-
{
1311-
if (current.backup_mode==BACKUP_MODE_DIFF_PTRACK||
1312-
current.backup_mode==BACKUP_MODE_DIFF_PAGE)
1313-
elog(ERROR,"You can't use incremental backup with compress tablespace");
13141421
continue;
1315-
}
13161422

13171423
/* name of data file start with digit */
13181424
if (fname==NULL)
@@ -1358,11 +1464,34 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
13581464
pgFiletmp_file;
13591465
tmp_file.path=pg_strdup(file->path);
13601466
tmp_file.path[path_len-4]='\0';
1361-
pre_search_file= (pgFile**)parray_bsearch(list_file,&tmp_file,pgFileComparePath);
1467+
pre_search_file= (pgFile**)parray_bsearch(list_file,
1468+
&tmp_file,pgFileComparePath);
13621469
if (pre_search_file!=NULL)
13631470
{
1471+
FileMap*map;
1472+
intmd=open(file->path,O_RDWR|PG_BINARY,0);
1473+
if (md<0)
1474+
elog(ERROR,"add_files(). cannot open cfm file '%s'",file->path);
1475+
1476+
map=cfs_mmap(md);
1477+
if (map==MAP_FAILED)
1478+
{
1479+
elog(LOG,"add_files(). cfs_compression_ration failed to map file %s: %m",file->path);
1480+
close(md);
1481+
break;
1482+
}
1483+
1484+
(*pre_search_file)->generation=map->generation;
13641485
(*pre_search_file)->is_datafile= false;
1486+
1487+
if (cfs_munmap(map)<0)
1488+
elog(LOG,"add_files(). CFS failed to unmap file %s: %m",file->path);
1489+
if (close(md)<0)
1490+
elog(LOG,"add_files(). CFS failed to close file %s: %m",file->path);
13651491
}
1492+
else
1493+
elog(ERROR,"corresponding segment '%s' is not found",tmp_file.path);
1494+
13661495
pg_free(tmp_file.path);
13671496
}
13681497
}
@@ -1636,3 +1765,34 @@ StreamLog(void *arg)
16361765
PQfinish(conn);
16371766
conn=NULL;
16381767
}
1768+
1769+
1770+
FileMap*cfs_mmap(intmd)
1771+
{
1772+
FileMap*map;
1773+
#ifdefWIN32
1774+
HANDLEmh=CreateFileMapping(_get_osfhandle(md),NULL,PAGE_READWRITE,
1775+
0, (DWORD)sizeof(FileMap),NULL);
1776+
if (mh==NULL)
1777+
return (FileMap*)MAP_FAILED;
1778+
1779+
map= (FileMap*)MapViewOfFile(mh,FILE_MAP_ALL_ACCESS,0,0,0);
1780+
CloseHandle(mh);
1781+
if (map==NULL)
1782+
return (FileMap*)MAP_FAILED;
1783+
1784+
#else
1785+
map= (FileMap*)mmap(NULL,sizeof(FileMap),
1786+
PROT_WRITE |PROT_READ,MAP_SHARED,md,0);
1787+
#endif
1788+
returnmap;
1789+
}
1790+
1791+
intcfs_munmap(FileMap*map)
1792+
{
1793+
#ifdefWIN32
1794+
returnUnmapViewOfFile(map) ?0 :-1;
1795+
#else
1796+
returnmunmap(map,sizeof(FileMap));
1797+
#endif
1798+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp