Skip to content

Commit 07d4b8a

Browse files
committed
Add threads for restore.
1 parent fed13c2 commit 07d4b8a

File tree

3 files changed

+89
-41
lines changed

3 files changed

+89
-41
lines changed

data.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,6 @@ restore_data_file(const char *from_root,
359359
}
360360
}
361361

362-
elog(LOG, "header block: %i, blknum: %i, hole_offset: %i, BLCKSZ:%i",
363-
header.block,
364-
blknum,
365-
header.hole_offset,
366-
BLCKSZ);
367362
if (header.block < blknum || header.hole_offset > BLCKSZ ||
368363
(int) header.hole_offset + (int) header.hole_length > BLCKSZ)
369364
{

restore.c

Lines changed: 88 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,18 @@
1313
#include <sys/stat.h>
1414
#include <sys/types.h>
1515
#include <unistd.h>
16+
#include <pthread.h>
1617

1718
#include "catalog/pg_control.h"
1819

20+
typedef struct
21+
{
22+
parray *files;
23+
pgBackup *backup;
24+
unsigned int start_file_idx;
25+
unsigned int end_file_idx;
26+
} restore_files_args;
27+
1928
static void backup_online_files(bool re_recovery);
2029
static void restore_database(pgBackup *backup);
2130
static void create_recovery_conf(const char *target_time,
@@ -35,6 +44,8 @@ static void print_backup_lsn(const pgBackup *backup);
3544
static void search_next_wal(const char *path,
3645
XLogRecPtr *need_lsn,
3746
parray *timelines);
47+
static void restore_files(void *arg);
48+
3849

3950
int
4051
do_restore(const char *target_time,
@@ -230,6 +241,8 @@ restore_database(pgBackup *backup)
230241
int ret;
231242
parray *files;
232243
int i;
244+
pthread_t restore_threads[num_threads];
245+
restore_files_args *restore_threads_args[num_threads];
233246

234247
/* confirm block size compatibility */
235248
if (backup->block_size != BLCKSZ)
@@ -300,46 +313,36 @@ restore_database(pgBackup *backup)
300313
pgFileFree(parray_remove(files, i));
301314
}
302315

316+
if (num_threads < 1)
317+
num_threads = 1;
318+
303319
/* restore files into $PGDATA */
304-
for (i = 0; i < parray_num(files); i++)
320+
for (i = 0; i < num_threads; i++)
305321
{
306-
char from_root[MAXPGPATH];
307-
pgFile *file = (pgFile *) parray_get(files, i);
308-
309-
pgBackupGetPath(backup, from_root, lengthof(from_root), DATABASE_DIR);
310-
311-
/* check for interrupt */
312-
if (interrupted)
313-
elog(ERROR, "interrupted during restore database");
314-
315-
/* print progress */
316-
if (!check)
317-
elog(LOG, "(%d/%lu) %s ", i + 1, (unsigned long) parray_num(files),
318-
file->path + strlen(from_root) + 1);
319-
320-
/* directories are created with mkdirs.sh */
321-
if (S_ISDIR(file->mode))
322-
{
323-
if (!check)
324-
elog(LOG, "directory, skip");
325-
continue;
326-
}
322+
restore_files_args *arg = pg_malloc(sizeof(restore_files_args));
323+
arg->files = files;
324+
arg->backup = backup;
325+
arg->start_file_idx = i * (parray_num(files)/num_threads);
326+
if (i == num_threads - 1)
327+
arg->end_file_idx = parray_num(files);
328+
else
329+
arg->end_file_idx = (i + 1) * (parray_num(files)/num_threads);
327330

328-
/* not backed up */
329-
if (file->write_size == BYTES_INVALID)
330-
{
331-
if (!check)
332-
elog(LOG, "not backed up, skip");
333-
continue;
334-
}
331+
if (verbose)
332+
elog(WARNING, "Start thread for start_file_idx:%i end_file_idx:%i num:%li",
333+
arg->start_file_idx,
334+
arg->end_file_idx,
335+
parray_num(files));
335336

336-
/* restore file */
337-
if (!check)
338-
restore_data_file(from_root, pgdata, file);
337+
restore_threads_args[i] = arg;
338+
pthread_create(&restore_threads[i], NULL, (void *(*)(void *)) restore_files, arg);
339+
}
339340

340-
/* print size of restored file */
341-
if (!check)
342-
elog(LOG, "restored %lu\n", (unsigned long) file->write_size);
341+
/* Wait theads */
342+
for (i = 0; i < num_threads; i++)
343+
{
344+
pthread_join(restore_threads[i], NULL);
345+
pg_free(restore_threads_args[i]);
343346
}
344347

345348
/* Delete files which are not in file list. */
@@ -391,6 +394,56 @@ restore_database(pgBackup *backup)
391394
}
392395

393396

397+
static void
398+
restore_files(void *arg)
399+
{
400+
int i;
401+
402+
restore_files_args *arguments = (restore_files_args *)arg;
403+
404+
/* restore files into $PGDATA */
405+
for (i = arguments->start_file_idx; i < arguments->end_file_idx; i++)
406+
{
407+
char from_root[MAXPGPATH];
408+
pgFile *file = (pgFile *) parray_get(arguments->files, i);
409+
410+
pgBackupGetPath(arguments->backup, from_root, lengthof(from_root), DATABASE_DIR);
411+
412+
/* check for interrupt */
413+
if (interrupted)
414+
elog(ERROR, "interrupted during restore database");
415+
416+
/* print progress */
417+
if (!check)
418+
elog(LOG, "(%d/%lu) %s ", i + 1, (unsigned long) parray_num(arguments->files),
419+
file->path + strlen(from_root) + 1);
420+
421+
/* directories are created with mkdirs.sh */
422+
if (S_ISDIR(file->mode))
423+
{
424+
if (!check)
425+
elog(LOG, "directory, skip");
426+
continue;
427+
}
428+
429+
/* not backed up */
430+
if (file->write_size == BYTES_INVALID)
431+
{
432+
if (!check)
433+
elog(LOG, "not backed up, skip");
434+
continue;
435+
}
436+
437+
/* restore file */
438+
if (!check)
439+
restore_data_file(from_root, pgdata, file);
440+
441+
/* print size of restored file */
442+
if (!check)
443+
elog(LOG, "restored %lu\n", (unsigned long) file->write_size);
444+
}
445+
}
446+
394447
static void
395448
create_recovery_conf(const char *target_time,
396449
const char *target_xid,

sql/restore.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pg_arman backup -B ${BACKUP_PATH} -b page -p ${TEST_PGPORT} -d postgres --verbos
5050
pg_arman validate -B ${BACKUP_PATH} --verbose >> ${TEST_BASE}/TEST-0002-run.out 2>&1
5151
psql --no-psqlrc -p ${TEST_PGPORT} -d pgbench -c "SELECT * FROM pgbench_branches;" > ${TEST_BASE}/TEST-0002-before.out
5252
pg_ctl stop -m immediate > /dev/null 2>&1
53-
pg_arman restore -B ${BACKUP_PATH} --verbose >> ${TEST_BASE}/TEST-0002-run.out 2>&1;echo $?
53+
pg_arman restore -B ${BACKUP_PATH} -j 4 --verbose >> ${TEST_BASE}/TEST-0002-run.out 2>&1;echo $?
5454
pg_ctl start -w -t 600 > /dev/null 2>&1
5555
psql --no-psqlrc -p ${TEST_PGPORT} -d pgbench -c "SELECT * FROM pgbench_branches;" > ${TEST_BASE}/TEST-0002-after.out
5656
diff ${TEST_BASE}/TEST-0002-before.out ${TEST_BASE}/TEST-0002-after.out

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