Add error pattern checks for some TAP tests for non-existing objects
[pgsql.git] / src / bin / pg_dump / pg_backup_directory.c
blob240a1d41062e4dee647dbf191277ec6ac90b1469
1 /*-------------------------------------------------------------------------
3 * pg_backup_directory.c
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).
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'.
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.
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
26 * Rights are granted to use this software in any way so long
27 * as this notice is not removed.
29 * The author is not responsible for loss or damages that may
30 * result from its use.
32 * IDENTIFICATION
33 * src/bin/pg_dump/pg_backup_directory.c
35 *-------------------------------------------------------------------------
37 #include "postgres_fe.h"
39 #include <dirent.h>
40 #include <sys/stat.h>
42 #include "common/file_utils.h"
43 #include "compress_io.h"
44 #include "parallel.h"
45 #include "pg_backup_utils.h"
47 typedef struct
50 * Our archive location. This is basically what the user specified as his
51 * backup file but of course here it is a directory.
53 char *directory;
55 CompressFileHandle *dataFH; /* currently open data file */
56 CompressFileHandle *LOsTocFH; /* file handle for blobs_NNN.toc */
57 ParallelState *pstate; /* for parallel backup / restore */
58 } lclContext;
60 typedef struct
62 char *filename; /* filename excluding the directory (basename) */
63 } lclTocEntry;
65 /* prototypes for private functions */
66 static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te);
67 static void _StartData(ArchiveHandle *AH, TocEntry *te);
68 static void _EndData(ArchiveHandle *AH, TocEntry *te);
69 static void _WriteData(ArchiveHandle *AH, const void *data, size_t dLen);
70 static int _WriteByte(ArchiveHandle *AH, const int i);
71 static int _ReadByte(ArchiveHandle *AH);
72 static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len);
73 static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len);
74 static void _CloseArchive(ArchiveHandle *AH);
75 static void _ReopenArchive(ArchiveHandle *AH);
76 static void _PrintTocData(ArchiveHandle *AH, TocEntry *te);
78 static void _WriteExtraToc(ArchiveHandle *AH, TocEntry *te);
79 static void _ReadExtraToc(ArchiveHandle *AH, TocEntry *te);
80 static void _PrintExtraToc(ArchiveHandle *AH, TocEntry *te);
82 static void _StartLOs(ArchiveHandle *AH, TocEntry *te);
83 static void _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid);
84 static void _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid);
85 static void _EndLOs(ArchiveHandle *AH, TocEntry *te);
86 static void _LoadLOs(ArchiveHandle *AH, TocEntry *te);
88 static void _PrepParallelRestore(ArchiveHandle *AH);
89 static void _Clone(ArchiveHandle *AH);
90 static void _DeClone(ArchiveHandle *AH);
92 static int _WorkerJobRestoreDirectory(ArchiveHandle *AH, TocEntry *te);
93 static int _WorkerJobDumpDirectory(ArchiveHandle *AH, TocEntry *te);
95 static void setFilePath(ArchiveHandle *AH, char *buf,
96 const char *relativeFilename);
99 * Init routine required by ALL formats. This is a global routine
100 * and should be declared in pg_backup_archiver.h
102 * Its task is to create any extra archive context (using AH->formatData),
103 * and to initialize the supported function pointers.
105 * It should also prepare whatever its input source is for reading/writing,
106 * and in the case of a read mode connection, it should load the Header & TOC.
108 void
109 InitArchiveFmt_Directory(ArchiveHandle *AH)
111 lclContext *ctx;
113 /* Assuming static functions, this can be copied for each format. */
114 AH->ArchiveEntryPtr = _ArchiveEntry;
115 AH->StartDataPtr = _StartData;
116 AH->WriteDataPtr = _WriteData;
117 AH->EndDataPtr = _EndData;
118 AH->WriteBytePtr = _WriteByte;
119 AH->ReadBytePtr = _ReadByte;
120 AH->WriteBufPtr = _WriteBuf;
121 AH->ReadBufPtr = _ReadBuf;
122 AH->ClosePtr = _CloseArchive;
123 AH->ReopenPtr = _ReopenArchive;
124 AH->PrintTocDataPtr = _PrintTocData;
125 AH->ReadExtraTocPtr = _ReadExtraToc;
126 AH->WriteExtraTocPtr = _WriteExtraToc;
127 AH->PrintExtraTocPtr = _PrintExtraToc;
129 AH->StartLOsPtr = _StartLOs;
130 AH->StartLOPtr = _StartLO;
131 AH->EndLOPtr = _EndLO;
132 AH->EndLOsPtr = _EndLOs;
134 AH->PrepParallelRestorePtr = _PrepParallelRestore;
135 AH->ClonePtr = _Clone;
136 AH->DeClonePtr = _DeClone;
138 AH->WorkerJobRestorePtr = _WorkerJobRestoreDirectory;
139 AH->WorkerJobDumpPtr = _WorkerJobDumpDirectory;
141 /* Set up our private context */
142 ctx = (lclContext *) pg_malloc0(sizeof(lclContext));
143 AH->formatData = ctx;
145 ctx->dataFH = NULL;
146 ctx->LOsTocFH = NULL;
149 * Now open the TOC file
152 if (!AH->fSpec || strcmp(AH->fSpec, "") == 0)
153 pg_fatal("no output directory specified");
155 ctx->directory = AH->fSpec;
157 if (AH->mode == archModeWrite)
159 struct stat st;
160 bool is_empty = false;
162 /* we accept an empty existing directory */
163 if (stat(ctx->directory, &st) == 0 && S_ISDIR(st.st_mode))
165 DIR *dir = opendir(ctx->directory);
167 if (dir)
169 struct dirent *d;
171 is_empty = true;
172 while (errno = 0, (d = readdir(dir)))
174 if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0)
176 is_empty = false;
177 break;
181 if (errno)
182 pg_fatal("could not read directory \"%s\": %m",
183 ctx->directory);
185 if (closedir(dir))
186 pg_fatal("could not close directory \"%s\": %m",
187 ctx->directory);
191 if (!is_empty && mkdir(ctx->directory, 0700) < 0)
192 pg_fatal("could not create directory \"%s\": %m",
193 ctx->directory);
195 else
196 { /* Read Mode */
197 char fname[MAXPGPATH];
198 CompressFileHandle *tocFH;
200 setFilePath(AH, fname, "toc.dat");
202 tocFH = InitDiscoverCompressFileHandle(fname, PG_BINARY_R);
203 if (tocFH == NULL)
204 pg_fatal("could not open input file \"%s\": %m", fname);
206 ctx->dataFH = tocFH;
209 * The TOC of a directory format dump shares the format code of the
210 * tar format.
212 AH->format = archTar;
213 ReadHead(AH);
214 AH->format = archDirectory;
215 ReadToc(AH);
217 /* Nothing else in the file, so close it again... */
218 if (!EndCompressFileHandle(tocFH))
219 pg_fatal("could not close TOC file: %m");
220 ctx->dataFH = NULL;
225 * Called by the Archiver when the dumper creates a new TOC entry.
227 * We determine the filename for this entry.
229 static void
230 _ArchiveEntry(ArchiveHandle *AH, TocEntry *te)
232 lclTocEntry *tctx;
233 char fn[MAXPGPATH];
235 tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
236 if (strcmp(te->desc, "BLOBS") == 0)
238 snprintf(fn, MAXPGPATH, "blobs_%d.toc", te->dumpId);
239 tctx->filename = pg_strdup(fn);
241 else if (te->dataDumper)
243 snprintf(fn, MAXPGPATH, "%d.dat", te->dumpId);
244 tctx->filename = pg_strdup(fn);
246 else
247 tctx->filename = NULL;
249 te->formatData = tctx;
253 * Called by the Archiver to save any extra format-related TOC entry
254 * data.
256 * Use the Archiver routines to write data - they are non-endian, and
257 * maintain other important file information.
259 static void
260 _WriteExtraToc(ArchiveHandle *AH, TocEntry *te)
262 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
265 * A dumpable object has set tctx->filename, any other object has not.
266 * (see _ArchiveEntry).
268 if (tctx->filename)
269 WriteStr(AH, tctx->filename);
270 else
271 WriteStr(AH, "");
275 * Called by the Archiver to read any extra format-related TOC data.
277 * Needs to match the order defined in _WriteExtraToc, and should also
278 * use the Archiver input routines.
280 static void
281 _ReadExtraToc(ArchiveHandle *AH, TocEntry *te)
283 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
285 if (tctx == NULL)
287 tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
288 te->formatData = tctx;
291 tctx->filename = ReadStr(AH);
292 if (strlen(tctx->filename) == 0)
294 free(tctx->filename);
295 tctx->filename = NULL;
300 * Called by the Archiver when restoring an archive to output a comment
301 * that includes useful information about the TOC entry.
303 static void
304 _PrintExtraToc(ArchiveHandle *AH, TocEntry *te)
306 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
308 if (AH->public.verbose && tctx->filename)
309 ahprintf(AH, "-- File: %s\n", tctx->filename);
313 * Called by the archiver when saving TABLE DATA (not schema). This routine
314 * should save whatever format-specific information is needed to read
315 * the archive back.
317 * It is called just prior to the dumper's 'DataDumper' routine being called.
319 * We create the data file for writing.
321 static void
322 _StartData(ArchiveHandle *AH, TocEntry *te)
324 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
325 lclContext *ctx = (lclContext *) AH->formatData;
326 char fname[MAXPGPATH];
328 setFilePath(AH, fname, tctx->filename);
330 ctx->dataFH = InitCompressFileHandle(AH->compression_spec);
332 if (!ctx->dataFH->open_write_func(fname, PG_BINARY_W, ctx->dataFH))
333 pg_fatal("could not open output file \"%s\": %m", fname);
337 * Called by archiver when dumper calls WriteData. This routine is
338 * called for both LO and table data; it is the responsibility of
339 * the format to manage each kind of data using StartLO/StartData.
341 * It should only be called from within a DataDumper routine.
343 * We write the data to the open data file.
345 static void
346 _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
348 lclContext *ctx = (lclContext *) AH->formatData;
349 CompressFileHandle *CFH = ctx->dataFH;
351 errno = 0;
352 if (dLen > 0 && !CFH->write_func(data, dLen, CFH))
354 /* if write didn't set errno, assume problem is no disk space */
355 if (errno == 0)
356 errno = ENOSPC;
357 pg_fatal("could not write to output file: %s",
358 CFH->get_error_func(CFH));
363 * Called by the archiver when a dumper's 'DataDumper' routine has
364 * finished.
366 * We close the data file.
368 static void
369 _EndData(ArchiveHandle *AH, TocEntry *te)
371 lclContext *ctx = (lclContext *) AH->formatData;
373 /* Close the file */
374 if (!EndCompressFileHandle(ctx->dataFH))
375 pg_fatal("could not close data file: %m");
377 ctx->dataFH = NULL;
381 * Print data for a given file (can be a LO as well)
383 static void
384 _PrintFileData(ArchiveHandle *AH, char *filename)
386 size_t cnt = 0;
387 char *buf;
388 size_t buflen;
389 CompressFileHandle *CFH;
391 if (!filename)
392 return;
394 CFH = InitDiscoverCompressFileHandle(filename, PG_BINARY_R);
395 if (!CFH)
396 pg_fatal("could not open input file \"%s\": %m", filename);
398 buflen = DEFAULT_IO_BUFFER_SIZE;
399 buf = pg_malloc(buflen);
401 while (CFH->read_func(buf, buflen, &cnt, CFH) && cnt > 0)
403 ahwrite(buf, 1, cnt, AH);
406 free(buf);
407 if (!EndCompressFileHandle(CFH))
408 pg_fatal("could not close data file \"%s\": %m", filename);
412 * Print data for a given TOC entry
414 static void
415 _PrintTocData(ArchiveHandle *AH, TocEntry *te)
417 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
419 if (!tctx->filename)
420 return;
422 if (strcmp(te->desc, "BLOBS") == 0)
423 _LoadLOs(AH, te);
424 else
426 char fname[MAXPGPATH];
428 setFilePath(AH, fname, tctx->filename);
429 _PrintFileData(AH, fname);
433 static void
434 _LoadLOs(ArchiveHandle *AH, TocEntry *te)
436 Oid oid;
437 lclContext *ctx = (lclContext *) AH->formatData;
438 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
439 CompressFileHandle *CFH;
440 char tocfname[MAXPGPATH];
441 char line[MAXPGPATH];
443 StartRestoreLOs(AH);
446 * Note: before archive v16, there was always only one BLOBS TOC entry,
447 * now there can be multiple. We don't need to worry what version we are
448 * reading though, because tctx->filename should be correct either way.
450 setFilePath(AH, tocfname, tctx->filename);
452 CFH = ctx->LOsTocFH = InitDiscoverCompressFileHandle(tocfname, PG_BINARY_R);
454 if (ctx->LOsTocFH == NULL)
455 pg_fatal("could not open large object TOC file \"%s\" for input: %m",
456 tocfname);
458 /* Read the LOs TOC file line-by-line, and process each LO */
459 while ((CFH->gets_func(line, MAXPGPATH, CFH)) != NULL)
461 char lofname[MAXPGPATH + 1];
462 char path[MAXPGPATH];
464 /* Can't overflow because line and lofname are the same length */
465 if (sscanf(line, "%u %" CppAsString2(MAXPGPATH) "s\n", &oid, lofname) != 2)
466 pg_fatal("invalid line in large object TOC file \"%s\": \"%s\"",
467 tocfname, line);
469 StartRestoreLO(AH, oid, AH->public.ropt->dropSchema);
470 snprintf(path, MAXPGPATH, "%s/%s", ctx->directory, lofname);
471 _PrintFileData(AH, path);
472 EndRestoreLO(AH, oid);
474 if (!CFH->eof_func(CFH))
475 pg_fatal("error reading large object TOC file \"%s\"",
476 tocfname);
478 if (!EndCompressFileHandle(ctx->LOsTocFH))
479 pg_fatal("could not close large object TOC file \"%s\": %m",
480 tocfname);
482 ctx->LOsTocFH = NULL;
484 EndRestoreLOs(AH);
489 * Write a byte of data to the archive.
490 * Called by the archiver to do integer & byte output to the archive.
491 * These routines are only used to read & write the headers & TOC.
493 static int
494 _WriteByte(ArchiveHandle *AH, const int i)
496 unsigned char c = (unsigned char) i;
497 lclContext *ctx = (lclContext *) AH->formatData;
498 CompressFileHandle *CFH = ctx->dataFH;
500 errno = 0;
501 if (!CFH->write_func(&c, 1, CFH))
503 /* if write didn't set errno, assume problem is no disk space */
504 if (errno == 0)
505 errno = ENOSPC;
506 pg_fatal("could not write to output file: %s",
507 CFH->get_error_func(CFH));
510 return 1;
514 * Read a byte of data from the archive.
515 * Called by the archiver to read bytes & integers from the archive.
516 * These routines are only used to read & write headers & TOC.
517 * EOF should be treated as a fatal error.
519 static int
520 _ReadByte(ArchiveHandle *AH)
522 lclContext *ctx = (lclContext *) AH->formatData;
523 CompressFileHandle *CFH = ctx->dataFH;
525 return CFH->getc_func(CFH);
529 * Write a buffer of data to the archive.
530 * Called by the archiver to write a block of bytes to the TOC or a data file.
532 static void
533 _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
535 lclContext *ctx = (lclContext *) AH->formatData;
536 CompressFileHandle *CFH = ctx->dataFH;
538 errno = 0;
539 if (!CFH->write_func(buf, len, CFH))
541 /* if write didn't set errno, assume problem is no disk space */
542 if (errno == 0)
543 errno = ENOSPC;
544 pg_fatal("could not write to output file: %s",
545 CFH->get_error_func(CFH));
550 * Read a block of bytes from the archive.
552 * Called by the archiver to read a block of bytes from the archive
554 static void
555 _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
557 lclContext *ctx = (lclContext *) AH->formatData;
558 CompressFileHandle *CFH = ctx->dataFH;
561 * If there was an I/O error, we already exited in readF(), so here we
562 * exit on short reads.
564 if (!CFH->read_func(buf, len, NULL, CFH))
565 pg_fatal("could not read from input file: end of file");
569 * Close the archive.
571 * When writing the archive, this is the routine that actually starts
572 * the process of saving it to files. No data should be written prior
573 * to this point, since the user could sort the TOC after creating it.
575 * If an archive is to be written, this routine must call:
576 * WriteHead to save the archive header
577 * WriteToc to save the TOC entries
578 * WriteDataChunks to save all data & LOs.
580 static void
581 _CloseArchive(ArchiveHandle *AH)
583 lclContext *ctx = (lclContext *) AH->formatData;
585 if (AH->mode == archModeWrite)
587 CompressFileHandle *tocFH;
588 pg_compress_specification compression_spec = {0};
589 char fname[MAXPGPATH];
591 setFilePath(AH, fname, "toc.dat");
593 /* this will actually fork the processes for a parallel backup */
594 ctx->pstate = ParallelBackupStart(AH);
596 /* The TOC is always created uncompressed */
597 compression_spec.algorithm = PG_COMPRESSION_NONE;
598 tocFH = InitCompressFileHandle(compression_spec);
599 if (!tocFH->open_write_func(fname, PG_BINARY_W, tocFH))
600 pg_fatal("could not open output file \"%s\": %m", fname);
601 ctx->dataFH = tocFH;
604 * Write 'tar' in the format field of the toc.dat file. The directory
605 * is compatible with 'tar', so there's no point having a different
606 * format code for it.
608 AH->format = archTar;
609 WriteHead(AH);
610 AH->format = archDirectory;
611 WriteToc(AH);
612 if (!EndCompressFileHandle(tocFH))
613 pg_fatal("could not close TOC file: %m");
614 WriteDataChunks(AH, ctx->pstate);
616 ParallelBackupEnd(AH, ctx->pstate);
619 * In directory mode, there is no need to sync all the entries
620 * individually. Just recurse once through all the files generated.
622 if (AH->dosync)
623 sync_dir_recurse(ctx->directory, AH->sync_method);
625 AH->FH = NULL;
629 * Reopen the archive's file handle.
631 static void
632 _ReopenArchive(ArchiveHandle *AH)
635 * Our TOC is in memory, our data files are opened by each child anyway as
636 * they are separate. We support reopening the archive by just doing
637 * nothing.
642 * LO support
646 * Called by the archiver when starting to save BLOB DATA (not schema).
647 * It is called just prior to the dumper's DataDumper routine.
649 * We open the large object TOC file here, so that we can append a line to
650 * it for each LO.
652 static void
653 _StartLOs(ArchiveHandle *AH, TocEntry *te)
655 lclContext *ctx = (lclContext *) AH->formatData;
656 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
657 pg_compress_specification compression_spec = {0};
658 char fname[MAXPGPATH];
660 setFilePath(AH, fname, tctx->filename);
662 /* The LO TOC file is never compressed */
663 compression_spec.algorithm = PG_COMPRESSION_NONE;
664 ctx->LOsTocFH = InitCompressFileHandle(compression_spec);
665 if (!ctx->LOsTocFH->open_write_func(fname, "ab", ctx->LOsTocFH))
666 pg_fatal("could not open output file \"%s\": %m", fname);
670 * Called by the archiver when we're about to start dumping a LO.
672 * We create a file to write the LO to.
674 static void
675 _StartLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
677 lclContext *ctx = (lclContext *) AH->formatData;
678 char fname[MAXPGPATH];
680 snprintf(fname, MAXPGPATH, "%s/blob_%u.dat", ctx->directory, oid);
682 ctx->dataFH = InitCompressFileHandle(AH->compression_spec);
683 if (!ctx->dataFH->open_write_func(fname, PG_BINARY_W, ctx->dataFH))
684 pg_fatal("could not open output file \"%s\": %m", fname);
688 * Called by the archiver when the dumper is finished writing a LO.
690 * We close the LO file and write an entry to the LO TOC file for it.
692 static void
693 _EndLO(ArchiveHandle *AH, TocEntry *te, Oid oid)
695 lclContext *ctx = (lclContext *) AH->formatData;
696 CompressFileHandle *CFH = ctx->LOsTocFH;
697 char buf[50];
698 int len;
700 /* Close the BLOB data file itself */
701 if (!EndCompressFileHandle(ctx->dataFH))
702 pg_fatal("could not close LO data file: %m");
703 ctx->dataFH = NULL;
705 /* register the LO in blobs_NNN.toc */
706 len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid);
707 if (!CFH->write_func(buf, len, CFH))
709 /* if write didn't set errno, assume problem is no disk space */
710 if (errno == 0)
711 errno = ENOSPC;
712 pg_fatal("could not write to LOs TOC file: %s",
713 CFH->get_error_func(CFH));
718 * Called by the archiver when finishing saving BLOB DATA.
720 * We close the LOs TOC file.
722 static void
723 _EndLOs(ArchiveHandle *AH, TocEntry *te)
725 lclContext *ctx = (lclContext *) AH->formatData;
727 if (!EndCompressFileHandle(ctx->LOsTocFH))
728 pg_fatal("could not close LOs TOC file: %m");
729 ctx->LOsTocFH = NULL;
733 * Gets a relative file name and prepends the output directory, writing the
734 * result to buf. The caller needs to make sure that buf is MAXPGPATH bytes
735 * big. Can't use a static char[MAXPGPATH] inside the function because we run
736 * multithreaded on Windows.
738 static void
739 setFilePath(ArchiveHandle *AH, char *buf, const char *relativeFilename)
741 lclContext *ctx = (lclContext *) AH->formatData;
742 char *dname;
744 dname = ctx->directory;
746 if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH)
747 pg_fatal("file name too long: \"%s\"", dname);
749 strcpy(buf, dname);
750 strcat(buf, "/");
751 strcat(buf, relativeFilename);
755 * Prepare for parallel restore.
757 * The main thing that needs to happen here is to fill in TABLE DATA and BLOBS
758 * TOC entries' dataLength fields with appropriate values to guide the
759 * ordering of restore jobs. The source of said data is format-dependent,
760 * as is the exact meaning of the values.
762 * A format module might also choose to do other setup here.
764 static void
765 _PrepParallelRestore(ArchiveHandle *AH)
767 TocEntry *te;
769 for (te = AH->toc->next; te != AH->toc; te = te->next)
771 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
772 char fname[MAXPGPATH];
773 struct stat st;
776 * A dumpable object has set tctx->filename, any other object has not.
777 * (see _ArchiveEntry).
779 if (tctx->filename == NULL)
780 continue;
782 /* We may ignore items not due to be restored */
783 if ((te->reqs & REQ_DATA) == 0)
784 continue;
787 * Stat the file and, if successful, put its size in dataLength. When
788 * using compression, the physical file size might not be a very good
789 * guide to the amount of work involved in restoring the file, but we
790 * only need an approximate indicator of that.
792 setFilePath(AH, fname, tctx->filename);
794 if (stat(fname, &st) == 0)
795 te->dataLength = st.st_size;
796 else if (AH->compression_spec.algorithm != PG_COMPRESSION_NONE)
798 if (AH->compression_spec.algorithm == PG_COMPRESSION_GZIP)
799 strlcat(fname, ".gz", sizeof(fname));
800 else if (AH->compression_spec.algorithm == PG_COMPRESSION_LZ4)
801 strlcat(fname, ".lz4", sizeof(fname));
802 else if (AH->compression_spec.algorithm == PG_COMPRESSION_ZSTD)
803 strlcat(fname, ".zst", sizeof(fname));
805 if (stat(fname, &st) == 0)
806 te->dataLength = st.st_size;
810 * If this is a BLOBS entry, what we stat'd was blobs_NNN.toc, which
811 * most likely is a lot smaller than the actual blob data. We don't
812 * have a cheap way to estimate how much smaller, but fortunately it
813 * doesn't matter too much as long as we get the LOs processed
814 * reasonably early. Arbitrarily scale up by a factor of 1K.
816 if (strcmp(te->desc, "BLOBS") == 0)
817 te->dataLength *= 1024;
822 * Clone format-specific fields during parallel restoration.
824 static void
825 _Clone(ArchiveHandle *AH)
827 lclContext *ctx = (lclContext *) AH->formatData;
829 AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
830 memcpy(AH->formatData, ctx, sizeof(lclContext));
831 ctx = (lclContext *) AH->formatData;
834 * TOC-entry-local state isn't an issue because any one TOC entry is
835 * touched by just one worker child.
839 * We also don't copy the ParallelState pointer (pstate), only the leader
840 * process ever writes to it.
844 static void
845 _DeClone(ArchiveHandle *AH)
847 lclContext *ctx = (lclContext *) AH->formatData;
849 free(ctx);
853 * This function is executed in the child of a parallel backup for a
854 * directory-format archive and dumps the actual data for one TOC entry.
856 static int
857 _WorkerJobDumpDirectory(ArchiveHandle *AH, TocEntry *te)
860 * This function returns void. We either fail and die horribly or
861 * succeed... A failure will be detected by the parent when the child dies
862 * unexpectedly.
864 WriteDataChunksForTocEntry(AH, te);
866 return 0;
870 * This function is executed in the child of a parallel restore from a
871 * directory-format archive and restores the actual data for one TOC entry.
873 static int
874 _WorkerJobRestoreDirectory(ArchiveHandle *AH, TocEntry *te)
876 return parallel_restore(AH, te);