aboutsummaryrefslogtreecommitdiff
path: root/src/backend/replication/basebackup_gzip.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2022-08-10 14:03:23 -0400
committerRobert Haas <rhaas@postgresql.org>2022-08-10 14:03:23 -0400
commita8c012869763c711abc9085f54b2a100b60a85fa (patch)
tree1a278296a8f719835afe477ffa43d89c29f0e43b /src/backend/replication/basebackup_gzip.c
parent309857f9c1825d0591579579bdde2a8c8bd3e491 (diff)
downloadpostgresql-a8c012869763c711abc9085f54b2a100b60a85fa.tar.gz
postgresql-a8c012869763c711abc9085f54b2a100b60a85fa.zip
Move basebackup code to new directory src/backend/backup
Reviewed by David Steele and Justin Pryzby Discussion: http://postgr.es/m/CA+TgmoafqboATDSoXHz8VLrSwK_MDhjthK4hEpYjqf9_1Fmczw%40mail.gmail.com
Diffstat (limited to 'src/backend/replication/basebackup_gzip.c')
-rw-r--r--src/backend/replication/basebackup_gzip.c308
1 files changed, 0 insertions, 308 deletions
diff --git a/src/backend/replication/basebackup_gzip.c b/src/backend/replication/basebackup_gzip.c
deleted file mode 100644
index ef2b954946a..00000000000
--- a/src/backend/replication/basebackup_gzip.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * basebackup_gzip.c
- * Basebackup sink implementing gzip compression.
- *
- * Portions Copyright (c) 2010-2022, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- * src/backend/replication/basebackup_gzip.c
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
-#include "replication/basebackup_sink.h"
-
-#ifdef HAVE_LIBZ
-typedef struct bbsink_gzip
-{
- /* Common information for all types of sink. */
- bbsink base;
-
- /* Compression level. */
- int compresslevel;
-
- /* Compressed data stream. */
- z_stream zstream;
-
- /* Number of bytes staged in output buffer. */
- size_t bytes_written;
-} bbsink_gzip;
-
-static void bbsink_gzip_begin_backup(bbsink *sink);
-static void bbsink_gzip_begin_archive(bbsink *sink, const char *archive_name);
-static void bbsink_gzip_archive_contents(bbsink *sink, size_t len);
-static void bbsink_gzip_manifest_contents(bbsink *sink, size_t len);
-static void bbsink_gzip_end_archive(bbsink *sink);
-static void *gzip_palloc(void *opaque, unsigned items, unsigned size);
-static void gzip_pfree(void *opaque, void *address);
-
-static const bbsink_ops bbsink_gzip_ops = {
- .begin_backup = bbsink_gzip_begin_backup,
- .begin_archive = bbsink_gzip_begin_archive,
- .archive_contents = bbsink_gzip_archive_contents,
- .end_archive = bbsink_gzip_end_archive,
- .begin_manifest = bbsink_forward_begin_manifest,
- .manifest_contents = bbsink_gzip_manifest_contents,
- .end_manifest = bbsink_forward_end_manifest,
- .end_backup = bbsink_forward_end_backup,
- .cleanup = bbsink_forward_cleanup
-};
-#endif
-
-/*
- * Create a new basebackup sink that performs gzip compression.
- */
-bbsink *
-bbsink_gzip_new(bbsink *next, pg_compress_specification *compress)
-{
-#ifndef HAVE_LIBZ
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("gzip compression is not supported by this build")));
- return NULL; /* keep compiler quiet */
-#else
- bbsink_gzip *sink;
- int compresslevel;
-
- Assert(next != NULL);
-
- if ((compress->options & PG_COMPRESSION_OPTION_LEVEL) == 0)
- compresslevel = Z_DEFAULT_COMPRESSION;
- else
- {
- compresslevel = compress->level;
- Assert(compresslevel >= 1 && compresslevel <= 9);
- }
-
- sink = palloc0(sizeof(bbsink_gzip));
- *((const bbsink_ops **) &sink->base.bbs_ops) = &bbsink_gzip_ops;
- sink->base.bbs_next = next;
- sink->compresslevel = compresslevel;
-
- return &sink->base;
-#endif
-}
-
-#ifdef HAVE_LIBZ
-
-/*
- * Begin backup.
- */
-static void
-bbsink_gzip_begin_backup(bbsink *sink)
-{
- /*
- * We need our own buffer, because we're going to pass different data to
- * the next sink than what gets passed to us.
- */
- sink->bbs_buffer = palloc(sink->bbs_buffer_length);
-
- /*
- * Since deflate() doesn't require the output buffer to be of any
- * particular size, we can just make it the same size as the input buffer.
- */
- bbsink_begin_backup(sink->bbs_next, sink->bbs_state,
- sink->bbs_buffer_length);
-}
-
-/*
- * Prepare to compress the next archive.
- */
-static void
-bbsink_gzip_begin_archive(bbsink *sink, const char *archive_name)
-{
- bbsink_gzip *mysink = (bbsink_gzip *) sink;
- char *gz_archive_name;
- z_stream *zs = &mysink->zstream;
-
- /* Initialize compressor object. */
- memset(zs, 0, sizeof(z_stream));
- zs->zalloc = gzip_palloc;
- zs->zfree = gzip_pfree;
- zs->next_out = (uint8 *) sink->bbs_next->bbs_buffer;
- zs->avail_out = sink->bbs_next->bbs_buffer_length;
-
- /*
- * We need to use deflateInit2() rather than deflateInit() here so that we
- * can request a gzip header rather than a zlib header. Otherwise, we want
- * to supply the same values that would have been used by default if we
- * had just called deflateInit().
- *
- * Per the documentation for deflateInit2, the third argument must be
- * Z_DEFLATED; the fourth argument is the number of "window bits", by
- * default 15, but adding 16 gets you a gzip header rather than a zlib
- * header; the fifth argument controls memory usage, and 8 is the default;
- * and likewise Z_DEFAULT_STRATEGY is the default for the sixth argument.
- */
- if (deflateInit2(zs, mysink->compresslevel, Z_DEFLATED, 15 + 16, 8,
- Z_DEFAULT_STRATEGY) != Z_OK)
- ereport(ERROR,
- errcode(ERRCODE_INTERNAL_ERROR),
- errmsg("could not initialize compression library"));
-
- /*
- * Add ".gz" to the archive name. Note that the pg_basebackup -z produces
- * archives named ".tar.gz" rather than ".tgz", so we match that here.
- */
- gz_archive_name = psprintf("%s.gz", archive_name);
- Assert(sink->bbs_next != NULL);
- bbsink_begin_archive(sink->bbs_next, gz_archive_name);
- pfree(gz_archive_name);
-}
-
-/*
- * Compress the input data to the output buffer until we run out of input
- * data. Each time the output buffer fills up, invoke the archive_contents()
- * method for then next sink.
- *
- * Note that since we're compressing the input, it may very commonly happen
- * that we consume all the input data without filling the output buffer. In
- * that case, the compressed representation of the current input data won't
- * actually be sent to the next bbsink until a later call to this function,
- * or perhaps even not until bbsink_gzip_end_archive() is invoked.
- */
-static void
-bbsink_gzip_archive_contents(bbsink *sink, size_t len)
-{
- bbsink_gzip *mysink = (bbsink_gzip *) sink;
- z_stream *zs = &mysink->zstream;
-
- /* Compress data from input buffer. */
- zs->next_in = (uint8 *) mysink->base.bbs_buffer;
- zs->avail_in = len;
-
- while (zs->avail_in > 0)
- {
- int res;
-
- /* Write output data into unused portion of output buffer. */
- Assert(mysink->bytes_written < mysink->base.bbs_next->bbs_buffer_length);
- zs->next_out = (uint8 *)
- mysink->base.bbs_next->bbs_buffer + mysink->bytes_written;
- zs->avail_out =
- mysink->base.bbs_next->bbs_buffer_length - mysink->bytes_written;
-
- /*
- * Try to compress. Note that this will update zs->next_in and
- * zs->avail_in according to how much input data was consumed, and
- * zs->next_out and zs->avail_out according to how many output bytes
- * were produced.
- *
- * According to the zlib documentation, Z_STREAM_ERROR should only
- * occur if we've made a programming error, or if say there's been a
- * memory clobber; we use elog() rather than Assert() here out of an
- * abundance of caution.
- */
- res = deflate(zs, Z_NO_FLUSH);
- if (res == Z_STREAM_ERROR)
- elog(ERROR, "could not compress data: %s", zs->msg);
-
- /* Update our notion of how many bytes we've written. */
- mysink->bytes_written =
- mysink->base.bbs_next->bbs_buffer_length - zs->avail_out;
-
- /*
- * If the output buffer is full, it's time for the next sink to
- * process the contents.
- */
- if (mysink->bytes_written >= mysink->base.bbs_next->bbs_buffer_length)
- {
- bbsink_archive_contents(sink->bbs_next, mysink->bytes_written);
- mysink->bytes_written = 0;
- }
- }
-}
-
-/*
- * There might be some data inside zlib's internal buffers; we need to get
- * that flushed out and forwarded to the successor sink as archive content.
- *
- * Then we can end processing for this archive.
- */
-static void
-bbsink_gzip_end_archive(bbsink *sink)
-{
- bbsink_gzip *mysink = (bbsink_gzip *) sink;
- z_stream *zs = &mysink->zstream;
-
- /* There is no more data available. */
- zs->next_in = (uint8 *) mysink->base.bbs_buffer;
- zs->avail_in = 0;
-
- while (1)
- {
- int res;
-
- /* Write output data into unused portion of output buffer. */
- Assert(mysink->bytes_written < mysink->base.bbs_next->bbs_buffer_length);
- zs->next_out = (uint8 *)
- mysink->base.bbs_next->bbs_buffer + mysink->bytes_written;
- zs->avail_out =
- mysink->base.bbs_next->bbs_buffer_length - mysink->bytes_written;
-
- /*
- * As bbsink_gzip_archive_contents, but pass Z_FINISH since there is
- * no more input.
- */
- res = deflate(zs, Z_FINISH);
- if (res == Z_STREAM_ERROR)
- elog(ERROR, "could not compress data: %s", zs->msg);
-
- /* Update our notion of how many bytes we've written. */
- mysink->bytes_written =
- mysink->base.bbs_next->bbs_buffer_length - zs->avail_out;
-
- /*
- * Apparently we had no data in the output buffer and deflate() was
- * not able to add any. We must be done.
- */
- if (mysink->bytes_written == 0)
- break;
-
- /* Send whatever accumulated output bytes we have. */
- bbsink_archive_contents(sink->bbs_next, mysink->bytes_written);
- mysink->bytes_written = 0;
- }
-
- /* Must also pass on the information that this archive has ended. */
- bbsink_forward_end_archive(sink);
-}
-
-/*
- * Manifest contents are not compressed, but we do need to copy them into
- * the successor sink's buffer, because we have our own.
- */
-static void
-bbsink_gzip_manifest_contents(bbsink *sink, size_t len)
-{
- memcpy(sink->bbs_next->bbs_buffer, sink->bbs_buffer, len);
- bbsink_manifest_contents(sink->bbs_next, len);
-}
-
-/*
- * Wrapper function to adjust the signature of palloc to match what libz
- * expects.
- */
-static void *
-gzip_palloc(void *opaque, unsigned items, unsigned size)
-{
- return palloc(items * size);
-}
-
-/*
- * Wrapper function to adjust the signature of pfree to match what libz
- * expects.
- */
-static void
-gzip_pfree(void *opaque, void *address)
-{
- pfree(address);
-}
-
-#endif