v28-0003-Add-default_toast_compression-GUC.patch
text/x-patch
Filename: v28-0003-Add-default_toast_compression-GUC.patch
Type: text/x-patch
Part: 2
Patch
Format: format-patch
Series: patch v28-0003
Subject: Add default_toast_compression GUC
| File | + | − |
|---|---|---|
| src/backend/access/common/tupdesc.c | 1 | 1 |
| src/backend/bootstrap/bootstrap.c | 2 | 1 |
| src/backend/commands/amcmds.c | 137 | 1 |
| src/backend/commands/tablecmds.c | 2 | 2 |
| src/backend/utils/init/postinit.c | 4 | 0 |
| src/backend/utils/misc/guc.c | 12 | 0 |
| src/backend/utils/misc/postgresql.conf.sample | 1 | 0 |
| src/bin/pg_dump/pg_dump.c | 1 | 6 |
| src/include/access/amapi.h | 2 | 0 |
| src/include/access/compressamapi.h | 11 | 1 |
From 6e9d3a0b45f8f1a4dc125268d8177e1cea63a546 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 29 Jan 2021 21:37:46 -0600
Subject: [PATCH v28 3/4] Add default_toast_compression GUC
Justin Pryzby with modification from Dilip Kumar
---
src/backend/access/common/tupdesc.c | 2 +-
src/backend/bootstrap/bootstrap.c | 3 +-
src/backend/commands/amcmds.c | 138 +++++++++++++++++++++++++-
src/backend/commands/tablecmds.c | 4 +-
src/backend/utils/init/postinit.c | 4 +
src/backend/utils/misc/guc.c | 12 +++
src/backend/utils/misc/postgresql.conf.sample | 1 +
src/bin/pg_dump/pg_dump.c | 7 +-
src/include/access/amapi.h | 2 +
src/include/access/compressamapi.h | 12 ++-
10 files changed, 173 insertions(+), 12 deletions(-)
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index ca26fab..7afaea0 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -668,7 +668,7 @@ TupleDescInitEntry(TupleDesc desc,
att->attcollation = typeForm->typcollation;
if (IsStorageCompressible(typeForm->typstorage))
- att->attcompression = DefaultCompressionOid;
+ att->attcompression = GetDefaultToastCompression();
else
att->attcompression = InvalidOid;
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 9b451ea..ec3376c 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -732,8 +732,9 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
attrtypes[attnum]->attcacheoff = -1;
attrtypes[attnum]->atttypmod = -1;
attrtypes[attnum]->attislocal = true;
+
if (IsStorageCompressible(attrtypes[attnum]->attstorage))
- attrtypes[attnum]->attcompression = DefaultCompressionOid;
+ attrtypes[attnum]->attcompression = GetDefaultToastCompression();
else
attrtypes[attnum]->attcompression = InvalidOid;
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index 3ad4a61..54edeff 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -13,8 +13,11 @@
*/
#include "postgres.h"
+#include "access/amapi.h"
+#include "access/compressamapi.h"
#include "access/htup_details.h"
#include "access/table.h"
+#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
@@ -27,13 +30,20 @@
#include "parser/parse_func.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
+#include "utils/guc.h"
+#include "utils/inval.h"
#include "utils/rel.h"
#include "utils/syscache.h"
-
static Oid lookup_am_handler_func(List *handler_name, char amtype);
static const char *get_am_type_string(char amtype);
+/* Compile-time default */
+char *default_toast_compression = DEFAULT_TOAST_COMPRESSION;
+/* Invalid means need to lookup the text value in the catalog */
+static Oid default_toast_compression_oid = InvalidOid;
+
+static void AccessMethodCallback(Datum arg, int cacheid, uint32 hashvalue);
/*
* CreateAccessMethod
@@ -277,3 +287,129 @@ lookup_am_handler_func(List *handler_name, char amtype)
return handlerOid;
}
+
+/* check_hook: validate new default_toast_compression */
+bool
+check_default_toast_compression(char **newval, void **extra, GucSource source)
+{
+ if (**newval == '\0')
+ {
+ GUC_check_errdetail("%s cannot be empty.",
+ "default_toast_compression");
+ return false;
+ }
+
+ if (strlen(*newval) >= NAMEDATALEN)
+ {
+ GUC_check_errdetail("%s is too long (maximum %d characters).",
+ "default_toast_compression", NAMEDATALEN - 1);
+ return false;
+ }
+
+ /*
+ * If we aren't inside a transaction, or not connected to a database, we
+ * cannot do the catalog access necessary to verify the method. Must
+ * accept the value on faith.
+ */
+ if (IsTransactionState() && MyDatabaseId != InvalidOid)
+ {
+ if (!OidIsValid(get_compression_am_oid(*newval, true)))
+ {
+ /*
+ * When source == PGC_S_TEST, don't throw a hard error for a
+ * nonexistent table access method, only a NOTICE. See comments in
+ * guc.h.
+ */
+ if (source == PGC_S_TEST)
+ {
+ ereport(NOTICE,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("compression access method \"%s\" does not exist",
+ *newval)));
+ }
+ else
+ {
+ GUC_check_errdetail("Compression access method \"%s\" does not exist.",
+ *newval);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/*
+ * assign_default_toast_compression: GUC assign_hook for default_toast_compression
+ */
+void
+assign_default_toast_compression(const char *newval, void *extra)
+{
+ /*
+ * Invalidate setting, forcing it to be looked up as needed.
+ * This avoids trying to do database access during GUC initialization,
+ * or outside a transaction.
+ */
+ default_toast_compression = NULL;
+}
+
+
+/*
+ * GetDefaultToastCompression -- get the OID of the current toast compression
+ *
+ * This exists to hide and optimize the use of the default_toast_compression
+ * GUC variable.
+ */
+Oid
+GetDefaultToastCompression(void)
+{
+ /* use pglz as default in bootstrap mode */
+ if (IsBootstrapProcessingMode())
+ return PGLZ_COMPRESSION_AM_OID;
+
+ Assert(!IsBootstrapProcessingMode());
+
+ /*
+ * If cached value isn't valid, look up the current default value, caching
+ * the result.
+ */
+ if (!OidIsValid(default_toast_compression_oid))
+ default_toast_compression_oid =
+ get_am_type_oid(default_toast_compression, AMTYPE_COMPRESSION,
+ false);
+
+ return default_toast_compression_oid;
+}
+
+/*
+ * InitializeAccessMethods: initialize module during InitPostgres.
+ *
+ * This is called after we are up enough to be able to do catalog lookups.
+ */
+void
+InitializeAccessMethods(void)
+{
+ if (IsBootstrapProcessingMode())
+ return;
+
+ /*
+ * In normal mode, arrange for a callback on any syscache invalidation
+ * of pg_am rows.
+ */
+ CacheRegisterSyscacheCallback(AMOID,
+ AccessMethodCallback,
+ (Datum) 0);
+ /* Force cached default access method to be recomputed on next use */
+ default_toast_compression_oid = InvalidOid;
+}
+
+/*
+ * AccessMethodCallback
+ * Syscache inval callback function
+ */
+static void
+AccessMethodCallback(Datum arg, int cacheid, uint32 hashvalue)
+{
+ /* Force look up of compression oid on next use */
+ default_toast_compression_oid = false;
+}
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 811dbc3..7adeaed 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -11925,7 +11925,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
if (!IsStorageCompressible(tform->typstorage))
attTup->attcompression = InvalidOid;
else if (!OidIsValid(attTup->attcompression))
- attTup->attcompression = DefaultCompressionOid;
+ attTup->attcompression = GetDefaultToastCompression();
}
else
attTup->attcompression = InvalidOid;
@@ -17762,7 +17762,7 @@ GetAttributeCompression(Form_pg_attribute att, char *compression)
/* fallback to default compression if it's not specified */
if (compression == NULL)
- return DefaultCompressionOid;
+ return GetDefaultToastCompression();
amoid = get_compression_am_oid(compression, false);
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index e5965bc..6a02bbd 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -25,6 +25,7 @@
#include "access/session.h"
#include "access/sysattr.h"
#include "access/tableam.h"
+#include "access/amapi.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/catalog.h"
@@ -1060,6 +1061,9 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
/* set default namespace search path */
InitializeSearchPath();
+ /* set callback for changes to pg_am */
+ InitializeAccessMethods();
+
/* initialize client encoding */
InitializeClientEncoding();
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 7a770fb..5cdf305 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -30,6 +30,7 @@
#include <unistd.h>
#include "access/commit_ts.h"
+#include "access/compressamapi.h"
#include "access/gin.h"
#include "access/rmgr.h"
#include "access/tableam.h"
@@ -3916,6 +3917,17 @@ static struct config_string ConfigureNamesString[] =
},
{
+ {"default_toast_compression", PGC_USERSET, CLIENT_CONN_STATEMENT,
+ gettext_noop("Sets the default compression for new columns."),
+ NULL,
+ GUC_IS_NAME
+ },
+ &default_toast_compression,
+ DEFAULT_TOAST_COMPRESSION,
+ check_default_toast_compression, assign_default_toast_compression, NULL, NULL
+ },
+
+ {
{"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT,
gettext_noop("Sets the default tablespace to create tables and indexes in."),
gettext_noop("An empty string selects the database's default tablespace."),
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index ee06528..82af1bf 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -658,6 +658,7 @@
#temp_tablespaces = '' # a list of tablespace names, '' uses
# only default tablespace
#default_table_access_method = 'heap'
+#default_toast_compression = 'pglz' # 'pglz' or 'lz4'
#check_function_bodies = on
#default_transaction_isolation = 'read committed'
#default_transaction_read_only = off
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 46044cb..f100e36 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -15851,7 +15851,6 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
{
bool print_default;
bool print_notnull;
- bool has_non_default_compression;
/*
* Default value --- suppress if to be printed separately.
@@ -15876,9 +15875,6 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
!dopt->binary_upgrade)
continue;
- has_non_default_compression = (tbinfo->attcmnames[j] &&
- (strcmp(tbinfo->attcmnames[j], "pglz") != 0));
-
/* Format properly if not first attr */
if (actual_atts == 0)
appendPQExpBufferStr(q, " (");
@@ -15918,8 +15914,7 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
* Attribute compression
*/
if (!dopt->no_compression_methods &&
- tbinfo->attcmnames[j] && strlen(tbinfo->attcmnames[j]) &&
- (has_non_default_compression || dopt->binary_upgrade))
+ tbinfo->attcmnames[j] && strlen(tbinfo->attcmnames[j]))
{
appendPQExpBuffer(q, " COMPRESSION %s",
tbinfo->attcmnames[j]);
diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h
index d357ebb..1513caf 100644
--- a/src/include/access/amapi.h
+++ b/src/include/access/amapi.h
@@ -287,4 +287,6 @@ typedef struct IndexAmRoutine
extern IndexAmRoutine *GetIndexAmRoutine(Oid amhandler);
extern IndexAmRoutine *GetIndexAmRoutineByAmId(Oid amoid, bool noerror);
+void InitializeAccessMethods(void);
+
#endif /* AMAPI_H */
diff --git a/src/include/access/compressamapi.h b/src/include/access/compressamapi.h
index 4e4d5e1..c7e681f 100644
--- a/src/include/access/compressamapi.h
+++ b/src/include/access/compressamapi.h
@@ -17,6 +17,7 @@
#include "catalog/pg_am_d.h"
#include "nodes/nodes.h"
+#include "utils/guc.h"
/*
* Built-in compression method-id. The toast compression header will store
@@ -29,8 +30,17 @@ typedef enum CompressionId
LZ4_COMPRESSION_ID = 1
} CompressionId;
-/* Use default compression method if it is not specified. */
+/* Default compression method if not specified. */
+#define DEFAULT_TOAST_COMPRESSION "pglz"
#define DefaultCompressionOid PGLZ_COMPRESSION_AM_OID
+
+/* GUC */
+extern char *default_toast_compression;
+extern void assign_default_toast_compression(const char *newval, void *extra);
+extern bool check_default_toast_compression(char **newval, void **extra, GucSource source);
+
+extern Oid GetDefaultToastCompression(void);
+
#define IsStorageCompressible(storage) ((storage) != TYPSTORAGE_PLAIN && \
(storage) != TYPSTORAGE_EXTERNAL)
/* compression handler routines */
--
1.8.3.1