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

Commitfed1ec6

Browse files
committed
Merge branch 'PGPRO-177_cfs_backup' into PGPROEE9_6
2 parents8c4bd45 +b2184c6 commitfed1ec6

File tree

5 files changed

+508
-23
lines changed

5 files changed

+508
-23
lines changed

‎contrib/pg_probackup/backup.c

Lines changed: 177 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,76 @@ backup_cleanup(bool fatal, void *userdata)
11091109
}
11101110
}
11111111

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

12091279
/* copy the file into backup */
1210-
if (!(file->is_datafile
1211-
?backup_data_file(arguments->from_root,arguments->to_root,file,arguments->lsn)
1212-
:copy_file(arguments->from_root,arguments->to_root,file)))
1280+
if (file->is_datafile)
1281+
{
1282+
if (!backup_data_file(arguments->from_root,
1283+
arguments->to_root,file,
1284+
arguments->lsn))
1285+
{
1286+
/* record as skipped file in file_xxx.txt */
1287+
file->write_size=BYTES_INVALID;
1288+
elog(LOG,"skip");
1289+
continue;
1290+
}
1291+
}
1292+
elseif (is_compressed_data_file(file))
1293+
{
1294+
size_tskip_size=0;
1295+
if (backup_compressed_file_partially(file,arguments,&skip_size))
1296+
{
1297+
/* backup cfs segment partly */
1298+
if (!copy_file_partly(arguments->from_root,
1299+
arguments->to_root,
1300+
file,skip_size))
1301+
{
1302+
/* record as skipped file in file_xxx.txt */
1303+
file->write_size=BYTES_INVALID;
1304+
elog(LOG,"skip");
1305+
continue;
1306+
}
1307+
}
1308+
elseif (!copy_file(arguments->from_root,
1309+
arguments->to_root,
1310+
file))
1311+
{
1312+
/* record as skipped file in file_xxx.txt */
1313+
file->write_size=BYTES_INVALID;
1314+
elog(LOG,"skip");
1315+
continue;
1316+
}
1317+
}
1318+
elseif (!copy_file(arguments->from_root,
1319+
arguments->to_root,
1320+
file))
12131321
{
12141322
/* record as skipped file in file_xxx.txt */
12151323
file->write_size=BYTES_INVALID;
@@ -1258,14 +1366,14 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
12581366
relative=file->path+strlen(root)+1;
12591367
if (is_pgdata&&
12601368
!path_is_prefix_of_path("base",relative)&&
1261-
/*!path_is_prefix_of_path("global", relative) &&*/
1369+
/*!path_is_prefix_of_path("global", relative) &&*///TODO What's wrong with this line?
12621370
!path_is_prefix_of_path("pg_tblspc",relative))
12631371
continue;
12641372

12651373
/* Get file name from path */
12661374
fname=last_dir_separator(relative);
12671375

1268-
/* Remove temp tables */
1376+
/* Remove temp tablesfrom the list*/
12691377
if (fname[0]=='t'&&isdigit(fname[1]))
12701378
{
12711379
pgFileFree(file);
@@ -1275,7 +1383,7 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
12751383
}
12761384

12771385
path_len=strlen(file->path);
1278-
/* Get link ptrack file torealations files */
1386+
/* Get link ptrack file torelations files */
12791387
if (path_len>6&&strncmp(file->path+(path_len-6),"ptrack",6)==0)
12801388
{
12811389
pgFile*search_file;
@@ -1284,12 +1392,15 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
12841392
while(true) {
12851393
pgFiletmp_file;
12861394
tmp_file.path=pg_strdup(file->path);
1287-
/* I hope segno not more than 999999 */
1395+
1396+
/* Segno fits into 6 digits since it is not more than 4000 */
12881397
if (segno>0)
12891398
sprintf(tmp_file.path+path_len-7,".%d",segno);
12901399
else
12911400
tmp_file.path[path_len-7]='\0';
1401+
12921402
pre_search_file= (pgFile**)parray_bsearch(list_file,&tmp_file,pgFileComparePath);
1403+
12931404
if (pre_search_file!=NULL)
12941405
{
12951406
search_file=*pre_search_file;
@@ -1303,6 +1414,7 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
13031414
segno++;
13041415
}
13051416

1417+
/* Remove ptrack file itself from backup list */
13061418
pgFileFree(file);
13071419
parray_remove(list_file,i);
13081420
i--;
@@ -1312,9 +1424,9 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
13121424
/* compress map file it is not data file */
13131425
if (path_len>4&&strncmp(file->path+(path_len-4),".cfm",4)==0)
13141426
{
1315-
if (current.backup_mode==BACKUP_MODE_DIFF_PTRACK||
1316-
current.backup_mode==BACKUP_MODE_DIFF_PAGE)
1317-
elog(ERROR,"You can't use incremental backup with compress tablespace");
1427+
if (current.backup_mode==BACKUP_MODE_DIFF_PAGE)
1428+
elog(ERROR,"You can't use PAGE mode backup with compressed tablespace.\n"
1429+
"Try FULL or PTRACK mode instead.");
13181430
continue;
13191431
}
13201432

@@ -1362,11 +1474,34 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
13621474
pgFiletmp_file;
13631475
tmp_file.path=pg_strdup(file->path);
13641476
tmp_file.path[path_len-4]='\0';
1365-
pre_search_file= (pgFile**)parray_bsearch(list_file,&tmp_file,pgFileComparePath);
1477+
pre_search_file= (pgFile**)parray_bsearch(list_file,
1478+
&tmp_file,pgFileComparePath);
13661479
if (pre_search_file!=NULL)
13671480
{
1481+
FileMap*map;
1482+
intmd=open(file->path,O_RDWR|PG_BINARY,0);
1483+
if (md<0)
1484+
elog(ERROR,"add_files(). cannot open cfm file '%s'",file->path);
1485+
1486+
map=cfs_mmap(md);
1487+
if (map==MAP_FAILED)
1488+
{
1489+
elog(LOG,"add_files(). cfs_compression_ration failed to map file %s: %m",file->path);
1490+
close(md);
1491+
break;
1492+
}
1493+
1494+
(*pre_search_file)->generation=map->generation;
13681495
(*pre_search_file)->is_datafile= false;
1496+
1497+
if (cfs_munmap(map)<0)
1498+
elog(LOG,"add_files(). CFS failed to unmap file %s: %m",file->path);
1499+
if (close(md)<0)
1500+
elog(LOG,"add_files(). CFS failed to close file %s: %m",file->path);
13691501
}
1502+
else
1503+
elog(ERROR,"corresponding segment '%s' is not found",tmp_file.path);
1504+
13701505
pg_free(tmp_file.path);
13711506
}
13721507
}
@@ -1638,3 +1773,34 @@ StreamLog(void *arg)
16381773
PQfinish(conn);
16391774
conn=NULL;
16401775
}
1776+
1777+
1778+
FileMap*cfs_mmap(intmd)
1779+
{
1780+
FileMap*map;
1781+
#ifdefWIN32
1782+
HANDLEmh=CreateFileMapping(_get_osfhandle(md),NULL,PAGE_READWRITE,
1783+
0, (DWORD)sizeof(FileMap),NULL);
1784+
if (mh==NULL)
1785+
return (FileMap*)MAP_FAILED;
1786+
1787+
map= (FileMap*)MapViewOfFile(mh,FILE_MAP_ALL_ACCESS,0,0,0);
1788+
CloseHandle(mh);
1789+
if (map==NULL)
1790+
return (FileMap*)MAP_FAILED;
1791+
1792+
#else
1793+
map= (FileMap*)mmap(NULL,sizeof(FileMap),
1794+
PROT_WRITE |PROT_READ,MAP_SHARED,md,0);
1795+
#endif
1796+
returnmap;
1797+
}
1798+
1799+
intcfs_munmap(FileMap*map)
1800+
{
1801+
#ifdefWIN32
1802+
returnUnmapViewOfFile(map) ?0 :-1;
1803+
#else
1804+
returnmunmap(map,sizeof(FileMap));
1805+
#endif
1806+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp