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)