PostgreSQL Source Code git master
pg_backup_directory.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * pg_backup_directory.c
4 *
5 * A directory format dump is a directory, which contains a "toc.dat" file
6 * for the TOC, and a separate file for each data entry, named "<oid>.dat".
7 * Large objects are stored in separate files named "blob_<oid>.dat",
8 * and there's a plain-text TOC file for each BLOBS TOC entry named
9 * "blobs_<dumpID>.toc" (or just "blobs.toc" in archive versions before 16).
10 *
11 * If compression is used, each data file is individually compressed and the
12 * ".gz" suffix is added to the filenames. The TOC files are never
13 * compressed by pg_dump, however they are accepted with the .gz suffix too,
14 * in case the user has manually compressed them with 'gzip'.
15 *
16 * NOTE: This format is identical to the files written in the tar file in
17 * the 'tar' format, except that we don't write the restore.sql file (TODO),
18 * and the tar format doesn't support compression. Please keep the formats in
19 * sync.
20 *
21 *
22 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
23 * Portions Copyright (c) 1994, Regents of the University of California
24 * Portions Copyright (c) 2000, Philip Warner
25 *
26 * Rights are granted to use this software in any way so long
27 * as this notice is not removed.
28 *
29 * The author is not responsible for loss or damages that may
30 * result from its use.
31 *
32 * IDENTIFICATION
33 * src/bin/pg_dump/pg_backup_directory.c
34 *
35 *-------------------------------------------------------------------------
36 */
37#include "postgres_fe.h"
38
39#include <dirent.h>
40#include <sys/stat.h>
41
42#include "common/file_utils.h"
43#include "compress_io.h"
44#include "dumputils.h"
45#include "parallel.h"
46#include "pg_backup_utils.h"
47
48typedef struct
49{
50 /*
51 * Our archive location. This is basically what the user specified as his
52 * backup file but of course here it is a directory.
53 */
54 char *directory;
55
56 CompressFileHandle *dataFH; /* currently open data file */
57 CompressFileHandle *LOsTocFH; /* file handle for blobs_NNN.toc */
58 ParallelState *pstate; /* for parallel backup / restore */
60
61typedef struct
62{
63 char *filename; /* filename excluding the directory (basename) */
65
66/* prototypes for private functions */
67static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
68static void _StartData(ArchiveHandle *AH, TocEntry *te);
69static void _EndData(ArchiveHandle *AH, TocEntry *te);
70static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
71static int _WriteByte(ArchiveHandle *AH, const int i);
72static int _ReadByte(ArchiveHandle *AH);
73static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
74static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
75static void _CloseArchive(ArchiveHandle *AH);
76static void _ReopenArchive(ArchiveHandle *AH);
77static void _PrintTocData(ArchiveHandle *AH, TocEntry *te);
78
79static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te);
80static void _ReadExtraToc(ArchiveHandle *AH, TocEntry *te);
81static void _PrintExtraToc(ArchiveHandle *AH, TocEntry *te);
82
83static void _StartLOs(ArchiveHandle *AH, TocEntry *te);
84static void _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid);
85static void _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid);
86static void _EndLOs(ArchiveHandle *AH, TocEntry *te);
87static void _LoadLOs(ArchiveHandle *AH, TocEntry *te);
88
89static void _PrepParallelRestore(ArchiveHandle *AH);
90static void _Clone(ArchiveHandle *AH);
91static void _DeClone(ArchiveHandle *AH);
92
95
96static void setFilePath(ArchiveHandle *AH, char *buf,
97 const char *relativeFilename);
98
99/*
100 * Init routine required by ALL formats. This is a global routine
101 * and should be declared in pg_backup_archiver.h
102 *
103 * Its task is to create any extra archive context (using AH->formatData),
104 * and to initialize the supported function pointers.
105 *
106 * It should also prepare whatever its input source is for reading/writing,
107 * and in the case of a read mode connection, it should load the Header & TOC.
108 */
109void
111{
112 lclContext *ctx;
113
114 /* Assuming static functions, this can be copied for each format. */
118 AH->EndDataPtr = _EndData;
122 AH->ReadBufPtr = _ReadBuf;
129
131 AH->StartLOPtr = _StartLO;
132 AH->EndLOPtr = _EndLO;
133 AH->EndLOsPtr = _EndLOs;
134
136 AH->ClonePtr = _Clone;
137 AH->DeClonePtr = _DeClone;
138
141
142 /* Set up our private context */
143 ctx = (lclContext *) pg_malloc0(sizeof(lclContext));
144 AH->formatData = ctx;
145
146 ctx->dataFH = NULL;
147 ctx->LOsTocFH = NULL;
148
149 /*
150 * Now open the TOC file
151 */
152
153 if (!AH->fSpec || strcmp(AH->fSpec, "") == 0)
154 pg_fatal("no output directory specified");
155
156 ctx->directory = AH->fSpec;
157
158 if (AH->mode == archModeWrite)
159 {
160 /* we accept an empty existing directory */
162 }
163 else
164 { /* Read Mode */
165 char fname[MAXPGPATH];
166 CompressFileHandle *tocFH;
167
168 setFilePath(AH, fname, "toc.dat");
169
171 if (tocFH == NULL)
172 pg_fatal("could not open input file \"%s\": %m", fname);
173
174 ctx->dataFH = tocFH;
175
176 /*
177 * The TOC of a directory format dump shares the format code of the
178 * tar format.
179 */
180 AH->format = archTar;
181 ReadHead(AH);
182 AH->format = archDirectory;
183 ReadToc(AH);
184
185 /* Nothing else in the file, so close it again... */
186 if (!EndCompressFileHandle(tocFH))
187 pg_fatal("could not close TOC file: %m");
188 ctx->dataFH = NULL;
189 }
190}
191
192/*
193 * Called by the Archiver when the dumper creates a new TOC entry.
194 *
195 * We determine the filename for this entry.
196*/
197static void
199{
200 lclTocEntry *tctx;
201 char fn[MAXPGPATH];
202
203 tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
204 if (strcmp(te->desc, "BLOBS") == 0)
205 {
206 snprintf(fn, MAXPGPATH, "blobs_%d.toc", te->dumpId);
207 tctx->filename = pg_strdup(fn);
208 }
209 else if (te->dataDumper)
210 {
211 snprintf(fn, MAXPGPATH, "%d.dat", te->dumpId);
212 tctx->filename = pg_strdup(fn);
213 }
214 else
215 tctx->filename = NULL;
216
217 te->formatData = tctx;
218}
219
220/*
221 * Called by the Archiver to save any extra format-related TOC entry
222 * data.
223 *
224 * Use the Archiver routines to write data - they are non-endian, and
225 * maintain other important file information.
226 */
227static void
229{
230 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
231
232 /*
233 * A dumpable object has set tctx->filename, any other object has not.
234 * (see _ArchiveEntry).
235 */
236 if (tctx->filename)
237 WriteStr(AH, tctx->filename);
238 else
239 WriteStr(AH, "");
240}
241
242/*
243 * Called by the Archiver to read any extra format-related TOC data.
244 *
245 * Needs to match the order defined in _WriteExtraToc, and should also
246 * use the Archiver input routines.
247 */
248static void
250{
251 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
252
253 if (tctx == NULL)
254 {
255 tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
256 te->formatData = tctx;
257 }
258
259 tctx->filename = ReadStr(AH);
260 if (strlen(tctx->filename) == 0)
261 {
262 free(tctx->filename);
263 tctx->filename = NULL;
264 }
265}
266
267/*
268 * Called by the Archiver when restoring an archive to output a comment
269 * that includes useful information about the TOC entry.
270 */
271static void
273{
274 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
275
276 if (AH->public.verbose && tctx->filename)
277 ahprintf(AH, "-- File: %s\n", tctx->filename);
278}
279
280/*
281 * Called by the archiver when saving TABLE DATA (not schema). This routine
282 * should save whatever format-specific information is needed to read
283 * the archive back.
284 *
285 * It is called just prior to the dumper's 'DataDumper' routine being called.
286 *
287 * We create the data file for writing.
288 */
289static void
291{
292 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
293 lclContext *ctx = (lclContext *) AH->formatData;
294 char fname[MAXPGPATH];
295
296 setFilePath(AH, fname, tctx->filename);
297
298 ctx->dataFH = InitCompressFileHandle(AH->compression_spec);
299
300 if (!ctx->dataFH->open_write_func(fname, PG_BINARY_W, ctx->dataFH))
301 pg_fatal("could not open output file \"%s\": %m", fname);
302}
303
304/*
305 * Called by archiver when dumper calls WriteData. This routine is
306 * called for both LO and table data; it is the responsibility of
307 * the format to manage each kind of data using StartLO/StartData.
308 *
309 * It should only be called from within a DataDumper routine.
310 *
311 * We write the data to the open data file.
312 */
313static void
314_WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
315{
316 lclContext *ctx = (lclContext *) AH->formatData;
317 CompressFileHandle *CFH = ctx->dataFH;
318
319 errno = 0;
320 if (dLen > 0 && !CFH->write_func(data, dLen, CFH))
321 {
322 /* if write didn't set errno, assume problem is no disk space */
323 if (errno == 0)
324 errno = ENOSPC;
325 pg_fatal("could not write to output file: %s",
326 CFH->get_error_func(CFH));
327 }
328}
329
330/*
331 * Called by the archiver when a dumper's 'DataDumper' routine has
332 * finished.
333 *
334 * We close the data file.
335 */
336static void
338{
339 lclContext *ctx = (lclContext *) AH->formatData;
340
341 /* Close the file */
343 pg_fatal("could not close data file: %m");
344
345 ctx->dataFH = NULL;
346}
347
348/*
349 * Print data for a given file (can be a LO as well)
350 */
351static void
353{
354 size_t cnt = 0;
355 char *buf;
356 size_t buflen;
358
359 if (!filename)
360 return;
361
363 if (!CFH)
364 pg_fatal("could not open input file \"%s\": %m", filename);
365
366 buflen = DEFAULT_IO_BUFFER_SIZE;
367 buf = pg_malloc(buflen);
368
369 while (CFH->read_func(buf, buflen, &cnt, CFH) && cnt > 0)
370 {
371 ahwrite(buf, 1, cnt, AH);
372 }
373
374 free(buf);
375 if (!EndCompressFileHandle(CFH))
376 pg_fatal("could not close data file \"%s\": %m", filename);
377}
378
379/*
380 * Print data for a given TOC entry
381*/
382static void
384{
385 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
386
387 if (!tctx->filename)
388 return;
389
390 if (strcmp(te->desc, "BLOBS") == 0)
391 _LoadLOs(AH, te);
392 else
393 {
394 char fname[MAXPGPATH];
395
396 setFilePath(AH, fname, tctx->filename);
397 _PrintFileData(AH, fname);
398 }
399}
400
401static void
403{
404 Oid oid;
405 lclContext *ctx = (lclContext *) AH->formatData;
406 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
408 char tocfname[MAXPGPATH];
409 char line[MAXPGPATH];
410
411 StartRestoreLOs(AH);
412
413 /*
414 * Note: before archive v16, there was always only one BLOBS TOC entry,
415 * now there can be multiple. We don't need to worry what version we are
416 * reading though, because tctx->filename should be correct either way.
417 */
418 setFilePath(AH, tocfname, tctx->filename);
419
421
422 if (ctx->LOsTocFH == NULL)
423 pg_fatal("could not open large object TOC file \"%s\" for input: %m",
424 tocfname);
425
426 /* Read the LOs TOC file line-by-line, and process each LO */
427 while ((CFH->gets_func(line, MAXPGPATH, CFH)) != NULL)
428 {
429 char lofname[MAXPGPATH + 1];
430 char path[MAXPGPATH];
431
432 /* Can't overflow because line and lofname are the same length */
433 if (sscanf(line, "%u %" CppAsString2(MAXPGPATH) "s\n", &oid, lofname) != 2)
434 pg_fatal("invalid line in large object TOC file \"%s\": \"%s\"",
435 tocfname, line);
436
437 StartRestoreLO(AH, oid, AH->public.ropt->dropSchema);
438 snprintf(path, MAXPGPATH, "%s/%s", ctx->directory, lofname);
439 _PrintFileData(AH, path);
440 EndRestoreLO(AH, oid);
441 }
442 if (!CFH->eof_func(CFH))
443 pg_fatal("error reading large object TOC file \"%s\"",
444 tocfname);
445
447 pg_fatal("could not close large object TOC file \"%s\": %m",
448 tocfname);
449
450 ctx->LOsTocFH = NULL;
451
452 EndRestoreLOs(AH);
453}
454
455
456/*
457 * Write a byte of data to the archive.
458 * Called by the archiver to do integer & byte output to the archive.
459 * These routines are only used to read & write the headers & TOC.
460 */
461static int
463{
464 unsigned char c = (unsigned char) i;
465 lclContext *ctx = (lclContext *) AH->formatData;
466 CompressFileHandle *CFH = ctx->dataFH;
467
468 errno = 0;
469 if (!CFH->write_func(&c, 1, CFH))
470 {
471 /* if write didn't set errno, assume problem is no disk space */
472 if (errno == 0)
473 errno = ENOSPC;
474 pg_fatal("could not write to output file: %s",
475 CFH->get_error_func(CFH));
476 }
477
478 return 1;
479}
480
481/*
482 * Read a byte of data from the archive.
483 * Called by the archiver to read bytes & integers from the archive.
484 * These routines are only used to read & write headers & TOC.
485 * EOF should be treated as a fatal error.
486 */
487static int
489{
490 lclContext *ctx = (lclContext *) AH->formatData;
491 CompressFileHandle *CFH = ctx->dataFH;
492
493 return CFH->getc_func(CFH);
494}
495
496/*
497 * Write a buffer of data to the archive.
498 * Called by the archiver to write a block of bytes to the TOC or a data file.
499 */
500static void
501_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
502{
503 lclContext *ctx = (lclContext *) AH->formatData;
504 CompressFileHandle *CFH = ctx->dataFH;
505
506 errno = 0;
507 if (!CFH->write_func(buf, len, CFH))
508 {
509 /* if write didn't set errno, assume problem is no disk space */
510 if (errno == 0)
511 errno = ENOSPC;
512 pg_fatal("could not write to output file: %s",
513 CFH->get_error_func(CFH));
514 }
515}
516
517/*
518 * Read a block of bytes from the archive.
519 *
520 * Called by the archiver to read a block of bytes from the archive
521 */
522static void
523_ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
524{
525 lclContext *ctx = (lclContext *) AH->formatData;
526 CompressFileHandle *CFH = ctx->dataFH;
527
528 /*
529 * If there was an I/O error, we already exited in readF(), so here we
530 * exit on short reads.
531 */
532 if (!CFH->read_func(buf, len, NULL, CFH))
533 pg_fatal("could not read from input file: end of file");
534}
535
536/*
537 * Close the archive.
538 *
539 * When writing the archive, this is the routine that actually starts
540 * the process of saving it to files. No data should be written prior
541 * to this point, since the user could sort the TOC after creating it.
542 *
543 * If an archive is to be written, this routine must call:
544 * WriteHead to save the archive header
545 * WriteToc to save the TOC entries
546 * WriteDataChunks to save all data & LOs.
547 */
548static void
550{
551 lclContext *ctx = (lclContext *) AH->formatData;
552
553 if (AH->mode == archModeWrite)
554 {
555 CompressFileHandle *tocFH;
556 pg_compress_specification compression_spec = {0};
557 char fname[MAXPGPATH];
558
559 setFilePath(AH, fname, "toc.dat");
560
561 /* this will actually fork the processes for a parallel backup */
562 ctx->pstate = ParallelBackupStart(AH);
563
564 /* The TOC is always created uncompressed */
565 compression_spec.algorithm = PG_COMPRESSION_NONE;
566 tocFH = InitCompressFileHandle(compression_spec);
567 if (!tocFH->open_write_func(fname, PG_BINARY_W, tocFH))
568 pg_fatal("could not open output file \"%s\": %m", fname);
569 ctx->dataFH = tocFH;
570
571 /*
572 * Write 'tar' in the format field of the toc.dat file. The directory
573 * is compatible with 'tar', so there's no point having a different
574 * format code for it.
575 */
576 AH->format = archTar;
577 WriteHead(AH);
578 AH->format = archDirectory;
579 WriteToc(AH);
580 if (!EndCompressFileHandle(tocFH))
581 pg_fatal("could not close TOC file: %m");
582 WriteDataChunks(AH, ctx->pstate);
583
584 ParallelBackupEnd(AH, ctx->pstate);
585
586 /*
587 * In directory mode, there is no need to sync all the entries
588 * individually. Just recurse once through all the files generated.
589 */
590 if (AH->dosync)
591 sync_dir_recurse(ctx->directory, AH->sync_method);
592 }
593 AH->FH = NULL;
594}
595
596/*
597 * Reopen the archive's file handle.
598 */
599static void
601{
602 /*
603 * Our TOC is in memory, our data files are opened by each child anyway as
604 * they are separate. We support reopening the archive by just doing
605 * nothing.
606 */
607}
608
609/*
610 * LO support
611 */
612
613/*
614 * Called by the archiver when starting to save BLOB DATA (not schema).
615 * It is called just prior to the dumper's DataDumper routine.
616 *
617 * We open the large object TOC file here, so that we can append a line to
618 * it for each LO.
619 */
620static void
622{
623 lclContext *ctx = (lclContext *) AH->formatData;
624 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
625 pg_compress_specification compression_spec = {0};
626 char fname[MAXPGPATH];
627
628 setFilePath(AH, fname, tctx->filename);
629
630 /* The LO TOC file is never compressed */
631 compression_spec.algorithm = PG_COMPRESSION_NONE;
632 ctx->LOsTocFH = InitCompressFileHandle(compression_spec);
633 if (!ctx->LOsTocFH->open_write_func(fname, "ab", ctx->LOsTocFH))
634 pg_fatal("could not open output file \"%s\": %m", fname);
635}
636
637/*
638 * Called by the archiver when we're about to start dumping a LO.
639 *
640 * We create a file to write the LO to.
641 */
642static void
644{
645 lclContext *ctx = (lclContext *) AH->formatData;
646 char fname[MAXPGPATH];
647
648 snprintf(fname, MAXPGPATH, "%s/blob_%u.dat", ctx->directory, oid);
649
651 if (!ctx->dataFH->open_write_func(fname, PG_BINARY_W, ctx->dataFH))
652 pg_fatal("could not open output file \"%s\": %m", fname);
653}
654
655/*
656 * Called by the archiver when the dumper is finished writing a LO.
657 *
658 * We close the LO file and write an entry to the LO TOC file for it.
659 */
660static void
662{
663 lclContext *ctx = (lclContext *) AH->formatData;
664 CompressFileHandle *CFH = ctx->LOsTocFH;
665 char buf[50];
666 int len;
667
668 /* Close the BLOB data file itself */
670 pg_fatal("could not close LO data file: %m");
671 ctx->dataFH = NULL;
672
673 /* register the LO in blobs_NNN.toc */
674 len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid);
675 if (!CFH->write_func(buf, len, CFH))
676 {
677 /* if write didn't set errno, assume problem is no disk space */
678 if (errno == 0)
679 errno = ENOSPC;
680 pg_fatal("could not write to LOs TOC file: %s",
681 CFH->get_error_func(CFH));
682 }
683}
684
685/*
686 * Called by the archiver when finishing saving BLOB DATA.
687 *
688 * We close the LOs TOC file.
689 */
690static void
692{
693 lclContext *ctx = (lclContext *) AH->formatData;
694
696 pg_fatal("could not close LOs TOC file: %m");
697 ctx->LOsTocFH = NULL;
698}
699
700/*
701 * Gets a relative file name and prepends the output directory, writing the
702 * result to buf. The caller needs to make sure that buf is MAXPGPATH bytes
703 * big. Can't use a static char[MAXPGPATH] inside the function because we run
704 * multithreaded on Windows.
705 */
706static void
707setFilePath(ArchiveHandle *AH, char *buf, const char *relativeFilename)
708{
709 lclContext *ctx = (lclContext *) AH->formatData;
710 char *dname;
711
712 dname = ctx->directory;
713
714 if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH)
715 pg_fatal("file name too long: \"%s\"", dname);
716
717 strcpy(buf, dname);
718 strcat(buf, "/");
719 strcat(buf, relativeFilename);
720}
721
722/*
723 * Prepare for parallel restore.
724 *
725 * The main thing that needs to happen here is to fill in TABLE DATA and BLOBS
726 * TOC entries' dataLength fields with appropriate values to guide the
727 * ordering of restore jobs. The source of said data is format-dependent,
728 * as is the exact meaning of the values.
729 *
730 * A format module might also choose to do other setup here.
731 */
732static void
734{
735 TocEntry *te;
736
737 for (te = AH->toc->next; te != AH->toc; te = te->next)
738 {
739 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
740 char fname[MAXPGPATH];
741 struct stat st;
742
743 /*
744 * A dumpable object has set tctx->filename, any other object has not.
745 * (see _ArchiveEntry).
746 */
747 if (tctx->filename == NULL)
748 continue;
749
750 /* We may ignore items not due to be restored */
751 if ((te->reqs & (REQ_DATA | REQ_STATS)) == 0)
752 continue;
753
754 /*
755 * Stat the file and, if successful, put its size in dataLength. When
756 * using compression, the physical file size might not be a very good
757 * guide to the amount of work involved in restoring the file, but we
758 * only need an approximate indicator of that.
759 */
760 setFilePath(AH, fname, tctx->filename);
761
762 if (stat(fname, &st) == 0)
763 te->dataLength = st.st_size;
765 {
767 strlcat(fname, ".gz", sizeof(fname));
769 strlcat(fname, ".lz4", sizeof(fname));
771 strlcat(fname, ".zst", sizeof(fname));
772
773 if (stat(fname, &st) == 0)
774 te->dataLength = st.st_size;
775 }
776
777 /*
778 * If this is a BLOBS entry, what we stat'd was blobs_NNN.toc, which
779 * most likely is a lot smaller than the actual blob data. We don't
780 * have a cheap way to estimate how much smaller, but fortunately it
781 * doesn't matter too much as long as we get the LOs processed
782 * reasonably early. Arbitrarily scale up by a factor of 1K.
783 */
784 if (strcmp(te->desc, "BLOBS") == 0)
785 te->dataLength *= 1024;
786 }
787}
788
789/*
790 * Clone format-specific fields during parallel restoration.
791 */
792static void
794{
795 lclContext *ctx = (lclContext *) AH->formatData;
796
797 AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
798 memcpy(AH->formatData, ctx, sizeof(lclContext));
799 ctx = (lclContext *) AH->formatData;
800
801 /*
802 * TOC-entry-local state isn't an issue because any one TOC entry is
803 * touched by just one worker child.
804 */
805
806 /*
807 * We also don't copy the ParallelState pointer (pstate), only the leader
808 * process ever writes to it.
809 */
810}
811
812static void
814{
815 lclContext *ctx = (lclContext *) AH->formatData;
816
817 free(ctx);
818}
819
820/*
821 * This function is executed in the child of a parallel backup for a
822 * directory-format archive and dumps the actual data for one TOC entry.
823 */
824static int
826{
827 /*
828 * This function returns void. We either fail and die horribly or
829 * succeed... A failure will be detected by the parent when the child dies
830 * unexpectedly.
831 */
833
834 return 0;
835}
836
837/*
838 * This function is executed in the child of a parallel restore from a
839 * directory-format archive and restores the actual data for one TOC entry.
840 */
841static int
843{
844 return parallel_restore(AH, te);
845}
void ParallelBackupEnd(ArchiveHandle *AH, ParallelState *pstate)
Definition: parallel.c:1071
ParallelState * ParallelBackupStart(ArchiveHandle *AH)
Definition: parallel.c:909
#define PG_BINARY_R
Definition: c.h:1246
#define CppAsString2(x)
Definition: c.h:363
#define PG_BINARY_W
Definition: c.h:1247
bool EndCompressFileHandle(CompressFileHandle *CFH)
Definition: compress_io.c:288
CompressFileHandle * InitDiscoverCompressFileHandle(const char *path, const char *mode)
Definition: compress_io.c:240
CompressFileHandle * InitCompressFileHandle(const pg_compress_specification compression_spec)
Definition: compress_io.c:194
#define DEFAULT_IO_BUFFER_SIZE
Definition: compress_io.h:27
@ PG_COMPRESSION_GZIP
Definition: compression.h:24
@ PG_COMPRESSION_LZ4
Definition: compression.h:25
@ PG_COMPRESSION_NONE
Definition: compression.h:23
@ PG_COMPRESSION_ZSTD
Definition: compression.h:26
void create_or_open_dir(const char *dirname)
Definition: dumputils.c:897
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define free(a)
Definition: header.h:65
int i
Definition: isn.c:77
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
@ archModeWrite
Definition: pg_backup.h:51
@ archTar
Definition: pg_backup.h:43
@ archDirectory
Definition: pg_backup.h:45
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
void WriteDataChunksForTocEntry(ArchiveHandle *AH, TocEntry *te)
void WriteHead(ArchiveHandle *AH)
char * ReadStr(ArchiveHandle *AH)
void StartRestoreLOs(ArchiveHandle *AH)
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
void ReadHead(ArchiveHandle *AH)
void ReadToc(ArchiveHandle *AH)
void EndRestoreLO(ArchiveHandle *AH, Oid oid)
void WriteToc(ArchiveHandle *AH)
void EndRestoreLOs(ArchiveHandle *AH)
void StartRestoreLO(ArchiveHandle *AH, Oid oid, bool drop)
int parallel_restore(ArchiveHandle *AH, TocEntry *te)
size_t WriteStr(ArchiveHandle *AH, const char *c)
#define REQ_STATS
#define REQ_DATA
static void _PrintTocData(ArchiveHandle *AH, TocEntry *te)
static void _StartData(ArchiveHandle *AH, TocEntry *te)
static void _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
static void _CloseArchive(ArchiveHandle *AH)
static void _DeClone(ArchiveHandle *AH)
static void _ReopenArchive(ArchiveHandle *AH)
static void _StartLOs(ArchiveHandle *AH, TocEntry *te)
static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
static void _EndLOs(ArchiveHandle *AH, TocEntry *te)
static int _WriteByte(ArchiveHandle *AH, const int i)
static void _PrepParallelRestore(ArchiveHandle *AH)
static void _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
static int _ReadByte(ArchiveHandle *AH)
static void _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
static void _EndData(ArchiveHandle *AH, TocEntry *te)
static void _Clone(ArchiveHandle *AH)
static int _WorkerJobRestoreDirectory(ArchiveHandle *AH, TocEntry *te)
void InitArchiveFmt_Directory(ArchiveHandle *AH)
static void _PrintFileData(ArchiveHandle *AH, char *filename)
static void setFilePath(ArchiveHandle *AH, char *buf, const char *relativeFilename)
static void _LoadLOs(ArchiveHandle *AH, TocEntry *te)
static int _WorkerJobDumpDirectory(ArchiveHandle *AH, TocEntry *te)
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
#define pg_fatal(...)
#define MAXPGPATH
const void size_t len
const void * data
static char * filename
Definition: pg_dumpall.c:123
static char * buf
Definition: pg_test_fsync.c:72
#define snprintf
Definition: port.h:239
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: strlcat.c:33
unsigned int Oid
Definition: postgres_ext.h:30
char * c
int verbose
Definition: pg_backup.h:227
RestoreOptions * ropt
Definition: pg_backup.h:225
char *(* gets_func)(char *s, int size, CompressFileHandle *CFH)
Definition: compress_io.h:152
bool(* open_write_func)(const char *path, const char *mode, CompressFileHandle *CFH)
Definition: compress_io.h:122
int(* getc_func)(CompressFileHandle *CFH)
Definition: compress_io.h:161
bool(* eof_func)(CompressFileHandle *CFH)
Definition: compress_io.h:168
bool(* read_func)(void *ptr, size_t size, size_t *rsize, CompressFileHandle *CFH)
Definition: compress_io.h:131
ArchiveFormat format
struct _tocEntry * toc
DeClonePtrType DeClonePtr
EndLOsPtrType EndLOsPtr
DataDirSyncMethod sync_method
ReadExtraTocPtrType ReadExtraTocPtr
WorkerJobDumpPtrType WorkerJobDumpPtr
StartLOsPtrType StartLOsPtr
ArchiveEntryPtrType ArchiveEntryPtr
pg_compress_specification compression_spec
WriteDataPtrType WriteDataPtr
StartLOPtrType StartLOPtr
ClonePtrType ClonePtr
WriteBufPtrType WriteBufPtr
PrepParallelRestorePtrType PrepParallelRestorePtr
EndLOPtrType EndLOPtr
WriteExtraTocPtrType WriteExtraTocPtr
ReadBytePtrType ReadBytePtr
WorkerJobRestorePtrType WorkerJobRestorePtr
PrintTocDataPtrType PrintTocDataPtr
WriteBytePtrType WriteBytePtr
ReadBufPtrType ReadBufPtr
PrintExtraTocPtrType PrintExtraTocPtr
StartDataPtrType StartDataPtr
ReopenPtrType ReopenPtr
EndDataPtrType EndDataPtr
ClosePtrType ClosePtr
DataDumperPtr dataDumper
pgoff_t dataLength
struct _tocEntry * next
ParallelState * pstate
CompressFileHandle * LOsTocFH
CompressFileHandle * dataFH
pg_compress_algorithm algorithm
Definition: compression.h:34
static void * fn(void *arg)
Definition: thread-alloc.c:119
#define stat
Definition: win32_port.h:274