Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4ac5ae0

Browse files
committed
Mostly works. todo: find bug in restore_compressed_file
1 parent f8ad8c2 commit 4ac5ae0

File tree

6 files changed

+255
-98
lines changed

6 files changed

+255
-98
lines changed

contrib/pg_probackup/backup.c

Lines changed: 77 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,9 +1109,7 @@ backup_cleanup(bool fatal, void *userdata)
11091109
}
11101110
}
11111111

1112-
/*
1113-
* Count bytes in file
1114-
*/
1112+
/* Count bytes in file */
11151113
static long
11161114
file_size(const char *file)
11171115
{
@@ -1120,8 +1118,8 @@ file_size(const char *file)
11201118

11211119
if (!f)
11221120
{
1123-
fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
1124-
progname, file, strerror(errno));
1121+
elog(ERROR, "pg_probackup: could not open file \"%s\" for reading: %s\n",
1122+
file, strerror(errno));
11251123
return -1;
11261124
}
11271125
fseek(f, 0, SEEK_END);
@@ -1130,6 +1128,55 @@ file_size(const char *file)
11301128
return r;
11311129
}
11321130

1131+
bool
1132+
backup_compressed_file_partially(pgFile *file, void *arg, size_t *skip_size)
1133+
{
1134+
bool result = false;
1135+
pgFile *prev_file = NULL;
1136+
size_t current_file_size;
1137+
backup_files_args *arguments = (backup_files_args *) arg;
1138+
1139+
if (arguments->prev_files)
1140+
{
1141+
pgFile **p = (pgFile **) parray_bsearch(arguments->prev_files,
1142+
file, pgFileComparePath);
1143+
if (p)
1144+
prev_file = *p;
1145+
1146+
elog(NOTICE, "file '%s' generation: prev %d, now %d",
1147+
file->path, prev_file->generation, file->generation);
1148+
1149+
/* If file's gc generation has changed since last backup, just copy it*/
1150+
if (prev_file
1151+
&& prev_file->generation == file->generation)
1152+
{
1153+
current_file_size = file_size(file->path);
1154+
1155+
elog(NOTICE, "prev->write_size %lu, current_file_size %lu",
1156+
prev_file->write_size, current_file_size);
1157+
1158+
if (prev_file->write_size == BYTES_INVALID)
1159+
return false;
1160+
1161+
*skip_size = prev_file->write_size;
1162+
1163+
if (current_file_size >= prev_file->write_size)
1164+
{
1165+
elog(NOTICE, "Backup part of the file. %s : %lu",
1166+
file->path, current_file_size - *skip_size);
1167+
result = true;
1168+
}
1169+
else
1170+
elog(ERROR, "Something went wrong. current_file_size %lu, prev %lu",
1171+
current_file_size, prev_file->write_size);
1172+
}
1173+
else
1174+
elog(NOTICE, "Copy full file. Generations are different");
1175+
}
1176+
1177+
return result;
1178+
}
1179+
11331180
/*
11341181
* Take differential backup at page level.
11351182
*/
@@ -1138,6 +1185,7 @@ backup_files(void *arg)
11381185
{
11391186
int i;
11401187
struct timeval tv;
1188+
11411189
backup_files_args *arguments = (backup_files_args *) arg;
11421190

11431191
gettimeofday(&tv, NULL);
@@ -1239,52 +1287,15 @@ backup_files(void *arg)
12391287
continue;
12401288
}
12411289
}
1242-
else
1290+
else if (is_compressed_data_file(file, arguments->files))
12431291
{
1244-
/* Check first if the file is a cfs relation's segment */
1245-
bool is_cfs_relation_segment = false;
1246-
pgFile tmp_file;
1247-
pgFile **pre_search_file;
1248-
pgFile *prev_file = NULL;
1249-
1250-
tmp_file.path = psprintf("%s.cfm", file->path);
1251-
pre_search_file = (pgFile **) parray_bsearch(arguments->files, &tmp_file, pgFileComparePath);
1252-
if (pre_search_file != NULL)
1253-
{
1254-
/* Now check if it's generation has changed since last backup */
1255-
if (arguments->prev_files)
1256-
{
1257-
pgFile **p = (pgFile **) parray_bsearch(arguments->prev_files, file, pgFileComparePath);
1258-
if (p)
1259-
prev_file = *p;
1260-
elog(NOTICE, "file '%s' is a cfs relation's segment generation prev %d, now %d",
1261-
file->path, prev_file->generation, file->generation);
1262-
1263-
if (prev_file && prev_file->generation == file->generation)
1264-
{
1265-
elog(NOTICE, "prev->write_size %lu, file_size %lu", prev_file->write_size, file_size(file->path));
1266-
if (prev_file->write_size == file_size(file->path))
1267-
{
1268-
elog(NOTICE, "File hasn't changed since last backup. Don't copy at all");
1269-
is_cfs_relation_segment = true;
1270-
}
1271-
else
1272-
{
1273-
elog(NOTICE, "Backup part of the file. %s", file->path);
1274-
is_cfs_relation_segment = true;
1275-
}
1276-
}
1277-
}
1278-
}
1279-
pg_free(tmp_file.path);
1280-
1281-
1282-
if (is_cfs_relation_segment)
1292+
size_t skip_size = 0;
1293+
if (backup_compressed_file_partially(file, arguments, &skip_size))
12831294
{
12841295
/* backup cfs segment partly */
12851296
if (!copy_file_partly(arguments->from_root,
12861297
arguments->to_root,
1287-
file, prev_file->write_size))
1298+
file, skip_size))
12881299
{
12891300
/* record as skipped file in file_xxx.txt */
12901301
file->write_size = BYTES_INVALID;
@@ -1302,6 +1313,15 @@ backup_files(void *arg)
13021313
continue;
13031314
}
13041315
}
1316+
else if (!copy_file(arguments->from_root,
1317+
arguments->to_root,
1318+
file))
1319+
{
1320+
/* record as skipped file in file_xxx.txt */
1321+
file->write_size = BYTES_INVALID;
1322+
elog(LOG, "skip");
1323+
continue;
1324+
}
13051325

13061326
elog(LOG, "copied %lu", (unsigned long) file->write_size);
13071327
}
@@ -1377,30 +1397,23 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
13771397
tmp_file.path[path_len-7] = '\0';
13781398

13791399
pre_search_file = (pgFile **) parray_bsearch(list_file, &tmp_file, pgFileComparePath);
1380-
/* Use another scheme for compressed files */
1381-
pgFile map_file;
1382-
pgFile **map_search_file;
1383-
map_file.path = pg_strdup(file->path);
1384-
if (segno > 0)
1385-
sprintf(map_file.path+path_len-7, ".%d.cfm", segno);
1386-
else
1387-
sprintf(map_file.path+path_len-7, ".cfm");
1388-
map_search_file = (pgFile **) parray_bsearch(list_file, &map_file, pgFileComparePath);
13891400

1390-
if (pre_search_file != NULL
1391-
&& map_search_file == NULL)
1401+
if (is_compressed_data_file(&tmp_file, list_file))
1402+
{
1403+
elog(NOTICE, "file %s is compressed, don't remove it from list", tmp_file.path);
1404+
pg_free(tmp_file.path);
1405+
break;
1406+
}
1407+
1408+
if (pre_search_file != NULL)
13921409
{
13931410
search_file = *pre_search_file;
13941411
search_file->ptrack_path = pg_strdup(file->path);
13951412
search_file->segno = segno;
1396-
}
1397-
else
1398-
{
1413+
} else {
13991414
pg_free(tmp_file.path);
1400-
pg_free(map_file.path);
14011415
break;
14021416
}
1403-
pg_free(map_file.path);
14041417
pg_free(tmp_file.path);
14051418
segno++;
14061419
}
@@ -1453,9 +1466,6 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
14531466
}
14541467

14551468
/* mark cfs relations as not data */
1456-
/* TODO
1457-
* Don't mark cfs relations as not_datafile?
1458-
* We can use similar code to check if the file is compressed */
14591469
for (i = 0; i < (int) parray_num(list_file); i++)
14601470
{
14611471
pgFile *file = (pgFile *) parray_get(list_file, i);
@@ -1467,7 +1477,8 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
14671477
pgFile tmp_file;
14681478
tmp_file.path = pg_strdup(file->path);
14691479
tmp_file.path[path_len-4] = '\0';
1470-
pre_search_file = (pgFile **) parray_bsearch(list_file, &tmp_file, pgFileComparePath);
1480+
pre_search_file = (pgFile **) parray_bsearch(list_file,
1481+
&tmp_file, pgFileComparePath);
14711482
if (pre_search_file != NULL)
14721483
{
14731484
FileMap* map;
@@ -1483,13 +1494,9 @@ add_files(parray *files, const char *root, bool add_root, bool is_pgdata)
14831494
break;
14841495
}
14851496

1486-
(*pre_search_file)->last_backup_write_size = map->last_backup_write_size;
14871497
(*pre_search_file)->generation = map->generation;
14881498
(*pre_search_file)->is_datafile = false;
1489-
map->last_backup_write_size = map->physSize;
14901499

1491-
if (cfs_msync(map) < 0)
1492-
elog(LOG, "add_files(). CFS failed to sync map %s: %m", file->path);
14931500
if (cfs_munmap(map) < 0)
14941501
elog(LOG, "add_files(). CFS failed to unmap file %s: %m", file->path);
14951502
if (close(md) < 0)
@@ -1799,12 +1806,3 @@ int cfs_munmap(FileMap* map)
17991806
return munmap(map, sizeof(FileMap));
18001807
#endif
18011808
}
1802-
1803-
int cfs_msync(FileMap* map)
1804-
{
1805-
#ifdef WIN32
1806-
return FlushViewOfFile(map, sizeof(FileMap)) ? 0 : -1;
1807-
#else
1808-
return msync(map, sizeof(FileMap), MS_SYNC);
1809-
#endif
1810-
}

0 commit comments

Comments
 (0)