diff options
author | Robert Haas <rhaas@postgresql.org> | 2022-08-10 14:03:23 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2022-08-10 14:03:23 -0400 |
commit | a8c012869763c711abc9085f54b2a100b60a85fa (patch) | |
tree | 1a278296a8f719835afe477ffa43d89c29f0e43b /src/backend/replication/basebackup_gzip.c | |
parent | 309857f9c1825d0591579579bdde2a8c8bd3e491 (diff) | |
download | postgresql-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.c | 308 |
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 |