PostgreSQL Source Code git master
pg_backup_custom.c File Reference
#include "postgres_fe.h"
#include "common/file_utils.h"
#include "compress_io.h"
#include "pg_backup_utils.h"
Include dependency graph for pg_backup_custom.c:

Go to the source code of this file.

Data Structures

struct  lclContext
 
struct  lclTocEntry
 

Functions

static void _ArchiveEntry (ArchiveHandle *AH, TocEntry *te)
 
static void _StartData (ArchiveHandle *AH, TocEntry *te)
 
static void _WriteData (ArchiveHandle *AH, const void *data, size_t dLen)
 
static void _EndData (ArchiveHandle *AH, TocEntry *te)
 
static int _WriteByte (ArchiveHandle *AH, const int i)
 
static int _ReadByte (ArchiveHandle *AH)
 
static void _WriteBuf (ArchiveHandle *AH, const void *buf, size_t len)
 
static void _ReadBuf (ArchiveHandle *AH, void *buf, size_t len)
 
static void _CloseArchive (ArchiveHandle *AH)
 
static void _ReopenArchive (ArchiveHandle *AH)
 
static void _PrintTocData (ArchiveHandle *AH, TocEntry *te)
 
static void _WriteExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _ReadExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _PrintExtraToc (ArchiveHandle *AH, TocEntry *te)
 
static void _PrintData (ArchiveHandle *AH)
 
static void _skipData (ArchiveHandle *AH)
 
static void _skipLOs (ArchiveHandle *AH)
 
static void _StartLOs (ArchiveHandle *AH, TocEntry *te)
 
static void _StartLO (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndLO (ArchiveHandle *AH, TocEntry *te, Oid oid)
 
static void _EndLOs (ArchiveHandle *AH, TocEntry *te)
 
static void _LoadLOs (ArchiveHandle *AH, bool drop)
 
static void _PrepParallelRestore (ArchiveHandle *AH)
 
static void _Clone (ArchiveHandle *AH)
 
static void _DeClone (ArchiveHandle *AH)
 
static int _WorkerJobRestoreCustom (ArchiveHandle *AH, TocEntry *te)
 
static void _readBlockHeader (ArchiveHandle *AH, int *type, int *id)
 
static pgoff_t _getFilePos (ArchiveHandle *AH, lclContext *ctx)
 
static void _CustomWriteFunc (ArchiveHandle *AH, const char *buf, size_t len)
 
static size_t _CustomReadFunc (ArchiveHandle *AH, char **buf, size_t *buflen)
 
void InitArchiveFmt_Custom (ArchiveHandle *AH)
 

Function Documentation

◆ _ArchiveEntry()

static void _ArchiveEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 198 of file pg_backup_custom.c.

199{
200 lclTocEntry *ctx;
201
202 ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
203 if (te->dataDumper)
205 else
207
208 te->formatData = ctx;
209}
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define K_OFFSET_NO_DATA
#define K_OFFSET_POS_NOT_SET
DataDumperPtr dataDumper

References _tocEntry::dataDumper, lclTocEntry::dataState, _tocEntry::formatData, K_OFFSET_NO_DATA, K_OFFSET_POS_NOT_SET, and pg_malloc0().

Referenced by InitArchiveFmt_Custom().

◆ _Clone()

static void _Clone ( ArchiveHandle AH)
static

Definition at line 889 of file pg_backup_custom.c.

890{
891 lclContext *ctx = (lclContext *) AH->formatData;
892
893 /*
894 * Each thread must have private lclContext working state.
895 */
896 AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
897 memcpy(AH->formatData, ctx, sizeof(lclContext));
898 ctx = (lclContext *) AH->formatData;
899
900 /* sanity check, shouldn't happen */
901 if (ctx->cs != NULL)
902 pg_fatal("compressor active");
903
904 /*
905 * We intentionally do not clone TOC-entry-local state: it's useful to
906 * share knowledge about where the data blocks are across threads.
907 * _PrintTocData has to be careful about the order of operations on that
908 * state, though.
909 */
910}
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
#define pg_fatal(...)
CompressorState * cs

References lclContext::cs, _archiveHandle::formatData, if(), pg_fatal, and pg_malloc().

Referenced by InitArchiveFmt_Custom().

◆ _CloseArchive()

static void _CloseArchive ( ArchiveHandle AH)
static

Definition at line 746 of file pg_backup_custom.c.

747{
748 lclContext *ctx = (lclContext *) AH->formatData;
749 pgoff_t tpos;
750
751 if (AH->mode == archModeWrite)
752 {
753 WriteHead(AH);
754 /* Remember TOC's seek position for use below */
755 tpos = ftello(AH->FH);
756 if (tpos < 0 && ctx->hasSeek)
757 pg_fatal("could not determine seek position in archive file: %m");
758 WriteToc(AH);
759 WriteDataChunks(AH, NULL);
760
761 /*
762 * If possible, re-write the TOC in order to update the data offset
763 * information. This is not essential, as pg_restore can cope in most
764 * cases without it; but it can make pg_restore significantly faster
765 * in some situations (especially parallel restore). We can skip this
766 * step if we're not dumping any data; there are no offsets to update
767 * in that case.
768 */
769 if (ctx->hasSeek && AH->public.dopt->dumpData &&
770 fseeko(AH->FH, tpos, SEEK_SET) == 0)
771 WriteToc(AH);
772 }
773
774 if (fclose(AH->FH) != 0)
775 pg_fatal("could not close archive file: %m");
776
777 /* Sync the output file if one is defined */
778 if (AH->dosync && AH->mode == archModeWrite && AH->fSpec)
779 (void) fsync_fname(AH->fSpec, false);
780
781 AH->FH = NULL;
782}
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:753
@ archModeWrite
Definition: pg_backup.h:51
void WriteHead(ArchiveHandle *AH)
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
void WriteToc(ArchiveHandle *AH)
#define pgoff_t
Definition: port.h:422
DumpOptions * dopt
Definition: pg_backup.h:228
bool dumpData
Definition: pg_backup.h:216
#define ftello(stream)
Definition: win32_port.h:209
#define fseeko(stream, offset, origin)
Definition: win32_port.h:206

References archModeWrite, Archive::dopt, _archiveHandle::dosync, _dumpOptions::dumpData, _archiveHandle::FH, _archiveHandle::formatData, fseeko, _archiveHandle::fSpec, fsync_fname(), ftello, lclContext::hasSeek, if(), _archiveHandle::mode, pg_fatal, pgoff_t, _archiveHandle::public, WriteDataChunks(), WriteHead(), and WriteToc().

Referenced by InitArchiveFmt_Custom().

◆ _CustomReadFunc()

static size_t _CustomReadFunc ( ArchiveHandle AH,
char **  buf,
size_t *  buflen 
)
static

Definition at line 1011 of file pg_backup_custom.c.

1012{
1013 size_t blkLen;
1014
1015 /* Read length */
1016 blkLen = ReadInt(AH);
1017 if (blkLen == 0)
1018 return 0;
1019
1020 /* If the caller's buffer is not large enough, allocate a bigger one */
1021 if (blkLen > *buflen)
1022 {
1023 free(*buf);
1024 *buf = (char *) pg_malloc(blkLen);
1025 *buflen = blkLen;
1026 }
1027
1028 /* exits app on read errors */
1029 _ReadBuf(AH, *buf, blkLen);
1030
1031 return blkLen;
1032}
#define free(a)
Definition: header.h:65
int ReadInt(ArchiveHandle *AH)
static void _ReadBuf(ArchiveHandle *AH, void *buf, size_t len)
static char * buf
Definition: pg_test_fsync.c:72

References _ReadBuf(), buf, free, pg_malloc(), and ReadInt().

Referenced by _PrintData().

◆ _CustomWriteFunc()

static void _CustomWriteFunc ( ArchiveHandle AH,
const char *  buf,
size_t  len 
)
static

Definition at line 996 of file pg_backup_custom.c.

997{
998 /* never write 0-byte blocks (this should not happen) */
999 if (len > 0)
1000 {
1001 WriteInt(AH, len);
1002 _WriteBuf(AH, buf, len);
1003 }
1004}
size_t WriteInt(ArchiveHandle *AH, int i)
static void _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
const void size_t len

References _WriteBuf(), buf, len, and WriteInt().

Referenced by _StartData(), and _StartLO().

◆ _DeClone()

static void _DeClone ( ArchiveHandle AH)
static

Definition at line 913 of file pg_backup_custom.c.

914{
915 lclContext *ctx = (lclContext *) AH->formatData;
916
917 free(ctx);
918}

References _archiveHandle::formatData, and free.

Referenced by InitArchiveFmt_Custom().

◆ _EndData()

static void _EndData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 328 of file pg_backup_custom.c.

329{
330 lclContext *ctx = (lclContext *) AH->formatData;
331
332 EndCompressor(AH, ctx->cs);
333 ctx->cs = NULL;
334
335 /* Send the end marker */
336 WriteInt(AH, 0);
337}
void EndCompressor(ArchiveHandle *AH, CompressorState *cs)
Definition: compress_io.c:148

References lclContext::cs, EndCompressor(), _archiveHandle::formatData, and WriteInt().

Referenced by InitArchiveFmt_Custom().

◆ _EndLO()

static void _EndLO ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 390 of file pg_backup_custom.c.

391{
392 lclContext *ctx = (lclContext *) AH->formatData;
393
394 EndCompressor(AH, ctx->cs);
395 /* Send the end marker */
396 WriteInt(AH, 0);
397}

References lclContext::cs, EndCompressor(), _archiveHandle::formatData, and WriteInt().

Referenced by InitArchiveFmt_Custom().

◆ _EndLOs()

static void _EndLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 405 of file pg_backup_custom.c.

406{
407 /* Write out a fake zero OID to mark end-of-LOs. */
408 WriteInt(AH, 0);
409}

References WriteInt().

Referenced by InitArchiveFmt_Custom().

◆ _getFilePos()

static pgoff_t _getFilePos ( ArchiveHandle AH,
lclContext ctx 
)
static

Definition at line 944 of file pg_backup_custom.c.

945{
946 pgoff_t pos;
947
948 pos = ftello(AH->FH);
949 if (pos < 0)
950 {
951 /* Not expected if we found we can seek. */
952 if (ctx->hasSeek)
953 pg_fatal("could not determine seek position in archive file: %m");
954 }
955 return pos;
956}

References _archiveHandle::FH, ftello, lclContext::hasSeek, pg_fatal, and pgoff_t.

Referenced by _PrintTocData(), _StartData(), _StartLOs(), and InitArchiveFmt_Custom().

◆ _LoadLOs()

static void _LoadLOs ( ArchiveHandle AH,
bool  drop 
)
static

Definition at line 579 of file pg_backup_custom.c.

580{
581 Oid oid;
582
583 StartRestoreLOs(AH);
584
585 oid = ReadInt(AH);
586 while (oid != 0)
587 {
588 StartRestoreLO(AH, oid, drop);
589 _PrintData(AH);
590 EndRestoreLO(AH, oid);
591 oid = ReadInt(AH);
592 }
593
594 EndRestoreLOs(AH);
595}
void StartRestoreLOs(ArchiveHandle *AH)
void EndRestoreLO(ArchiveHandle *AH, Oid oid)
void EndRestoreLOs(ArchiveHandle *AH)
void StartRestoreLO(ArchiveHandle *AH, Oid oid, bool drop)
static void _PrintData(ArchiveHandle *AH)
unsigned int Oid
Definition: postgres_ext.h:32

References _PrintData(), EndRestoreLO(), EndRestoreLOs(), ReadInt(), StartRestoreLO(), and StartRestoreLOs().

Referenced by _PrintTocData().

◆ _PrepParallelRestore()

static void _PrepParallelRestore ( ArchiveHandle AH)
static

Definition at line 837 of file pg_backup_custom.c.

838{
839 lclContext *ctx = (lclContext *) AH->formatData;
840 TocEntry *prev_te = NULL;
841 lclTocEntry *prev_tctx = NULL;
842 TocEntry *te;
843
844 /*
845 * Knowing that the data items were dumped out in TOC order, we can
846 * reconstruct the length of each item as the delta to the start offset of
847 * the next data item.
848 */
849 for (te = AH->toc->next; te != AH->toc; te = te->next)
850 {
851 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
852
853 /*
854 * Ignore entries without a known data offset; if we were unable to
855 * seek to rewrite the TOC when creating the archive, this'll be all
856 * of them, and we'll end up with no size estimates.
857 */
858 if (tctx->dataState != K_OFFSET_POS_SET)
859 continue;
860
861 /* Compute previous data item's length */
862 if (prev_te)
863 {
864 if (tctx->dataPos > prev_tctx->dataPos)
865 prev_te->dataLength = tctx->dataPos - prev_tctx->dataPos;
866 }
867
868 prev_te = te;
869 prev_tctx = tctx;
870 }
871
872 /* If OK to seek, we can determine the length of the last item */
873 if (prev_te && ctx->hasSeek)
874 {
876
877 if (fseeko(AH->FH, 0, SEEK_END) != 0)
878 pg_fatal("error during file seek: %m");
879 endpos = ftello(AH->FH);
880 if (endpos > prev_tctx->dataPos)
881 prev_te->dataLength = endpos - prev_tctx->dataPos;
882 }
883}
for(;;)
#define K_OFFSET_POS_SET
static XLogRecPtr endpos
Definition: pg_receivewal.c:56
struct _tocEntry * toc
struct _tocEntry * next

References lclTocEntry::dataPos, lclTocEntry::dataState, endpos, _archiveHandle::FH, for(), _archiveHandle::formatData, fseeko, ftello, lclContext::hasSeek, if(), K_OFFSET_POS_SET, _tocEntry::next, pg_fatal, pgoff_t, and _archiveHandle::toc.

Referenced by InitArchiveFmt_Custom().

◆ _PrintData()

static void _PrintData ( ArchiveHandle AH)
static

Definition at line 568 of file pg_backup_custom.c.

569{
570 CompressorState *cs;
571
573 _CustomReadFunc, NULL);
574 cs->readData(AH, cs);
575 EndCompressor(AH, cs);
576}
CompressorState * AllocateCompressor(const pg_compress_specification compression_spec, ReadFunc readF, WriteFunc writeF)
Definition: compress_io.c:123
static size_t _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen)
void(* readData)(ArchiveHandle *AH, CompressorState *cs)
Definition: compress_io.h:56
pg_compress_specification compression_spec

References _CustomReadFunc(), AllocateCompressor(), _archiveHandle::compression_spec, EndCompressor(), and CompressorState::readData.

Referenced by _LoadLOs(), and _PrintTocData().

◆ _PrintExtraToc()

static void _PrintExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 264 of file pg_backup_custom.c.

265{
266 lclTocEntry *ctx = (lclTocEntry *) te->formatData;
267
268 if (AH->public.verbose)
269 ahprintf(AH, "-- Data Pos: " INT64_FORMAT "\n",
270 (int64) ctx->dataPos);
271}
#define INT64_FORMAT
Definition: c.h:559
int64_t int64
Definition: c.h:538
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
int verbose
Definition: pg_backup.h:231

References ahprintf(), lclTocEntry::dataPos, _tocEntry::formatData, if(), INT64_FORMAT, _archiveHandle::public, and Archive::verbose.

Referenced by InitArchiveFmt_Custom().

◆ _PrintTocData()

static void _PrintTocData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 415 of file pg_backup_custom.c.

416{
417 lclContext *ctx = (lclContext *) AH->formatData;
418 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
419 int blkType;
420 int id;
421
422 if (tctx->dataState == K_OFFSET_NO_DATA)
423 return;
424
425 if (!ctx->hasSeek || tctx->dataState == K_OFFSET_POS_NOT_SET)
426 {
427 /*
428 * We cannot seek directly to the desired block. Instead, skip over
429 * block headers until we find the one we want. Remember the
430 * positions of skipped-over blocks, so that if we later decide we
431 * need to read one, we'll be able to seek to it.
432 *
433 * When our input file is seekable, we can do the search starting from
434 * the point after the last data block we scanned in previous
435 * iterations of this function.
436 */
437 if (ctx->hasSeek)
438 {
439 if (fseeko(AH->FH, ctx->lastFilePos, SEEK_SET) != 0)
440 pg_fatal("error during file seek: %m");
441 }
442
443 for (;;)
444 {
445 pgoff_t thisBlkPos = _getFilePos(AH, ctx);
446
447 _readBlockHeader(AH, &blkType, &id);
448
449 if (blkType == EOF || id == te->dumpId)
450 break;
451
452 /* Remember the block position, if we got one */
453 if (thisBlkPos >= 0)
454 {
455 TocEntry *otherte = getTocEntryByDumpId(AH, id);
456
457 if (otherte && otherte->formatData)
458 {
459 lclTocEntry *othertctx = (lclTocEntry *) otherte->formatData;
460
461 /*
462 * Note: on Windows, multiple threads might access/update
463 * the same lclTocEntry concurrently, but that should be
464 * safe as long as we update dataPos before dataState.
465 * Ideally, we'd use pg_write_barrier() to enforce that,
466 * but the needed infrastructure doesn't exist in frontend
467 * code. But Windows only runs on machines with strong
468 * store ordering, so it should be okay for now.
469 */
470 if (othertctx->dataState == K_OFFSET_POS_NOT_SET)
471 {
472 othertctx->dataPos = thisBlkPos;
473 othertctx->dataState = K_OFFSET_POS_SET;
474 }
475 else if (othertctx->dataPos != thisBlkPos ||
476 othertctx->dataState != K_OFFSET_POS_SET)
477 {
478 /* sanity check */
479 pg_log_warning("data block %d has wrong seek position",
480 id);
481 }
482 }
483 }
484
485 switch (blkType)
486 {
487 case BLK_DATA:
488 _skipData(AH);
489 break;
490
491 case BLK_BLOBS:
492 _skipLOs(AH);
493 break;
494
495 default: /* Always have a default */
496 pg_fatal("unrecognized data block type (%d) while searching archive",
497 blkType);
498 break;
499 }
500 }
501 }
502 else
503 {
504 /* We can just seek to the place we need to be. */
505 if (fseeko(AH->FH, tctx->dataPos, SEEK_SET) != 0)
506 pg_fatal("error during file seek: %m");
507
508 _readBlockHeader(AH, &blkType, &id);
509 }
510
511 /*
512 * If we reached EOF without finding the block we want, then either it
513 * doesn't exist, or it does but we lack the ability to seek back to it.
514 */
515 if (blkType == EOF)
516 {
517 if (!ctx->hasSeek)
518 pg_fatal("could not find block ID %d in archive -- "
519 "possibly due to out-of-order restore request, "
520 "which cannot be handled due to non-seekable input file",
521 te->dumpId);
522 else
523 pg_fatal("could not find block ID %d in archive -- "
524 "possibly corrupt archive",
525 te->dumpId);
526 }
527
528 /* Are we sane? */
529 if (id != te->dumpId)
530 pg_fatal("found unexpected block ID (%d) when reading data -- expected %d",
531 id, te->dumpId);
532
533 switch (blkType)
534 {
535 case BLK_DATA:
536 _PrintData(AH);
537 break;
538
539 case BLK_BLOBS:
540 _LoadLOs(AH, AH->public.ropt->dropSchema);
541 break;
542
543 default: /* Always have a default */
544 pg_fatal("unrecognized data block type %d while restoring archive",
545 blkType);
546 break;
547 }
548
549 /*
550 * If our input file is seekable but lacks data offsets, update our
551 * knowledge of where to start future searches from. (Note that we did
552 * not update the current TE's dataState/dataPos. We could have, but
553 * there is no point since it will not be visited again.)
554 */
555 if (ctx->hasSeek && tctx->dataState == K_OFFSET_POS_NOT_SET)
556 {
557 pgoff_t curPos = _getFilePos(AH, ctx);
558
559 if (curPos > ctx->lastFilePos)
560 ctx->lastFilePos = curPos;
561 }
562}
TocEntry * getTocEntryByDumpId(ArchiveHandle *AH, DumpId id)
#define BLK_DATA
#define BLK_BLOBS
static void _skipData(ArchiveHandle *AH)
static void _skipLOs(ArchiveHandle *AH)
static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx)
static void _readBlockHeader(ArchiveHandle *AH, int *type, int *id)
static void _LoadLOs(ArchiveHandle *AH, bool drop)
#define pg_log_warning(...)
Definition: pgfnames.c:24
RestoreOptions * ropt
Definition: pg_backup.h:229
pgoff_t lastFilePos

References _getFilePos(), _LoadLOs(), _PrintData(), _readBlockHeader(), _skipData(), _skipLOs(), BLK_BLOBS, BLK_DATA, lclTocEntry::dataPos, lclTocEntry::dataState, _restoreOptions::dropSchema, _tocEntry::dumpId, _archiveHandle::FH, _archiveHandle::formatData, _tocEntry::formatData, fseeko, getTocEntryByDumpId(), lclContext::hasSeek, if(), K_OFFSET_NO_DATA, K_OFFSET_POS_NOT_SET, K_OFFSET_POS_SET, lclContext::lastFilePos, pg_fatal, pg_log_warning, pgoff_t, _archiveHandle::public, and Archive::ropt.

Referenced by InitArchiveFmt_Custom().

◆ _readBlockHeader()

static void _readBlockHeader ( ArchiveHandle AH,
int *  type,
int *  id 
)
static

Definition at line 964 of file pg_backup_custom.c.

965{
966 int byt;
967
968 /*
969 * Note: if we are at EOF with a pre-1.3 input file, we'll pg_fatal()
970 * inside ReadInt rather than returning EOF. It doesn't seem worth
971 * jumping through hoops to deal with that case better, because no such
972 * files are likely to exist in the wild: only some 7.1 development
973 * versions of pg_dump ever generated such files.
974 */
975 if (AH->version < K_VERS_1_3)
976 *type = BLK_DATA;
977 else
978 {
979 byt = getc(AH->FH);
980 *type = byt;
981 if (byt == EOF)
982 {
983 *id = 0; /* don't return an uninitialized value */
984 return;
985 }
986 }
987
988 *id = ReadInt(AH);
989}
#define K_VERS_1_3
const char * type

References BLK_DATA, _archiveHandle::FH, K_VERS_1_3, ReadInt(), type, and _archiveHandle::version.

Referenced by _PrintTocData().

◆ _ReadBuf()

static void _ReadBuf ( ArchiveHandle AH,
void *  buf,
size_t  len 
)
static

Definition at line 724 of file pg_backup_custom.c.

725{
726 if (fread(buf, 1, len, AH->FH) != len)
727 READ_ERROR_EXIT(AH->FH);
728}
#define READ_ERROR_EXIT(fd)

References buf, _archiveHandle::FH, len, and READ_ERROR_EXIT.

Referenced by _CustomReadFunc(), and InitArchiveFmt_Custom().

◆ _ReadByte()

static int _ReadByte ( ArchiveHandle AH)
static

Definition at line 692 of file pg_backup_custom.c.

693{
694 int res;
695
696 res = getc(AH->FH);
697 if (res == EOF)
698 READ_ERROR_EXIT(AH->FH);
699 return res;
700}

References _archiveHandle::FH, and READ_ERROR_EXIT.

Referenced by InitArchiveFmt_Custom().

◆ _ReadExtraToc()

static void _ReadExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 237 of file pg_backup_custom.c.

238{
239 lclTocEntry *ctx = (lclTocEntry *) te->formatData;
240
241 if (ctx == NULL)
242 {
243 ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
244 te->formatData = ctx;
245 }
246
247 ctx->dataState = ReadOffset(AH, &(ctx->dataPos));
248
249 /*
250 * Prior to V1.7 (pg7.3), we dumped the data size as an int now we don't
251 * dump it at all.
252 */
253 if (AH->version < K_VERS_1_7)
254 ReadInt(AH);
255}
int ReadOffset(ArchiveHandle *AH, pgoff_t *o)
#define K_VERS_1_7

References lclTocEntry::dataPos, lclTocEntry::dataState, _tocEntry::formatData, if(), K_VERS_1_7, pg_malloc0(), ReadInt(), ReadOffset(), and _archiveHandle::version.

Referenced by InitArchiveFmt_Custom().

◆ _ReopenArchive()

static void _ReopenArchive ( ArchiveHandle AH)
static

Definition at line 792 of file pg_backup_custom.c.

793{
794 lclContext *ctx = (lclContext *) AH->formatData;
795 pgoff_t tpos;
796
797 if (AH->mode == archModeWrite)
798 pg_fatal("can only reopen input archives");
799
800 /*
801 * These two cases are user-facing errors since they represent unsupported
802 * (but not invalid) use-cases. Word the error messages appropriately.
803 */
804 if (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0)
805 pg_fatal("parallel restore from standard input is not supported");
806 if (!ctx->hasSeek)
807 pg_fatal("parallel restore from non-seekable file is not supported");
808
809 tpos = ftello(AH->FH);
810 if (tpos < 0)
811 pg_fatal("could not determine seek position in archive file: %m");
812
813#ifndef WIN32
814 if (fclose(AH->FH) != 0)
815 pg_fatal("could not close archive file: %m");
816#endif
817
818 AH->FH = fopen(AH->fSpec, PG_BINARY_R);
819 if (!AH->FH)
820 pg_fatal("could not open input file \"%s\": %m", AH->fSpec);
821
822 if (fseeko(AH->FH, tpos, SEEK_SET) != 0)
823 pg_fatal("could not set seek position in archive file: %m");
824}
#define PG_BINARY_R
Definition: c.h:1263

References archModeWrite, _archiveHandle::FH, _archiveHandle::formatData, fseeko, _archiveHandle::fSpec, ftello, lclContext::hasSeek, if(), _archiveHandle::mode, PG_BINARY_R, pg_fatal, and pgoff_t.

Referenced by InitArchiveFmt_Custom().

◆ _skipData()

static void _skipData ( ArchiveHandle AH)
static

Definition at line 622 of file pg_backup_custom.c.

623{
624 lclContext *ctx = (lclContext *) AH->formatData;
625 size_t blkLen;
626 char *buf = NULL;
627 size_t buflen = 0;
628
629 blkLen = ReadInt(AH);
630 while (blkLen != 0)
631 {
632 /*
633 * Seeks of less than stdio's buffer size are less efficient than just
634 * reading the data, at least on common platforms. We don't know the
635 * buffer size for sure, but 4kB is the usual value. (While pg_dump
636 * currently tries to avoid producing such short data blocks, older
637 * dump files often contain them.)
638 */
639 if (ctx->hasSeek && blkLen >= 4 * 1024)
640 {
641 if (fseeko(AH->FH, blkLen, SEEK_CUR) != 0)
642 pg_fatal("error during file seek: %m");
643 }
644 else
645 {
646 if (blkLen > buflen)
647 {
648 free(buf);
649 buflen = Max(blkLen, 4 * 1024);
650 buf = (char *) pg_malloc(buflen);
651 }
652 if (fread(buf, 1, blkLen, AH->FH) != blkLen)
653 {
654 if (feof(AH->FH))
655 pg_fatal("could not read from input file: end of file");
656 else
657 pg_fatal("could not read from input file: %m");
658 }
659 }
660
661 blkLen = ReadInt(AH);
662 }
663
664 free(buf);
665}
#define Max(x, y)
Definition: c.h:1000

References buf, _archiveHandle::FH, _archiveHandle::formatData, free, fseeko, lclContext::hasSeek, Max, pg_fatal, pg_malloc(), and ReadInt().

Referenced by _PrintTocData(), and _skipLOs().

◆ _skipLOs()

static void _skipLOs ( ArchiveHandle AH)
static

Definition at line 604 of file pg_backup_custom.c.

605{
606 Oid oid;
607
608 oid = ReadInt(AH);
609 while (oid != 0)
610 {
611 _skipData(AH);
612 oid = ReadInt(AH);
613 }
614}

References _skipData(), and ReadInt().

Referenced by _PrintTocData().

◆ _StartData()

static void _StartData ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 284 of file pg_backup_custom.c.

285{
286 lclContext *ctx = (lclContext *) AH->formatData;
287 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
288
289 tctx->dataPos = _getFilePos(AH, ctx);
290 if (tctx->dataPos >= 0)
291 tctx->dataState = K_OFFSET_POS_SET;
292
293 _WriteByte(AH, BLK_DATA); /* Block type */
294 WriteInt(AH, te->dumpId); /* For sanity check */
295
297 NULL,
299}
static int _WriteByte(ArchiveHandle *AH, const int i)
static void _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len)

References _CustomWriteFunc(), _getFilePos(), _WriteByte(), AllocateCompressor(), BLK_DATA, _archiveHandle::compression_spec, lclContext::cs, _tocEntry::dumpId, _archiveHandle::formatData, _tocEntry::formatData, K_OFFSET_POS_SET, and WriteInt().

Referenced by InitArchiveFmt_Custom().

◆ _StartLO()

static void _StartLO ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
)
static

Definition at line 370 of file pg_backup_custom.c.

371{
372 lclContext *ctx = (lclContext *) AH->formatData;
373
374 if (oid == 0)
375 pg_fatal("invalid OID for large object");
376
377 WriteInt(AH, oid);
378
380 NULL,
382}

References _CustomWriteFunc(), AllocateCompressor(), _archiveHandle::compression_spec, lclContext::cs, _archiveHandle::formatData, if(), pg_fatal, and WriteInt().

Referenced by InitArchiveFmt_Custom().

◆ _StartLOs()

static void _StartLOs ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 349 of file pg_backup_custom.c.

350{
351 lclContext *ctx = (lclContext *) AH->formatData;
352 lclTocEntry *tctx = (lclTocEntry *) te->formatData;
353
354 tctx->dataPos = _getFilePos(AH, ctx);
355 if (tctx->dataPos >= 0)
356 tctx->dataState = K_OFFSET_POS_SET;
357
358 _WriteByte(AH, BLK_BLOBS); /* Block type */
359 WriteInt(AH, te->dumpId); /* For sanity check */
360}

References _getFilePos(), _WriteByte(), BLK_BLOBS, _tocEntry::dumpId, _archiveHandle::formatData, _tocEntry::formatData, K_OFFSET_POS_SET, and WriteInt().

Referenced by InitArchiveFmt_Custom().

◆ _WorkerJobRestoreCustom()

static int _WorkerJobRestoreCustom ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 925 of file pg_backup_custom.c.

926{
927 return parallel_restore(AH, te);
928}
int parallel_restore(ArchiveHandle *AH, TocEntry *te)

References parallel_restore().

Referenced by InitArchiveFmt_Custom().

◆ _WriteBuf()

static void _WriteBuf ( ArchiveHandle AH,
const void *  buf,
size_t  len 
)
static

Definition at line 710 of file pg_backup_custom.c.

711{
712 if (fwrite(buf, 1, len, AH->FH) != len)
714}
#define WRITE_ERROR_EXIT

References buf, _archiveHandle::FH, len, and WRITE_ERROR_EXIT.

Referenced by _CustomWriteFunc(), and InitArchiveFmt_Custom().

◆ _WriteByte()

static int _WriteByte ( ArchiveHandle AH,
const int  i 
)
static

Definition at line 675 of file pg_backup_custom.c.

676{
677 if (fputc(i, AH->FH) == EOF)
679
680 return 1;
681}
int i
Definition: isn.c:77

References _archiveHandle::FH, i, and WRITE_ERROR_EXIT.

Referenced by _StartData(), _StartLOs(), and InitArchiveFmt_Custom().

◆ _WriteData()

static void _WriteData ( ArchiveHandle AH,
const void *  data,
size_t  dLen 
)
static

Definition at line 311 of file pg_backup_custom.c.

312{
313 lclContext *ctx = (lclContext *) AH->formatData;
314 CompressorState *cs = ctx->cs;
315
316 if (dLen > 0)
317 /* writeData() internally throws write errors */
318 cs->writeData(AH, cs, data, dLen);
319}
const void * data

References lclContext::cs, data, _archiveHandle::formatData, and if().

Referenced by InitArchiveFmt_Custom().

◆ _WriteExtraToc()

static void _WriteExtraToc ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 221 of file pg_backup_custom.c.

222{
223 lclTocEntry *ctx = (lclTocEntry *) te->formatData;
224
225 WriteOffset(AH, ctx->dataPos, ctx->dataState);
226}
size_t WriteOffset(ArchiveHandle *AH, pgoff_t o, int wasSet)

References lclTocEntry::dataPos, lclTocEntry::dataState, _tocEntry::formatData, and WriteOffset().

Referenced by InitArchiveFmt_Custom().

◆ InitArchiveFmt_Custom()

void InitArchiveFmt_Custom ( ArchiveHandle AH)

Definition at line 105 of file pg_backup_custom.c.

106{
107 lclContext *ctx;
108
109 /* Assuming static functions, this can be copied for each format. */
113 AH->EndDataPtr = _EndData;
117 AH->ReadBufPtr = _ReadBuf;
124
126 AH->StartLOPtr = _StartLO;
127 AH->EndLOPtr = _EndLO;
128 AH->EndLOsPtr = _EndLOs;
129
131 AH->ClonePtr = _Clone;
132 AH->DeClonePtr = _DeClone;
133
134 /* no parallel dump in the custom archive, only parallel restore */
135 AH->WorkerJobDumpPtr = NULL;
137
138 /* Set up a private area. */
139 ctx = (lclContext *) pg_malloc0(sizeof(lclContext));
140 AH->formatData = ctx;
141
142 /*
143 * Now open the file
144 */
145 if (AH->mode == archModeWrite)
146 {
147 if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
148 {
149 AH->FH = fopen(AH->fSpec, PG_BINARY_W);
150 if (!AH->FH)
151 pg_fatal("could not open output file \"%s\": %m", AH->fSpec);
152 }
153 else
154 {
155 AH->FH = stdout;
156 if (!AH->FH)
157 pg_fatal("could not open output file: %m");
158 }
159
160 ctx->hasSeek = checkSeek(AH->FH);
161 }
162 else
163 {
164 if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
165 {
166 AH->FH = fopen(AH->fSpec, PG_BINARY_R);
167 if (!AH->FH)
168 pg_fatal("could not open input file \"%s\": %m", AH->fSpec);
169 }
170 else
171 {
172 AH->FH = stdin;
173 if (!AH->FH)
174 pg_fatal("could not open input file: %m");
175 }
176
177 ctx->hasSeek = checkSeek(AH->FH);
178
179 ReadHead(AH);
180 ReadToc(AH);
181
182 /*
183 * Remember location of first data block (i.e., the point after TOC)
184 * in case we have to search for desired data blocks.
185 */
186 ctx->lastFilePos = _getFilePos(AH, ctx);
187 }
188}
#define PG_BINARY_W
Definition: c.h:1264
bool checkSeek(FILE *fp)
void ReadHead(ArchiveHandle *AH)
void ReadToc(ArchiveHandle *AH)
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 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 _EndData(ArchiveHandle *AH, TocEntry *te)
static int _WorkerJobRestoreCustom(ArchiveHandle *AH, TocEntry *te)
static void _Clone(ArchiveHandle *AH)
DeClonePtrType DeClonePtr
EndLOsPtrType EndLOsPtr
ReadExtraTocPtrType ReadExtraTocPtr
WorkerJobDumpPtrType WorkerJobDumpPtr
StartLOsPtrType StartLOsPtr
ArchiveEntryPtrType ArchiveEntryPtr
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

References _ArchiveEntry(), _Clone(), _CloseArchive(), _DeClone(), _EndData(), _EndLO(), _EndLOs(), _getFilePos(), _PrepParallelRestore(), _PrintExtraToc(), _PrintTocData(), _ReadBuf(), _ReadByte(), _ReadExtraToc(), _ReopenArchive(), _StartData(), _StartLO(), _StartLOs(), _WorkerJobRestoreCustom(), _WriteBuf(), _WriteByte(), _WriteData(), _WriteExtraToc(), _archiveHandle::ArchiveEntryPtr, archModeWrite, checkSeek(), _archiveHandle::ClonePtr, _archiveHandle::ClosePtr, _archiveHandle::DeClonePtr, _archiveHandle::EndDataPtr, _archiveHandle::EndLOPtr, _archiveHandle::EndLOsPtr, _archiveHandle::FH, _archiveHandle::formatData, _archiveHandle::fSpec, lclContext::hasSeek, lclContext::lastFilePos, _archiveHandle::mode, PG_BINARY_R, PG_BINARY_W, pg_fatal, pg_malloc0(), _archiveHandle::PrepParallelRestorePtr, _archiveHandle::PrintExtraTocPtr, _archiveHandle::PrintTocDataPtr, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, _archiveHandle::ReadExtraTocPtr, ReadHead(), ReadToc(), _archiveHandle::ReopenPtr, _archiveHandle::StartDataPtr, _archiveHandle::StartLOPtr, _archiveHandle::StartLOsPtr, generate_unaccent_rules::stdout, _archiveHandle::WorkerJobDumpPtr, _archiveHandle::WorkerJobRestorePtr, _archiveHandle::WriteBufPtr, _archiveHandle::WriteBytePtr, _archiveHandle::WriteDataPtr, and _archiveHandle::WriteExtraTocPtr.

Referenced by _allocAH().