Skip to content

Commit 6ed7350

Browse files
committed
[Issue #153] Optimize memory consumption: get rid of pgFile.path and pgFile.forkname, use pgFile.rel_path substring for pgFile.name
1 parent 7d8dd36 commit 6ed7350

File tree

10 files changed

+135
-245
lines changed

10 files changed

+135
-245
lines changed

src/archive.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ setup_push_filelist(const char *archive_status_dir, const char *first_file,
945945
/* get list of files from archive_status */
946946
status_files = parray_new();
947947
dir_list_file(status_files, archive_status_dir, false, false, false, 0, FIO_DB_HOST);
948-
parray_qsort(status_files, pgFileComparePath);
948+
parray_qsort(status_files, pgFileCompareName);
949949

950950
for (i = 0; i < parray_num(status_files); i++)
951951
{

src/backup.c

+41-56
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync)
149149
parray *external_dirs = NULL;
150150
parray *database_map = NULL;
151151

152-
pgFile *pg_control = NULL;
153152
PGconn *master_conn = NULL;
154153
PGconn *pg_startbackup_conn = NULL;
155154

@@ -394,7 +393,7 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync)
394393
* Sorted array is used at least in parse_filelist_filenames(),
395394
* extractPageMap(), make_pagemap_from_ptrack().
396395
*/
397-
parray_qsort(backup_files_list, pgFileComparePath);
396+
parray_qsort(backup_files_list, pgFileCompareRelPathWithExternal);
398397

399398
/* Extract information about files in backup_list parsing their names:*/
400399
parse_filelist_filenames(backup_files_list, instance_config.pgdata);
@@ -468,26 +467,18 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync)
468467
if (S_ISDIR(file->mode))
469468
{
470469
char dirpath[MAXPGPATH];
471-
char *dir_name;
472-
473-
if (file->external_dir_num)
474-
dir_name = GetRelativePath(file->path,
475-
parray_get(external_dirs,
476-
file->external_dir_num - 1));
477-
else
478-
dir_name = GetRelativePath(file->path, instance_config.pgdata);
479-
480-
elog(VERBOSE, "Create directory \"%s\"", dir_name);
481470

482471
if (file->external_dir_num)
483472
{
484473
char temp[MAXPGPATH];
485474
snprintf(temp, MAXPGPATH, "%s%d", external_prefix,
486475
file->external_dir_num);
487-
join_path_components(dirpath, temp, dir_name);
476+
join_path_components(dirpath, temp, file->rel_path);
488477
}
489478
else
490-
join_path_components(dirpath, database_path, dir_name);
479+
join_path_components(dirpath, database_path, file->rel_path);
480+
481+
elog(VERBOSE, "Create directory '%s'", dirpath);
491482
fio_mkdir(dirpath, DIR_PERMISSION, FIO_BACKUP_HOST);
492483
}
493484

@@ -590,16 +581,14 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync)
590581
*/
591582
if (current.from_replica && !exclusive_backup)
592583
{
593-
char pg_control_path[MAXPGPATH];
594-
595-
snprintf(pg_control_path, sizeof(pg_control_path), "%s/%s",
596-
instance_config.pgdata, XLOG_CONTROL_FILE);
584+
pgFile *pg_control = NULL;
597585

598586
for (i = 0; i < parray_num(backup_files_list); i++)
599587
{
600588
pgFile *tmp_file = (pgFile *) parray_get(backup_files_list, i);
601589

602-
if (strcmp(tmp_file->path, pg_control_path) == 0)
590+
if (tmp_file->external_dir_num == 0 &&
591+
(strcmp(tmp_file->rel_path, XLOG_CONTROL_FILE) == 0))
603592
{
604593
pg_control = tmp_file;
605594
break;
@@ -608,7 +597,7 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync)
608597

609598
if (!pg_control)
610599
elog(ERROR, "Failed to find file \"%s\" in backup filelist.",
611-
pg_control_path);
600+
XLOG_CONTROL_FILE);
612601

613602
set_min_recovery_point(pg_control, database_path, current.stop_lsn);
614603
}
@@ -636,21 +625,23 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync)
636625

637626
join_path_components(wal_full_path, pg_xlog_path, file->rel_path);
638627

639-
if (S_ISREG(file->mode))
640-
{
641-
file->crc = pgFileGetCRC(wal_full_path, true, false);
642-
file->write_size = file->size;
643-
}
644-
/* Remove file path root prefix*/
645-
if (strstr(file->path, database_path) == file->path)
646-
{
647-
char *ptr = file->path;
628+
if (!S_ISREG(file->mode))
629+
continue;
648630

649-
file->path = pgut_strdup(GetRelativePath(ptr, database_path));
650-
file->rel_path = pgut_strdup(file->path);
651-
free(ptr);
652-
}
631+
file->crc = pgFileGetCRC(wal_full_path, true, false);
632+
file->write_size = file->size;
633+
634+
/* overwrite rel_path, because now it is relative to
635+
* /backup_dir/backups/instance_name/backup_id/database/pg_xlog/
636+
*/
637+
pg_free(file->rel_path);
638+
639+
file->rel_path = pgut_strdup(GetRelativePath(wal_full_path, database_path));
640+
file->name = last_dir_separator(file->rel_path);
641+
642+
/* Now it is relative to /backup_dir/backups/instance_name/backup_id/database/ */
653643
}
644+
654645
/* Add xlog files into the list of backed up files */
655646
parray_concat(backup_files_list, xlog_files_list);
656647
parray_free(xlog_files_list);
@@ -1884,8 +1875,6 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
18841875

18851876
file->write_size = file->size;
18861877
file->uncompressed_size = file->size;
1887-
free(file->path);
1888-
file->path = strdup(PG_BACKUP_LABEL_FILE);
18891878
parray_append(backup_files_list, file);
18901879
}
18911880
}
@@ -1932,8 +1921,7 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
19321921
file->crc = pgFileGetCRC(tablespace_map, true, false);
19331922
file->write_size = file->size;
19341923
}
1935-
free(file->path);
1936-
file->path = strdup(PG_TABLESPACE_MAP_FILE);
1924+
19371925
parray_append(backup_files_list, file);
19381926
}
19391927
}
@@ -2204,13 +2192,13 @@ parse_filelist_filenames(parray *files, const char *root)
22042192
while (i < parray_num(files))
22052193
{
22062194
pgFile *file = (pgFile *) parray_get(files, i);
2207-
char *relative;
2195+
// char *relative;
22082196
int sscanf_result;
22092197

2210-
relative = GetRelativePath(file->path, root);
2198+
// relative = GetRelativePath(file->rel_path, root);
22112199

22122200
if (S_ISREG(file->mode) &&
2213-
path_is_prefix_of_path(PG_TBLSPC_DIR, relative))
2201+
path_is_prefix_of_path(PG_TBLSPC_DIR, file->rel_path))
22142202
{
22152203
/*
22162204
* Found file in pg_tblspc/tblsOid/TABLESPACE_VERSION_DIRECTORY
@@ -2225,21 +2213,21 @@ parse_filelist_filenames(parray *files, const char *root)
22252213
* Check that the file is located under
22262214
* TABLESPACE_VERSION_DIRECTORY
22272215
*/
2228-
sscanf_result = sscanf(relative, PG_TBLSPC_DIR "/%u/%s/%u",
2216+
sscanf_result = sscanf(file->rel_path, PG_TBLSPC_DIR "/%u/%s/%u",
22292217
&tblspcOid, tmp_rel_path, &dbOid);
22302218

22312219
/* Yes, it is */
22322220
if (sscanf_result == 2 &&
22332221
strncmp(tmp_rel_path, TABLESPACE_VERSION_DIRECTORY,
22342222
strlen(TABLESPACE_VERSION_DIRECTORY)) == 0)
2235-
set_cfs_datafiles(files, root, relative, i);
2223+
set_cfs_datafiles(files, root, file->rel_path, i);
22362224
}
22372225
}
22382226

22392227
if (S_ISREG(file->mode) && file->tblspcOid != 0 &&
22402228
file->name && file->name[0])
22412229
{
2242-
if (strcmp(file->forkName, "init") == 0)
2230+
if (file->forkName == INIT)
22432231
{
22442232
/*
22452233
* Do not backup files of unlogged relations.
@@ -2290,7 +2278,6 @@ set_cfs_datafiles(parray *files, const char *root, char *relative, size_t i)
22902278
int p;
22912279
pgFile *prev_file;
22922280
char *cfs_tblspc_path;
2293-
char *relative_prev_file;
22942281

22952282
cfs_tblspc_path = strdup(relative);
22962283
if(!cfs_tblspc_path)
@@ -2302,22 +2289,21 @@ set_cfs_datafiles(parray *files, const char *root, char *relative, size_t i)
23022289
for (p = (int) i; p >= 0; p--)
23032290
{
23042291
prev_file = (pgFile *) parray_get(files, (size_t) p);
2305-
relative_prev_file = GetRelativePath(prev_file->path, root);
23062292

2307-
elog(VERBOSE, "Checking file in cfs tablespace %s", relative_prev_file);
2293+
elog(VERBOSE, "Checking file in cfs tablespace %s", prev_file->rel_path);
23082294

2309-
if (strstr(relative_prev_file, cfs_tblspc_path) != NULL)
2295+
if (strstr(prev_file->rel_path, cfs_tblspc_path) != NULL)
23102296
{
23112297
if (S_ISREG(prev_file->mode) && prev_file->is_datafile)
23122298
{
23132299
elog(VERBOSE, "Setting 'is_cfs' on file %s, name %s",
2314-
relative_prev_file, prev_file->name);
2300+
prev_file->rel_path, prev_file->name);
23152301
prev_file->is_cfs = true;
23162302
}
23172303
}
23182304
else
23192305
{
2320-
elog(VERBOSE, "Breaking on %s", relative_prev_file);
2306+
elog(VERBOSE, "Breaking on %s", prev_file->rel_path);
23212307
break;
23222308
}
23232309
}
@@ -2331,7 +2317,7 @@ set_cfs_datafiles(parray *files, const char *root, char *relative, size_t i)
23312317
void
23322318
process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno)
23332319
{
2334-
char *path;
2320+
// char *path;
23352321
char *rel_path;
23362322
BlockNumber blkno_inseg;
23372323
int segno;
@@ -2343,16 +2329,15 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno)
23432329

23442330
rel_path = relpathperm(rnode, forknum);
23452331
if (segno > 0)
2346-
path = psprintf("%s/%s.%u", instance_config.pgdata, rel_path, segno);
2332+
f.rel_path = psprintf("%s.%u", rel_path, segno);
23472333
else
2348-
path = psprintf("%s/%s", instance_config.pgdata, rel_path);
2334+
f.rel_path = rel_path;
23492335

2350-
pg_free(rel_path);
2336+
f.external_dir_num = 0;
23512337

2352-
f.path = path;
23532338
/* backup_files_list should be sorted before */
23542339
file_item = (pgFile **) parray_bsearch(backup_files_list, &f,
2355-
pgFileComparePath);
2340+
pgFileCompareRelPathWithExternal);
23562341

23572342
/*
23582343
* If we don't have any record of this file in the file map, it means
@@ -2372,7 +2357,7 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno)
23722357
pthread_mutex_unlock(&backup_pagemap_mutex);
23732358
}
23742359

2375-
pg_free(path);
2360+
pg_free(rel_path);
23762361
}
23772362

23782363
/*

src/catalog.c

+10-11
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,9 @@ catalog_get_backup_list(const char *instance_name, time_t requested_backup_id)
471471

472472
backup->root_dir = pgut_strdup(data_path);
473473

474+
backup->database_dir = pgut_malloc(MAXPGPATH);
475+
join_path_components(backup->database_dir, backup->root_dir, DATABASE_DIR);
476+
474477
/* TODO: save encoded backup id */
475478
backup->backup_id = backup->start_time;
476479
if (requested_backup_id != INVALID_BACKUP_ID
@@ -841,6 +844,9 @@ pgBackupCreateDir(pgBackup *backup)
841844
fio_mkdir(path, DIR_PERMISSION, FIO_BACKUP_HOST);
842845
backup->root_dir = pgut_strdup(path);
843846

847+
backup->database_dir = pgut_malloc(MAXPGPATH);
848+
join_path_components(backup->database_dir, backup->root_dir, DATABASE_DIR);
849+
844850
/* create directories for actual backup files */
845851
for (i = 0; i < parray_num(subdirs); i++)
846852
{
@@ -873,7 +879,7 @@ catalog_get_timelines(InstanceConfig *instance)
873879
/* read all xlog files that belong to this archive */
874880
sprintf(arclog_path, "%s/%s/%s", backup_path, "wal", instance->name);
875881
dir_list_file(xlog_files_list, arclog_path, false, false, false, 0, FIO_BACKUP_HOST);
876-
parray_qsort(xlog_files_list, pgFileComparePath);
882+
parray_qsort(xlog_files_list, pgFileCompareName);
877883

878884
timelineinfos = parray_new();
879885
tlinfo = NULL;
@@ -1849,7 +1855,6 @@ write_backup_filelist(pgBackup *backup, parray *files, const char *root,
18491855
int len = 0;
18501856
char line[BLCKSZ];
18511857
pgFile *file = (pgFile *) parray_get(files, i);
1852-
char *path = file->path; /* for streamed WAL files */
18531858

18541859
if (S_ISDIR(file->mode))
18551860
{
@@ -1873,20 +1878,12 @@ write_backup_filelist(pgBackup *backup, parray *files, const char *root,
18731878
}
18741879
}
18751880

1876-
/* for files from PGDATA and external files use rel_path
1877-
* streamed WAL files has rel_path relative not to "database/"
1878-
* but to "database/pg_wal", so for them use path.
1879-
*/
1880-
if ((root && strstr(path, root) == path) ||
1881-
(file->external_dir_num && external_list))
1882-
path = file->rel_path;
1883-
18841881
len = sprintf(line, "{\"path\":\"%s\", \"size\":\"" INT64_FORMAT "\", "
18851882
"\"mode\":\"%u\", \"is_datafile\":\"%u\", "
18861883
"\"is_cfs\":\"%u\", \"crc\":\"%u\", "
18871884
"\"compress_alg\":\"%s\", \"external_dir_num\":\"%d\", "
18881885
"\"dbOid\":\"%u\"",
1889-
path, file->write_size, file->mode,
1886+
file->rel_path, file->write_size, file->mode,
18901887
file->is_datafile ? 1 : 0,
18911888
file->is_cfs ? 1 : 0,
18921889
file->crc,
@@ -2257,6 +2254,7 @@ pgBackupInit(pgBackup *backup)
22572254
backup->server_version[0] = '\0';
22582255
backup->external_dir_str = NULL;
22592256
backup->root_dir = NULL;
2257+
backup->database_dir = NULL;
22602258
backup->files = NULL;
22612259
backup->note = NULL;
22622260
backup->content_crc = 0;
@@ -2272,6 +2270,7 @@ pgBackupFree(void *backup)
22722270
pfree(b->primary_conninfo);
22732271
pfree(b->external_dir_str);
22742272
pfree(b->root_dir);
2273+
pfree(b->database_dir);
22752274
pfree(b->note);
22762275
pfree(backup);
22772276
}

src/checkdb.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ do_block_validation(char *pgdata, uint32 checksum_version)
217217
* 1 - create 'base'
218218
* 2 - create 'base/1'
219219
*/
220-
parray_qsort(files_list, pgFileComparePath);
220+
parray_qsort(files_list, pgFileCompareRelPathWithExternal);
221221
/* Extract information about files in pgdata parsing their names:*/
222222
parse_filelist_filenames(files_list, pgdata);
223223

0 commit comments

Comments
 (0)