Skip to content

Commit b127345

Browse files
committed
Add muti-thread validation.
1 parent 2eb6d92 commit b127345

File tree

3 files changed

+66
-21
lines changed

3 files changed

+66
-21
lines changed

pg_probackup.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ main(int argc, char *argv[])
178178
if (target_time != NULL && target_xid != NULL)
179179
elog(ERROR, "You can't specify recovery-target-time and recovery-target-xid at the same time");
180180

181+
if (num_threads < 1)
182+
num_threads = 1;
183+
181184
/* do actual operation */
182185
if (pg_strcasecmp(cmd, "init") == 0)
183186
return do_init();

restore.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,6 @@ restore_database(pgBackup *backup)
335335
pgFileFree(parray_remove(files, i));
336336
}
337337

338-
if (num_threads < 1)
339-
num_threads = 1;
340-
341338
for (i = 0; i < parray_num(files); i++)
342339
{
343340
pgFile *file = (pgFile *) parray_get(files, i);

validate.c

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,17 @@
1010
#include "pg_probackup.h"
1111

1212
#include <sys/stat.h>
13+
#include <pthread.h>
1314

14-
static bool pgBackupValidateFiles(parray *files, const char *root, bool size_only);
15+
static void pgBackupValidateFiles(void *arg);
16+
17+
typedef struct
18+
{
19+
parray *files;
20+
const char *root;
21+
bool size_only;
22+
bool corrupted;
23+
} validate_files_args;
1524

1625
/*
1726
* Validate files in the backup and update its status to OK.
@@ -85,6 +94,8 @@ pgBackupValidate(pgBackup *backup,
8594
char path[MAXPGPATH];
8695
parray *files;
8796
bool corrupted = false;
97+
pthread_t validate_threads[num_threads];
98+
validate_files_args *validate_threads_args[num_threads];
8899

89100
time2iso(timestamp, lengthof(timestamp), backup->recovery_time);
90101
if (!for_get_timeline)
@@ -102,13 +113,41 @@ pgBackupValidate(pgBackup *backup,
102113
backup->backup_mode == BACKUP_MODE_DIFF_PAGE ||
103114
backup->backup_mode == BACKUP_MODE_DIFF_PTRACK)
104115
{
116+
int i;
105117
elog(LOG, "database files...");
106118
pgBackupGetPath(backup, base_path, lengthof(base_path), DATABASE_DIR);
107119
pgBackupGetPath(backup, path, lengthof(path),
108120
DATABASE_FILE_LIST);
109121
files = dir_read_file_list(base_path, path);
110-
if (!pgBackupValidateFiles(files, base_path, size_only))
111-
corrupted = true;
122+
123+
/* setup threads */
124+
for (i = 0; i < parray_num(files); i++)
125+
{
126+
pgFile *file = (pgFile *) parray_get(files, i);
127+
__sync_lock_release(&file->lock);
128+
}
129+
130+
/* restore files into $PGDATA */
131+
for (i = 0; i < num_threads; i++)
132+
{
133+
validate_files_args *arg = pg_malloc(sizeof(validate_files_args));
134+
arg->files = files;
135+
arg->root = base_path;
136+
arg->size_only = size_only;
137+
arg->corrupted = false;
138+
139+
validate_threads_args[i] = arg;
140+
pthread_create(&validate_threads[i], NULL, (void *(*)(void *)) pgBackupValidateFiles, arg);
141+
}
142+
143+
/* Wait theads */
144+
for (i = 0; i < num_threads; i++)
145+
{
146+
pthread_join(validate_threads[i], NULL);
147+
if (validate_threads_args[i]->corrupted)
148+
corrupted = true;
149+
pg_free(validate_threads_args[i]);
150+
}
112151
parray_walk(files, pgFileFree);
113152
parray_free(files);
114153
}
@@ -140,16 +179,21 @@ get_relative_path(const char *path, const char *root)
140179
/*
141180
* Validate files in the backup with size or CRC.
142181
*/
143-
static bool
144-
pgBackupValidateFiles(parray *files, const char *root, bool size_only)
182+
static void
183+
pgBackupValidateFiles(void *arg)
145184
{
146185
int i;
147186

148-
for (i = 0; i < parray_num(files); i++)
187+
validate_files_args *arguments = (validate_files_args *)arg;
188+
189+
190+
for (i = 0; i < parray_num(arguments->files); i++)
149191
{
150192
struct stat st;
151193

152-
pgFile *file = (pgFile *) parray_get(files, i);
194+
pgFile *file = (pgFile *) parray_get(arguments->files, i);
195+
if (__sync_lock_test_and_set(&file->lock, 1) != 0)
196+
continue;
153197

154198
if (interrupted)
155199
elog(ERROR, "interrupted during validate");
@@ -159,8 +203,8 @@ pgBackupValidateFiles(parray *files, const char *root, bool size_only)
159203
continue;
160204

161205
/* print progress */
162-
elog(LOG, "(%d/%lu) %s", i + 1, (unsigned long) parray_num(files),
163-
get_relative_path(file->path, root));
206+
elog(LOG, "(%d/%lu) %s", i + 1, (unsigned long) parray_num(arguments->files),
207+
get_relative_path(file->path, arguments->root));
164208

165209
/* always validate file size */
166210
if (stat(file->path, &st) == -1)
@@ -169,32 +213,33 @@ pgBackupValidateFiles(parray *files, const char *root, bool size_only)
169213
elog(WARNING, "backup file \"%s\" vanished", file->path);
170214
else
171215
elog(ERROR, "cannot stat backup file \"%s\": %s",
172-
get_relative_path(file->path, root), strerror(errno));
173-
return false;
216+
get_relative_path(file->path, arguments->root), strerror(errno));
217+
arguments->corrupted = true;
218+
return;
174219
}
175220
if (file->write_size != st.st_size)
176221
{
177222
elog(WARNING, "size of backup file \"%s\" must be %lu but %lu",
178-
get_relative_path(file->path, root),
223+
get_relative_path(file->path, arguments->root),
179224
(unsigned long) file->write_size,
180225
(unsigned long) st.st_size);
181-
return false;
226+
arguments->corrupted = true;
227+
return;
182228
}
183229

184230
/* validate CRC too */
185-
if (!size_only)
231+
if (!arguments->size_only)
186232
{
187233
pg_crc32 crc;
188234

189235
crc = pgFileGetCRC(file);
190236
if (crc != file->crc)
191237
{
192238
elog(WARNING, "CRC of backup file \"%s\" must be %X but %X",
193-
get_relative_path(file->path, root), file->crc, crc);
194-
return false;
239+
get_relative_path(file->path, arguments->root), file->crc, crc);
240+
arguments->corrupted = true;
241+
return;
195242
}
196243
}
197244
}
198-
199-
return true;
200245
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy