Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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 if (dLen <= 0)
320 return;
321 CFH->write_func(data, dLen, CFH);
322}
323
324/*
325 * Called by the archiver when a dumper's 'DataDumper' routine has
326 * finished.
327 *
328 * We close the data file.
329 */
330static void
332{
333 lclContext *ctx = (lclContext *) AH->formatData;
334
335 /* Close the file */
337 pg_fatal("could not close data file: %m");
338
339 ctx->dataFH = NULL;
340}
341
342/*
343 * Print data for a given file (can be a LO as well)
344 */
345static void
347{
348 size_t cnt;
349 char *buf;
350 size_t buflen;
352
353 if (!filename)
354 return;
355
357 if (!CFH)
358 pg_fatal("could not open input file \"%s\": %m", filename);
359
360 buflen = DEFAULT_IO_BUFFER_SIZE;
361 buf = pg_malloc(buflen);
362
363 while ((cnt = CFH->read_func(buf, buflen, CFH)) > 0)
364 {
365 ahwrite(buf, 1, cnt, AH);
366 }
367
368 free(buf);
369 if (!EndCompressFileHandle(CFH))
370 pg_fatal("could not close data file \"%s\": %m", filename);
371}
372
373/*
374 * Print data for a given TOC entry
375*/
376static void
378{
379 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
380
381 if (!tctx->filename)
382 return;
383
384 if (strcmp(te->desc, "BLOBS") == 0)
385 _LoadLOs(AH, te);
386 else
387 {
388 char fname[MAXPGPATH];
389
390 setFilePath(AH, fname, tctx->filename);
391 _PrintFileData(AH, fname);
392 }
393}
394
395static void
397{
398 Oid oid;
399 lclContext *ctx = (lclContext *) AH->formatData;
400 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
402 char tocfname[MAXPGPATH];
403 char line[MAXPGPATH];
404
405 StartRestoreLOs(AH);
406
407 /*
408 * Note: before archive v16, there was always only one BLOBS TOC entry,
409 * now there can be multiple. Furthermore, although the actual filename
410 * was always "blobs.toc" before v16, the value of tctx->filename did not
411 * match that before commit 548e50976 fixed it. For simplicity we assume
412 * it must be "blobs.toc" in all archives before v16.
413 */
414 if (AH->version < K_VERS_1_16)
415 setFilePath(AH, tocfname, "blobs.toc");
416 else
417 setFilePath(AH, tocfname, tctx->filename);
418
420
421 if (ctx->LOsTocFH == NULL)
422 pg_fatal("could not open large object TOC file \"%s\" for input: %m",
423 tocfname);
424
425 /* Read the LOs TOC file line-by-line, and process each LO */
426 while ((CFH->gets_func(line, MAXPGPATH, CFH)) != NULL)
427 {
428 char lofname[MAXPGPATH + 1];
429 char path[MAXPGPATH];
430
431 /* Can't overflow because line and lofname are the same length */
432 if (sscanf(line, "%u %" CppAsString2(MAXPGPATH) "s\n", &oid, lofname) != 2)
433 pg_fatal("invalid line in large object TOC file \"%s\": \"%s\"",
434 tocfname, line);
435
436 StartRestoreLO(AH, oid, AH->public.ropt->dropSchema);
437 snprintf(path, MAXPGPATH, "%s/%s", ctx->directory, lofname);
438 _PrintFileData(AH, path);
439 EndRestoreLO(AH, oid);
440 }
441 if (!CFH->eof_func(CFH))
442 pg_fatal("error reading large object TOC file \"%s\"",
443 tocfname);
444
446 pg_fatal("could not close large object TOC file \"%s\": %m",
447 tocfname);
448
449 ctx->LOsTocFH = NULL;
450
451 EndRestoreLOs(AH);
452}
453
454
455/*
456 * Write a byte of data to the archive.
457 * Called by the archiver to do integer & byte output to the archive.
458 * These routines are only used to read & write the headers & TOC.
459 */
460static int
462{
463 unsigned char c = (unsigned char) i;
464 lclContext *ctx = (lclContext *) AH->formatData;
465 CompressFileHandle *CFH = ctx->dataFH;
466
467 CFH->write_func(&c, 1, CFH);
468 return 1;
469}
470
471/*
472 * Read a byte of data from the archive.
473 * Called by the archiver to read bytes & integers from the archive.
474 * These routines are only used to read & write headers & TOC.
475 * EOF should be treated as a fatal error.
476 */
477static int
479{
480 lclContext *ctx = (lclContext *) AH->formatData;
481 CompressFileHandle *CFH = ctx->dataFH;
482
483 return CFH->getc_func(CFH);
484}
485
486/*
487 * Write a buffer of data to the archive.
488 * Called by the archiver to write a block of bytes to the TOC or a data file.
489 */
490static void
491_WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
492{
493 lclContext *ctx = (lclContext *) AH->formatData;
494 CompressFileHandle *CFH = ctx->dataFH;
495
496 CFH->write_func(buf, len, CFH);
497}
498
499/*
500 * Read a block of bytes from the archive.
501 *
502 * Called by the archiver to read a block of bytes from the archive
503 */
504static void
505_ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
506{
507 lclContext *ctx = (lclContext *) AH->formatData;
508 CompressFileHandle *CFH = ctx->dataFH;
509
510 /*
511 * We do not expect a short read, so fail if we get one. The read_func
512 * already dealt with any outright I/O error.
513 */
514 if (CFH->read_func(buf, len, CFH) != len)
515 pg_fatal("could not read from input file: end of file");
516}
517
518/*
519 * Close the archive.
520 *
521 * When writing the archive, this is the routine that actually starts
522 * the process of saving it to files. No data should be written prior
523 * to this point, since the user could sort the TOC after creating it.
524 *
525 * If an archive is to be written, this routine must call:
526 * WriteHead to save the archive header
527 * WriteToc to save the TOC entries
528 * WriteDataChunks to save all data & LOs.
529 */
530static void
532{
533 lclContext *ctx = (lclContext *) AH->formatData;
534
535 if (AH->mode == archModeWrite)
536 {
537 CompressFileHandle *tocFH;
538 pg_compress_specification compression_spec = {0};
539 char fname[MAXPGPATH];
540
541 setFilePath(AH, fname, "toc.dat");
542
543 /* this will actually fork the processes for a parallel backup */
544 ctx->pstate = ParallelBackupStart(AH);
545
546 /* The TOC is always created uncompressed */
547 compression_spec.algorithm = PG_COMPRESSION_NONE;
548 tocFH = InitCompressFileHandle(compression_spec);
549 if (!tocFH->open_write_func(fname, PG_BINARY_W, tocFH))
550 pg_fatal("could not open output file \"%s\": %m", fname);
551 ctx->dataFH = tocFH;
552
553 /*
554 * Write 'tar' in the format field of the toc.dat file. The directory
555 * is compatible with 'tar', so there's no point having a different
556 * format code for it.
557 */
558 AH->format = archTar;
559 WriteHead(AH);
560 AH->format = archDirectory;
561 WriteToc(AH);
562 if (!EndCompressFileHandle(tocFH))
563 pg_fatal("could not close TOC file: %m");
564 WriteDataChunks(AH, ctx->pstate);
565
566 ParallelBackupEnd(AH, ctx->pstate);
567
568 /*
569 * In directory mode, there is no need to sync all the entries
570 * individually. Just recurse once through all the files generated.
571 */
572 if (AH->dosync)
573 sync_dir_recurse(ctx->directory, AH->sync_method);
574 }
575 AH->FH = NULL;
576}
577
578/*
579 * Reopen the archive's file handle.
580 */
581static void
583{
584 /*
585 * Our TOC is in memory, our data files are opened by each child anyway as
586 * they are separate. We support reopening the archive by just doing
587 * nothing.
588 */
589}
590
591/*
592 * LO support
593 */
594
595/*
596 * Called by the archiver when starting to save BLOB DATA (not schema).
597 * It is called just prior to the dumper's DataDumper routine.
598 *
599 * We open the large object TOC file here, so that we can append a line to
600 * it for each LO.
601 */
602static void
604{
605 lclContext *ctx = (lclContext *) AH->formatData;
606 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
607 pg_compress_specification compression_spec = {0};
608 char fname[MAXPGPATH];
609
610 setFilePath(AH, fname, tctx->filename);
611
612 /* The LO TOC file is never compressed */
613 compression_spec.algorithm = PG_COMPRESSION_NONE;
614 ctx->LOsTocFH = InitCompressFileHandle(compression_spec);
615 if (!ctx->LOsTocFH->open_write_func(fname, "ab", ctx->LOsTocFH))
616 pg_fatal("could not open output file \"%s\": %m", fname);
617}
618
619/*
620 * Called by the archiver when we're about to start dumping a LO.
621 *
622 * We create a file to write the LO to.
623 */
624static void
626{
627 lclContext *ctx = (lclContext *) AH->formatData;
628 char fname[MAXPGPATH];
629
630 snprintf(fname, MAXPGPATH, "%s/blob_%u.dat", ctx->directory, oid);
631
633 if (!ctx->dataFH->open_write_func(fname, PG_BINARY_W, ctx->dataFH))
634 pg_fatal("could not open output file \"%s\": %m", fname);
635}
636
637/*
638 * Called by the archiver when the dumper is finished writing a LO.
639 *
640 * We close the LO file and write an entry to the LO TOC file for it.
641 */
642static void
644{
645 lclContext *ctx = (lclContext *) AH->formatData;
646 CompressFileHandle *CFH = ctx->LOsTocFH;
647 char buf[50];
648 int len;
649
650 /* Close the BLOB data file itself */
652 pg_fatal("could not close LO data file: %m");
653 ctx->dataFH = NULL;
654
655 /* register the LO in blobs_NNN.toc */
656 len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid);
657 CFH->write_func(buf, len, CFH);
658}
659
660/*
661 * Called by the archiver when finishing saving BLOB DATA.
662 *
663 * We close the LOs TOC file.
664 */
665static void
667{
668 lclContext *ctx = (lclContext *) AH->formatData;
669
671 pg_fatal("could not close LOs TOC file: %m");
672 ctx->LOsTocFH = NULL;
673}
674
675/*
676 * Gets a relative file name and prepends the output directory, writing the
677 * result to buf. The caller needs to make sure that buf is MAXPGPATH bytes
678 * big. Can't use a static char[MAXPGPATH] inside the function because we run
679 * multithreaded on Windows.
680 */
681static void
682setFilePath(ArchiveHandle *AH, char *buf, const char *relativeFilename)
683{
684 lclContext *ctx = (lclContext *) AH->formatData;
685 char *dname;
686
687 dname = ctx->directory;
688
689 if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH)
690 pg_fatal("file name too long: \"%s\"", dname);
691
692 strcpy(buf, dname);
693 strcat(buf, "/");
694 strcat(buf, relativeFilename);
695}
696
697/*
698 * Prepare for parallel restore.
699 *
700 * The main thing that needs to happen here is to fill in TABLE DATA and BLOBS
701 * TOC entries' dataLength fields with appropriate values to guide the
702 * ordering of restore jobs. The source of said data is format-dependent,
703 * as is the exact meaning of the values.
704 *
705 * A format module might also choose to do other setup here.
706 */
707static void
709{
710 TocEntry *te;
711
712 for (te = AH->toc->next; te != AH->toc; te = te->next)
713 {
714 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
715 char fname[MAXPGPATH];
716 struct stat st;
717
718 /*
719 * A dumpable object has set tctx->filename, any other object has not.
720 * (see _ArchiveEntry).
721 */
722 if (tctx->filename == NULL)
723 continue;
724
725 /* We may ignore items not due to be restored */
726 if ((te->reqs & (REQ_DATA | REQ_STATS)) == 0)
727 continue;
728
729 /*
730 * Stat the file and, if successful, put its size in dataLength. When
731 * using compression, the physical file size might not be a very good
732 * guide to the amount of work involved in restoring the file, but we
733 * only need an approximate indicator of that.
734 */
735 setFilePath(AH, fname, tctx->filename);
736
737 if (stat(fname, &st) == 0)
738 te->dataLength = st.st_size;
740 {
742 strlcat(fname, ".gz", sizeof(fname));
744 strlcat(fname, ".lz4", sizeof(fname));
746 strlcat(fname, ".zst", sizeof(fname));
747
748 if (stat(fname, &st) == 0)
749 te->dataLength = st.st_size;
750 }
751
752 /*
753 * If this is a BLOBS entry, what we stat'd was blobs_NNN.toc, which
754 * most likely is a lot smaller than the actual blob data. We don't
755 * have a cheap way to estimate how much smaller, but fortunately it
756 * doesn't matter too much as long as we get the LOs processed
757 * reasonably early. Arbitrarily scale up by a factor of 1K.
758 */
759 if (strcmp(te->desc, "BLOBS") == 0)
760 te->dataLength *= 1024;
761 }
762}
763
764/*
765 * Clone format-specific fields during parallel restoration.
766 */
767static void
769{
770 lclContext *ctx = (lclContext *) AH->formatData;
771
772 AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
773 memcpy(AH->formatData, ctx, sizeof(lclContext));
774 ctx = (lclContext *) AH->formatData;
775
776 /*
777 * TOC-entry-local state isn't an issue because any one TOC entry is
778 * touched by just one worker child.
779 */
780
781 /*
782 * We also don't copy the ParallelState pointer (pstate), only the leader
783 * process ever writes to it.
784 */
785}
786
787static void
789{
790 lclContext *ctx = (lclContext *) AH->formatData;
791
792 free(ctx);
793}
794
795/*
796 * This function is executed in the child of a parallel backup for a
797 * directory-format archive and dumps the actual data for one TOC entry.
798 */
799static int
801{
802 /*
803 * This function returns void. We either fail and die horribly or
804 * succeed... A failure will be detected by the parent when the child dies
805 * unexpectedly.
806 */
808
809 return 0;
810}
811
812/*
813 * This function is executed in the child of a parallel restore from a
814 * directory-format archive and restores the actual data for one TOC entry.
815 */
816static int
818{
819 return parallel_restore(AH, te);
820}
void ParallelBackupEnd(ArchiveHandle *AH, ParallelState *pstate)
Definition: parallel.c:1061
ParallelState * ParallelBackupStart(ArchiveHandle *AH)
Definition: parallel.c:899
#define PG_BINARY_R
Definition: c.h:1275
#define CppAsString2(x)
Definition: c.h:419
#define PG_BINARY_W
Definition: c.h:1276
bool EndCompressFileHandle(CompressFileHandle *CFH)
Definition: compress_io.c:289
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:935
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
#define K_VERS_1_16
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:120
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:32
char * c
int verbose
Definition: pg_backup.h:231
RestoreOptions * ropt
Definition: pg_backup.h:229
char *(* gets_func)(char *s, int size, CompressFileHandle *CFH)
Definition: compress_io.h:153
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:162
bool(* eof_func)(CompressFileHandle *CFH)
Definition: compress_io.h:169
size_t(* read_func)(void *ptr, size_t size, CompressFileHandle *CFH)
Definition: compress_io.h:132
void(* write_func)(const void *ptr, size_t size, CompressFileHandle *CFH)
Definition: compress_io.h:140
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